package uk.nhs.kch.rassyeyanie.framework.route; import static org.apache.camel.component.hl7.HL7.terser; 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.Processor; import org.apache.camel.Route; import org.apache.camel.builder.PredicateBuilder; import org.apache.camel.component.hl7.HL7Constants; import org.apache.camel.component.mina.MinaConstants; import org.apache.camel.model.ChoiceDefinition; import org.apache.camel.model.RouteDefinition; import org.apache.commons.lang.StringUtils; import org.apache.mina.common.IoSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.nhs.kch.rassyeyanie.framework.HL7AdditionalConstants; public class GenericListener extends AbstractListener { private static final Logger logger = LoggerFactory .getLogger(GenericListener.class); private String queue; private int workerTotal; public String getQueue() { return this.queue; } public void setQueue(String queue) { this.queue = queue; } @Override protected void createRoute(ListenerConfig listenerConfig) { String endpoint = listenerConfig.getEndpoint(); boolean autoStart = listenerConfig.isAutoStart(); final String routeName = listenerConfig.getName(); if (StringUtils.isEmpty(routeName)) { throw new IllegalArgumentException( "routeName"); } if (StringUtils.isEmpty(endpoint)) { throw new IllegalArgumentException( "endpoint"); } logger.info("Attempting to create route {}", routeName); RouteDefinition route = this.from(endpoint); route.routeId(routeName); route.autoStartup(autoStart); route.process(new Processor() { @Override public void process(Exchange exchange) throws Exception { String connectionStatus = "Connection Status"; CamelContext camelContext = exchange.getContext(); Route camelRoute = camelContext.getRoute(routeName); Map<String, Object> routeProperties = camelRoute.getProperties(); IoSession session = (IoSession) exchange.getIn().getHeader( MinaConstants.MINA_IOSESSION); routeProperties.put(connectionStatus, new IoSessionStatus( session)); } }); this .createExceptionBlock(route, listenerConfig.getExceptionProcessor()); if (listenerConfig.getPreFormatter() != null) { route.unmarshal(listenerConfig.getPreFormatter()); } if (listenerConfig.getIcmAckCleaner() != null) { route.process(listenerConfig.getIcmAckCleaner()); } route.unmarshal().custom("hl7dataformat"); route .choice() .when(PredicateBuilder.in( this.header(HL7Constants.HL7_MESSAGE_TYPE).isEqualTo("ORM"), this.header(HL7Constants.HL7_MESSAGE_TYPE).isEqualTo("ORU"), this.header(HL7Constants.HL7_MESSAGE_TYPE).isEqualTo("ORG"), this.header(HL7Constants.HL7_MESSAGE_TYPE).isEqualTo("OMG"), PredicateBuilder.and(this.header(HL7Constants.HL7_MESSAGE_TYPE).isEqualTo("ADT"), this.header(HL7Constants.HL7_TRIGGER_EVENT).isNotEqualTo("ACK")) ) ) .setHeader( HL7AdditionalConstants.HL7_EXTERNAL_PATIENT_ID, terser("/.PID-2")) .setHeader( HL7AdditionalConstants.HL7_INTERNAL_PATIENT_ID, terser("/.PID-3")) .end(); route.convertBodyTo(String.class); route.process(new HeaderOverrideProcessor(listenerConfig, this .getWorkerTotal())); ChoiceDefinition workerChoice = route.choice(); for (int i = 0; i < this.getWorkerTotal(); i++) { workerChoice .when( this .header(HL7AdditionalConstants.HL7_PATIENT_GROUP) .isEqualTo(i + "")) .setExchangePattern(ExchangePattern.InOnly) .toF(this.queue, i) .log( String .format( "Processing MsgId: ${header.%s} / ${id} / %s / ${header.%s} / ${header.%s}", HL7Constants.HL7_MESSAGE_CONTROL, i, HL7AdditionalConstants.HL7_INTERNAL_PATIENT_ID, HL7AdditionalConstants.HL7_EXTERNAL_PATIENT_ID)); } workerChoice .otherwise() .setExchangePattern(ExchangePattern.InOnly) .toF(this.queue, 0) .log( String .format( "Processing MsgId: ${header.%s} / ${id} / %s / ${header.%s} / ${header.%s}", HL7Constants.HL7_MESSAGE_CONTROL, "default", HL7AdditionalConstants.HL7_INTERNAL_PATIENT_ID, HL7AdditionalConstants.HL7_EXTERNAL_PATIENT_ID)); // log message route.log(String.format( "Processing MsgId: ${header.%s} / ${id}", HL7Constants.HL7_MESSAGE_CONTROL)); route.log("body"); route.unmarshal().custom("hl7dataformat"); // acknowledge this.createAcknowledgementBlock( route, listenerConfig.getAcknowledgementProcessor()); // log acknowledgement route.log("body"); } private void createAcknowledgementBlock(RouteDefinition route, Processor acknowledgementProcessor) { route.process(acknowledgementProcessor); } private void createExceptionBlock(RouteDefinition route, Processor exceptionHandler) { route .onException(Exception.class) .log(LoggingLevel.ERROR, this.exceptionMessage().toString()) .to(ERROR_LOG) .handled(true) .process(exceptionHandler) .end(); } public int getWorkerTotal() { return this.workerTotal; } public void setWorkerTotal(int workerTotal) { this.workerTotal = workerTotal; } private class IoSessionStatus { private final IoSession session; public IoSessionStatus(IoSession session) { this.session = session; } @Override public String toString() { return this.session.isConnected() ? "Connected" : "Disconnected"; } } }