/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright 2008 - 2009 Pentaho Corporation. All rights reserved.
*/
package org.pentaho.pac.server;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.pac.client.PacService;
import org.pentaho.pac.client.utils.ExceptionParser;
import org.pentaho.pac.common.HibernateConfigException;
import org.pentaho.pac.common.PacServiceException;
import org.pentaho.pac.common.PentahoSecurityException;
import org.pentaho.pac.common.ServiceInitializationException;
import org.pentaho.pac.common.datasources.DataSourceManagementException;
import org.pentaho.pac.common.datasources.DuplicateDataSourceException;
import org.pentaho.pac.common.datasources.NonExistingDataSourceException;
import org.pentaho.pac.common.datasources.PentahoDataSource;
import org.pentaho.pac.common.roles.DuplicateRoleException;
import org.pentaho.pac.common.roles.NonExistingRoleException;
import org.pentaho.pac.common.users.DuplicateUserException;
import org.pentaho.pac.common.users.NonExistingUserException;
import org.pentaho.pac.server.biplatformproxy.xmlserializer.XActionXmlSerializer;
import org.pentaho.pac.server.biplatformproxy.xmlserializer.XmlSerializerException;
import org.pentaho.pac.server.common.AppConfigProperties;
import org.pentaho.pac.server.common.BiServerTrustedProxy;
import org.pentaho.pac.server.common.DAOException;
import org.pentaho.pac.server.common.HibernateSessionFactory;
import org.pentaho.pac.server.common.PasswordServiceFactory;
import org.pentaho.pac.server.common.ProxyException;
import org.pentaho.pac.server.common.ThreadSafeHttpClient;
import org.pentaho.pac.server.common.ThreadSafeHttpClient.HttpMethodType;
import org.pentaho.pac.server.datasources.DataSourceMgmtService;
import org.pentaho.pac.server.datasources.IDataSourceMgmtService;
import org.pentaho.pac.server.i18n.Messages;
import org.pentaho.platform.api.repository.datasource.IDatasource;
import org.pentaho.platform.api.util.IPasswordService;
import org.pentaho.platform.api.util.PasswordServiceException;
import org.pentaho.platform.engine.security.userroledao.IPentahoRole;
import org.pentaho.platform.engine.security.userroledao.IPentahoUser;
import org.pentaho.platform.engine.security.userroledao.PentahoRole;
import org.pentaho.platform.engine.security.userroledao.ws.ProxyPentahoRole;
import org.pentaho.platform.engine.security.userroledao.ws.ProxyPentahoUser;
import org.pentaho.platform.engine.security.userroledao.ws.ProxyPentahoUserRoleHelper;
import org.pentaho.platform.engine.security.userroledao.ws.UserRoleSecurityInfo;
import org.pentaho.platform.engine.security.userroledao.ws.UserToRoleAssignment;
import org.pentaho.platform.repository.datasource.Datasource;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
public class PacServiceImpl extends RemoteServiceServlet implements PacService {
// ~ Static fields/initializers ======================================================================================
private static final String PUBLISH_SERVICE_NAME = "PublishService"; //$NON-NLS-1$
private static final String SERVICE_ACTION_SERVICE_NAME = "ServiceActionService"; //$NON-NLS-1$
private static final String RESET_REPOSITORY_SERVICE_NAME = "ResetRepositoryService"; //$NON-NLS-1$
private static final Log logger = LogFactory.getLog(PacServiceImpl.class);
private static final long serialVersionUID = 420L;
private static ThreadSafeHttpClient HTTP_CLIENT = new ThreadSafeHttpClient();
private static final int DEFAULT_CHECK_PERIOD = 30000; // 30 seconds
private static BiServerTrustedProxy biServerProxy;
static {
biServerProxy = BiServerTrustedProxy.getInstance();
}
// ~ Instance fields =================================================================================================
private IUserRoleMgmtService userRoleMgmtService;
private IDataSourceMgmtService dataSourceMgmtService;
// ~ Constructors ====================================================================================================
public PacServiceImpl() {
super();
}
// ~ Methods =========================================================================================================
public Boolean isValidConfiguration() throws PacServiceException {
return AppConfigProperties.getInstance().isValidConfiguration();
}
public UserRoleSecurityInfo getUserRoleSecurityInfo() throws PacServiceException {
UserRoleSecurityInfo userRoleSecurityInfo = new UserRoleSecurityInfo();
try {
List<IPentahoUser> users = getUserRoleMgmtService().getUsers();
for (IPentahoUser user : users) {
userRoleSecurityInfo.getUsers().add(ProxyPentahoUserRoleHelper.toProxyUser(user));
Set<IPentahoRole> roles = user.getRoles();
for (IPentahoRole role : roles) {
userRoleSecurityInfo.getAssignments().add(new UserToRoleAssignment(user.getUsername(), role.getName()));
}
}
userRoleSecurityInfo.getRoles().addAll(Arrays.asList(getRoles()));
// add default roles
List<ProxyPentahoRole> defaultRoles = new ArrayList<ProxyPentahoRole>();
List<String> defaultRoleStrings = AppConfigProperties.getInstance().getDefaultRoles();
for (String defaultRoleString : defaultRoleStrings) {
defaultRoles.add(new ProxyPentahoRole(defaultRoleString));
}
userRoleSecurityInfo.getDefaultRoles().addAll(defaultRoles);
} catch (DAOException e) {
throw new PacServiceException(
Messages.getErrorString("PacService.ERROR_0033_FAILED_TO_GET_USER_NAME" ), e ); //$NON-NLS-1$
}
return userRoleSecurityInfo;
}
// ~ User/Role Methods ===============================================================================================
public boolean createUser(ProxyPentahoUser proxyUser) throws HibernateConfigException, DuplicateUserException, PentahoSecurityException,
PacServiceException {
boolean result = false;
IPentahoUser user = ProxyPentahoUserRoleHelper.syncUsers(null, proxyUser);
try {
getUserRoleMgmtService().createUser(user);
result = true;
} catch (DAOException e) {
String msg = Messages.getErrorString("PacService.ERROR_0004_USER_CREATION_FAILED", proxyUser.getName()) //$NON-NLS-1$
+ " " + e.getMessage(); //$NON-NLS-1$
throw new PacServiceException(msg, e);
}
return result;
}
public boolean deleteUsers(ProxyPentahoUser[] users) throws HibernateConfigException, NonExistingUserException, PentahoSecurityException,
PacServiceException {
boolean result = false;
IPentahoUser[] persistedUsers;
try {
persistedUsers = new IPentahoUser[users.length];
for (int i = 0; i < users.length; i++) {
persistedUsers[i] = getUserRoleMgmtService().getUser(users[i].getName());
if (null == persistedUsers[i]) {
throw new NonExistingUserException(users[i].getName());
}
}
for (int i = 0; i < persistedUsers.length; i++) {
getUserRoleMgmtService().deleteUser(persistedUsers[i]);
}
result = true;
} catch (DAOException e) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0013_USER_DELETION_FAILED_NO_USER", e.getMessage())); //$NON-NLS-1$
}
return result;
}
public ProxyPentahoUser getUser(String pUserName) throws HibernateConfigException, PacServiceException {
ProxyPentahoUser proxyPentahoUser = null;
try {
IPentahoUser user = getUserRoleMgmtService().getUser(pUserName);
if (null != user) {
proxyPentahoUser = ProxyPentahoUserRoleHelper.toProxyUser(user);
}
} catch (DAOException e) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0032_FAILED_TO_FIND_USER", pUserName), e); //$NON-NLS-1$
}
return proxyPentahoUser;
}
public ProxyPentahoUser[] getUsers() throws HibernateConfigException, PacServiceException {
ProxyPentahoUser[] proxyUsers;
try {
List<IPentahoUser> users = getUserRoleMgmtService().getUsers();
proxyUsers = new ProxyPentahoUser[users.size()];
int i = 0;
for (IPentahoUser user : users) {
proxyUsers[i++] = ProxyPentahoUserRoleHelper.toProxyUser(user);
}
} catch (DAOException e) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0033_FAILED_TO_GET_USER_NAME"), e); //$NON-NLS-1$
}
return proxyUsers;
}
public ProxyPentahoUser[] getUsers(ProxyPentahoRole proxyRole) throws HibernateConfigException, NonExistingRoleException, PacServiceException {
ArrayList<ProxyPentahoUser> users = new ArrayList<ProxyPentahoUser>();
try {
IPentahoRole role = getUserRoleMgmtService().getRole(proxyRole.getName());
if (null != role) {
for (IPentahoUser user : role.getUsers()) {
users.add(ProxyPentahoUserRoleHelper.toProxyUser(user));
}
} else {
throw new NonExistingRoleException(proxyRole.getName());
}
} catch (DAOException e) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0032_FAILED_TO_FIND_USER", proxyRole.getName()), e); //$NON-NLS-1$
}
return users.toArray(new ProxyPentahoUser[0]);
}
public boolean updateUser(ProxyPentahoUser proxyUser) throws HibernateConfigException, NonExistingUserException, PentahoSecurityException,
PacServiceException {
boolean result = false;
try {
IPentahoUser user = getUserRoleMgmtService().getUser(proxyUser.getName());
if (null == user) {
throw new NonExistingUserException(proxyUser.getName());
}
getUserRoleMgmtService().updateUser(ProxyPentahoUserRoleHelper.syncUsers(user, proxyUser));
result = true;
} catch (DAOException e) {
String msg = Messages.getErrorString("PacService.ERROR_0038_USER_UPDATE_FAILED", proxyUser.getName()) //$NON-NLS-1$
+ " " + e.getMessage(); //$NON-NLS-1$
throw new PacServiceException(msg, e);
}
return result;
}
public void setRoles(ProxyPentahoUser proxyUser, ProxyPentahoRole[] assignedRoles) throws HibernateConfigException, NonExistingRoleException, NonExistingUserException, PentahoSecurityException, PacServiceException{
try {
IPentahoUser user = getUserRoleMgmtService().getUser( proxyUser.getName() );
if ( null == user )
{
throw new NonExistingUserException(proxyUser.getName());
}
Set<IPentahoRole> rolesToSet = new HashSet<IPentahoRole>();
for (ProxyPentahoRole proxyRole : assignedRoles) {
rolesToSet.add(ProxyPentahoUserRoleHelper.syncRoles(null, proxyRole));
}
user.setRoles(rolesToSet);
getUserRoleMgmtService().updateUser(user);
} catch (DAOException e) {
rollbackTransaction();
throw new PacServiceException(
Messages.getErrorString("PacService.ERROR_0034_ROLE_UPDATE_FAILED", proxyUser.getName() ), e ); //$NON-NLS-1$
}
}
public void setUsers( ProxyPentahoRole proxyRole, ProxyPentahoUser[] assignedUsers ) throws HibernateConfigException, NonExistingRoleException, NonExistingUserException, PentahoSecurityException, PacServiceException
{
try {
IPentahoRole role = getUserRoleMgmtService().getRole( proxyRole.getName() );
if ( null == role )
{
throw new NonExistingRoleException(proxyRole.getName());
}
Set<IPentahoUser> usersToSet = new HashSet<IPentahoUser>();
for (ProxyPentahoUser proxyUser : assignedUsers) {
usersToSet.add(ProxyPentahoUserRoleHelper.syncUsers(null, proxyUser));
}
role.setUsers(usersToSet);
getUserRoleMgmtService().updateRole(role);
} catch (DAOException e) {
rollbackTransaction();
throw new PacServiceException(
Messages.getErrorString("PacService.ERROR_0034_ROLE_UPDATE_FAILED", proxyRole.getName() ), e ); //$NON-NLS-1$
}
}
public void updateRole(String roleName, String description, List<String> usernames) throws HibernateConfigException, NonExistingRoleException,
NonExistingUserException, PentahoSecurityException, PacServiceException {
try {
IPentahoRole role = getUserRoleMgmtService().getRole(roleName);
if (null == role) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0034_ROLE_UPDATE_FAILED", roleName)); //$NON-NLS-1$
}
Set<IPentahoUser> users = new HashSet<IPentahoUser>();
for (String username : usernames) {
IPentahoUser user = getUserRoleMgmtService().getUser(username);
if (null == user) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0034_ROLE_UPDATE_FAILED", roleName)); //$NON-NLS-1$
}
users.add(user);
}
role.setDescription(description);
role.setUsers(users);
getUserRoleMgmtService().updateRole(role);
} catch (DAOException e) {
rollbackTransaction();
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0034_ROLE_UPDATE_FAILED", roleName), e); //$NON-NLS-1$
}
}
public boolean createRole(ProxyPentahoRole proxyRole) throws HibernateConfigException, DuplicateRoleException, PentahoSecurityException, PacServiceException {
boolean result = false;
IPentahoRole role = new PentahoRole(proxyRole.getName());
try {
getUserRoleMgmtService().createRole(ProxyPentahoUserRoleHelper.syncRoles(role, proxyRole));
result = true;
} catch ( DAOException e) {
throw new PacServiceException(e);
}
return result;
}
public boolean deleteRoles(ProxyPentahoRole[] roles) throws HibernateConfigException, NonExistingRoleException, PentahoSecurityException, PacServiceException {
boolean result = false;
IPentahoRole[] persistedRoles;
try {
persistedRoles = new IPentahoRole[roles.length];
for (int i = 0; i < roles.length; i++) {
persistedRoles[i] = getUserRoleMgmtService().getRole(roles[i].getName());
if ( null == persistedRoles[i] )
{
throw new PacServiceException(
Messages.getErrorString("PacService.ERROR_0010_ROLE_DELETION_FAILED_NO_ROLE", roles[i].getName() ) ); //$NON-NLS-1$
}
}
for (int i = 0; i < persistedRoles.length; i++) {
getUserRoleMgmtService().deleteRole( persistedRoles[i] );
}
result = true;
} catch (DAOException e) {
throw new PacServiceException(
Messages.getErrorString("PacService.ERROR_0011_ROLE_DELETION_FAILED", e.getMessage())); //$NON-NLS-1$
}
return result;
}
public ProxyPentahoRole[] getRoles(ProxyPentahoUser proxyUser) throws HibernateConfigException, NonExistingUserException, PacServiceException {
List<ProxyPentahoRole> proxyRoles = new ArrayList<ProxyPentahoRole>();
try {
IPentahoUser user = getUserRoleMgmtService().getUser( proxyUser.getName());
if ( null != user )
{
for (IPentahoRole role : user.getRoles()) {
proxyRoles.add(ProxyPentahoUserRoleHelper.toProxyRole(role));
}
} else {
throw new NonExistingUserException(proxyUser.getName());
}
} catch (DAOException e) {
throw new PacServiceException(
Messages.getErrorString("PacService.ERROR_0032_FAILED_TO_FIND_USER", proxyUser.getName() ), e ); //$NON-NLS-1$
}
return proxyRoles.toArray(new ProxyPentahoRole[0]);
}
public ProxyPentahoRole[] getRoles() throws HibernateConfigException, PacServiceException {
List<ProxyPentahoRole> proxyRoles = new ArrayList<ProxyPentahoRole>();
try {
List<IPentahoRole> roles = getUserRoleMgmtService().getRoles();
for (IPentahoRole role : roles) {
proxyRoles.add(ProxyPentahoUserRoleHelper.toProxyRole(role));
}
} catch (DAOException e) {
throw new PacServiceException(
Messages.getErrorString("PacService.ERROR_0031_FAILED_TO_GET_ROLE_NAME" ), e ); //$NON-NLS-1$
}
return proxyRoles.toArray(new ProxyPentahoRole[0]);
}
public boolean updateRole(ProxyPentahoRole proxyPentahoRole) throws HibernateConfigException, PacServiceException {
boolean result = false;
try {
IPentahoRole role = getUserRoleMgmtService().getRole(proxyPentahoRole.getName());
if ( null == role )
{
throw new PacServiceException(
Messages.getErrorString("PacService.ERROR_0036_ROLE_UPDATE_FAILED_DOES_NOT_EXIST", proxyPentahoRole.getName()) ); //$NON-NLS-1$
}
getUserRoleMgmtService().updateRole(ProxyPentahoUserRoleHelper.syncRoles(role, proxyPentahoRole));
result = true;
} catch (DAOException e) {
throw new PacServiceException(
Messages.getErrorString("PacService.ERROR_0034_ROLE_UPDATE_FAILED", proxyPentahoRole.getName() ), e ); //$NON-NLS-1$
} catch (PentahoSecurityException e) {
throw new PacServiceException(
Messages.getErrorString("PacService.ERROR_0035_ROLE_UPDATE_FAILED_NO_PERMISSION", proxyPentahoRole.getName() ), e ); //$NON-NLS-1$
} catch (NonExistingRoleException e) {
throw new PacServiceException(
Messages.getErrorString("PacService.ERROR_0037_ROLE_UPDATE_FAILED_USER_DOES_NOT_EXIST", proxyPentahoRole.getName(), /*role name*/e.getMessage() ), e ); //$NON-NLS-1$
}
return result;
}
public boolean createDataSource(PentahoDataSource dataSource) throws PacServiceException, HibernateConfigException {
boolean result = false;
try {
getDataSourceMgmtService().beginTransaction();
// Get the password service
IPasswordService passwordService = PasswordServiceFactory.getPasswordService();
// Store the new encrypted password in the datasource object
String encryptedPassword = passwordService.encrypt(dataSource.getPassword());
dataSource.setPassword(encryptedPassword);
getDataSourceMgmtService().createDataSource(toDatasource(dataSource));
getDataSourceMgmtService().commitTransaction();
result = true;
} catch(PasswordServiceException pse) {
throw new PacServiceException( pse.getMessage(), pse );
} catch (DuplicateDataSourceException dde) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0009_DATASOURCE_ALREADY_EXIST", dataSource.getName()), dde); //$NON-NLS-1$
} catch (DAOException e) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0007_DATASOURCE_CREATION_FAILED", dataSource.getName()), e); //$NON-NLS-1$
} catch (PentahoSecurityException pse) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0008_NO_CREATE_DATASOURCE_PERMISSION", dataSource.getName()), pse); //$NON-NLS-1$
} finally {
if (!result) {
rollbackTransaction();
}
getDataSourceMgmtService().closeSession();
}
return result;
}
public boolean deleteDataSources(PentahoDataSource[] dataSources) throws HibernateConfigException, PacServiceException {
boolean result = false;
IDatasource persistedDatasource = null;
try {
getDataSourceMgmtService().beginTransaction();
for (int i = 0; i < dataSources.length; i++) {
persistedDatasource = getDataSourceMgmtService().getDataSource(dataSources[i].getName());
getDataSourceMgmtService().deleteDataSource(persistedDatasource);
}
result = true;
getDataSourceMgmtService().commitTransaction();
} catch (NonExistingDataSourceException neds) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0016_DATASOURCE_DELETION_FAILED_NO_DATASOURCE", persistedDatasource.getName(),neds.getMessage()), neds); //$NON-NLS-1$
} catch (DAOException e) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0017_DATASOURCE_DELETION_FAILED", persistedDatasource.getName()), e); //$NON-NLS-1$
} catch (PentahoSecurityException pse) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0018_DATASOURCE_DELETION_FAILED_NO_PERMISSION", persistedDatasource.getName()), pse); //$NON-NLS-1$
} finally {
if (!result) {
rollbackTransaction();
}
getDataSourceMgmtService().closeSession();
}
return result;
}
public boolean updateDataSource(PentahoDataSource dataSource) throws HibernateConfigException, PacServiceException {
boolean result = false;
try {
IDatasource ds = getDataSourceMgmtService().getDataSource(dataSource.getName());
if (null == ds) {
throw new NonExistingDataSourceException(dataSource.getName());
}
ds.setDriverClass(dataSource.getDriverClass());
if(dataSource.getIdleConn() < 0) {
ds.setIdleConn(0);
} else {
ds.setIdleConn(dataSource.getIdleConn());
}
if(dataSource.getMaxActConn() < 0) {
ds.setMaxActConn(0);
} else {
ds.setMaxActConn(dataSource.getMaxActConn());
}
IPasswordService passwordService = PasswordServiceFactory.getPasswordService();
// Store the new encrypted password in the datasource object
ds.setPassword(passwordService.encrypt(dataSource.getPassword()));
ds.setQuery(dataSource.getQuery());
ds.setUrl(dataSource.getUrl());
ds.setUserName(dataSource.getUserName());
if(dataSource.getMaxActConn() < 0) {
ds.setWait(0);
} else {
ds.setWait(dataSource.getWait());
}
getDataSourceMgmtService().beginTransaction();
getDataSourceMgmtService().updateDataSource(ds);
getDataSourceMgmtService().commitTransaction();
result = true;
} catch(PasswordServiceException pse) {
throw new PacServiceException( pse.getMessage(), pse );
} catch (NonExistingDataSourceException neds) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0021_DATASOURCE_UPDATE_FAILED_DOES_NOT_EXIST", dataSource.getName()), neds); //$NON-NLS-1$
} catch (DAOException e) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0019_DATASOURCE_UPDATE_FAILED", dataSource.getName()), e); //$NON-NLS-1$
} catch (PentahoSecurityException pse) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0020_DATASOURCE_UPDATE_FAILED_NO_PERMISSION", dataSource.getName()), pse); //$NON-NLS-1$
} finally {
if (!result) {
rollbackTransaction();
}
getDataSourceMgmtService().closeSession();
}
return result;
}
public PentahoDataSource[] getDataSources() throws HibernateConfigException, PacServiceException {
List<IDatasource> datasources;
PentahoDataSource[] pentahoDataSources;
try {
datasources = getDataSourceMgmtService().getDataSources();
pentahoDataSources = new PentahoDataSource[datasources.size()];
int i = 0;
for(IDatasource datasource: datasources) {
try {
// Get the password service
if(datasource != null) {
IPasswordService passwordService = PasswordServiceFactory.getPasswordService();
String decryptedPassword = passwordService.decrypt(datasource.getPassword());
datasource.setPassword(decryptedPassword);
pentahoDataSources[i++] = toPentahoDataSource(datasource);
}
} catch(PasswordServiceException pse) {
throw new DAOException( pse.getMessage(), pse );
}
}
} catch (DAOException e) {
// TODO need a way better error message here please, maybe include some information from the exception?
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0023_FAILED_TO_GET_DATASDOURCE", e.getLocalizedMessage()), e); //$NON-NLS-1$
} finally {
if (dataSourceMgmtService != null){
getDataSourceMgmtService().closeSession();
}
}
return pentahoDataSources;
}
/**
* NOTE: caller is responsible for closing connection
*
* @param ds
* @return
* @throws DataSourceManagementException
*/
private static Connection getDataSourceConnection(PentahoDataSource ds) throws DataSourceManagementException {
Connection conn = null;
String driverClass = ds.getDriverClass();
if (StringUtils.isEmpty(driverClass)) {
throw new DataSourceManagementException(Messages.getErrorString("PacService.ERROR_0024_CONNECTION_ATTEMPT_FAILED",driverClass)); //$NON-NLS-1$
}
Class<?> driverC = null;
try {
driverC = Class.forName(driverClass);
} catch (ClassNotFoundException e) {
throw new DataSourceManagementException(Messages.getErrorString("PacService.ERROR_0026_DRIVER_NOT_FOUND_IN_CLASSPATH",driverClass), e); //$NON-NLS-1$
}
if (!Driver.class.isAssignableFrom(driverC)) {
throw new DataSourceManagementException(Messages.getErrorString("PacService.ERROR_0026_DRIVER_NOT_FOUND_IN_CLASSPATH",driverClass)); //$NON-NLS-1$ }
}
Driver driver = null;
try {
driver = driverC.asSubclass(Driver.class).newInstance();
} catch (InstantiationException e) {
throw new DataSourceManagementException(Messages.getErrorString("PacService.ERROR_0027_UNABLE_TO_INSTANCE_DRIVER",driverClass), e); //$NON-NLS-1$
} catch (IllegalAccessException e) {
throw new DataSourceManagementException(Messages.getErrorString("PacService.ERROR_0027_UNABLE_TO_INSTANCE_DRIVER",driverClass), e); //$NON-NLS-1$ }
}
try {
DriverManager.registerDriver(driver);
conn = DriverManager.getConnection(ds.getUrl(), ds.getUserName(), ds.getPassword());
return conn;
} catch (SQLException e) {
throw new DataSourceManagementException(Messages.getErrorString("PacService.ERROR_0025_UNABLE_TO_CONNECT",e.getMessage()), e); //$NON-NLS-1$
}
}
public boolean testDataSourceConnection(PentahoDataSource ds) throws PacServiceException {
Connection conn = null;
try {
conn = getDataSourceConnection(ds);
} catch (DataSourceManagementException dme) {
throw new PacServiceException(dme.getMessage(), dme);
} finally {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
throw new PacServiceException(e);
}
}
return true;
}
public boolean testDataSourceValidationQuery(PentahoDataSource ds) throws PacServiceException {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = getDataSourceConnection(ds);
if (!StringUtils.isEmpty(ds.getQuery())) {
stmt = conn.createStatement();
rs = stmt.executeQuery(ds.getQuery());
} else {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0028_QUERY_NOT_VALID")); //$NON-NLS-1$
}
} catch (DataSourceManagementException dme) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0029_QUERY_VALIDATION_FAILED", dme.getLocalizedMessage()), dme); //$NON-NLS-1$
} catch (SQLException e) {
throw new PacServiceException(Messages.getErrorString("PacService.ERROR_0029_QUERY_VALIDATION_FAILED",e.getLocalizedMessage()), e); //$NON-NLS-1$
} finally {
try {
closeAll(conn, stmt, rs, true);
} catch (SQLException e) {
throw new PacServiceException(e);
}
}
return true;
}
private void rollbackTransaction()
{
try {
getDataSourceMgmtService().rollbackTransaction();
} catch (Exception e) {
logger.error( Messages.getErrorString( "PacService.ERROR_0048_ROLLBACK_FAILED" ) ); //$NON-NLS-1$
}
}
public String refreshSolutionRepository() throws PacServiceException {
return executePublishRequest("org.pentaho.platform.engine.services.solution.SolutionPublisher" ); //$NON-NLS-1$
}
public String cleanRepository() throws PacServiceException {
return executeXAction("admin", "", "clean_repository.xaction" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public String clearMondrianSchemaCache() throws PacServiceException {
return executeXAction("admin", "", "clear_mondrian_schema_cache.xaction" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public String scheduleRepositoryCleaning() throws PacServiceException {
return executeXAction("admin", "", "schedule-clean.xaction" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public String resetRepository() throws PacServiceException {
return resetSolutionRepository(getUserName() );
}
public String refreshSystemSettings() throws PacServiceException {
return executePublishRequest("org.pentaho.platform.engine.core.system.SettingsPublisher" ); //$NON-NLS-1$
}
public String executeGlobalActions() throws PacServiceException {
return executePublishRequest("org.pentaho.platform.engine.core.system.GlobalListsPublisher" ); //$NON-NLS-1$
}
public String refreshReportingMetadata() throws PacServiceException {
return executePublishRequest("org.pentaho.platform.engine.services.metadata.MetadataPublisher" ); //$NON-NLS-1$
}
public String getUserName() {
return StringUtils.defaultIfEmpty( AppConfigProperties.getInstance().getPlatformUsername(), System.getProperty(AppConfigProperties.KEY_PLATFORM_USERNAME) );
}
public String getPciContextPath() throws PacServiceException{
return StringUtils.defaultIfEmpty( AppConfigProperties.getInstance().getBiServerContextPath(), System.getProperty(AppConfigProperties.KEY_BISERVER_CONTEXT_PATH) );
}
public String getBIServerBaseUrl() {
return StringUtils.defaultIfEmpty( AppConfigProperties.getInstance().getBiServerBaseUrl(), System.getProperty(AppConfigProperties.KEY_BISERVER_BASE_URL) );
}
private String executeXAction(String solution, String path, String xAction ) throws PacServiceException{
Map<String,Object> params = new HashMap<String,Object>();
params.put( "solution", solution ); //$NON-NLS-1$
params.put( "path", path ); //$NON-NLS-1$
params.put( "action", xAction ); //$NON-NLS-1$
String strResponse;
try {
strResponse = biServerProxy.execRemoteMethod(getBIServerBaseUrl(), SERVICE_ACTION_SERVICE_NAME, HttpMethodType.GET, getUserName(), params );
} catch (ProxyException e) {
throw new PacServiceException( ExceptionParser.getErrorMessage(e.getMessage(), e.getMessage()), e );
}
XActionXmlSerializer s = new XActionXmlSerializer();
String errorMsg;
try {
errorMsg = s.getXActionResponseStatusFromXml( strResponse );
} catch (XmlSerializerException e) {
throw new PacServiceException( e.getMessage(), e );
}
if ( null != errorMsg ) {
throw new PacServiceException( errorMsg );
}
return Messages.getString( "PacService.ACTION_COMPLETE" ); //$NON-NLS-1$
}
private String executePublishRequest(String publisherClassName ) throws PacServiceException {
Map<String,Object> params = new HashMap<String,Object>();
params.put( "publish", "now" ); //$NON-NLS-1$ //$NON-NLS-2$
params.put( "style", "popup" ); //$NON-NLS-1$ //$NON-NLS-2$
params.put( "class", publisherClassName ); //$NON-NLS-1$
String strResponse;
try {
strResponse = biServerProxy.execRemoteMethod(getBIServerBaseUrl(), PUBLISH_SERVICE_NAME, HttpMethodType.GET, getUserName(), params );
} catch (ProxyException e) {
throw new PacServiceException( ExceptionParser.getErrorMessage(e.getMessage(), e.getMessage()), e );
}
XActionXmlSerializer s = new XActionXmlSerializer();
String errorMsg = s.getPublishStatusFromXml( strResponse );
if ( null != errorMsg ) {
throw new PacServiceException( errorMsg );
}
return Messages.getString( "PacService.ACTION_COMPLETE" );//$NON-NLS-1$
}
private String resetSolutionRepository(String userid ) throws PacServiceException {
try {
biServerProxy.execRemoteMethod(getBIServerBaseUrl(), RESET_REPOSITORY_SERVICE_NAME, HttpMethodType.GET, getUserName(), /*params*/null );
} catch (ProxyException e) {
throw new PacServiceException( ExceptionParser.getErrorMessage(e.getMessage(), e.getMessage()), e );
}
return Messages.getString( "PacService.ACTION_COMPLETE" ); //$NON-NLS-1$
}
public String getHomepageUrl() {
return AppConfigProperties.getInstance().getHomepageUrl();
}
public String getHomePageAsHtml(String url) {
String html = null;
HttpClient client = new HttpClient();
GetMethod get = null;
try {
String timeOut = AppConfigProperties.getInstance().getHomepageTimeout();
HttpMethodParams params = new HttpMethodParams();
params.setParameter(HttpMethodParams.SO_TIMEOUT, Integer.parseInt(timeOut));
get = new GetMethod(url);
get.setParams(params);
client.executeMethod(get);
//getResponseBodyAsString() and the like were decoding as ISO-8859-1 instead of UTF-8.
//This is indeed the default behavior of HttpClient if the charset is not defined in
//the Content-Type reponse header. We're overriding that since we know our source is
//UTF-8
byte[] bytes = get.getResponseBody();
html = new String(bytes, "UTF-8"); //$NON-NLS-1$
} catch (Exception e) {
logger.error(e);
html = showStatic();
} finally {
if(get != null) {
get.releaseConnection();
}
}
final String BODY_TAG = "<body>"; //$NON-NLS-1$
int afterBodyIdx = html.indexOf(BODY_TAG);
if ( -1 != afterBodyIdx ) {
html = html.substring( html.indexOf(BODY_TAG) + BODY_TAG.length() );
html = html.substring(0, html.indexOf("</body>")); //$NON-NLS-1$
}
return html;
}
private String showStatic(){
String templateFileName = "defaultHome.ftl"; //$NON-NLS-1$
InputStream flatFile = getClass().getResourceAsStream( templateFileName );
try {
return IOUtils.toString(flatFile);
} catch (IOException e) {
String msg = Messages.getErrorString( "PacService.ERROR_0047_IO_ERROR", templateFileName ); //$NON-NLS-1$
logger.error( msg,e);
return "<span>" + msg + "</span>"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void isBiServerAlive() throws PacServiceException {
try {
HTTP_CLIENT.execRemoteMethod(getBIServerBaseUrl(), "ping/alive.gif", HttpMethodType.GET, null );//$NON-NLS-1$
} catch (Exception e) {
throw new PacServiceException( e.getMessage(), e );
}
}
public int getBiServerStatusCheckPeriod() {
String strBiServerStatusCheckPeriod = StringUtils.defaultIfEmpty( AppConfigProperties.getInstance().getBiServerStatusCheckPeriod(), System.getProperty(AppConfigProperties.KEY_BISERVER_STATUS_CHECK_PERIOD) );
try {
if(strBiServerStatusCheckPeriod != null && strBiServerStatusCheckPeriod.length() > 0) {
return Integer.parseInt( strBiServerStatusCheckPeriod );
} else {
return DEFAULT_CHECK_PERIOD;
}
} catch( NumberFormatException e ) {
logger.error( Messages.getErrorString( "PacService.ERROR_0045_THREAD_SCHEDULING_FAILED" ), e ); //$NON-NLS-1$
return DEFAULT_CHECK_PERIOD;
}
}
public void initialze() throws ServiceInitializationException {
}
private IUserRoleMgmtService getUserRoleMgmtService() throws HibernateConfigException {
if (userRoleMgmtService == null) {
synchronized (this) {
if (userRoleMgmtService == null) {
refreshHibernateConfig();
}
}
}
return userRoleMgmtService;
}
private IDataSourceMgmtService getDataSourceMgmtService() throws HibernateConfigException {
if (dataSourceMgmtService == null) {
synchronized (this) {
if (dataSourceMgmtService == null) {
refreshHibernateConfig();
}
}
}
return dataSourceMgmtService;
}
public synchronized void refreshHibernateConfig() throws HibernateConfigException {
try {
HibernateSessionFactory.initDefaultConfiguration();
userRoleMgmtService = new UserRoleMgmtService();
dataSourceMgmtService = new DataSourceMgmtService();
} catch(Exception e) {
throw new HibernateConfigException(Messages.getString("PacService.ERROR_0062_UNABLE_TO_REFRESH_HIBERNATE"), e); //$NON-NLS-1$
}
}
public String getHelpUrl(){
return AppConfigProperties.getInstance().getHelpUrl();
}
//~ Datasource Support Methods ========================================================================================
protected PentahoDataSource toPentahoDataSource(IDatasource datasource) throws PacServiceException {
PentahoDataSource pentahoDataSource = new PentahoDataSource();
pentahoDataSource.setDriverClass(datasource.getDriverClass());
pentahoDataSource.setIdleConn(datasource.getIdleConn());
pentahoDataSource.setMaxActConn(datasource.getMaxActConn());
pentahoDataSource.setName(datasource.getName());
pentahoDataSource.setPassword(datasource.getPassword());
pentahoDataSource.setQuery(datasource.getQuery());
pentahoDataSource.setUrl(datasource.getUrl());
pentahoDataSource.setUserName(datasource.getUserName());
pentahoDataSource.setWait(datasource.getWait());
return pentahoDataSource;
}
protected IDatasource toDatasource(PentahoDataSource pentahoDataSource) throws PacServiceException {
IDatasource datasource = new Datasource();
datasource.setDriverClass(pentahoDataSource.getDriverClass());
datasource.setIdleConn(pentahoDataSource.getIdleConn());
datasource.setMaxActConn(pentahoDataSource.getMaxActConn());
datasource.setName(pentahoDataSource.getName());
datasource.setPassword(pentahoDataSource.getPassword());
datasource.setQuery(pentahoDataSource.getQuery());
datasource.setUrl(pentahoDataSource.getUrl());
datasource.setUserName(pentahoDataSource.getUserName());
datasource.setWait(pentahoDataSource.getWait());
return datasource;
}
private void closeAll(Connection conn, Statement stmt, ResultSet rs, boolean throwsException) throws SQLException {
SQLException rethrow = null;
if (rs != null) {
try {
rs.close();
} catch (SQLException ignored) {
rethrow = ignored;
}
rs = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException ignored) {
rethrow = ignored;
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException ignored) {
rethrow = ignored;
}
conn = null;
}
if (throwsException && rethrow != null) {
throw rethrow;
}
}
}