/*
* Copyright 2013-2015 the original author or authors.
*
* 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.springframework.xd.dirt.plugins.job;
import java.util.Properties;
import org.springframework.messaging.MessageChannel;
import org.springframework.util.Assert;
import org.springframework.xd.dirt.integration.bus.BusUtils;
import org.springframework.xd.dirt.integration.bus.MessageBus;
import org.springframework.xd.dirt.plugins.AbstractJobPlugin;
import org.springframework.xd.module.ModuleDescriptor;
import org.springframework.xd.module.core.Module;
/**
* Plugin to enable job partitioning.
*
* @author Gary Russell
* @author Ilayaperumal Gopinathan
* @since 1.0
*/
public class JobPartitionerPlugin extends AbstractJobPlugin {
private static final String JOB_PARTIONER_REQUEST_CHANNEL = "stepExecutionRequests.output";
private static final String JOB_PARTIONER_REPLY_CHANNEL = "stepExecutionReplies.input";
private static final String JOB_STEP_EXECUTION_REQUEST_CHANNEL = "stepExecutionRequests.input";
private static final String JOB_STEP_EXECUTION_REPLY_CHANNEL = "stepExecutionReplies.output";
public JobPartitionerPlugin(MessageBus messageBus) {
super(messageBus);
}
@Override
public void postProcessModule(Module module) {
if (messageBus != null) {
if (module.getComponent(JOB_PARTIONER_REQUEST_CHANNEL, MessageChannel.class) != null) {
this.processPartitionedJob(module);
}
}
}
private void processPartitionedJob(Module module) {
if (logger.isDebugEnabled()) {
logger.debug("binding job partitioning channels for " + module);
}
Properties[] properties = extractConsumerProducerProperties(module);
MessageChannel partitionsOut = module.getComponent(JOB_PARTIONER_REQUEST_CHANNEL, MessageChannel.class);
Assert.notNull(partitionsOut, "Partitioned jobs must have a " + JOB_PARTIONER_REQUEST_CHANNEL);
MessageChannel partitionsIn = module.getComponent(JOB_PARTIONER_REPLY_CHANNEL, MessageChannel.class);
Assert.notNull(partitionsIn, "Partitioned jobs must have a " + JOB_PARTIONER_REPLY_CHANNEL);
ModuleDescriptor descriptor = module.getDescriptor();
String name = getJobChannelName(BusUtils.constructPipeName(descriptor.getGroup(), descriptor.getIndex()));
messageBus.bindRequestor(name, partitionsOut, partitionsIn, properties[0]);
MessageChannel stepExecutionsIn = module.getComponent(JOB_STEP_EXECUTION_REQUEST_CHANNEL, MessageChannel.class);
Assert.notNull(stepExecutionsIn, "Partitioned jobs must have a " + JOB_STEP_EXECUTION_REQUEST_CHANNEL);
MessageChannel stepExecutionResultsOut = module.getComponent(JOB_STEP_EXECUTION_REPLY_CHANNEL,
MessageChannel.class);
Assert.notNull(stepExecutionResultsOut, "Partitioned jobs must have a " + JOB_STEP_EXECUTION_REPLY_CHANNEL);
messageBus.bindReplier(name, stepExecutionsIn, stepExecutionResultsOut, properties[0]);
}
private void unbindPartitionedJob(Module module) {
if (logger.isDebugEnabled()) {
logger.debug("unbinding job partitioning channels for " + module);
}
MessageChannel partitionsOut = module.getComponent(JOB_PARTIONER_REQUEST_CHANNEL, MessageChannel.class);
ModuleDescriptor descriptor = module.getDescriptor();
String name = getJobChannelName(BusUtils.constructPipeName(descriptor.getGroup(), descriptor.getIndex()));
if (partitionsOut != null) {
messageBus.unbindProducer(name, partitionsOut);
}
MessageChannel partitionsIn = module.getComponent(JOB_PARTIONER_REPLY_CHANNEL, MessageChannel.class);
if (partitionsIn != null) {
messageBus.unbindConsumer(name, partitionsIn);
}
MessageChannel stepExcutionsIn = module.getComponent(JOB_STEP_EXECUTION_REQUEST_CHANNEL, MessageChannel.class);
if (stepExcutionsIn != null) {
messageBus.unbindConsumer(name, stepExcutionsIn);
}
MessageChannel stepExecutionResultsOut = module.getComponent(JOB_STEP_EXECUTION_REPLY_CHANNEL,
MessageChannel.class);
if (stepExecutionResultsOut != null) {
messageBus.unbindProducer(name, stepExecutionResultsOut);
}
}
@Override
public void beforeShutdown(Module module) {
}
@Override
public void removeModule(Module module) {
if (module.getComponent(JOB_PARTIONER_REQUEST_CHANNEL, MessageChannel.class) != null) {
this.unbindPartitionedJob(module);
}
}
}