package net.codjo.segmentation.server.plugin;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import net.codjo.agent.Agent;
import net.codjo.agent.AgentContainer;
import net.codjo.agent.ContainerFailureException;
import net.codjo.aspect.AspectConfigException;
import net.codjo.aspect.AspectManager;
import net.codjo.mad.server.plugin.MadServerPlugin;
import net.codjo.plugin.common.ApplicationCore;
import net.codjo.plugin.server.AbstractServerPlugin;
import net.codjo.segmentation.common.message.SegmentationJobRequest;
import net.codjo.segmentation.server.audit.SegmentationStringifier;
import net.codjo.segmentation.server.paramExport.agent.ExportParticipantAgent;
import net.codjo.segmentation.server.paramImport.agent.ImportParticipantAgent;
import net.codjo.segmentation.server.participant.CalculatorParticipant;
import net.codjo.segmentation.server.participant.DeleteParticipant;
import net.codjo.segmentation.server.participant.JobRequestAnalyzerParticipant;
import net.codjo.segmentation.server.participant.PaginatorParticipant;
import net.codjo.segmentation.server.participant.SegmentationParticipant;
import net.codjo.segmentation.server.participant.context.ContextManager;
import net.codjo.segmentation.server.preference.family.BadConfigurationException;
import net.codjo.segmentation.server.preference.family.XmlPreferenceLoader;
import net.codjo.sql.server.JdbcServiceUtil;
import net.codjo.workflow.server.api.JobAgent.MODE;
import net.codjo.workflow.server.plugin.WorkflowServerPlugin;
import net.codjo.xml.XmlException;
import org.apache.log4j.Logger;
import org.xml.sax.InputSource;
public class SegmentationServerPlugin extends AbstractServerPlugin {
private static final Logger LOG = Logger.getLogger(SegmentationServerPlugin.class);
public static final String JOB_TYPE = SegmentationJobRequest.SEGMENTATION_REQUEST_TYPE;
private final SegmentationServerPluginConfigurationImpl configuration
= new SegmentationServerPluginConfigurationImpl();
private AgentContainer agentContainer;
private ContextManager manager;
private MadServerPlugin madServerPlugin;
private ApplicationCore core;
public SegmentationServerPlugin() {
}
public SegmentationServerPlugin(MadServerPlugin madServerPlugin, ApplicationCore core) {
this(madServerPlugin, core, null);
}
public SegmentationServerPlugin(MadServerPlugin madServerPlugin,
ApplicationCore core,
WorkflowServerPlugin workflowServerPlugin) {
this.madServerPlugin = madServerPlugin;
this.core = core;
madServerPlugin.getConfiguration().addHandlerCommand(GetSegmentationConfigCommand.class);
new SegmentationStringifier().install(workflowServerPlugin);
}
public SegmentationServerPluginConfiguration getConfiguration() {
return configuration;
}
@Override
public void start(AgentContainer container) throws Exception {
agentContainer = container;
manager = new ContextManager(createXmlPreferenceLoader());
core.addGlobalComponent(manager);
madServerPlugin.getConfiguration().addHandlerSql(GetSegmentationResultHandler.class);
madServerPlugin.getConfiguration().addHandlerCommand(ExpressionCompilerCommand.class);
madServerPlugin.getConfiguration().addHandlerCommand(DuplicateAxisCommand.class);
LOG.info("Starting segmentation plugin with configuration " + configuration);
for (int i = 0; i < configuration.getMaxSegmentationJobAgents(); i++) {
container.acceptNewAgent(String.format("segmentation-job-agent-%s", i),
createSegmentationAgent(MODE.NOT_DELEGATE))
.start();
}
final long timeWindowValue = configuration.getTimeWindowValue();
final TimeUnit timeWindowUnit = configuration.getTimeWindowUnit();
startParticipant(configuration.getMaxAnalyzerAgents(), "segmentation-analyzer",
new ParticipantBuilder() {
public SegmentationParticipant createParticipant() {
return new JobRequestAnalyzerParticipant(manager, timeWindowValue, timeWindowUnit);
}
});
startParticipant(configuration.getMaxDeleteAgents(), "segmentation-delete",
new ParticipantBuilder() {
public SegmentationParticipant createParticipant() {
return new DeleteParticipant(manager);
}
});
startParticipant(configuration.getMaxPaginatorAgents(), "segmentation-paginator",
new ParticipantBuilder() {
public SegmentationParticipant createParticipant() {
return new PaginatorParticipant(manager);
}
});
startParticipant(configuration.getMaxCalculatorAgents(), "segmentation-calculator",
new ParticipantBuilder() {
public SegmentationParticipant createParticipant() {
return new CalculatorParticipant(manager);
}
});
container.acceptNewAgent("segmentation-import-agent", new ImportParticipantAgent()).start();
container.acceptNewAgent("segmentation-export-agent", new ExportParticipantAgent()).start();
}
private SegmentationJobAgent createSegmentationAgent(MODE mode) throws AspectConfigException {
return new SegmentationJobAgent(manager, newAspectManager(), new JdbcServiceUtil(), mode);
}
@Override
public void stop() throws Exception {
core.removeGlobalComponent(ContextManager.class);
}
private static AspectManager newAspectManager() throws AspectConfigException {
AspectManager aspectManager = new AspectManager();
aspectManager.load();
return aspectManager;
}
private void startParticipant(int count, String name, ParticipantBuilder builder)
throws ContainerFailureException {
for (int i = 0; i < count; i++) {
startParticipant(name + "-" + i, builder.createParticipant());
}
}
private void startParticipant(String name, SegmentationParticipant participant)
throws ContainerFailureException {
agentContainer.acceptNewAgent(name, new ParticipantAgent(participant)).start();
}
private XmlPreferenceLoader createXmlPreferenceLoader()
throws IOException, XmlException, BadConfigurationException {
XmlPreferenceLoader loader = new XmlPreferenceLoader();
InputStream inputStream = configuration.configurationUrl.openStream();
try {
loader.load(new InputSource(inputStream));
}
finally {
inputStream.close();
}
return loader;
}
static class SegmentationServerPluginConfigurationImpl
implements SegmentationServerPluginConfiguration {
private URL configurationUrl = getClass().getResource("/META-INF/segmentation-configs.xml");
private int maxAnalyzerAgents = 2;
private int maxDeleteAgents = 3;
private int maxPaginatorAgents = 3;
private int maxCalculatorAgents = 12;
private int maxSegmentationJobAgents = 1;
private long timeWindowValue = 0;
private TimeUnit timeWindowUnit = TimeUnit.SECONDS;
public int getMaxAnalyzerAgents() {
return maxAnalyzerAgents;
}
public void setMaxAnalyzerAgents(int maxAnalyzerAgents) {
this.maxAnalyzerAgents = maxAnalyzerAgents;
}
public int getMaxDeleteAgents() {
return maxDeleteAgents;
}
public void setMaxDeleteAgents(int maxDeleteAgents) {
this.maxDeleteAgents = maxDeleteAgents;
}
public int getMaxPaginatorAgents() {
return maxPaginatorAgents;
}
public void setMaxPaginatorAgents(int maxPaginatorAgents) {
this.maxPaginatorAgents = maxPaginatorAgents;
}
public int getMaxCalculatorAgents() {
return maxCalculatorAgents;
}
public void setMaxCalculatorAgents(int maxCalculatorAgents) {
this.maxCalculatorAgents = maxCalculatorAgents;
}
public int getMaxSegmentationJobAgents() {
return maxSegmentationJobAgents;
}
public void setMaxSegmentationJobAgents(int maxSegmentationJobAgents) {
this.maxSegmentationJobAgents = maxSegmentationJobAgents;
}
public void setTimeWindowValue(long timeWindowValue) {
this.timeWindowValue = timeWindowValue;
}
public void setTimeWindowUnit(TimeUnit timeWindowUnit) {
this.timeWindowUnit = timeWindowUnit;
}
public void setConfigurationFileUrl(URL url) {
configurationUrl = url;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("SegmentationServerPluginConfigurationImpl");
sb.append("{maxAnalyzerAgents=").append(maxAnalyzerAgents);
sb.append(", maxDeleteAgents=").append(maxDeleteAgents);
sb.append(", maxPaginatorAgents=").append(maxPaginatorAgents);
sb.append(", maxCalculatorAgents=").append(maxCalculatorAgents);
sb.append(", maxSegmentationJobAgents=").append(maxSegmentationJobAgents);
sb.append(", timeWindow=").append(timeWindowValue).append(' ').append(timeWindowUnit);
sb.append('}');
return sb.toString();
}
public long getTimeWindowValue() {
return timeWindowValue;
}
public TimeUnit getTimeWindowUnit() {
return timeWindowUnit;
}
}
private static class ParticipantAgent extends Agent {
private final SegmentationParticipant segmentationParticipant;
private ParticipantAgent(SegmentationParticipant segmentationParticipant) {
this.segmentationParticipant = segmentationParticipant;
}
@Override
protected void setup() {
addBehaviour(segmentationParticipant.toBehaviour());
}
@Override
protected void tearDown() {
}
}
private interface ParticipantBuilder {
SegmentationParticipant createParticipant();
}
}