Package org.pentaho.test.platform.plugin.services.metadata

Source Code of org.pentaho.test.platform.plugin.services.metadata.SessionCachingMetadataDomainRepositoryTest

/*!
* 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 (c) 2002-2013 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.test.platform.plugin.services.metadata;

import org.pentaho.metadata.model.Domain;
import org.pentaho.metadata.model.LogicalModel;
import org.pentaho.metadata.repository.DomainAlreadyExistsException;
import org.pentaho.platform.api.engine.ICacheManager;
import org.pentaho.platform.api.engine.IPentahoObjectFactory;
import org.pentaho.platform.api.engine.IPentahoSession;
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.objfac.AggregateObjectFactory;
import org.pentaho.platform.plugin.services.metadata.SessionCachingMetadataDomainRepository;
import org.pentaho.test.platform.engine.core.BaseTest;
import org.pentaho.test.platform.engine.core.SimpleObjectFactory;

import java.io.File;
import java.util.Set;

import static org.pentaho.test.platform.plugin.services.metadata.MockSessionAwareMetadataDomainRepository.TEST_LOCALE;

public class SessionCachingMetadataDomainRepositoryTest extends BaseTest {

  private static final String SOLUTION_PATH = "test-src/metadata-solution"; //$NON-NLS-1$
  private static final String ALT_SOLUTION_PATH = "test-src/metadata-solution"; //$NON-NLS-1$
  private static final String PENTAHO_XML_PATH = "/system/pentahoObjects.spring.xml"; //$NON-NLS-1$

  private static final String CACHE_NAME = "metadata-domain-repository"; //$NON-NLS-1$

  @Override
  public String getSolutionPath() {
    File file = new File( SOLUTION_PATH + PENTAHO_XML_PATH );
    if ( file.exists() ) {
      return SOLUTION_PATH;
    } else {
      return ALT_SOLUTION_PATH;
    }
  }

  private Domain getTestDomain( String id ) {
    Domain d = new Domain();
    d.setId( id );
    return d;
  }

  public void tearDown() {
    // Clean the cache
    ICacheManager cacheManager = PentahoSystem.getCacheManager( null );
    cacheManager.clearRegionCache( CACHE_NAME );

    super.tearDown();
  }

  public void testCreate_no_delegate() throws Exception {
    try {
      new SessionCachingMetadataDomainRepository( null );
      fail( "Should not be able to create a Session Caching Repository without a base implementation (delegate)" ); //$NON-NLS-1$
    } catch ( NullPointerException ex ) {
      // expected
    }
  }

  public void testCannotCreateCache() throws Exception {
    SimpleObjectFactory factory = new SimpleObjectFactory();
    factory.defineObject( "ICacheManager", MockDisabledCacheManager.class.getName() ); //$NON-NLS-1$
    // Swap in an object factory with a cache manager that doesn't allow creating new caches

    Set<IPentahoObjectFactory> facts = ( (AggregateObjectFactory) PentahoSystem.getObjectFactory() ).getFactories();
    PentahoSystem.clearObjectFactory();
    PentahoSystem.registerObjectFactory( factory );
    try {
      try {
        new SessionCachingMetadataDomainRepository( new MockSessionAwareMetadataDomainRepository() );
        fail( "Should not be able to create a Session Caching Repository without an enabled cache" ); //$NON-NLS-1$
      } catch ( IllegalStateException ex ) {
        assertTrue( ex.getMessage().contains( "cannot be initialized" ) ); //$NON-NLS-1$
        // expected
      }
    } finally {
      // Replace the original object factory so the rest of the tests work
      PentahoSystem.clearObjectFactory();
      for ( IPentahoObjectFactory fact : facts ) {
        PentahoSystem.registerObjectFactory( fact );
      }
    }
  }

  public void testGetDomain() throws Exception {
    final String SESSION_ID = "1234-5678-90"; //$NON-NLS-1$
    final String ID = "1"; //$NON-NLS-1$
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();
    mock.storeDomain( getTestDomain( ID ), false );

    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", SESSION_ID ) ); //$NON-NLS-1$

    assertEquals( 0, mock.getInvocationCount( "getDomain" ) ); //$NON-NLS-1$
    Domain d = repo.getDomain( ID );
    assertEquals( ID, d.getId() );
    // Make sure the domain we got back has our session embedded in it (tests mock repository)
    assertEquals( SESSION_ID, d.getDescription( TEST_LOCALE ) );
    assertEquals( 1, mock.getInvocationCount( "getDomain" ) ); //$NON-NLS-1$
    // Cache should contain a domain for this session
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    d = repo.getDomain( ID );
    // Make sure cache was hit and delegate was not called
    assertEquals( 1, mock.getInvocationCount( "getDomain" ) ); //$NON-NLS-1$

    // Cache should contain a domain for this session
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );
  }

  public void testGetDomain_null_session() throws Exception {
    final String SESSION_ID = null;
    final String ID = "1"; //$NON-NLS-1$
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();
    mock.storeDomain( getTestDomain( ID ), false );

    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", SESSION_ID ) ); //$NON-NLS-1$

    Domain domain = repo.getDomain( ID );
    // Description will equal the id when no description is provided (null session)
    assertEquals( ID, domain.getDescription( TEST_LOCALE ) );
  }

  public void testGetDomain_differentSessions() throws Exception {
    final String SESSION_ID1 = "1234"; //$NON-NLS-1$
    final String SESSION_ID2 = "5678"; //$NON-NLS-1$
    final String ID = "1"; //$NON-NLS-1$
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();
    mock.storeDomain( getTestDomain( ID ), false );

    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", SESSION_ID1 ) ); //$NON-NLS-1$

    assertEquals( 0, mock.getInvocationCount( "getDomain" ) ); //$NON-NLS-1$
    Domain d = repo.getDomain( ID );
    assertEquals( ID, d.getId() );
    assertEquals( SESSION_ID1, d.getDescription( TEST_LOCALE ) );
    assertEquals( 1, mock.getInvocationCount( "getDomain" ) ); //$NON-NLS-1$
    // Cache should contain a domain for this session
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    // Get the same domain from a different session
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", SESSION_ID2 ) ); //$NON-NLS-1$

    d = repo.getDomain( ID );
    // Make sure we got a new, session-specific, domain
    assertEquals( SESSION_ID2, d.getDescription( TEST_LOCALE ) );
    // Make sure cache was missed and delegate was called
    assertEquals( 2, mock.getInvocationCount( "getDomain" ) ); //$NON-NLS-1$
    // We should now have two objects in the cache (1 domain per session)
    assertEquals( 2, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    // Domains in current session
    assertEquals( 1, repo.getDomainIds().size() );

    // Switch back to original session
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "1" ) ); //$NON-NLS-1$ //$NON-NLS-2$

    // Check for domains available for this session
    assertEquals( 1, repo.getDomainIds().size() );
  }

  /**
   * Getting the domain ids should always hit the delegate and not cache any objects
   */
  public void testGetDomainIds() throws Exception {
    final String ID = "1"; //$NON-NLS-1$
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();

    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "1234-5678-90" ) ); //$NON-NLS-1$ //$NON-NLS-2$

    Set<String> ids = repo.getDomainIds();
    assertEquals( 0, ids.size() );
    assertEquals( 1, mock.getInvocationCount( "getDomainIds" ) ); //$NON-NLS-1$

    repo.storeDomain( getTestDomain( ID ), false );
    assertEquals( 0, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    ids = repo.getDomainIds();
    assertEquals( 1, ids.size() );
    assertEquals( 2, mock.getInvocationCount( "getDomainIds" ) ); //$NON-NLS-1$
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    ids = repo.getDomainIds();
    assertEquals( 2, mock.getInvocationCount( "getDomainIds" ) ); //$NON-NLS-1$
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );
  }

  /**
   * Make sure all domain ids are returned in all sessions
   */
  public void testGetDomainIds_differentSessions() throws Exception {
    final String ID = "1"; //$NON-NLS-1$
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();

    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "1" ) ); //$NON-NLS-1$ //$NON-NLS-2$

    Set<String> ids = repo.getDomainIds();
    assertEquals( 0, ids.size() );
    assertEquals( 1, mock.getInvocationCount( "getDomainIds" ) ); //$NON-NLS-1$

    repo.storeDomain( getTestDomain( ID ), false );

    ids = repo.getDomainIds();
    assertEquals( 1, ids.size() );
    assertEquals( 2, mock.getInvocationCount( "getDomainIds" ) ); //$NON-NLS-1$

    // Switch the session
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "2" ) ); //$NON-NLS-1$ //$NON-NLS-2$

    // Make sure the domain id is returned
    ids = repo.getDomainIds();
    assertEquals( 1, ids.size() );
    assertEquals( 3, mock.getInvocationCount( "getDomainIds" ) ); //$NON-NLS-1$
  }

  public void testReloadDomains() throws Exception {
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();
    mock.setPersistedDomains( getTestDomain( "1" ) ); //$NON-NLS-1$

    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "1234-5678-90" ) ); //$NON-NLS-1$ //$NON-NLS-2$

    // Cache should be empty
    assertEquals( 0, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    assertEquals( 0, repo.getDomainIds().size() );

    repo.reloadDomains();
    assertEquals( 1, mock.getInvocationCount( "reloadDomains" ) ); //$NON-NLS-1$
    assertEquals( 1, repo.getDomainIds().size() );

    // Cache should only have the domain ids
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );
  }

  public void testFlushDomains() throws Exception {
    final String ID = "1"; //$NON-NLS-1$
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();

    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "1" ) ); //$NON-NLS-1$ //$NON-NLS-2$
    repo.storeDomain( getTestDomain( ID ), false );

    repo.getDomain( ID );
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "2" ) ); //$NON-NLS-1$ //$NON-NLS-2$
    repo.getDomain( ID );
    assertEquals( 2, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    assertEquals( 1, repo.getDomainIds().size() );

    repo.flushDomains();
    assertEquals( 1, mock.getInvocationCount( "flushDomains" ) ); //$NON-NLS-1$
    assertEquals( 0, repo.getDomainIds().size() );
    assertEquals( 0, mock.getDomainIds().size() );
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );
  }

  /**
   * Make sure removing a domain removes all cached instances of the domain
   */
  public void testRemoveDomain() throws Exception {
    final String ID1 = "1"; //$NON-NLS-1$
    final String ID2 = "2"; //$NON-NLS-1$
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();
    mock.storeDomain( getTestDomain( ID1 ), false );
    mock.storeDomain( getTestDomain( ID2 ), false );

    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "1" ) ); //$NON-NLS-1$ //$NON-NLS-2$

    Domain domainFromSession1 = repo.getDomain( ID1 );
    assertNotNull( domainFromSession1 );
    assertEquals( 1, mock.getInvocationCount( "getDomain" ) ); //$NON-NLS-1$

    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "2" ) ); //$NON-NLS-1$ //$NON-NLS-2$

    Domain domainFromSession2 = repo.getDomain( ID1 );
    assertNotNull( domainFromSession2 );
    assertEquals( 2, mock.getInvocationCount( "getDomain" ) ); //$NON-NLS-1$

    assertEquals( 2, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    repo.removeDomain( ID1 );
    assertEquals( 0, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    // Calling getDomain() now should increment the call count to the delegate
    repo.getDomain( ID2 );
    assertEquals( 3, mock.getInvocationCount( "getDomain" ) ); //$NON-NLS-1$

    // There should now only be one in the cache
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );
  }

  public void testStoreDomain() throws Exception {
    final String ID = "1"; //$NON-NLS-1$
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();

    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "1" ) ); //$NON-NLS-1$ //$NON-NLS-2$

    repo.storeDomain( getTestDomain( ID ), false );

    // No cache values when storing a domain
    assertEquals( 0, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    // Cache one domain
    repo.getDomain( ID );

    // Storing a domain under a different session should wipe out all cached domains with the same id
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "2" ) ); //$NON-NLS-1$ //$NON-NLS-2$
    try {
      repo.storeDomain( getTestDomain( ID ), false );
      fail( "Should have thrown a " + DomainAlreadyExistsException.class.getSimpleName() ); //$NON-NLS-1$
    } catch ( DomainAlreadyExistsException ex ) {
      // expected
    }
    repo.storeDomain( getTestDomain( ID ), true );
    // Storing a domain under a different session should wipe out all cached domains with the same id
    assertEquals( 0, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    assertEquals( 1, repo.getDomainIds().size() );
    repo.getDomain( ID );
    assertEquals( 2, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    // Storing a domain should only wipe out the cached domains with the same id
    repo.storeDomain( getTestDomain( "2" ), false ); //$NON-NLS-1$
    assertEquals( 2, repo.getDomainIds().size() );
    assertEquals( 2, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );
  }

  public void testRemoveModel() throws Exception {
    final String ID1 = "1"; //$NON-NLS-1$
    final String ID2 = "2"; //$NON-NLS-1$
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();

    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );
    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "1" ) ); //$NON-NLS-1$ //$NON-NLS-2$

    Domain domain = getTestDomain( ID1 );
    LogicalModel model = new LogicalModel();
    model.setId( "test" ); //$NON-NLS-1$
    domain.addLogicalModel( model );

    repo.storeDomain( domain, false );
    repo.storeDomain( getTestDomain( ID2 ), false );

    repo.getDomain( ID1 );
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );
    repo.getDomain( ID2 );
    assertEquals( 2, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "2" ) ); //$NON-NLS-1$ //$NON-NLS-2$
    repo.getDomain( ID1 );
    assertEquals( 3, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    repo.removeModel( ID1, "test" ); //$NON-NLS-1$
    // Removing a model should remove all domains with that same id, leaving others intact
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );
    assertEquals( 1, mock.getInvocationCount( "removeModel" ) ); //$NON-NLS-1$
  }

  public void testGenerateRowLevelSecurityConstraint() throws Exception {
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();
    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );

    // Only thing to do here is make sure the return value is the same; cache shouldn't do anything here
    assertEquals( mock.generateRowLevelSecurityConstraint( null ), repo.generateRowLevelSecurityConstraint( null ) );
    assertEquals( 2, mock.getInvocationCount( "generateRowLevelSecurityConstraint" ) ); //$NON-NLS-1$
  }

  public void testHasAccess() throws Exception {
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();
    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );

    // Only thing to do here is make sure the return value is the same; cache shouldn't do anything here
    assertEquals( mock.hasAccess( 0, null ), repo.hasAccess( 0, null ) );
    assertEquals( 2, mock.getInvocationCount( "hasAccess" ) ); //$NON-NLS-1$
  }

  public void testOnLogout() throws Exception {
    final String ID1 = "1"; //$NON-NLS-1$
    final String ID2 = "2"; //$NON-NLS-1$
    MockSessionAwareMetadataDomainRepository mock = new MockSessionAwareMetadataDomainRepository();

    SessionCachingMetadataDomainRepository repo = new SessionCachingMetadataDomainRepository( mock );
    repo.storeDomain( getTestDomain( ID1 ), false );
    repo.storeDomain( getTestDomain( ID2 ), false );

    PentahoSessionHolder.setSession( new StandaloneSession( "Standalone Session", "1" ) ); //$NON-NLS-1$ //$NON-NLS-2$
    repo.getDomain( ID1 );

    IPentahoSession session2 = new StandaloneSession( "Standalone Session", "2" ); //$NON-NLS-1$ //$NON-NLS-2$
    PentahoSessionHolder.setSession( session2 );
    repo.getDomain( ID2 );

    assertEquals( 2, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );

    // Logging out session 2 should only remove cached domains from session 2
    repo.onLogout( session2 );
    assertEquals( 1, PentahoSystem.getCacheManager( null ).getAllKeysFromRegionCache( CACHE_NAME ).size() );
  }
}
TOP

Related Classes of org.pentaho.test.platform.plugin.services.metadata.SessionCachingMetadataDomainRepositoryTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.