package org.jentrata.ebms.as4.internal.routes; import org.apache.camel.Exchange; import org.apache.camel.LoggingLevel; import org.apache.camel.builder.RouteBuilder; import org.jentrata.ebms.EbmsConstants; import org.jentrata.ebms.MessageStatusType; import org.jentrata.ebms.cpa.CPARepository; import org.jentrata.ebms.cpa.PartnerAgreement; import org.jentrata.ebms.messaging.MessageStore; /** * Setups and outbound route per trading partner * * @author aaronwalker */ public class EbmsOutboundRouteBuilder extends RouteBuilder { private String outboundEbmsQueue = "activemq:queue:jentrata_internal_ebms_outbound"; private String ebmsResponseInbound = "activemq:queue:jentrata_internal_ebms_response"; private String messageUpdateEndpoint = MessageStore.DEFAULT_MESSAGE_UPDATE_ENDPOINT; private CPARepository cpaRepository; private String httpProxyHost = null; private String httpProxyPort = null; private String httpClientOverride = null; @Override public void configure() throws Exception { from(outboundEbmsQueue) .log(LoggingLevel.DEBUG, "Outbound:${headers}\n${body}") .removeHeaders("Camel*") .removeHeaders("JMS*") .setHeader(EbmsConstants.MESSAGE_STATUS, constant(MessageStatusType.DELIVER)) .setHeader(EbmsConstants.MESSAGE_STATUS_DESCRIPTION, constant(null)) .to(messageUpdateEndpoint) .recipientList(simple("direct:outbox_${headers.JentrataCPAId}")) .routeId("_jentrataEbmsOutbound"); for(PartnerAgreement agreement : cpaRepository.getActivePartnerAgreements()) { from("direct:outbox_" + agreement.getCpaId()) .setProperty(EbmsConstants.CPA_ID,header(EbmsConstants.CPA_ID)) .setProperty(EbmsConstants.MESSAGE_ID,header(EbmsConstants.MESSAGE_ID)) .setProperty(EbmsConstants.MESSAGE_TYPE, header(EbmsConstants.MESSAGE_TYPE)) .setProperty(EbmsConstants.MESSAGE_DIRECTION, header(EbmsConstants.MESSAGE_DIRECTION)) .setProperty(EbmsConstants.MESSAGE_CONVERSATION_ID, header(EbmsConstants.MESSAGE_CONVERSATION_ID)) .setProperty(EbmsConstants.MESSAGE_DATE, header(EbmsConstants.MESSAGE_DATE)) .log(LoggingLevel.INFO, "Delivering message to cpaId:${property.JentrataCPAId} - type:${property.JentrataMessageType} - msgId:${property.JentrataMessageID}") .onException(Exception.class) .handled(true) .log(LoggingLevel.WARN, "Failed to send cpaId:${property.JentrataCPAId} - type:${property.JentrataMessageType} - msgId:${property.JentrataMessageID}: ${exception.message}") .to("direct:processFailure") .end() .removeHeaders("Jentrata*") .setHeader(Exchange.HTTP_METHOD, constant("POST")) .to(configureEndpoint(agreement.getProtocol().getAddress())) .setHeader(EbmsConstants.CPA_ID, property(EbmsConstants.CPA_ID)) .setHeader(EbmsConstants.MESSAGE_ID, property(EbmsConstants.MESSAGE_ID)) .setHeader(EbmsConstants.MESSAGE_TYPE, property(EbmsConstants.MESSAGE_TYPE)) .setHeader(EbmsConstants.MESSAGE_DIRECTION, property(EbmsConstants.MESSAGE_DIRECTION)) .setHeader(EbmsConstants.MESSAGE_CONVERSATION_ID, property(EbmsConstants.MESSAGE_CONVERSATION_ID)) .setHeader(EbmsConstants.MESSAGE_DATE, property(EbmsConstants.MESSAGE_DATE)) .convertBodyTo(String.class) .choice() .when(header(Exchange.HTTP_RESPONSE_CODE).isEqualTo(200)) .to("direct:processSuccess") .setProperty(EbmsConstants.CPA_ID,header(EbmsConstants.CPA_ID)) .setProperty(EbmsConstants.CONTENT_TYPE,header(Exchange.CONTENT_TYPE)) .removeHeaders("*") .setHeader(EbmsConstants.CONTENT_TYPE, property(EbmsConstants.CONTENT_TYPE)) .setHeader(Exchange.HTTP_METHOD, constant("POST")) .setHeader(EbmsConstants.CPA_ID, property(EbmsConstants.CPA_ID)) .inOnly(ebmsResponseInbound) .when(header(Exchange.HTTP_RESPONSE_CODE).isEqualTo(204)) .to("direct:processSuccess") .otherwise() .to("direct:processFailure") .routeId("_jentrataEbmsOutbound" + agreement.getCpaId()); } from("direct:processSuccess") .log(LoggingLevel.INFO,"Successfully delivered cpaId:${headers.JentrataCPAId} - type:${headers.JentrataMessageType} - msgId:${headers.JentrataMessageID} - responseCode:${headers.CamelHttpResponseCode}") .log(LoggingLevel.DEBUG, "responseCode:${headers.CamelHttpResponseCode}\nheaders:${headers}\n${body}") .setHeader(EbmsConstants.MESSAGE_STATUS, constant(MessageStatusType.DELIVERED)) .setHeader(EbmsConstants.MESSAGE_STATUS_DESCRIPTION, constant(null)) .to(messageUpdateEndpoint) .wireTap(EventNotificationRouteBuilder.SEND_NOTIFICATION_ENDPOINT) .routeId("_jentrataEbmsOutboundSuccess"); from("direct:processFailure") .log(LoggingLevel.ERROR, "Failed to deliver cpaId:${headers.JentrataCPAId} - type:${headers.JentrataMessageType} - msgId:${headers.JentrataMessageID} - responseCode:${headers.CamelHttpResponseCode}") .log(LoggingLevel.DEBUG, "responseCode:${headers.CamelHttpResponseCode}\nheaders:${headers}\n${body}") .setHeader(EbmsConstants.MESSAGE_STATUS, constant(MessageStatusType.FAILED)) .setHeader(EbmsConstants.MESSAGE_STATUS_DESCRIPTION, simple("${headers.CamelHttpResponseCode} - ${body}")) .to(messageUpdateEndpoint) .wireTap(EventNotificationRouteBuilder.SEND_NOTIFICATION_ENDPOINT) .routeId("_jentrataEbmsOutboundFailure"); } public String getOutboundEbmsQueue() { return outboundEbmsQueue; } public void setOutboundEbmsQueue(String outboundEbmsQueue) { this.outboundEbmsQueue = outboundEbmsQueue; } public String getEbmsResponseInbound() { return ebmsResponseInbound; } public void setEbmsResponseInbound(String ebmsResponseInbound) { this.ebmsResponseInbound = ebmsResponseInbound; } public String getMessageUpdateEndpoint() { return messageUpdateEndpoint; } public void setMessageUpdateEndpoint(String messageUpdateEndpoint) { this.messageUpdateEndpoint = messageUpdateEndpoint; } public CPARepository getCpaRepository() { return cpaRepository; } public void setCpaRepository(CPARepository cpaRepository) { this.cpaRepository = cpaRepository; } public String getHttpProxyHost() { return httpProxyHost; } public void setHttpProxyHost(String httpProxyHost) { this.httpProxyHost = httpProxyHost; } public String getHttpProxyPort() { return httpProxyPort; } public void setHttpProxyPort(String httpProxyPort) { this.httpProxyPort = httpProxyPort; } public String getHttpClientOverride() { return httpClientOverride; } public void setHttpClientOverride(String httpClientOverride) { this.httpClientOverride = httpClientOverride; } private String configureEndpoint(String endpoint) { if(endpoint.startsWith("http://") || endpoint.startsWith("https://")) { return endpoint + configureOptions(endpoint); } else { return endpoint; } } protected String configureOptions(String endpoint) { StringBuilder options = new StringBuilder(); if(endpoint.contains("?")) { options.append("&"); } else { options.append("?"); } options.append("throwExceptionOnFailure=false"); if(isNotEmpty(httpClientOverride)) { options.append("&" + httpClientOverride); } else { if(isNotEmpty(httpProxyHost) && isNotEmpty(httpProxyPort)) { options.append("&proxyHost=" + httpProxyHost); options.append("&proxyPort=" + httpProxyPort); } } return options.toString(); } private static boolean isNotEmpty(String s) { return s != null && s.length() > 0; } }