/*!
* Copyright 2010 - 2015 Pentaho Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
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() {
{
// Make sure we're registered with PentahoSystem so we can be found.
PentahoSystem.registerObject( this );
}
};
/**
* 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;
}
@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;
}
}
}