package uk.nhs.kch.rassyeyanie.framework.route;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.LoggingLevel;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
import org.apache.camel.Route;
import org.apache.camel.component.hl7.HL7DataFormat;
import org.apache.camel.model.FilterDefinition;
import org.apache.camel.model.ProcessorDefinition;
import org.apache.camel.model.RouteDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import uk.nhs.kch.rassyeyanie.framework.HL7AdditionalConstants;
import uk.nhs.kch.rassyeyanie.framework.HapiUtil;
import ca.uhn.hl7v2.model.AbstractMessage;
public class GenericTransformRoute
extends AbstractConsumer
{
private String outboundQueue;
private List<Object> identifiers;
private List<Object> processors;
// TODO: change to boolean -- currently checking for not null
private AbstractMessage outputPlaceholder;
private final Logger logger;
private String[] workerIds;
private HL7DataFormat hl7DataFormat;
public AbstractMessage getOutputPlaceholder()
{
return this.outputPlaceholder;
}
public void setOutputPlaceholder(AbstractMessage outputPlaceholder)
{
this.outputPlaceholder = outputPlaceholder;
}
public GenericTransformRoute()
{
this.identifiers = Collections.emptyList();
this.processors = Collections.emptyList();
this.logger = LoggerFactory.getLogger(this.getClass());
}
public String getOutboundQueue()
{
return this.outboundQueue;
}
public void setOutboundQueue(String outboundQueue)
{
this.outboundQueue = outboundQueue;
}
@Override
public void configure()
throws Exception
{
final String routeName = this.getRouteName();
String inboundQueue = this.getInboundQueue();
if (this.outputPlaceholder != null &&
(this.processors.isEmpty() || this.processors.size() == 0))
{
Exception ex =
new Exception(
String
.format(
"outputPlaceholder is set but no processors configured for %s",
routeName));
throw ex;
}
if (this.getWorkerIds() != null)
for (String workerid : this.getWorkerIds())
{
final String loopRouteName = String.format(routeName, workerid);
this.logger.info(String.format(
"Creating route %s",
loopRouteName));
RouteDefinition routeDefinition =
this.from(inboundQueue + "-" + workerid);
ProcessorDefinition<RouteDefinition> processDefinition =
routeDefinition.routeId(loopRouteName);
FilterDefinition rootChoice =
processDefinition.filter(new Predicate() {
@Override
public boolean matches(Exchange exchange)
{
return true;
}
});
FilterDefinition filterDefinition = rootChoice;
for (Object identifier : this.getIdentifiers())
{
filterDefinition =
filterDefinition.filter().method(identifier);
filterDefinition.id(identifier.toString());
}
this.attachFilterProcessAndDestination(
loopRouteName,
filterDefinition,
workerid);
routeDefinition
.choice()
.when()
.property(Exchange.FILTER_MATCHED)
.process(new Processor() {
@Override
public void process(Exchange exchange)
throws Exception
{
String exchangedFilterMatch =
"Exchanges matching filter";
CamelContext camelContext = exchange.getContext();
Route camelRoute =
camelContext.getRoute(loopRouteName);
Map<String, Object> routeProperties =
camelRoute.getProperties();
int totalExchangesFiltered = 1;
if (routeProperties
.containsKey(exchangedFilterMatch))
totalExchangesFiltered =
((Integer) routeProperties
.get(exchangedFilterMatch)) + 1;
routeProperties.put(
exchangedFilterMatch,
totalExchangesFiltered);
}
})
.end();
}
}
private void
attachFilterProcessAndDestination(String routeName,
FilterDefinition filterDefinition,
String workerId)
{
filterDefinition
.setHeader(HL7AdditionalConstants.HL7_SOURCE_MESSAGE)
.body();
if (this.outputPlaceholder != null)
{
filterDefinition.process(new Processor() {
@Override
public void process(Exchange exchange)
throws Exception
{
AbstractMessage message =
exchange.getIn().getBody(AbstractMessage.class);
exchange.getIn().setBody(
HapiUtil.createEmptyMessage(message, "2.4"));
}
});
// clear message for placeholder to be reused
filterDefinition.process(new Processor() {
@Override
public void process(Exchange exchange)
throws Exception
{
AbstractMessage message =
exchange.getIn().getBody(AbstractMessage.class);
message.clear();
}
});
}
for (Object processor : this.processors)
filterDefinition.bean(processor).id(processor.toString());
// remove from header before going to sender
filterDefinition
.removeHeader(HL7AdditionalConstants.HL7_SOURCE_MESSAGE);
filterDefinition.log(
LoggingLevel.DEBUG,
this.getBeginProcessMessage(routeName));
filterDefinition.to(
ExchangePattern.InOnly,
this.outboundQueue + "-" + workerId).log(
LoggingLevel.DEBUG,
this.getEndProcessMessage(routeName));
}
private String getEndProcessMessage(String routeName)
{
return String
.format(
"GenericTransformRoute: End of processing route \"%s\" to outbound Queue \"%s\"",
routeName,
this.outboundQueue);
}
private String getBeginProcessMessage(String routeName)
{
return String.format(
"GenericTransformRoute: Start of processing route \"%s\"",
routeName);
}
public List<Object> getIdentifiers()
{
return this.identifiers;
}
public void setIdentifiers(List<Object> identifiers)
{
this.identifiers = identifiers;
}
public List<Object> getProcessors()
{
return this.processors;
}
public void setProcessors(List<Object> processors)
{
this.processors = processors;
}
public String[] getWorkerIds()
{
return this.workerIds;
}
public void setWorkerIds(String[] workerIds)
{
this.workerIds = workerIds;
}
public HL7DataFormat getHl7DataFormat()
{
return this.hl7DataFormat;
}
@Autowired
public void setHl7DataFormat(HL7DataFormat hl7DataFormat)
{
this.hl7DataFormat = hl7DataFormat;
}
}