/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2016 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* 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.trans;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.pentaho.di.core.RowMetaAndData;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.plugins.PluginRegistry;
import org.pentaho.di.core.plugins.StepPluginType;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.variables.VariableSpace;
import org.pentaho.di.core.variables.Variables;
import org.pentaho.di.trans.step.StepErrorMeta;
import org.pentaho.di.trans.step.StepInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.StepMetaInterface;
import org.pentaho.di.trans.steps.dummytrans.DummyTransMeta;
import org.pentaho.di.trans.steps.injector.InjectorMeta;
/**
* We can use this factory to create transformations with a source and target step.<br>
* The source step is an Injector step.<br>
* The target step is a dummy step.<br>
* The middle step is the step specified.<br>
*
* @author Matt Casters (mcasters@pentaho.org)
*
*/
public class TransTestFactory {
public static final String INJECTOR_STEPNAME = "injector";
public static final String DUMMY_STEPNAME = "dummy";
public static final String ERROR_STEPNAME = "dummyError";
public static final String NUMBER_ERRORS_FIELD = "NumberErrors";
public static final String ERROR_DESC_FIELD = "ErrorDescription";
public static final String ERROR_FIELD_VALUE = "ErrorFieldValue";
public static final String ERROR_CODE_VALUE = "ErrorCodeValue";
static PluginRegistry registry = PluginRegistry.getInstance();
public static TransMeta generateTestTransformation( VariableSpace parent, StepMetaInterface oneMeta,
String oneStepname ) {
return generateTestTransformation( parent, oneMeta, oneStepname, null );
}
public static TransMeta generateTestTransformation( VariableSpace parent, StepMetaInterface oneMeta,
String oneStepname, RowMetaInterface injectorRowMeta ) {
TransMeta previewMeta = new TransMeta( parent );
// First the injector step...
StepMeta zero = getInjectorStepMeta( injectorRowMeta );
previewMeta.addStep( zero );
// Then the middle step to test...
//
StepMeta one = new StepMeta( registry.getPluginId( StepPluginType.class, oneMeta ), oneStepname, oneMeta );
one.setLocation( 150, 50 );
one.setDraw( true );
previewMeta.addStep( one );
// Then we add the dummy step to read the results from
StepMeta two = getReadStepMeta();
previewMeta.addStep( two );
// Add the hops between the 3 steps.
TransHopMeta zeroOne = new TransHopMeta( zero, one );
previewMeta.addTransHop( zeroOne );
TransHopMeta oneTwo = new TransHopMeta( one, two );
previewMeta.addTransHop( oneTwo );
return previewMeta;
}
public static TransMeta generateTestTransformationError( VariableSpace parent, StepMetaInterface oneMeta,
String oneStepname ) {
TransMeta previewMeta = new TransMeta( parent );
if ( parent == null ) {
parent = new Variables();
}
// First the injector step...
StepMeta zero = getInjectorStepMeta();
previewMeta.addStep( zero );
// Then the middle step to test...
//
StepMeta one = new StepMeta( registry.getPluginId( StepPluginType.class, oneMeta ), oneStepname, oneMeta );
one.setLocation( 150, 50 );
one.setDraw( true );
previewMeta.addStep( one );
// Then we add the dummy step to read the results from
StepMeta two = getReadStepMeta();
previewMeta.addStep( two );
// error handling step
StepMeta err = getReadStepMeta( ERROR_STEPNAME );
previewMeta.addStep( err );
// Add the hops between the 3 steps.
TransHopMeta zeroOne = new TransHopMeta( zero, one );
previewMeta.addTransHop( zeroOne );
TransHopMeta oneTwo = new TransHopMeta( one, two );
previewMeta.addTransHop( oneTwo );
StepErrorMeta errMeta = new StepErrorMeta( parent, one, err );
errMeta.setEnabled( true );
errMeta.setNrErrorsValuename( NUMBER_ERRORS_FIELD );
errMeta.setErrorDescriptionsValuename( ERROR_DESC_FIELD );
errMeta.setErrorFieldsValuename( ERROR_FIELD_VALUE );
errMeta.setErrorCodesValuename( ERROR_CODE_VALUE );
one.setStepErrorMeta( errMeta );
TransHopMeta oneErr = new TransHopMeta( one, err );
previewMeta.addTransHop( oneErr );
return previewMeta;
}
public static List<RowMetaAndData> executeTestTransformation( TransMeta transMeta,
String testStepname, List<RowMetaAndData> inputData ) throws KettleException {
return executeTestTransformation( transMeta, INJECTOR_STEPNAME, testStepname, DUMMY_STEPNAME, inputData );
}
public static List<RowMetaAndData> executeTestTransformation( TransMeta transMeta, String injectorStepname,
String testStepname, String dummyStepname, List<RowMetaAndData> inputData ) throws KettleException {
return executeTestTransformation( transMeta, injectorStepname, testStepname,
dummyStepname, inputData, null, null );
}
public static List<RowMetaAndData> executeTestTransformation( TransMeta transMeta, String injectorStepname,
String testStepname, String dummyStepname, List<RowMetaAndData> inputData,
VariableSpace runTimeVariables, VariableSpace runTimeParameters ) throws KettleException {
// Now execute the transformation...
Trans trans = new Trans( transMeta );
trans.initializeVariablesFrom( runTimeVariables );
if ( runTimeParameters != null ) {
for ( String param : trans.listParameters() ) {
String value = runTimeParameters.getVariable( param );
if ( value != null ) {
trans.setParameterValue( param, value );
transMeta.setParameterValue( param, value );
}
}
}
trans.prepareExecution( null );
// Capture the rows that come out of the dummy step...
//
StepInterface si = trans.getStepInterface( dummyStepname, 0 );
RowStepCollector dummyRc = new RowStepCollector();
si.addRowListener( dummyRc );
// Add a row producer...
//
RowProducer rp = trans.addRowProducer( injectorStepname, 0 );
// Start the steps...
//
trans.startThreads();
// Inject the actual test rows...
//
List<RowMetaAndData> inputList = inputData;
Iterator<RowMetaAndData> it = inputList.iterator();
while ( it.hasNext() ) {
RowMetaAndData rm = it.next();
rp.putRow( rm.getRowMeta(), rm.getData() );
}
rp.finished();
// Wait until the transformation is finished...
//
trans.waitUntilFinished();
// If there is an error in the result, throw an exception here...
//
if ( trans.getResult().getNrErrors() > 0 ) {
throw new KettleException( "Test transformation finished with errors. Check the log." );
}
// Return the result from the dummy step...
//
return dummyRc.getRowsRead();
}
public static Map<String, RowStepCollector> executeTestTransformationError( TransMeta transMeta, String testStepname,
List<RowMetaAndData> inputData ) throws KettleException {
return executeTestTransformationError( transMeta, INJECTOR_STEPNAME, testStepname, DUMMY_STEPNAME, ERROR_STEPNAME,
inputData );
}
public static Map<String, RowStepCollector> executeTestTransformationError( TransMeta transMeta,
String injectorStepname, String testStepname, String dummyStepname, String errorStepName,
List<RowMetaAndData> inputData ) throws KettleException {
// Now execute the transformation...
Trans trans = new Trans( transMeta );
trans.prepareExecution( null );
// Capture the rows that come out of the dummy step...
//
StepInterface si = trans.getStepInterface( dummyStepname, 0 );
RowStepCollector dummyRc = new RowStepCollector();
si.addRowListener( dummyRc );
StepInterface junit = trans.getStepInterface( testStepname, 0 );
RowStepCollector dummyJu = new RowStepCollector();
junit.addRowListener( dummyJu );
// add error handler
StepInterface er = trans.getStepInterface( errorStepName, 0 );
RowStepCollector erColl = new RowStepCollector();
er.addRowListener( erColl );
// Add a row producer...
//
RowProducer rp = trans.addRowProducer( injectorStepname, 0 );
// Start the steps...
//
trans.startThreads();
// Inject the actual test rows...
//
List<RowMetaAndData> inputList = inputData;
Iterator<RowMetaAndData> it = inputList.iterator();
while ( it.hasNext() ) {
RowMetaAndData rm = it.next();
rp.putRow( rm.getRowMeta(), rm.getData() );
}
rp.finished();
// Wait until the transformation is finished...
//
trans.waitUntilFinished();
// If there is an error in the result, throw an exception here...
//
if ( trans.getResult().getNrErrors() > 0 ) {
throw new KettleException( "Test transformation finished with errors. Check the log." );
}
// Return the result from the dummy step...
Map<String, RowStepCollector> ret = new HashMap<String, RowStepCollector>();
ret.put( dummyStepname, dummyRc );
ret.put( errorStepName, erColl );
ret.put( testStepname, dummyJu );
return ret;
}
static StepMeta getInjectorStepMeta() {
return getInjectorStepMeta( null );
}
static StepMeta getInjectorStepMeta( RowMetaInterface outputRowMeta ) {
InjectorMeta zeroMeta = new InjectorMeta();
// Sets output fields for cases when no rows are sent to the test step, but metadata is still needed
if ( outputRowMeta != null && outputRowMeta.size() > 0 ) {
String[] fieldName = new String[outputRowMeta.size()];;
int[] fieldLength = new int[outputRowMeta.size()];
int[] fieldPrecision = new int[outputRowMeta.size()];
int[] fieldType = new int[outputRowMeta.size()];
for ( int i = 0; i < outputRowMeta.size(); i++ ) {
ValueMetaInterface field = outputRowMeta.getValueMeta( i );
fieldName[i] = field.getName();
fieldLength[i] = field.getLength();
fieldPrecision[i] = field.getPrecision();
fieldType[i] = field.getType();
}
zeroMeta.setFieldname( fieldName );
zeroMeta.setLength( fieldLength );
zeroMeta.setPrecision( fieldPrecision );
zeroMeta.setType( fieldType );
}
StepMeta zero = new StepMeta( registry.getPluginId( StepPluginType.class, zeroMeta ), INJECTOR_STEPNAME, zeroMeta );
zero.setLocation( 50, 50 );
zero.setDraw( true );
return zero;
}
static StepMeta getReadStepMeta( String name ) {
DummyTransMeta twoMeta = new DummyTransMeta();
StepMeta two = new StepMeta( registry.getPluginId( StepPluginType.class, twoMeta ), name, twoMeta );
two.setLocation( 250, 50 );
two.setDraw( true );
return two;
}
static StepMeta getReadStepMeta() {
return getReadStepMeta( DUMMY_STEPNAME );
}
}