use of org.pentaho.di.trans.step.RemoteStep in project pentaho-kettle by pentaho.
the class TransMeta method getStepFields.
/**
* Returns the fields that are emitted by a certain step.
*
* @param stepMeta
* The step to be queried.
* @param targetStep
* the target step
* @param monitor
* The progress monitor for progress dialog. (null if not used!)
* @return A row containing the fields emitted.
* @throws KettleStepException
* the kettle step exception
*/
public RowMetaInterface getStepFields(StepMeta stepMeta, StepMeta targetStep, ProgressMonitorListener monitor) throws KettleStepException {
RowMetaInterface row = new RowMeta();
if (stepMeta == null) {
return row;
}
String fromToCacheEntry = stepMeta.getName() + (targetStep != null ? ("-" + targetStep.getName()) : "");
RowMetaInterface rowMeta = stepsFieldsCache.get(fromToCacheEntry);
if (rowMeta != null) {
return rowMeta;
}
//
if (targetStep != null && stepMeta.isSendingErrorRowsToStep(targetStep)) {
// The error rows are the same as the input rows for
// the step but with the selected error fields added
//
row = getPrevStepFields(stepMeta);
// Add to this the error fields...
StepErrorMeta stepErrorMeta = stepMeta.getStepErrorMeta();
row.addRowMeta(stepErrorMeta.getErrorFields());
// Store this row in the cache
//
stepsFieldsCache.put(fromToCacheEntry, row);
return row;
}
// Resume the regular program...
List<StepMeta> prevSteps = getPreviousSteps(stepMeta);
int nrPrevious = prevSteps.size();
if (log.isDebug()) {
log.logDebug(BaseMessages.getString(PKG, "TransMeta.Log.FromStepALookingAtPreviousStep", stepMeta.getName(), String.valueOf(nrPrevious)));
}
for (int i = 0; i < prevSteps.size(); i++) {
StepMeta prevStepMeta = prevSteps.get(i);
if (monitor != null) {
monitor.subTask(BaseMessages.getString(PKG, "TransMeta.Monitor.CheckingStepTask.Title", prevStepMeta.getName()));
}
RowMetaInterface add = getStepFields(prevStepMeta, stepMeta, monitor);
if (add == null) {
add = new RowMeta();
}
if (log.isDebug()) {
log.logDebug(BaseMessages.getString(PKG, "TransMeta.Log.FoundFieldsToAdd") + add.toString());
}
if (i == 0) {
row.addRowMeta(add);
} else {
// See if the add fields are not already in the row
for (int x = 0; x < add.size(); x++) {
ValueMetaInterface v = add.getValueMeta(x);
ValueMetaInterface s = row.searchValueMeta(v.getName());
if (s == null) {
row.addValueMeta(v);
}
}
}
}
if (nrPrevious == 0 && stepMeta.getRemoteInputSteps().size() > 0) {
//
for (RemoteStep remoteStep : stepMeta.getRemoteInputSteps()) {
RowMetaInterface inputFields = remoteStep.getRowMeta();
for (ValueMetaInterface inputField : inputFields.getValueMetaList()) {
if (row.searchValueMeta(inputField.getName()) == null) {
row.addValueMeta(inputField);
}
}
}
}
// Finally, see if we need to add/modify/delete fields with this step "name"
rowMeta = getThisStepFields(stepMeta, targetStep, row, monitor);
// Store this row in the cache
//
stepsFieldsCache.put(fromToCacheEntry, rowMeta);
return rowMeta;
}
use of org.pentaho.di.trans.step.RemoteStep in project pentaho-kettle by pentaho.
the class TransGraph method setToolTip.
private AreaOwner setToolTip(int x, int y, int screenX, int screenY) {
AreaOwner subject = null;
if (!spoon.getProperties().showToolTips()) {
return subject;
}
canvas.setToolTipText(null);
String newTip = null;
Image tipImage = null;
final TransHopMeta hi = findHop(x, y);
// check the area owner list...
//
StringBuilder tip = new StringBuilder();
AreaOwner areaOwner = getVisibleAreaOwner(x, y);
if (areaOwner != null && areaOwner.getAreaType() != null) {
switch(areaOwner.getAreaType()) {
case REMOTE_INPUT_STEP:
StepMeta step = (StepMeta) areaOwner.getParent();
tip.append("Remote input steps:").append(Const.CR).append("-----------------------").append(Const.CR);
for (RemoteStep remoteStep : step.getRemoteInputSteps()) {
tip.append(remoteStep.toString()).append(Const.CR);
}
break;
case REMOTE_OUTPUT_STEP:
step = (StepMeta) areaOwner.getParent();
tip.append("Remote output steps:").append(Const.CR).append("-----------------------").append(Const.CR);
for (RemoteStep remoteStep : step.getRemoteOutputSteps()) {
tip.append(remoteStep.toString()).append(Const.CR);
}
break;
case STEP_PARTITIONING:
step = (StepMeta) areaOwner.getParent();
tip.append("Step partitioning:").append(Const.CR).append("-----------------------").append(Const.CR);
tip.append(step.getStepPartitioningMeta().toString()).append(Const.CR);
if (step.getTargetStepPartitioningMeta() != null) {
tip.append(Const.CR).append(Const.CR).append("TARGET: " + step.getTargetStepPartitioningMeta().toString()).append(Const.CR);
}
break;
case STEP_ERROR_ICON:
String log = (String) areaOwner.getParent();
tip.append(log);
tipImage = GUIResource.getInstance().getImageStepError();
break;
case STEP_ERROR_RED_ICON:
String redLog = (String) areaOwner.getParent();
tip.append(redLog);
tipImage = GUIResource.getInstance().getImageRedStepError();
break;
case HOP_COPY_ICON:
step = (StepMeta) areaOwner.getParent();
tip.append(BaseMessages.getString(PKG, "TransGraph.Hop.Tooltip.HopTypeCopy", step.getName(), Const.CR));
tipImage = GUIResource.getInstance().getImageCopyHop();
break;
case ROW_DISTRIBUTION_ICON:
step = (StepMeta) areaOwner.getParent();
tip.append(BaseMessages.getString(PKG, "TransGraph.Hop.Tooltip.RowDistribution", step.getName(), step.getRowDistribution() == null ? "" : step.getRowDistribution().getDescription()));
tip.append(Const.CR);
tipImage = GUIResource.getInstance().getImageBalance();
break;
case HOP_INFO_ICON:
StepMeta from = (StepMeta) areaOwner.getParent();
StepMeta to = (StepMeta) areaOwner.getOwner();
tip.append(BaseMessages.getString(PKG, "TransGraph.Hop.Tooltip.HopTypeInfo", to.getName(), from.getName(), Const.CR));
tipImage = GUIResource.getInstance().getImageInfoHop();
break;
case HOP_ERROR_ICON:
from = (StepMeta) areaOwner.getParent();
to = (StepMeta) areaOwner.getOwner();
areaOwner.getOwner();
tip.append(BaseMessages.getString(PKG, "TransGraph.Hop.Tooltip.HopTypeError", from.getName(), to.getName(), Const.CR));
tipImage = GUIResource.getInstance().getImageErrorHop();
break;
case HOP_INFO_STEP_COPIES_ERROR:
from = (StepMeta) areaOwner.getParent();
to = (StepMeta) areaOwner.getOwner();
tip.append(BaseMessages.getString(PKG, "TransGraph.Hop.Tooltip.InfoStepCopies", from.getName(), to.getName(), Const.CR));
tipImage = GUIResource.getInstance().getImageStepError();
break;
case STEP_INPUT_HOP_ICON:
// StepMeta subjectStep = (StepMeta) (areaOwner.getParent());
tip.append(BaseMessages.getString(PKG, "TransGraph.StepInputConnector.Tooltip"));
tipImage = GUIResource.getInstance().getImageHopInput();
break;
case STEP_OUTPUT_HOP_ICON:
// subjectStep = (StepMeta) (areaOwner.getParent());
tip.append(BaseMessages.getString(PKG, "TransGraph.StepOutputConnector.Tooltip"));
tipImage = GUIResource.getInstance().getImageHopOutput();
break;
case STEP_INFO_HOP_ICON:
// subjectStep = (StepMeta) (areaOwner.getParent());
// StreamInterface stream = (StreamInterface) areaOwner.getOwner();
StepIOMetaInterface ioMeta = (StepIOMetaInterface) areaOwner.getOwner();
tip.append(BaseMessages.getString(PKG, "TransGraph.StepInfoConnector.Tooltip") + Const.CR + ioMeta.toString());
tipImage = GUIResource.getInstance().getImageHopOutput();
break;
case STEP_TARGET_HOP_ICON:
StreamInterface stream = (StreamInterface) areaOwner.getOwner();
tip.append(stream.getDescription());
tipImage = GUIResource.getInstance().getImageHopOutput();
break;
case STEP_ERROR_HOP_ICON:
StepMeta stepMeta = (StepMeta) areaOwner.getParent();
if (stepMeta.supportsErrorHandling()) {
tip.append(BaseMessages.getString(PKG, "TransGraph.StepSupportsErrorHandling.Tooltip"));
} else {
tip.append(BaseMessages.getString(PKG, "TransGraph.StepDoesNotSupportsErrorHandling.Tooltip"));
}
tipImage = GUIResource.getInstance().getImageHopOutput();
break;
case STEP_EDIT_ICON:
stepMeta = (StepMeta) (areaOwner.getParent());
tip.append(BaseMessages.getString(PKG, "TransGraph.EditStep.Tooltip"));
tipImage = GUIResource.getInstance().getImageEdit();
break;
case STEP_INJECT_ICON:
stepMeta = (StepMeta) (areaOwner.getParent());
Object injection = areaOwner.getOwner();
if (injection != null) {
tip.append(BaseMessages.getString(PKG, "TransGraph.StepInjectionSupported.Tooltip"));
} else {
tip.append(BaseMessages.getString(PKG, "TransGraph.StepInjectionNotSupported.Tooltip"));
}
tipImage = GUIResource.getInstance().getImageInject();
break;
case STEP_MENU_ICON:
tip.append(BaseMessages.getString(PKG, "TransGraph.ShowMenu.Tooltip"));
tipImage = GUIResource.getInstance().getImageContextMenu();
break;
default:
break;
}
}
if (hi != null) {
// We clicked on a HOP!
// Set the tooltip for the hop:
tip.append(Const.CR).append(BaseMessages.getString(PKG, "TransGraph.Dialog.HopInfo")).append(newTip = hi.toString()).append(Const.CR);
}
if (tip.length() == 0) {
newTip = null;
} else {
newTip = tip.toString();
}
if (newTip == null) {
toolTip.hide();
if (hi != null) {
// We clicked on a HOP!
// Set the tooltip for the hop:
newTip = BaseMessages.getString(PKG, "TransGraph.Dialog.HopInfo") + Const.CR + BaseMessages.getString(PKG, "TransGraph.Dialog.HopInfo.SourceStep") + " " + hi.getFromStep().getName() + Const.CR + BaseMessages.getString(PKG, "TransGraph.Dialog.HopInfo.TargetStep") + " " + hi.getToStep().getName() + Const.CR + BaseMessages.getString(PKG, "TransGraph.Dialog.HopInfo.Status") + " " + (hi.isEnabled() ? BaseMessages.getString(PKG, "TransGraph.Dialog.HopInfo.Enable") : BaseMessages.getString(PKG, "TransGraph.Dialog.HopInfo.Disable"));
toolTip.setText(newTip);
if (hi.isEnabled()) {
toolTip.setImage(GUIResource.getInstance().getImageHop());
} else {
toolTip.setImage(GUIResource.getInstance().getImageDisabledHop());
}
toolTip.show(new org.eclipse.swt.graphics.Point(screenX, screenY));
} else {
newTip = null;
}
} else if (!newTip.equalsIgnoreCase(getToolTipText())) {
Image tooltipImage = null;
if (tipImage != null) {
tooltipImage = tipImage;
} else {
tooltipImage = GUIResource.getInstance().getImageSpoonLow();
}
showTooltip(newTip, tooltipImage, screenX, screenY);
}
if (areaOwner != null && areaOwner.getExtensionAreaType() != null) {
try {
TransPainterFlyoutTooltipExtension extension = new TransPainterFlyoutTooltipExtension(areaOwner, this, new Point(screenX, screenY));
ExtensionPointHandler.callExtensionPoint(LogChannel.GENERAL, KettleExtensionPoint.TransPainterFlyoutTooltip.id, extension);
} catch (Exception e) {
LogChannel.GENERAL.logError("Error calling extension point(s) for the transformation painter step", e);
}
}
return subject;
}
use of org.pentaho.di.trans.step.RemoteStep in project pentaho-kettle by pentaho.
the class Mapping method processRow.
/**
* Process a single row. In our case, we send one row of data to a piece of transformation. In the transformation, we
* look up the MappingInput step to send our rows to it. As a consequence, for the time being, there can only be one
* MappingInput and one MappingOutput step in the Mapping.
*/
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException {
try {
meta = (MappingMeta) smi;
setData((MappingData) sdi);
MappingInput[] mappingInputs = getData().getMappingTrans().findMappingInput();
MappingOutput[] mappingOutputs = getData().getMappingTrans().findMappingOutput();
getData().wasStarted = true;
switch(getData().mappingTransMeta.getTransformationType()) {
case Normal:
case SerialSingleThreaded:
// Before we start, let's see if there are loose ends to tie up...
//
List<RowSet> inputRowSets = getInputRowSets();
if (!inputRowSets.isEmpty()) {
for (RowSet rowSet : inputRowSets) {
//
if (mappingInputs.length == 1) {
// Simple case: only one input mapping. Move the RowSet over
//
mappingInputs[0].addRowSetToInputRowSets(rowSet);
} else {
//
throw new KettleException("Unsupported situation detected where more than one Mapping Input step needs to be handled. " + "To solve it, insert a dummy step before the mapping step.");
}
}
clearInputRowSets();
}
//
if (!getRemoteInputSteps().isEmpty()) {
//
for (RemoteStep remoteStep : getRemoteInputSteps()) {
//
if (mappingInputs.length == 1) {
// Simple case: only one input mapping. Move the remote step over
//
mappingInputs[0].getRemoteInputSteps().add(remoteStep);
} else {
//
throw new KettleException("Unsupported situation detected where a remote input step is expecting data " + "to end up in a particular Mapping Input step of a sub-transformation. " + "To solve it, insert a dummy step before the mapping.");
}
}
getRemoteInputSteps().clear();
}
// Do the same thing for output row sets
//
List<RowSet> outputRowSets = getOutputRowSets();
if (!outputRowSets.isEmpty()) {
for (RowSet rowSet : outputRowSets) {
//
if (mappingOutputs.length == 1) {
// Simple case: only one output mapping. Move the RowSet over
//
mappingOutputs[0].addRowSetToOutputRowSets(rowSet);
} else {
//
throw new KettleException("Unsupported situation detected where more than one Mapping Output step needs to be handled. " + "To solve it, insert a dummy step after the mapping step.");
}
}
clearOutputRowSets();
}
//
if (!getRemoteOutputSteps().isEmpty()) {
//
for (RemoteStep remoteStep : getRemoteOutputSteps()) {
//
if (mappingOutputs.length == 1) {
// Simple case: only one output mapping. Move the remote step over
//
mappingOutputs[0].getRemoteOutputSteps().add(remoteStep);
} else {
//
throw new KettleException("Unsupported situation detected where a remote output step is expecting data " + "to end up in a particular Mapping Output step of a sub-transformation. " + "To solve it, insert a dummy step after the mapping.");
}
}
getRemoteOutputSteps().clear();
}
// Start the mapping/sub-transformation threads
//
getData().getMappingTrans().startThreads();
//
if (getTransMeta().getTransformationType() == TransformationType.Normal) {
getData().getMappingTrans().waitUntilFinished();
// Set some statistics from the mapping...
// This will show up in Spoon, etc.
//
Result result = getData().getMappingTrans().getResult();
setErrors(result.getNrErrors());
setLinesRead(result.getNrLinesRead());
setLinesWritten(result.getNrLinesWritten());
setLinesInput(result.getNrLinesInput());
setLinesOutput(result.getNrLinesOutput());
setLinesUpdated(result.getNrLinesUpdated());
setLinesRejected(result.getNrLinesRejected());
}
return false;
case SingleThreaded:
if (mappingInputs.length > 1 || mappingOutputs.length > 1) {
throw new KettleException("Multiple input or output steps are not supported for a single threaded mapping.");
}
if ((log != null) && log.isDebug()) {
List<RowSet> mappingInputRowSets = mappingInputs[0].getInputRowSets();
log.logDebug("# of input buffers: " + mappingInputRowSets.size());
if (mappingInputRowSets.size() > 0) {
log.logDebug("Input buffer 0 size: " + mappingInputRowSets.get(0).size());
}
}
// Now execute one batch...Basic logging
//
boolean result = getData().singleThreadedTransExcecutor.oneIteration();
if (!result) {
getData().singleThreadedTransExcecutor.dispose();
setOutputDone();
return false;
}
return true;
default:
throw new KettleException("Transformation type '" + getData().mappingTransMeta.getTransformationType().getDescription() + "' is an unsupported transformation type for a mapping");
}
} catch (Throwable t) {
//
if (getData().getMappingTrans() != null) {
getData().getMappingTrans().stopAll();
}
//
throw new KettleException(t);
}
}
use of org.pentaho.di.trans.step.RemoteStep in project pentaho-kettle by pentaho.
the class TransSplitter method splitOriginalTransformation.
public void splitOriginalTransformation() throws KettleException {
clear();
// Mixing clusters is not supported at the moment
// Perform some basic checks on the cluster configuration.
//
findUsedOriginalSteps();
checkClusterConfiguration();
generateSlavePartitionSchemas();
try {
SlaveServer masterSlaveServer = getMasterServer();
masterTransMeta = getOriginalCopy(false, null, null);
ClusterSchema clusterSchema = originalTransformation.findFirstUsedClusterSchema();
List<SlaveServer> slaveServers = clusterSchema.getSlaveServers();
int nrSlavesNodes = clusterSchema.findNrSlaves();
boolean encrypt = false;
byte[] transformationKey = null;
PublicKey pubK = null;
if (encrypt) {
KeyPair pair = CertificateGenEncryptUtil.generateKeyPair();
pubK = pair.getPublic();
PrivateKey privK = pair.getPrivate();
Key key1 = CertificateGenEncryptUtil.generateSingleKey();
try {
transformationKey = CertificateGenEncryptUtil.encodeKeyForTransmission(privK, key1);
} catch (InvalidKeyException ex) {
masterTransMeta.getLogChannel().logError("Invalid key was used for encoding", ex);
} catch (IllegalBlockSizeException ex) {
masterTransMeta.getLogChannel().logError("Error happenned during key encoding", ex);
} catch (Exception ex) {
masterTransMeta.getLogChannel().logError("Error happenned during encryption initialization", ex);
}
}
for (int r = 0; r < referenceSteps.length; r++) {
StepMeta referenceStep = referenceSteps[r];
List<StepMeta> prevSteps = originalTransformation.findPreviousSteps(referenceStep);
int nrPreviousSteps = prevSteps.size();
for (int p = 0; p < nrPreviousSteps; p++) {
StepMeta previousStep = prevSteps.get(p);
if (!referenceStep.isClustered()) {
if (!previousStep.isClustered()) {
// No clustering involved here: just add the reference step to the master
//
StepMeta target = masterTransMeta.findStep(referenceStep.getName());
if (target == null) {
target = (StepMeta) referenceStep.clone();
masterTransMeta.addStep(target);
}
StepMeta source = masterTransMeta.findStep(previousStep.getName());
if (source == null) {
source = (StepMeta) previousStep.clone();
masterTransMeta.addStep(source);
}
// Add a hop too...
//
TransHopMeta masterHop = new TransHopMeta(source, target);
masterTransMeta.addTransHop(masterHop);
} else {
// reference step is NOT clustered
// Previous step is clustered
// --> We read from the slave server using socket readers.
// We need a reader for each slave server in the cluster
//
// Also add the reference step to the master. (cloned)
//
StepMeta masterStep = masterTransMeta.findStep(referenceStep.getName());
if (masterStep == null) {
masterStep = (StepMeta) referenceStep.clone();
masterStep.setLocation(masterStep.getLocation().x, masterStep.getLocation().y);
masterTransMeta.addStep(masterStep);
}
Queue<Integer> masterStepCopyNumbers = new LinkedList<Integer>();
for (int i = 0; i < masterStep.getCopies(); i++) {
masterStepCopyNumbers.add(i);
}
//
for (int slaveNr = 0; slaveNr < slaveServers.size(); slaveNr++) {
SlaveServer sourceSlaveServer = slaveServers.get(slaveNr);
if (!sourceSlaveServer.isMaster()) {
// MASTER: add remote input steps to the master step. That way it can receive data over sockets.
//
// SLAVE : add remote output steps to the previous step
//
TransMeta slave = getSlaveTransformation(clusterSchema, sourceSlaveServer);
// See if we can add a link to the previous using the Remote Steps concept.
//
StepMeta slaveStep = slave.findStep(previousStep.getName());
if (slaveStep == null) {
slaveStep = addSlaveCopy(slave, previousStep, sourceSlaveServer);
}
// Make sure the data finds its way back to the master.
//
// Verify the partitioning for this slave step.
// It's running in 1 or more copies depending on the number of partitions
// Get the number of target partitions...
//
StepPartitioningMeta previousStepPartitioningMeta = previousStep.getStepPartitioningMeta();
PartitionSchema previousPartitionSchema = previousStepPartitioningMeta.getPartitionSchema();
int nrOfSourceCopies = determineNrOfStepCopies(sourceSlaveServer, previousStep);
//
if (masterStep.getCopies() != 1 && masterStep.getCopies() != nrOfSourceCopies) {
// this case might be handled correctly later
String message = BaseMessages.getString(PKG, "TransSplitter.Clustering.CopyNumberStep", nrSlavesNodes, previousStep.getName(), masterStep.getName());
throw new KettleException(message);
}
//
for (int sourceCopyNr = 0; sourceCopyNr < nrOfSourceCopies; sourceCopyNr++) {
// The masterStepCopy number is increasing for each remote copy on each slave.
// This makes the master distribute to each copy of the slave properly.
// There is a check above to make sure that the master has either 1 copy or the same as slave*copies
Integer masterStepCopyNr = masterStepCopyNumbers.poll();
if (masterStepCopyNr == null) {
masterStepCopyNr = 0;
}
// We open a port on the various slave servers...
// So the source is the slave server, the target the master.
//
int port = getPort(clusterSchema, sourceSlaveServer, slaveStep.getName(), sourceCopyNr, masterSlaveServer, masterStep.getName(), masterStepCopyNr);
RemoteStep remoteMasterStep = new RemoteStep(sourceSlaveServer.getHostname(), masterSlaveServer.getHostname(), Integer.toString(port), slaveStep.getName(), sourceCopyNr, masterStep.getName(), masterStepCopyNr, sourceSlaveServer.getName(), masterSlaveServer.getName(), socketsBufferSize, compressingSocketStreams, originalTransformation.getStepFields(previousStep));
remoteMasterStep.setEncryptingStreams(encrypt);
remoteMasterStep.setKey(transformationKey);
masterStep.getRemoteInputSteps().add(remoteMasterStep);
RemoteStep remoteSlaveStep = new RemoteStep(sourceSlaveServer.getHostname(), masterSlaveServer.getHostname(), Integer.toString(port), slaveStep.getName(), sourceCopyNr, masterStep.getName(), masterStepCopyNr, sourceSlaveServer.getName(), masterSlaveServer.getName(), socketsBufferSize, compressingSocketStreams, originalTransformation.getStepFields(previousStep));
remoteSlaveStep.setEncryptingStreams(encrypt);
remoteSlaveStep.setKey(transformationKey);
slaveStep.getRemoteOutputSteps().add(remoteSlaveStep);
//
if (slaveStep.isPartitioned()) {
slaveStepCopyPartitionDistribution.addPartition(sourceSlaveServer.getName(), previousPartitionSchema.getName(), sourceCopyNr);
}
}
//
if (referenceStep.isPartitioned()) {
// Set the target partitioning schema for the source step (master)
//
StepPartitioningMeta stepPartitioningMeta = previousStepPartitioningMeta.clone();
PartitionSchema partitionSchema = stepPartitioningMeta.getPartitionSchema();
partitionSchema.setName(createTargetPartitionSchemaName(partitionSchema.getName()));
if (partitionSchema.isDynamicallyDefined()) {
// Expand the cluster definition to: nrOfSlaves*nrOfPartitionsPerSlave...
//
partitionSchema.expandPartitionsDynamically(clusterSchema.findNrSlaves(), originalTransformation);
}
masterStep.setTargetStepPartitioningMeta(stepPartitioningMeta);
masterTransMeta.addOrReplacePartitionSchema(partitionSchema);
// Now set the partitioning schema for the slave step...
// For the slave step, we only should those partition IDs that are interesting for the current
// slave...
//
stepPartitioningMeta = previousStepPartitioningMeta.clone();
partitionSchema = stepPartitioningMeta.getPartitionSchema();
partitionSchema.setName(createSlavePartitionSchemaName(partitionSchema.getName()));
if (partitionSchema.isDynamicallyDefined()) {
// Expand the cluster definition to: nrOfSlaves*nrOfPartitionsPerSlave...
//
partitionSchema.expandPartitionsDynamically(clusterSchema.findNrSlaves(), originalTransformation);
}
partitionSchema.retainPartitionsForSlaveServer(clusterSchema.findNrSlaves(), getSlaveServerNumber(clusterSchema, sourceSlaveServer));
slave.addOrReplacePartitionSchema(partitionSchema);
}
}
}
}
} else {
if (!previousStep.isClustered()) {
// reference step is clustered
// previous step is not clustered
// --> Add a socket writer for each slave server
//
// MASTER : add remote output step to the previous step
//
StepMeta sourceStep = masterTransMeta.findStep(previousStep.getName());
if (sourceStep == null) {
sourceStep = (StepMeta) previousStep.clone();
sourceStep.setLocation(previousStep.getLocation().x, previousStep.getLocation().y);
masterTransMeta.addStep(sourceStep);
}
Queue<Integer> masterStepCopyNumbers = new LinkedList<Integer>();
for (int i = 0; i < sourceStep.getCopies(); i++) {
masterStepCopyNumbers.add(i);
}
for (int s = 0; s < slaveServers.size(); s++) {
SlaveServer targetSlaveServer = slaveServers.get(s);
if (!targetSlaveServer.isMaster()) {
// SLAVE : add remote input step to the reference slave step...
//
TransMeta slaveTransMeta = getSlaveTransformation(clusterSchema, targetSlaveServer);
// also add the step itself.
StepMeta targetStep = slaveTransMeta.findStep(referenceStep.getName());
if (targetStep == null) {
targetStep = addSlaveCopy(slaveTransMeta, referenceStep, targetSlaveServer);
}
// Verify the partitioning for this slave step.
// It's running in 1 or more copies depending on the number of partitions
// Get the number of target partitions...
//
StepPartitioningMeta targetStepPartitioningMeta = referenceStep.getStepPartitioningMeta();
PartitionSchema targetPartitionSchema = targetStepPartitioningMeta.getPartitionSchema();
int nrOfTargetCopies = determineNrOfStepCopies(targetSlaveServer, referenceStep);
//
for (int targetCopyNr = 0; targetCopyNr < nrOfTargetCopies; targetCopyNr++) {
// The masterStepCopy number is increasing for each remote copy on each slave.
// This makes the master distribute to each copy of the slave properly.
// There is a check above to make sure that the master has either 1 copy or the same as slave*copies
Integer masterStepCopyNr = masterStepCopyNumbers.poll();
if (masterStepCopyNr == null) {
masterStepCopyNr = 0;
}
// The master step opens server socket ports
// So the IP address should be the same, in this case, the master...
//
int port = getPort(clusterSchema, masterSlaveServer, sourceStep.getName(), masterStepCopyNr, targetSlaveServer, referenceStep.getName(), targetCopyNr);
RemoteStep remoteMasterStep = new RemoteStep(masterSlaveServer.getHostname(), targetSlaveServer.getHostname(), Integer.toString(port), sourceStep.getName(), masterStepCopyNr, referenceStep.getName(), targetCopyNr, masterSlaveServer.getName(), targetSlaveServer.getName(), socketsBufferSize, compressingSocketStreams, originalTransformation.getStepFields(previousStep));
remoteMasterStep.setEncryptingStreams(encrypt);
remoteMasterStep.setKey(transformationKey);
sourceStep.getRemoteOutputSteps().add(remoteMasterStep);
RemoteStep remoteSlaveStep = new RemoteStep(masterSlaveServer.getHostname(), targetSlaveServer.getHostname(), Integer.toString(port), sourceStep.getName(), masterStepCopyNr, referenceStep.getName(), targetCopyNr, masterSlaveServer.getName(), targetSlaveServer.getName(), socketsBufferSize, compressingSocketStreams, originalTransformation.getStepFields(previousStep));
remoteSlaveStep.setEncryptingStreams(encrypt);
remoteSlaveStep.setKey(transformationKey);
targetStep.getRemoteInputSteps().add(remoteSlaveStep);
//
if (targetStep.isPartitioned()) {
slaveStepCopyPartitionDistribution.addPartition(targetSlaveServer.getName(), targetPartitionSchema.getName(), targetCopyNr);
}
}
//
if (targetStepPartitioningMeta.isPartitioned()) {
// Set the target partitioning schema for the source step (master)
//
StepPartitioningMeta stepPartitioningMeta = targetStepPartitioningMeta.clone();
PartitionSchema partitionSchema = stepPartitioningMeta.getPartitionSchema();
partitionSchema.setName(createTargetPartitionSchemaName(partitionSchema.getName()));
if (partitionSchema.isDynamicallyDefined()) {
// Expand the cluster definition to: nrOfSlaves*nrOfPartitionsPerSlave...
//
partitionSchema.expandPartitionsDynamically(clusterSchema.findNrSlaves(), originalTransformation);
}
sourceStep.setTargetStepPartitioningMeta(stepPartitioningMeta);
masterTransMeta.addOrReplacePartitionSchema(partitionSchema);
// Now set the partitioning schema for the slave step...
// For the slave step, we only should those partition IDs that are interesting for the current
// slave...
//
stepPartitioningMeta = targetStepPartitioningMeta.clone();
partitionSchema = stepPartitioningMeta.getPartitionSchema();
partitionSchema.setName(createSlavePartitionSchemaName(partitionSchema.getName()));
if (partitionSchema.isDynamicallyDefined()) {
// Expand the cluster definition to: nrOfSlaves*nrOfPartitionsPerSlave...
//
partitionSchema.expandPartitionsDynamically(clusterSchema.findNrSlaves(), originalTransformation);
}
partitionSchema.retainPartitionsForSlaveServer(clusterSchema.findNrSlaves(), getSlaveServerNumber(clusterSchema, targetSlaveServer));
slaveTransMeta.addOrReplacePartitionSchema(partitionSchema);
}
}
}
} else {
//
for (int slaveNr = 0; slaveNr < slaveServers.size(); slaveNr++) {
SlaveServer targetSlaveServer = slaveServers.get(slaveNr);
if (!targetSlaveServer.isMaster()) {
// SLAVE
TransMeta slaveTransMeta = getSlaveTransformation(clusterSchema, targetSlaveServer);
// This is the target step
//
StepMeta targetStep = slaveTransMeta.findStep(referenceStep.getName());
if (targetStep == null) {
targetStep = addSlaveCopy(slaveTransMeta, referenceStep, targetSlaveServer);
}
// This is the source step
//
StepMeta sourceStep = slaveTransMeta.findStep(previousStep.getName());
if (sourceStep == null) {
sourceStep = addSlaveCopy(slaveTransMeta, previousStep, targetSlaveServer);
}
// Add a hop between source and target
//
TransHopMeta slaveHop = new TransHopMeta(sourceStep, targetStep);
slaveTransMeta.addTransHop(slaveHop);
// Verify the partitioning
// That means is this case that it is possible that
//
// 1) the number of partitions is larger than the number of slaves
// 2) the partitioning method might change requiring the source step to do re-partitioning.
//
// We need to provide the source step with the information to re-partition correctly.
//
// Case 1: both source and target are partitioned on the same partition schema.
//
StepPartitioningMeta sourceStepPartitioningMeta = previousStep.getStepPartitioningMeta();
StepPartitioningMeta targetStepPartitioningMeta = referenceStep.getStepPartitioningMeta();
if (previousStep.isPartitioned() && referenceStep.isPartitioned() && sourceStepPartitioningMeta.equals(targetStepPartitioningMeta)) {
// Just divide the partitions over the available slaves...
// set the appropriate partition schema for both step...
//
StepPartitioningMeta stepPartitioningMeta = sourceStepPartitioningMeta.clone();
PartitionSchema partitionSchema = stepPartitioningMeta.getPartitionSchema();
partitionSchema.setName(createSlavePartitionSchemaName(partitionSchema.getName()));
if (partitionSchema.isDynamicallyDefined()) {
partitionSchema.expandPartitionsDynamically(clusterSchema.findNrSlaves(), originalTransformation);
}
partitionSchema.retainPartitionsForSlaveServer(clusterSchema.findNrSlaves(), getSlaveServerNumber(clusterSchema, targetSlaveServer));
sourceStep.setStepPartitioningMeta(stepPartitioningMeta);
targetStep.setStepPartitioningMeta(stepPartitioningMeta);
slaveTransMeta.addOrReplacePartitionSchema(partitionSchema);
} else if ((!previousStep.isPartitioned() && referenceStep.isPartitioned()) || (previousStep.isPartitioned() && referenceStep.isPartitioned() && !sourceStepPartitioningMeta.equals(targetStep.getStepPartitioningMeta()))) {
// Case 2: both source and target are partitioned on a different partition schema.
// Case 3: source is not partitioned, target is partitioned.
//
// --> This means that we're re-partitioning!!
//
PartitionSchema targetPartitionSchema = targetStepPartitioningMeta.getPartitionSchema();
PartitionSchema sourcePartitionSchema = sourceStepPartitioningMeta.getPartitionSchema();
//
for (int partSlaveNr = 0; partSlaveNr < slaveServers.size(); partSlaveNr++) {
SlaveServer sourceSlaveServer = slaveServers.get(partSlaveNr);
if (!sourceSlaveServer.isMaster()) {
// It's running in 1 or more copies depending on the number of partitions
// Get the number of target partitions...
//
Map<PartitionSchema, List<String>> partitionsMap = slaveServerPartitionsMap.get(sourceSlaveServer);
int nrOfTargetPartitions = 1;
if (targetStep.isPartitioned() && targetPartitionSchema != null) {
List<String> targetPartitionsList = partitionsMap.get(targetPartitionSchema);
nrOfTargetPartitions = targetPartitionsList.size();
} else if (targetStep.getCopies() > 1) {
nrOfTargetPartitions = targetStep.getCopies();
}
// Get the number of source partitions...
//
int nrOfSourcePartitions = 1;
if (sourceStep.isPartitioned() && sourcePartitionSchema != null) {
List<String> sourcePartitionsList = partitionsMap.get(sourcePartitionSchema);
nrOfSourcePartitions = sourcePartitionsList.size();
} else if (sourceStep.getCopies() > 1) {
nrOfSourcePartitions = sourceStep.getCopies();
}
//
for (int sourceCopyNr = 0; sourceCopyNr < nrOfSourcePartitions; sourceCopyNr++) {
for (int targetCopyNr = 0; targetCopyNr < nrOfTargetPartitions; targetCopyNr++) {
if (!targetSlaveServer.equals(sourceSlaveServer)) {
// We hit only get the remote steps, NOT the local ones.
// That's why it's OK to generate all combinations.
//
int outPort = getPort(clusterSchema, targetSlaveServer, sourceStep.getName(), sourceCopyNr, sourceSlaveServer, targetStep.getName(), targetCopyNr);
RemoteStep remoteOutputStep = new RemoteStep(targetSlaveServer.getHostname(), sourceSlaveServer.getHostname(), Integer.toString(outPort), sourceStep.getName(), sourceCopyNr, targetStep.getName(), targetCopyNr, targetSlaveServer.getName(), sourceSlaveServer.getName(), socketsBufferSize, compressingSocketStreams, originalTransformation.getStepFields(previousStep));
remoteOutputStep.setEncryptingStreams(encrypt);
remoteOutputStep.setKey(transformationKey);
sourceStep.getRemoteOutputSteps().add(remoteOutputStep);
// OK, so the source step is sending rows out on the reserved ports
// What we need to do now is link all the OTHER slaves up to them.
//
int inPort = getPort(clusterSchema, sourceSlaveServer, sourceStep.getName(), sourceCopyNr, targetSlaveServer, targetStep.getName(), targetCopyNr);
RemoteStep remoteInputStep = new RemoteStep(sourceSlaveServer.getHostname(), targetSlaveServer.getHostname(), Integer.toString(inPort), sourceStep.getName(), sourceCopyNr, targetStep.getName(), targetCopyNr, sourceSlaveServer.getName(), targetSlaveServer.getName(), socketsBufferSize, compressingSocketStreams, originalTransformation.getStepFields(previousStep));
remoteInputStep.setEncryptingStreams(encrypt);
remoteInputStep.setKey(transformationKey);
targetStep.getRemoteInputSteps().add(remoteInputStep);
}
// OK, save the partition number for the target step in the partition distribution...
//
slaveStepCopyPartitionDistribution.addPartition(sourceSlaveServer.getName(), targetPartitionSchema.getName(), targetCopyNr);
}
}
if (sourceStepPartitioningMeta.isPartitioned()) {
// Set the correct partitioning schema for the source step.
//
// Set the target partitioning schema for the target step (slave)
//
StepPartitioningMeta stepPartitioningMeta = sourceStepPartitioningMeta.clone();
PartitionSchema partitionSchema = stepPartitioningMeta.getPartitionSchema();
partitionSchema.setName(createSlavePartitionSchemaName(partitionSchema.getName()));
if (partitionSchema.isDynamicallyDefined()) {
// Expand the cluster definition to: nrOfSlaves*nrOfPartitionsPerSlave...
//
partitionSchema.expandPartitionsDynamically(clusterSchema.findNrSlaves(), originalTransformation);
}
partitionSchema.retainPartitionsForSlaveServer(clusterSchema.findNrSlaves(), getSlaveServerNumber(clusterSchema, targetSlaveServer));
sourceStep.setStepPartitioningMeta(stepPartitioningMeta);
slaveTransMeta.addOrReplacePartitionSchema(partitionSchema);
}
if (targetStepPartitioningMeta.isPartitioned()) {
// Set the target partitioning schema for the target step (slave)
//
StepPartitioningMeta stepPartitioningMeta = targetStepPartitioningMeta.clone();
PartitionSchema partitionSchema = stepPartitioningMeta.getPartitionSchema();
partitionSchema.setName(createSlavePartitionSchemaName(partitionSchema.getName()));
if (partitionSchema.isDynamicallyDefined()) {
partitionSchema.expandPartitionsDynamically(clusterSchema.findNrSlaves(), originalTransformation);
}
partitionSchema.retainPartitionsForSlaveServer(clusterSchema.findNrSlaves(), getSlaveServerNumber(clusterSchema, targetSlaveServer));
targetStep.setStepPartitioningMeta(stepPartitioningMeta);
slaveTransMeta.addOrReplacePartitionSchema(partitionSchema);
}
//
if (!sourceStepPartitioningMeta.isPartitioned() || !sourceStepPartitioningMeta.equals(targetStepPartitioningMeta)) {
// Not partitioned means the target is partitioned.
// Set the target partitioning on the source...
// Set the correct partitioning schema for the source step.
//
// Set the target partitioning schema for the target step (slave)
//
StepPartitioningMeta stepPartitioningMeta = targetStepPartitioningMeta.clone();
PartitionSchema partitionSchema = stepPartitioningMeta.getPartitionSchema();
partitionSchema.setName(createTargetPartitionSchemaName(partitionSchema.getName()));
if (partitionSchema.isDynamicallyDefined()) {
// Expand the cluster definition to: nrOfSlaves*nrOfPartitionsPerSlave...
//
partitionSchema.expandPartitionsDynamically(clusterSchema.findNrSlaves(), originalTransformation);
}
sourceStep.setTargetStepPartitioningMeta(stepPartitioningMeta);
slaveTransMeta.addOrReplacePartitionSchema(partitionSchema);
}
}
}
}
}
}
}
}
}
if (nrPreviousSteps == 0) {
if (!referenceStep.isClustered()) {
// Not clustered, simply add the step.
if (masterTransMeta.findStep(referenceStep.getName()) == null) {
masterTransMeta.addStep((StepMeta) referenceStep.clone());
}
} else {
for (int s = 0; s < slaveServers.size(); s++) {
SlaveServer slaveServer = slaveServers.get(s);
if (!slaveServer.isMaster()) {
// SLAVE
TransMeta slave = getSlaveTransformation(clusterSchema, slaveServer);
if (slave.findStep(referenceStep.getName()) == null) {
addSlaveCopy(slave, referenceStep, slaveServer);
}
}
}
}
}
}
//
for (int i = 0; i < referenceSteps.length; i++) {
StepMeta originalStep = referenceSteps[i];
// Also take care of the info steps...
// For example: StreamLookup, Table Input, etc.
//
StepMeta[] infoSteps = originalTransformation.getInfoStep(originalStep);
for (int p = 0; infoSteps != null && p < infoSteps.length; p++) {
StepMeta infoStep = infoSteps[p];
if (infoStep != null) {
if (!originalStep.isClustered()) {
if (!infoStep.isClustered()) {
// No clustering involved here: just add a link between the reference step and the infostep
//
StepMeta target = masterTransMeta.findStep(originalStep.getName());
StepMeta source = masterTransMeta.findStep(infoStep.getName());
// Add a hop too...
TransHopMeta masterHop = new TransHopMeta(source, target);
masterTransMeta.addTransHop(masterHop);
} else {
// reference step is NOT clustered
// Previous step is clustered
// --> We read from the slave server using socket readers.
// We need a reader for each slave server in the cluster
// On top of that we need to merge the data from all these steps using a dummy. (to make sure)
// That dummy needs to feed into Merge Join
//
int nrSlaves = clusterSchema.getSlaveServers().size();
for (int s = 0; s < nrSlaves; s++) {
SlaveServer sourceSlaveServer = clusterSchema.getSlaveServers().get(s);
if (!sourceSlaveServer.isMaster()) {
// //////////////////////////////////////////////////////////////////////////////////////////
// On the SLAVES: add a socket writer...
//
TransMeta slave = getSlaveTransformation(clusterSchema, sourceSlaveServer);
SocketWriterMeta socketWriterMeta = new SocketWriterMeta();
int port = getPort(clusterSchema, sourceSlaveServer, infoStep.getName(), 0, masterSlaveServer, originalStep.getName(), 0);
socketWriterMeta.setPort("" + port);
socketWriterMeta.setBufferSize(clusterSchema.getSocketsBufferSize());
socketWriterMeta.setFlushInterval(clusterSchema.getSocketsFlushInterval());
socketWriterMeta.setCompressed(clusterSchema.isSocketsCompressed());
StepMeta writerStep = new StepMeta(getWriterName(clusterSchema, sourceSlaveServer, infoStep.getName(), 0, masterSlaveServer, originalStep.getName(), 0), socketWriterMeta);
writerStep.setLocation(infoStep.getLocation().x + 50, infoStep.getLocation().y + 50);
writerStep.setDraw(true);
slave.addStep(writerStep);
// We also need to add a hop between infoStep and the new writer step
//
TransHopMeta slaveHop = new TransHopMeta(infoStep, writerStep);
if (slave.findTransHop(slaveHop) == null) {
slave.addTransHop(slaveHop);
}
// //////////////////////////////////////////////////////////////////////////////////////////
// On the MASTER : add a socket reader and a dummy step to merge the data...
//
SocketReaderMeta socketReaderMeta = new SocketReaderMeta();
socketReaderMeta.setPort("" + port);
socketReaderMeta.setBufferSize(clusterSchema.getSocketsBufferSize());
socketReaderMeta.setCompressed(clusterSchema.isSocketsCompressed());
StepMeta readerStep = new StepMeta(getReaderName(clusterSchema, sourceSlaveServer, infoStep.getName(), 0, masterSlaveServer, originalStep.getName(), 0), socketReaderMeta);
readerStep.setLocation(infoStep.getLocation().x, infoStep.getLocation().y + (s * FANOUT * 2) - (nrSlaves * FANOUT / 2));
readerStep.setDraw(true);
masterTransMeta.addStep(readerStep);
// Also add a single dummy step in the master that will merge the data from the slave
// transformations.
//
String dummyName = infoStep.getName();
StepMeta dummyStep = masterTransMeta.findStep(dummyName);
if (dummyStep == null) {
DummyTransMeta dummy = new DummyTransMeta();
dummyStep = new StepMeta(dummyName, dummy);
dummyStep.setLocation(infoStep.getLocation().x + (SPLIT / 2), infoStep.getLocation().y);
dummyStep.setDraw(true);
dummyStep.setDescription("This step merges the data from the various data streams coming " + "from the slave transformations.\nIt does that right before it hits the step that " + "reads from a specific (info) step.");
masterTransMeta.addStep(dummyStep);
// Now we need a hop from the dummy merge step to the actual target step (original step)
//
StepMeta masterTargetStep = masterTransMeta.findStep(originalStep.getName());
TransHopMeta targetHop = new TransHopMeta(dummyStep, masterTargetStep);
masterTransMeta.addTransHop(targetHop);
// Set the master target step as an info step... (use the cloned copy)
//
String[] infoStepNames = masterTargetStep.getStepMetaInterface().getStepIOMeta().getInfoStepnames();
if (infoStepNames != null) {
StepMeta[] is = new StepMeta[infoStepNames.length];
for (int n = 0; n < infoStepNames.length; n++) {
// OK, info steps moved to the slave steps
is[n] = slave.findStep(infoStepNames[n]);
if (infoStepNames[n].equals(infoStep.getName())) {
// We want to replace this one with the reader step: that's where we source from now
infoSteps[n] = readerStep;
}
}
masterTargetStep.getStepMetaInterface().getStepIOMeta().setInfoSteps(infoSteps);
}
}
// Add a hop between the reader step and the dummy
//
TransHopMeta mergeHop = new TransHopMeta(readerStep, dummyStep);
if (masterTransMeta.findTransHop(mergeHop) == null) {
masterTransMeta.addTransHop(mergeHop);
}
}
}
}
} else {
if (!infoStep.isClustered()) {
//
for (int s = 0; s < slaveServers.size(); s++) {
SlaveServer targetSlaveServer = slaveServers.get(s);
if (!targetSlaveServer.isMaster()) {
// MASTER
SocketWriterMeta socketWriterMeta = new SocketWriterMeta();
socketWriterMeta.setPort("" + getPort(clusterSchema, masterSlaveServer, infoStep.getName(), 0, targetSlaveServer, originalStep.getName(), 0));
socketWriterMeta.setBufferSize(clusterSchema.getSocketsBufferSize());
socketWriterMeta.setFlushInterval(clusterSchema.getSocketsFlushInterval());
socketWriterMeta.setCompressed(clusterSchema.isSocketsCompressed());
StepMeta writerStep = new StepMeta(getWriterName(clusterSchema, masterSlaveServer, infoStep.getName(), 0, targetSlaveServer, originalStep.getName(), 0), socketWriterMeta);
writerStep.setLocation(originalStep.getLocation().x, originalStep.getLocation().y + (s * FANOUT * 2) - (nrSlavesNodes * FANOUT / 2));
writerStep.setDraw(originalStep.isDrawn());
masterTransMeta.addStep(writerStep);
// The previous step: add a hop to it.
// It still has the original name as it is not clustered.
//
StepMeta previous = masterTransMeta.findStep(infoStep.getName());
if (previous == null) {
previous = (StepMeta) infoStep.clone();
masterTransMeta.addStep(previous);
}
TransHopMeta masterHop = new TransHopMeta(previous, writerStep);
masterTransMeta.addTransHop(masterHop);
// SLAVE
TransMeta slave = getSlaveTransformation(clusterSchema, targetSlaveServer);
SocketReaderMeta socketReaderMeta = new SocketReaderMeta();
socketReaderMeta.setHostname(masterSlaveServer.getHostname());
socketReaderMeta.setPort("" + getPort(clusterSchema, masterSlaveServer, infoStep.getName(), 0, targetSlaveServer, originalStep.getName(), 0));
socketReaderMeta.setBufferSize(clusterSchema.getSocketsBufferSize());
socketReaderMeta.setCompressed(clusterSchema.isSocketsCompressed());
StepMeta readerStep = new StepMeta(getReaderName(clusterSchema, masterSlaveServer, infoStep.getName(), 0, targetSlaveServer, originalStep.getName(), 0), socketReaderMeta);
readerStep.setLocation(originalStep.getLocation().x - (SPLIT / 2), originalStep.getLocation().y);
readerStep.setDraw(originalStep.isDrawn());
slave.addStep(readerStep);
// also add the step itself.
StepMeta slaveStep = slave.findStep(originalStep.getName());
if (slaveStep == null) {
slaveStep = addSlaveCopy(slave, originalStep, targetSlaveServer);
}
// And a hop from the
TransHopMeta slaveHop = new TransHopMeta(readerStep, slaveStep);
slave.addTransHop(slaveHop);
//
// Now we have to explain to the slaveStep that it has to source from previous
//
String[] infoStepNames = slaveStep.getStepMetaInterface().getStepIOMeta().getInfoStepnames();
if (infoStepNames != null) {
StepMeta[] is = new StepMeta[infoStepNames.length];
for (int n = 0; n < infoStepNames.length; n++) {
// OK, info steps moved to the slave steps
is[n] = slave.findStep(infoStepNames[n]);
if (infoStepNames[n].equals(infoStep.getName())) {
// We want to replace this one with the reader step: that's where we source from now
infoSteps[n] = readerStep;
}
}
slaveStep.getStepMetaInterface().getStepIOMeta().setInfoSteps(infoSteps);
}
}
}
} else {
//
for (int s = 0; s < slaveServers.size(); s++) {
SlaveServer slaveServer = slaveServers.get(s);
if (!slaveServer.isMaster()) {
TransMeta slave = getSlaveTransformation(clusterSchema, slaveServer);
StepMeta slaveStep = slave.findStep(originalStep.getName());
String[] infoStepNames = slaveStep.getStepMetaInterface().getStepIOMeta().getInfoStepnames();
if (infoStepNames != null) {
StepMeta[] is = new StepMeta[infoStepNames.length];
for (int n = 0; n < infoStepNames.length; n++) {
// OK, info steps moved to the slave steps
is[n] = slave.findStep(infoStepNames[n]);
// Hang on... is there a hop to the previous step?
if (slave.findTransHop(is[n], slaveStep) == null) {
TransHopMeta infoHop = new TransHopMeta(is[n], slaveStep);
slave.addTransHop(infoHop);
}
}
slaveStep.getStepMetaInterface().getStepIOMeta().setInfoSteps(infoSteps);
}
}
}
}
}
}
}
}
// Also add the original list of partition schemas to the slave step copy partition distribution...
//
slaveStepCopyPartitionDistribution.setOriginalPartitionSchemas(originalTransformation.getPartitionSchemas());
//
for (TransMeta transMeta : slaveTransMap.values()) {
transMeta.setSlaveStepCopyPartitionDistribution(slaveStepCopyPartitionDistribution);
if (encrypt) {
transMeta.setKey(pubK.getEncoded());
transMeta.setPrivateKey(false);
}
transMeta.clearChanged();
}
// do not erase partitioning schema for master transformation
// if some of steps is expected to run on master partitioned, that is the case
// when partition schema should exists as 'local' partition schema instead of slave's remote one
// see PDI-12766
masterTransMeta.setPartitionSchemas(originalTransformation.getPartitionSchemas());
masterTransMeta.setSlaveStepCopyPartitionDistribution(slaveStepCopyPartitionDistribution);
if (encrypt) {
masterTransMeta.setKey(pubK.getEncoded());
masterTransMeta.setPrivateKey(!false);
}
masterTransMeta.clearChanged();
// We're absolutely done here...
} catch (Exception e) {
throw new KettleException("Unexpected problem while generating master transformation", e);
}
}
Aggregations