/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, version 2 as published by the Free Software * Foundation. * * You should have received a copy of the GNU General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.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 General Public License for more details. * * * Copyright 2006 - 2013 Pentaho Corporation. All rights reserved. */ package org.pentaho.platform.dataaccess.datasource.wizard.csv; import junit.framework.Assert; import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Test; import org.pentaho.agilebi.modeler.ModelerMessagesHolder; import org.pentaho.agilebi.modeler.models.JoinFieldModel; import org.pentaho.agilebi.modeler.models.JoinRelationshipModel; import org.pentaho.agilebi.modeler.models.JoinTableModel; import org.pentaho.agilebi.modeler.models.SchemaModel; import org.pentaho.agilebi.modeler.util.MultiTableModelerSource; import org.pentaho.agilebi.modeler.util.SpoonModelerMessages; import org.pentaho.database.model.IDatabaseConnection; import org.pentaho.di.core.KettleEnvironment; import org.pentaho.di.core.Props; import org.pentaho.di.core.database.DatabaseMeta; import org.pentaho.metadata.model.Domain; import org.pentaho.metadata.model.olap.OlapDimension; import org.pentaho.metadata.repository.IMetadataDomainRepository; import org.pentaho.platform.api.data.IDBDatasourceService; import org.pentaho.platform.api.engine.IApplicationContext; import org.pentaho.platform.api.engine.IAuthorizationPolicy; import org.pentaho.platform.api.engine.IPentahoDefinableObjectFactory.Scope; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPluginResourceLoader; import org.pentaho.platform.api.engine.ISecurityHelper; import org.pentaho.platform.api.engine.ISolutionEngine; import org.pentaho.platform.api.engine.IUserRoleListService; import org.pentaho.platform.api.mt.ITenant; import org.pentaho.platform.api.repository.IClientRepositoryPathsStrategy; import org.pentaho.platform.api.repository.datasource.DatasourceMgmtServiceException; import org.pentaho.platform.api.repository.datasource.DuplicateDatasourceException; import org.pentaho.platform.api.repository.datasource.IDatasourceMgmtService; import org.pentaho.platform.api.repository.datasource.NonExistingDatasourceException; import org.pentaho.platform.api.repository2.unified.IBackingRepositoryLifecycleManager; import org.pentaho.platform.api.repository2.unified.IUnifiedRepository; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.dataaccess.datasource.wizard.service.agile.AgileHelper; import org.pentaho.platform.dataaccess.datasource.wizard.service.impl.ModelerService; import org.pentaho.platform.engine.core.system.PentahoSessionHolder; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.core.system.StandaloneSession; import org.pentaho.platform.engine.core.system.SystemSettings; import org.pentaho.platform.engine.services.connection.datasource.dbcp.JndiDatasourceService; import org.pentaho.platform.engine.services.solution.SolutionEngine; import org.pentaho.platform.plugin.action.mondrian.catalog.IMondrianCatalogService; import org.pentaho.platform.plugin.action.mondrian.catalog.MondrianCatalogHelper; import org.pentaho.platform.plugin.action.mondrian.mapper.MondrianOneToOneUserRoleListMapper; import org.pentaho.platform.plugin.services.connections.mondrian.MDXConnection; import org.pentaho.platform.plugin.services.connections.mondrian.MDXOlap4jConnection; import org.pentaho.platform.plugin.services.connections.sql.SQLConnection; import org.pentaho.platform.plugin.services.metadata.PentahoMetadataDomainRepository; import org.pentaho.platform.plugin.services.pluginmgr.PluginClassLoader; import org.pentaho.platform.plugin.services.pluginmgr.PluginResourceLoader; import org.pentaho.platform.repository2.unified.DefaultUnifiedRepository; import org.pentaho.platform.repository2.unified.RepositoryUtils; import org.pentaho.platform.repository2.unified.fs.FileSystemBackedUnifiedRepository; import org.pentaho.test.platform.MethodTrackingData; import org.pentaho.test.platform.engine.core.MicroPlatform; import org.pentaho.test.platform.engine.security.MockSecurityHelper; import org.springframework.context.ApplicationContextAware; import org.springframework.dao.DataAccessException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import java.io.File; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** * Integration test. Tests {@link DefaultUnifiedRepository} and * {@link IAuthorizationPolicy} fully configured behind Spring Security's method * security and Spring's transaction interceptor. * * <p> * Note the RunWith annotation that uses a special runner that knows how to * setup a Spring application context. The application context config files are * listed in the ContextConfiguration annotation. By implementing * {@link ApplicationContextAware}, this unit test can access various beans * defined in the application context, including the bean under test. * </p> * * @author mlowery */ @SuppressWarnings("nls") public class SerializeMultiTableServiceIT { private String tenantAdminAuthorityNamePattern = "{0}_Admin"; private String tenantAuthenticatedAuthorityNamePattern = "{0}_Authenticated"; private static final String USER_PARAMETER = "user"; private IBackingRepositoryLifecycleManager manager; private MicroPlatform booter; @Before public void setUp() throws Exception { manager = new MockBackingRepositoryLifecycleManager(new MockSecurityHelper()); IAuthorizationPolicy mockAuthorizationPolicy = mock(IAuthorizationPolicy.class); when( mockAuthorizationPolicy.isAllowed( anyString() ) ).thenReturn( true ); IUserRoleListService mockUserRoleListService = mock(IUserRoleListService.class); System.setProperty("org.osjava.sj.root", "target/test-classes/solution1/system/simple-jndi"); //$NON-NLS-1$ //$NON-NLS-2$ booter = new MicroPlatform("target/test-classes/solution1"); booter.define(ISolutionEngine.class, SolutionEngine.class, Scope.GLOBAL); booter.define(IUnifiedRepository.class, TestFileSystemBackedUnifiedRepository.class, Scope.GLOBAL); booter.define(IMondrianCatalogService.class, MondrianCatalogHelper.class, Scope.GLOBAL); booter.define("connection-SQL", SQLConnection.class); booter.define("connection-MDX", MDXConnection.class); booter.define("connection-MDXOlap4j", MDXOlap4jConnection.class); booter.define(IDBDatasourceService.class, JndiDatasourceService.class, Scope.GLOBAL); booter.define(MDXConnection.MDX_CONNECTION_MAPPER_KEY, MondrianOneToOneUserRoleListMapper.class, Scope.GLOBAL); booter.define(IDatasourceMgmtService.class, MockDatasourceMgmtService.class); booter.define(IClientRepositoryPathsStrategy.class, MockClientRepositoryPathsStrategy.class); booter.defineInstance(IMetadataDomainRepository.class, createMetadataDomainRepository()); booter.define(ISecurityHelper.class, MockSecurityHelper.class); booter.define(UserDetailsService.class, MockUserDetailService.class); booter.define("singleTenantAdminUserName", new String("admin")); booter.defineInstance( IAuthorizationPolicy.class, mockAuthorizationPolicy ); booter.defineInstance(IPluginResourceLoader.class, new PluginResourceLoader() { protected PluginClassLoader getOverrideClassloader() { return new PluginClassLoader(new File(".", "target/test-classes/solution1/system/simple-jndi"), this); } }); booter.defineInstance(IUserRoleListService.class, mockUserRoleListService); booter.setSettingsProvider(new SystemSettings()); booter.start(); PentahoSessionHolder.setStrategyName(PentahoSessionHolder.MODE_GLOBAL); SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_GLOBAL); } @Test public void testSerialize() throws Exception { if (ModelerMessagesHolder.getMessages() == null) { ModelerMessagesHolder.setMessages(new SpoonModelerMessages()); } try { KettleEnvironment.init(); Props.init(Props.TYPE_PROPERTIES_EMPTY); } catch (Exception e) { // may already be initialized by another test } login("suzy", "", false); String solutionStorage = AgileHelper.getDatasourceSolutionStorage(); String path = solutionStorage + RepositoryFile.SEPARATOR + "resources" + RepositoryFile.SEPARATOR + "metadata" + RepositoryFile.SEPARATOR; //$NON-NLS-1$ //$NON-NLS-2$ String olapPath = null; IApplicationContext appContext = PentahoSystem.getApplicationContext(); if (appContext != null) { path = PentahoSystem.getApplicationContext().getSolutionPath(path); olapPath = PentahoSystem.getApplicationContext().getSolutionPath( "system" + RepositoryFile.SEPARATOR + "olap" + RepositoryFile.SEPARATOR); //$NON-NLS-1$ //$NON-NLS-2$ } File olap1 = new File(olapPath + "datasources.xml"); //$NON-NLS-1$ File olap2 = new File(olapPath + "tmp_datasources.xml"); //$NON-NLS-1$ FileUtils.copyFile(olap1, olap2); DatabaseMeta database = getDatabaseMeta(); MultiTableModelerSource multiTable = new MultiTableModelerSource(database, getSchema(), database.getName(), Arrays.asList("CUSTOMERS", "PRODUCTS", "CUSTOMERNAME", "PRODUCTCODE")); Domain domain = multiTable.generateDomain(); List<OlapDimension> olapDimensions = new ArrayList<OlapDimension>(); OlapDimension dimension = new OlapDimension(); dimension.setName("test");//$NON-NLS-1$ dimension.setTimeDimension(false); olapDimensions.add(dimension); domain.getLogicalModels().get(0).setProperty("olap_dimensions", olapDimensions);//$NON-NLS-1$ ModelerService service = new ModelerService(); service.serializeModels(domain, "test_file");//$NON-NLS-1$ Assert.assertEquals( ( String) domain.getLogicalModels().get(0).getProperty("MondrianCatalogRef"), "SampleData"); } private SchemaModel getSchema() { List<JoinRelationshipModel> joins = new ArrayList<JoinRelationshipModel>(); JoinTableModel joinTable1 = new JoinTableModel(); joinTable1.setName("CUSTOMERS"); JoinTableModel joinTable2 = new JoinTableModel(); joinTable2.setName("PRODUCTS"); JoinRelationshipModel join1 = new JoinRelationshipModel(); JoinFieldModel lField1 = new JoinFieldModel(); lField1.setName("CUSTOMERNAME"); lField1.setParentTable(joinTable1); join1.setLeftKeyFieldModel(lField1); JoinFieldModel rField1 = new JoinFieldModel(); rField1.setName("PRODUCTCODE"); rField1.setParentTable(joinTable2); join1.setRightKeyFieldModel(rField1); joins.add(join1); SchemaModel model = new SchemaModel(); model.setJoins(joins); return model; } private DatabaseMeta getDatabaseMeta() { DatabaseMeta database = new DatabaseMeta(); try { //database.setDatabaseInterface(new HypersonicDatabaseMeta()); database.setDatabaseType("Hypersonic");//$NON-NLS-1$ //database.setUsername("sa");//$NON-NLS-1$ //database.setPassword("");//$NON-NLS-1$ database.setAccessType(DatabaseMeta.TYPE_ACCESS_JNDI); //database.setHostname("."); database.setDBName("SampleData");//$NON-NLS-1$ //database.setDBPort("9001");//$NON-NLS-1$ database.setName("SampleData");//$NON-NLS-1$ } catch (Exception e) { e.printStackTrace(); } return database; } protected void login(final String username, final String tenantId, final boolean tenantAdmin) { StandaloneSession pentahoSession = new StandaloneSession(username); pentahoSession.setAuthenticated(username); pentahoSession.setAttribute(IPentahoSession.TENANT_ID_KEY, tenantId); final String password = "password"; List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(); authList.add(new SimpleGrantedAuthority(MessageFormat.format(tenantAuthenticatedAuthorityNamePattern, tenantId))); if (tenantAdmin) { authList.add(new SimpleGrantedAuthority(MessageFormat.format(tenantAdminAuthorityNamePattern, tenantId))); } //GrantedAuthority[] authorities = authList.toArray(new GrantedAuthority[0]); UserDetails userDetails = new User(username, password, true, true, true, true, authList); Authentication auth = new UsernamePasswordAuthenticationToken(userDetails, password, authList); PentahoSessionHolder.setSession(pentahoSession); // this line necessary for Spring Security's MethodSecurityInterceptor SecurityContextHolder.getContext().setAuthentication(auth); manager.newTenant(); manager.newUser(); } protected void logout() { PentahoSessionHolder.removeSession(); SecurityContextHolder.getContext().setAuthentication(null); } private class MockBackingRepositoryLifecycleManager implements IBackingRepositoryLifecycleManager { public static final String UNIT_TEST_EXCEPTION_MESSAGE = "Unit Test Exception"; private ArrayList<MethodTrackingData> methodTrackerHistory = new ArrayList<MethodTrackingData>(); private boolean throwException = false; private MockSecurityHelper securityHelper; private MockBackingRepositoryLifecycleManager(final MockSecurityHelper securityHelper) { assert (null != securityHelper); this.securityHelper = securityHelper; } public void startup() { methodTrackerHistory.add(new MethodTrackingData("startup") .addParameter(USER_PARAMETER, securityHelper.getCurrentUser())); if (throwException) throw new RuntimeException(UNIT_TEST_EXCEPTION_MESSAGE); } public void shutdown() { methodTrackerHistory.add(new MethodTrackingData("shutdown") .addParameter(USER_PARAMETER, securityHelper.getCurrentUser())); if (throwException) throw new RuntimeException(UNIT_TEST_EXCEPTION_MESSAGE); } public void newTenant(final ITenant tenant) { methodTrackerHistory.add(new MethodTrackingData("newTenant") .addParameter(USER_PARAMETER, securityHelper.getCurrentUser()) .addParameter("tenant", tenant)); if (throwException) throw new RuntimeException(UNIT_TEST_EXCEPTION_MESSAGE); } public void newTenant() { methodTrackerHistory.add(new MethodTrackingData("newTenant") .addParameter(USER_PARAMETER, securityHelper.getCurrentUser())); if (throwException) throw new RuntimeException(UNIT_TEST_EXCEPTION_MESSAGE); } public void newUser(final ITenant tenant, final String username) { methodTrackerHistory.add(new MethodTrackingData("newUser") .addParameter(USER_PARAMETER, securityHelper.getCurrentUser()) .addParameter("tenant", tenant) .addParameter("username", username)); if (throwException) throw new RuntimeException(UNIT_TEST_EXCEPTION_MESSAGE); } public void newUser() { methodTrackerHistory.add(new MethodTrackingData("newUser") .addParameter(USER_PARAMETER, securityHelper.getCurrentUser())); if (throwException) throw new RuntimeException(UNIT_TEST_EXCEPTION_MESSAGE); } @Override public void addMetadataToRepository(String arg0) { // TODO Auto-generated method stub } @Override public Boolean doesMetadataExists(String arg0) { // TODO Auto-generated method stub return null; } } public static class MockUserDetailService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException, DataAccessException { //GrantedAuthority[] auths = new GrantedAuthority[2]; List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(); authList.add( new SimpleGrantedAuthority("Authenticated") ); authList.add( new SimpleGrantedAuthority("Administrator") ); UserDetails user = new User(name, "password", true, true, true, true, authList); return user; } } public static class TestFileSystemBackedUnifiedRepository extends FileSystemBackedUnifiedRepository { public TestFileSystemBackedUnifiedRepository() { super("bin/test-solutions/solution"); } } public static class MockDatasourceMgmtService implements IDatasourceMgmtService{ @Override public void init(IPentahoSession arg0) { } @Override public String createDatasource(IDatabaseConnection arg0) throws DuplicateDatasourceException, DatasourceMgmtServiceException { return null; } @Override public void deleteDatasourceById(String arg0) throws NonExistingDatasourceException, DatasourceMgmtServiceException { } @Override public void deleteDatasourceByName(String arg0) throws NonExistingDatasourceException, DatasourceMgmtServiceException { } @Override public IDatabaseConnection getDatasourceById(String arg0) throws DatasourceMgmtServiceException { return null; } @Override public IDatabaseConnection getDatasourceByName(String arg0) throws DatasourceMgmtServiceException { return null; } @Override public List<String> getDatasourceIds() throws DatasourceMgmtServiceException { return null; } @Override public List<IDatabaseConnection> getDatasources() throws DatasourceMgmtServiceException { return null; } @Override public String updateDatasourceById(String arg0, IDatabaseConnection arg1) throws NonExistingDatasourceException, DatasourceMgmtServiceException { return null; } @Override public String updateDatasourceByName(String arg0, IDatabaseConnection arg1) throws NonExistingDatasourceException, DatasourceMgmtServiceException { return null; } } public static class MockClientRepositoryPathsStrategy implements IClientRepositoryPathsStrategy { @Override public String getEtcFolderName() { return null; } @Override public String getEtcFolderPath() { return null; } @Override public String getHomeFolderName() { return null; } @Override public String getHomeFolderPath() { return null; } @Override public String getPublicFolderName() { return null; } @Override public String getPublicFolderPath() { return null; } @Override public String getRootFolderPath() { return null; } @Override public String getUserHomeFolderName(String arg0) { return null; } @Override public String getUserHomeFolderPath(String arg0) { return null; } } public PentahoMetadataDomainRepository createMetadataDomainRepository() throws Exception { IUnifiedRepository repository = new FileSystemBackedUnifiedRepository("target/test-classes/solution1"); booter.defineInstance(IUnifiedRepository.class, repository); Assert.assertNotNull(new RepositoryUtils(repository).getFolder("/etc/metadata", true, true, null)); Assert.assertNotNull(new RepositoryUtils(repository).getFolder("/etc/mondrian", true, true, null)); Assert.assertNotNull(new RepositoryUtils(repository).getFolder("/savetest", true, true, null)); PentahoMetadataDomainRepository pentahoMetadataDomainRepository = new PentahoMetadataDomainRepository(repository); return pentahoMetadataDomainRepository; } }