Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[BISERVER-12904] Adding new IRepositoryFactory interface and implemen…
…tations for obtaining PDI Repository instances. Implementation utilizing ICacheManager put in place to prevent new Repository instances from being created for every call. Converted PDIImportUtil to use these new classes.
- Loading branch information
1 parent
7f7a0cf
commit 1f167c1
Showing
5 changed files
with
301 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
168 changes: 168 additions & 0 deletions
168
plugins/pdi-pur-plugin/src/org/pentaho/di/repository/utils/IRepositoryFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
package org.pentaho.di.repository.utils; | ||
|
||
import org.pentaho.di.core.exception.KettleException; | ||
import org.pentaho.di.core.plugins.PluginRegistry; | ||
import org.pentaho.di.core.plugins.RepositoryPluginType; | ||
import org.pentaho.di.repository.RepositoriesMeta; | ||
import org.pentaho.di.repository.Repository; | ||
import org.pentaho.di.repository.RepositoryMeta; | ||
import org.pentaho.platform.api.engine.ICacheManager; | ||
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.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.io.ByteArrayInputStream; | ||
|
||
/** | ||
* Implementations can be used to obtain a PDI Repository instance in the platform. Created by nbaker on 11/5/15. | ||
*/ | ||
public interface IRepositoryFactory { | ||
|
||
String SINGLE_DI_SERVER_INSTANCE = "singleDiServerInstance"; | ||
|
||
Repository connect( String repositoryName ) throws KettleException; | ||
|
||
IRepositoryFactory DEFAULT = new CachingRepositoryFactory(); | ||
|
||
/** | ||
* Sets the "ID" of the Repository Plugin Type to use (filebased, db, enterprise) | ||
* | ||
* @param id | ||
*/ | ||
void setRepositoryId( String id ); | ||
|
||
|
||
/** | ||
* Decorating implementation which caches Repository instances by Principal name in the ICacheManager. | ||
* DefaultRepositoryFactory used by default if a delegate factory isn't supplied. | ||
*/ | ||
class CachingRepositoryFactory implements IRepositoryFactory { | ||
|
||
public static final String REGION = "pdi-repository-cache"; | ||
private IRepositoryFactory delegate; | ||
private Logger logger = LoggerFactory.getLogger( getClass() ); | ||
|
||
public CachingRepositoryFactory() { | ||
this( new DefaultRepositoryFactory() ); | ||
} | ||
|
||
public CachingRepositoryFactory( IRepositoryFactory delegate ) { | ||
this.delegate = delegate; | ||
// Make sure we're registered with PentahoSystem so we can be found. | ||
PentahoSystem.registerObject( this ); | ||
} | ||
|
||
@Override public void setRepositoryId( String id ) { | ||
delegate.setRepositoryId( id ); | ||
} | ||
|
||
@Override public Repository connect( String repositoryName ) throws KettleException { | ||
|
||
IPentahoSession session = PentahoSessionHolder.getSession(); | ||
if ( session == null ) { | ||
logger.debug( "No active Pentaho Session, attempting to load PDI repository unauthenticated." ); | ||
throw new KettleException( "Attempting to create PDI Repository with no Active PentahoSession. " | ||
+ "This is not allowed." ); | ||
} | ||
ICacheManager cacheManager = PentahoSystem.getCacheManager( session ); | ||
|
||
|
||
String sessionName = session.getName(); | ||
Repository repository = (Repository) cacheManager.getFromRegionCache( REGION, sessionName ); | ||
if ( repository == null ) { | ||
logger.debug( "Repository not cached for user: " + sessionName + ". Creating new Repository." ); | ||
repository = delegate.connect( repositoryName ); | ||
if ( !cacheManager.cacheEnabled( REGION ) ) { | ||
cacheManager.addCacheRegion( REGION ); | ||
} | ||
cacheManager.putInRegionCache( REGION, sessionName, repository ); | ||
} else { | ||
logger.debug( "Repository was cached for user: " + sessionName ); | ||
} | ||
return repository; | ||
} | ||
} | ||
|
||
/** | ||
* Default implementation of the RepositoryFactory. Code moved from PDIImportUtil here pretty much as-is. | ||
*/ | ||
class DefaultRepositoryFactory implements IRepositoryFactory { | ||
private String repositoryId = "PentahoEnterpriseRepository"; | ||
|
||
@Override public void setRepositoryId( String id ) { | ||
this.repositoryId = id; | ||
} | ||
|
||
@Override public Repository connect( String repositoryName ) throws KettleException { | ||
|
||
RepositoriesMeta repositoriesMeta = new RepositoriesMeta(); | ||
boolean singleDiServerInstance = | ||
"true".equals( | ||
PentahoSystem.getSystemSetting( SINGLE_DI_SERVER_INSTANCE, "true" ) ); //$NON-NLS-1$ //$NON-NLS-2$ | ||
|
||
try { | ||
if ( singleDiServerInstance ) { | ||
|
||
// only load a default enterprise repository. If this option is set, then you cannot load | ||
// transformations or jobs from anywhere but the local server. | ||
|
||
String repositoriesXml = | ||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><repositories>" //$NON-NLS-1$ | ||
+ "<repository><id>" + repositoryId + "</id>" //$NON-NLS-1$ | ||
+ "<name>" + SINGLE_DI_SERVER_INSTANCE + "</name>" //$NON-NLS-1$ //$NON-NLS-2$ | ||
+ "<description>" + SINGLE_DI_SERVER_INSTANCE + "</description>" //$NON-NLS-1$ //$NON-NLS-2$ | ||
+ "<repository_location_url>" + PentahoSystem.getApplicationContext().getFullyQualifiedServerURL() | ||
+ "</repository_location_url>" //$NON-NLS-1$ //$NON-NLS-2$ | ||
+ "<version_comment_mandatory>N</version_comment_mandatory>" //$NON-NLS-1$ | ||
+ "</repository>" //$NON-NLS-1$ | ||
+ "</repositories>"; //$NON-NLS-1$ | ||
|
||
ByteArrayInputStream sbis = new ByteArrayInputStream( repositoriesXml.getBytes( "UTF8" ) ); | ||
repositoriesMeta.readDataFromInputStream( sbis ); | ||
} else { | ||
// TODO: add support for specified repositories.xml files... | ||
repositoriesMeta.readData(); // Read from the default $HOME/.kettle/repositories.xml file. | ||
} | ||
} catch ( Exception e ) { | ||
throw new KettleException( "Meta repository not populated", e ); //$NON-NLS-1$ | ||
} | ||
|
||
// Find the specified repository. | ||
RepositoryMeta repositoryMeta = null; | ||
try { | ||
if ( singleDiServerInstance ) { | ||
repositoryMeta = repositoriesMeta.findRepository( SINGLE_DI_SERVER_INSTANCE ); | ||
} else { | ||
repositoryMeta = repositoriesMeta.findRepository( repositoryName ); | ||
} | ||
|
||
} catch ( Exception e ) { | ||
throw new KettleException( "Repository not found", e ); //$NON-NLS-1$ | ||
} | ||
|
||
if ( repositoryMeta == null ) { | ||
throw new KettleException( "RepositoryMeta is null" ); //$NON-NLS-1$ | ||
} | ||
|
||
Repository repository = null; | ||
try { | ||
repository = | ||
PluginRegistry.getInstance().loadClass( RepositoryPluginType.class, | ||
repositoryMeta.getId(), Repository.class ); | ||
repository.init( repositoryMeta ); | ||
|
||
} catch ( Exception e ) { | ||
throw new KettleException( "Could not get repository instance", e ); //$NON-NLS-1$ | ||
} | ||
|
||
// Two scenarios here: internal to server or external to server. If internal, you are already authenticated. If | ||
// external, you must provide a username and additionally specify that the IP address of the machine running this | ||
// code is trusted. | ||
repository.connect( PentahoSessionHolder.getSession().getName(), "password" ); | ||
|
||
return repository; | ||
} | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
plugins/pdi-pur-plugin/test/com/pentaho/repository/importexport/PDIImportUtilTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.pentaho.repository.importexport; | ||
|
||
import org.junit.Test; | ||
import org.pentaho.di.repository.utils.IRepositoryFactory; | ||
|
||
import static org.junit.Assert.*; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.times; | ||
import static org.mockito.Mockito.verify; | ||
|
||
/** | ||
* Created by nbaker on 11/5/15. | ||
*/ | ||
public class PDIImportUtilTest { | ||
|
||
@Test | ||
public void testConnectToRepository() throws Exception { | ||
IRepositoryFactory mock = mock( IRepositoryFactory.class ); | ||
PDIImportUtil.setRepositoryFactory( mock ); | ||
|
||
PDIImportUtil.connectToRepository( "foo" ); | ||
|
||
verify( mock, times(1) ).connect( "foo" ); | ||
} | ||
} |
Oops, something went wrong.