/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.synapse.transport.fix; import org.apache.axiom.attachments.ByteArrayDataSource; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNamespace; import org.apache.axiom.soap.SOAPBody; import org.apache.axiom.soap.SOAPEnvelope; import org.apache.axiom.soap.SOAPFactory; import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory; import org.apache.axis2.AxisFault; import org.apache.axis2.context.MessageContext; import org.apache.axis2.transport.base.BaseUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import quickfix.*; import quickfix.field.*; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.xml.namespace.QName; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.*; public class FIXUtils { private static final Log log = LogFactory.getLog(FIXUtils.class); private static FIXUtils _instance = new FIXUtils(); public static FIXUtils getInstance() { return _instance; } /** * FIX messages are non-XML. So convert them into XML using the AXIOM API. * Put the FIX message into an Axis2 MessageContext.The basic format of the * generated SOAP envelope; * <p/> * <soapEnvelope> * <soapBody> * <message> * <header> ....</header> * <body> .... </body> * <trailer> .... </trailer> * </message> * </soapBody> * </soapEnvelope> * * @param message the FIX message * @param counter application level sequence number of the message * @param sessionID the incoming session * @param msgCtx the Axis2 MessageContext to hold the FIX message * @throws AxisFault the exception thrown when invalid soap envelopes are set to the msgCtx */ public void setSOAPEnvelope(Message message, int counter, String sessionID, MessageContext msgCtx) throws AxisFault { if (log.isDebugEnabled()) { log.debug("Creating SOAP envelope for FIX message..."); } SOAPFactory soapFactory = new SOAP11Factory(); OMElement msg = soapFactory.createOMElement(FIXConstants.FIX_MESSAGE, null); msg.addAttribute(soapFactory.createOMAttribute(FIXConstants.FIX_MESSAGE_INCOMING_SESSION, null, sessionID)); msg.addAttribute(soapFactory.createOMAttribute (FIXConstants.FIX_MESSAGE_COUNTER, null, String.valueOf(counter))); OMElement header = soapFactory.createOMElement(FIXConstants.FIX_HEADER, null); OMElement body = soapFactory.createOMElement(FIXConstants.FIX_BODY, null); OMElement trailer = soapFactory.createOMElement(FIXConstants.FIX_TRAILER, null); //process FIX header Iterator<Field<?>> iter = message.getHeader().iterator(); if (iter != null) { while (iter.hasNext()) { Field<?> field = iter.next(); OMElement msgField = soapFactory.createOMElement(FIXConstants.FIX_FIELD, null); msgField.addAttribute(soapFactory.createOMAttribute(FIXConstants.FIX_FIELD_ID, null, String.valueOf(field.getTag()))); Object value = field.getObject(); if (value instanceof byte[]) { DataSource dataSource = new ByteArrayDataSource((byte[]) value); DataHandler dataHandler = new DataHandler(dataSource); String contentID = msgCtx.addAttachment(dataHandler); OMElement binaryData = soapFactory.createOMElement( FIXConstants.FIX_BINARY_FIELD, null); String binaryCID = "cid:" + contentID; binaryData.addAttribute(FIXConstants.FIX_MESSAGE_REFERENCE, binaryCID, null); msgField.addChild(binaryData); } else { createOMText(soapFactory, msgField, value.toString()); } header.addChild(msgField); } } //process FIX body convertFIXBodyToXML(message, body, soapFactory, msgCtx); //process FIX trailer iter = message.getTrailer().iterator(); if (iter != null) { while (iter.hasNext()) { Field<?> field = iter.next(); OMElement msgField = soapFactory.createOMElement(FIXConstants.FIX_FIELD, null); msgField.addAttribute(soapFactory. createOMAttribute(FIXConstants.FIX_FIELD_ID, null, String.valueOf(field.getTag()))); Object value = field.getObject(); if (value instanceof byte[]) { DataSource dataSource = new ByteArrayDataSource((byte[]) value); DataHandler dataHandler = new DataHandler(dataSource); String contentID = msgCtx.addAttachment(dataHandler); OMElement binaryData = soapFactory.createOMElement( FIXConstants.FIX_BINARY_FIELD, null); String binaryCID = "cid:" + contentID; binaryData.addAttribute(FIXConstants.FIX_MESSAGE_REFERENCE, binaryCID, null); msgField.addChild(binaryData); } else { createOMText(soapFactory, msgField, value.toString()); } trailer.addChild(msgField); } } msg.addChild(header); msg.addChild(body); msg.addChild(trailer); SOAPEnvelope envelope = soapFactory.getDefaultEnvelope(); envelope.getBody().addChild(msg); msgCtx.setEnvelope(envelope); } /** * Constructs the XML infoset for the FIX message body * * @param message the FIX message * @param body the body element of the XML infoset * @param soapFactory the SOAP factory to create XML elements * @param msgCtx the Axis2 Message context * @throws AxisFault on error */ private void convertFIXBodyToXML(FieldMap message, OMElement body, SOAPFactory soapFactory, MessageContext msgCtx) throws AxisFault{ if (log.isDebugEnabled()) { log.debug("Generating FIX message body (Message ID: " + msgCtx.getMessageID() + ")"); } Iterator<Field<?>> iter = message.iterator(); if (iter != null) { while (iter.hasNext()) { Field<?> field = iter.next(); OMElement msgField = soapFactory.createOMElement(FIXConstants.FIX_FIELD, null); msgField.addAttribute(soapFactory. createOMAttribute(FIXConstants.FIX_FIELD_ID, null, String.valueOf(field.getTag()))); Object value = field.getObject(); if (value instanceof byte[]) { DataSource dataSource = new ByteArrayDataSource((byte[]) value); DataHandler dataHandler = new DataHandler(dataSource); String contentID = msgCtx.addAttachment(dataHandler); OMElement binaryData = soapFactory.createOMElement( FIXConstants.FIX_BINARY_FIELD, null); String binaryCID = "cid:" + contentID; binaryData.addAttribute(FIXConstants.FIX_MESSAGE_REFERENCE, binaryCID, null); msgField.addChild(binaryData); } else { createOMText(soapFactory, msgField, value.toString()); } body.addChild(msgField); } } //process FIX repeating groups Iterator<Integer> groupKeyItr = message.groupKeyIterator(); if (groupKeyItr != null) { while (groupKeyItr.hasNext()) { int groupKey = groupKeyItr.next(); OMElement groupsField = soapFactory.createOMElement(FIXConstants.FIX_GROUPS, null); groupsField.addAttribute(FIXConstants.FIX_FIELD_ID, String.valueOf(groupKey),null); List<Group> groupList = message.getGroups(groupKey); Iterator<Group> groupIterator = groupList.iterator(); while (groupIterator.hasNext()) { Group msgGroup = groupIterator.next(); OMElement groupField = soapFactory.createOMElement(FIXConstants.FIX_GROUP, null); // rec. call the method to process the repeating groups convertFIXBodyToXML(msgGroup, groupField, soapFactory, msgCtx); groupsField.addChild(groupField); } body.addChild(groupsField); } } } private void generateFIXBody(OMElement node, FieldMap message, MessageContext msgCtx, boolean withNs, String nsURI, String nsPrefix) throws IOException { Iterator bodyElements = node.getChildElements(); while (bodyElements.hasNext()) { OMElement bodyNode = (OMElement) bodyElements.next(); String nodeLocalName = bodyNode.getLocalName(); //handle repeating groups if (nodeLocalName.equals(FIXConstants.FIX_GROUPS)){ int groupsKey = Integer.parseInt(bodyNode.getAttributeValue( new QName(FIXConstants.FIX_FIELD_ID))); Group group; Iterator groupElements = bodyNode.getChildElements(); while (groupElements.hasNext()){ OMElement groupNode = (OMElement) groupElements.next(); Iterator groupFields = groupNode.getChildrenWithName(new QName(FIXConstants.FIX_FIELD)); List<Integer> idList = new ArrayList<Integer>(); while (groupFields.hasNext()) { OMElement fieldNode = (OMElement) groupFields.next(); idList.add(Integer.parseInt(fieldNode.getAttributeValue( new QName(FIXConstants.FIX_FIELD_ID)))); } int[] order = new int[idList.size()]; for (int i = 0; i < order.length; i++) { order[i] = idList.get(i); } group = new Group(groupsKey, order[0], order); generateFIXBody(groupNode, group, msgCtx, withNs, nsURI, nsPrefix); message.addGroup(group); } } else { String tag; if (withNs) { tag = bodyNode.getAttributeValue(new QName(nsURI, FIXConstants.FIX_FIELD_ID, nsPrefix)); } else { tag = bodyNode.getAttributeValue(new QName(FIXConstants.FIX_FIELD_ID)); } String value = null; OMElement child = bodyNode.getFirstElement(); if (child != null) { String href; if (withNs) { href = bodyNode.getFirstElement(). getAttributeValue(new QName(nsURI, FIXConstants.FIX_FIELD_ID, nsPrefix)) ; } else { href = bodyNode.getFirstElement(). getAttributeValue(new QName(FIXConstants.FIX_MESSAGE_REFERENCE)); } if (href != null) { DataHandler binaryDataHandler = msgCtx.getAttachment(href.substring(4)); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); binaryDataHandler.writeTo(outputStream); value = new String(outputStream.toByteArray()); } } else { value = bodyNode.getText(); } if (value != null) { message.setString(Integer.parseInt(tag), value); } } } } /** * Extract the FIX message embedded in an Axis2 MessageContext * * @param msgCtx the Axis2 MessageContext * @return a FIX message * @throws java.io.IOException the exception thrown when handling erroneous binary content */ public Message createFIXMessage(MessageContext msgCtx) throws IOException { if (log.isDebugEnabled()) { log.debug("Extracting FIX message from the message context (Message ID: " + msgCtx.getMessageID() + ")"); } boolean withNs = false; String nsPrefix = null; String nsURI = null; Message message = new Message(); SOAPBody soapBody = msgCtx.getEnvelope().getBody(); //find namespace information embedded in the FIX payload OMNamespace ns = getNamespaceOfFIXPayload(soapBody); if (ns != null) { withNs = true; nsPrefix = ns.getPrefix(); nsURI = ns.getNamespaceURI(); } OMElement messageNode; if (withNs) { messageNode = soapBody.getFirstChildWithName(new QName(nsURI, FIXConstants.FIX_MESSAGE, nsPrefix)); } else { messageNode = soapBody.getFirstChildWithName(new QName(FIXConstants.FIX_MESSAGE)); } Iterator messageElements = messageNode.getChildElements(); while (messageElements.hasNext()) { OMElement node = (OMElement) messageElements.next(); //create FIX header if (node.getQName().getLocalPart().equals(FIXConstants.FIX_HEADER)) { Iterator headerElements = node.getChildElements(); while (headerElements.hasNext()) { OMElement headerNode = (OMElement) headerElements.next(); String tag; if (withNs) { tag = headerNode.getAttributeValue(new QName(nsURI, FIXConstants.FIX_FIELD_ID, nsPrefix)); } else { tag = headerNode.getAttributeValue(new QName(FIXConstants.FIX_FIELD_ID)); } String value = null; OMElement child = headerNode.getFirstElement(); if (child != null) { String href; if (withNs) { href = headerNode.getFirstElement().getAttributeValue( new QName(nsURI, FIXConstants.FIX_MESSAGE_REFERENCE, nsPrefix)); } else { href = headerNode.getFirstElement(). getAttributeValue(new QName(FIXConstants.FIX_MESSAGE_REFERENCE)); } if (href != null) { DataHandler binaryDataHandler = msgCtx.getAttachment(href.substring(4)); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); binaryDataHandler.writeTo(outputStream); value = new String(outputStream.toByteArray()); } } else { value = headerNode.getText(); } if (value != null) { message.getHeader().setString(Integer.parseInt(tag), value); } } } else if (node.getQName().getLocalPart().equals(FIXConstants.FIX_BODY)) { //create FIX body generateFIXBody(node, message, msgCtx, withNs, nsURI, nsPrefix); } else if (node.getQName().getLocalPart().equals(FIXConstants.FIX_TRAILER)) { //create FIX trailer Iterator trailerElements = node.getChildElements(); while (trailerElements.hasNext()) { OMElement trailerNode = (OMElement) trailerElements.next(); String tag; if (withNs) { tag = trailerNode.getAttributeValue(new QName(nsURI, FIXConstants.FIX_FIELD_ID, nsPrefix)); } else { tag = trailerNode.getAttributeValue(new QName(FIXConstants.FIX_FIELD_ID)); } String value = null; OMElement child = trailerNode.getFirstElement(); if (child != null) { String href; if (withNs) { href = trailerNode.getFirstElement().getAttributeValue( new QName(nsURI, FIXConstants.FIX_FIELD_ID, nsPrefix)); } else { href = trailerNode.getFirstElement(). getAttributeValue(new QName(FIXConstants.FIX_MESSAGE_REFERENCE)); } if (href != null) { DataHandler binaryDataHandler = msgCtx.getAttachment(href.substring(4)); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); binaryDataHandler.writeTo(outputStream); value = new String(outputStream.toByteArray()); } } else { value = trailerNode.getText(); } if (value != null) { message.getTrailer().setString(Integer.parseInt(tag), value); } } } } return message; } /** * Generate EPRs for the specified FIX service. A FIX end point can be uniquely * identified by a <host(IP), port> pair. Add some additional FIX session details * so the EPRs are more self descriptive. * A FIX EPR generated here looks like; * fix://10.100.1.80:9898?BeginString=FIX.4.4&SenderCompID=BANZAI&TargetCompID=EXEC& * SessionQualifier=mySession&Serviec=StockQuoteProxy * * @param acceptor the SocketAcceptor associated with the service * @param serviceName the name of the service * @param ip the IP address of the host * @return an array of EPRs for the specified service in String format */ public static String[] generateEPRs(SocketAcceptor acceptor, String serviceName, String ip) { //Get all the addresses associated with the acceptor Map<SessionID, SocketAddress> socketAddresses = acceptor.getAcceptorAddresses(); //Get all the sessions (SessionIDs) associated with the acceptor ArrayList<SessionID> sessions = acceptor.getSessions(); String[] EPRList = new String[sessions.size()]; //Generate an EPR for each session/socket address for (int i = 0; i < sessions.size(); i++) { SessionID sessionID = sessions.get(i); InetSocketAddress socketAddress = (InetSocketAddress) socketAddresses.get(sessionID); EPRList[i] = FIXConstants.FIX_PREFIX + ip + ":" + socketAddress.getPort() + "?" + FIXConstants.BEGIN_STRING + "=" + sessionID.getBeginString() + "&" + FIXConstants.SENDER_COMP_ID + "=" + sessionID.getTargetCompID() + "&" + FIXConstants.TARGET_COMP_ID + "=" + sessionID.getSenderCompID(); String sessionQualifier = sessionID.getSessionQualifier(); if (sessionQualifier != null && !sessionQualifier.equals("")) { EPRList[i] += "&" + FIXConstants.SESSION_QUALIFIER + "=" + sessionQualifier; } String senderSubID = sessionID.getSenderSubID(); if (senderSubID != null && !senderSubID.equals("")) { EPRList[i] += "&" + FIXConstants.SENDER_SUB_ID + "=" + senderSubID; } String targetSubID = sessionID.getTargetSubID(); if (targetSubID != null && !targetSubID.equals("")) { EPRList[i] += "&" + FIXConstants.TARGET_SUB_ID + "=" + targetSubID; } String senderLocationID = sessionID.getSenderLocationID(); if (senderLocationID != null && !senderLocationID.equals("")) { EPRList[i] += "&" + FIXConstants.SENDER_LOCATION_ID + "=" + senderLocationID; } String targetLocationID = sessionID.getTargetLocationID(); if (targetLocationID != null && !targetLocationID.equals("")) { EPRList[i] += "&" + FIXConstants.TARGET_LOCATION_ID + "=" + targetLocationID; } EPRList[i] += "&Service=" + serviceName; } return EPRList; } public static String[] getEPRs(SessionSettings settings) throws FieldConvertError, ConfigError { Iterator<SessionID> sessions = settings.sectionIterator(); String[] EPRs = new String[settings.size()]; int i = 0; while (sessions.hasNext()) { SessionID session = sessions.next(); String EPR = FIXConstants.FIX_PREFIX; String paramValue; EPR += settings.getString(session, FIXConstants.SOCKET_CONNECT_HOST); EPR += ":" + settings.getString(session, FIXConstants.SOCKET_CONNECT_PORT); EPR += "?" + FIXConstants.BEGIN_STRING + "="; EPR += settings.getString(session, FIXConstants.BEGIN_STRING); EPR += "&" + FIXConstants.SENDER_COMP_ID + "="; EPR += settings.getString(session, FIXConstants.SENDER_COMP_ID); EPR += "&" + FIXConstants.TARGET_COMP_ID + "="; EPR += settings.getString(session, FIXConstants.TARGET_COMP_ID); try { paramValue = settings.getString(session, FIXConstants.SENDER_SUB_ID); if (paramValue != null) { EPR += "&" + FIXConstants.SENDER_SUB_ID + "="; EPR += paramValue; } } catch (ConfigError ignore) { } try { paramValue = settings.getString(session, FIXConstants.SENDER_LOCATION_ID); if (paramValue != null) { EPR += "&" + FIXConstants.SENDER_LOCATION_ID + "="; EPR += paramValue; } } catch (ConfigError ignore) { } try { paramValue = settings.getString(session, FIXConstants.TARGET_SUB_ID); if (paramValue != null) { EPR += "&" + FIXConstants.TARGET_SUB_ID + "="; EPR += paramValue; } } catch (ConfigError ignore) { } try { paramValue = settings.getString(session, FIXConstants.TARGET_LOCATION_ID); if (paramValue != null) { EPR += "&" + FIXConstants.TARGET_LOCATION_ID + "="; EPR += paramValue; } } catch (ConfigError ignore) { } EPRs[i] = EPR; } return EPRs; } /** * Compares two given FIX URL strings. The second URL is considered equal to the * first URL if all the properties in the first URL also exist in the second URL * and if they have equals values. * * @param url1 a FIX URL String * @param url2 a FIX URL String * @return a boolean value */ public static boolean compareURLs(String url1, String url2) { if (!url1.substring(0, url1.indexOf("?")).equals(url2.substring(0, url2.indexOf("?")))) { return false; } else { Hashtable<String,String> properties1 = BaseUtils.getEPRProperties(url1); Hashtable<String, String> properties2 = BaseUtils.getEPRProperties(url2); for (Map.Entry<String,String> entry : properties1.entrySet()) { if (!properties2.containsKey(entry.getKey())) { return false; } else if (!properties1.get(entry.getKey()).equals(entry.getValue())) { return false; } } } return true; } /* * This is here because AXIOM does not support removing CDATA tags yet. Given a String embedded in * CDATA tags this method will return the String element only. * * @param str the String with CDATA tags * @return String with CDATA tags stripped * private static String removeCDATA(String str) { if (str.indexOf("<![CDATA[") != -1) { str = str.split("CDATA")[1].split("]></field>")[0]; str= str.substring(1, str.length()-1); return str; } else { return str; } }*/ /** * Extracts the fields related to message forwarding (third party routing) from * the FIX header. * * @param message the FIX message * @return a Map of forwarding parameters */ public static Map<String, String> getMessageForwardingParameters(Message message) { Map<String, String> map = new HashMap<String, String>(); String value = getHeaderFieldValue(message, BeginString.FIELD); map.put(FIXConstants.BEGIN_STRING, value); value = getHeaderFieldValue(message, SenderCompID.FIELD); map.put(FIXConstants.SENDER_COMP_ID, value); value = getHeaderFieldValue(message, SenderSubID.FIELD); map.put(FIXConstants.SENDER_SUB_ID, value); value = getHeaderFieldValue(message, SenderLocationID.FIELD); map.put(FIXConstants.SENDER_LOCATION_ID, value); value = getHeaderFieldValue(message, TargetCompID.FIELD); map.put(FIXConstants.TARGET_COMP_ID, value); value = getHeaderFieldValue(message, DeliverToCompID.FIELD); map.put(FIXConstants.DELIVER_TO_COMP_ID, value); value = getHeaderFieldValue(message, DeliverToSubID.FIELD); map.put(FIXConstants.DELIVER_TO_SUB_ID, value); value = getHeaderFieldValue(message, DeliverToLocationID.FIELD); map.put(FIXConstants.DELIVER_TO_LOCATION_ID, value); value = getHeaderFieldValue(message, OnBehalfOfCompID.FIELD); map.put(FIXConstants.ON_BEHALF_OF_COMP_ID, value); value = getHeaderFieldValue(message, OnBehalfOfSubID.FIELD); map.put(FIXConstants.ON_BEHALF_OF_SUB_ID, value); value = getHeaderFieldValue(message, OnBehalfOfLocationID.FIELD); map.put(FIXConstants.ON_BEHALF_OF_LOCATION_ID, value); return map; } private static String getHeaderFieldValue(Message message, int tag) { try { return message.getHeader().getString(tag); } catch (FieldNotFound fieldNotFound) { return null; } } /** * Extracts the name of the service which processed the message from the MessageContext * * @param msgCtx Axis2 MessageContext of a message * @return name of the AxisService * @throws org.apache.axis2.AxisFault on error */ public static String getServiceName(MessageContext msgCtx) throws AxisFault { Object serviceParam = msgCtx.getProperty(FIXConstants.FIX_SERVICE_NAME); if (serviceParam != null) { String serviceName = serviceParam.toString(); if (serviceName != null && !serviceName.equals("")) { return serviceName; } } Map trpHeaders = (Map) msgCtx.getProperty(MessageContext.TRANSPORT_HEADERS); //try to get the service from the transport headers if (trpHeaders != null) { String serviceName = (String) trpHeaders.get(FIXConstants.FIX_MESSAGE_SERVICE); if (serviceName != null) { return serviceName; } } throw new AxisFault("Unable to find a valid service for the message"); } /** * Extracts the application type for the message from the message context * * @param msgCtx Axis2 Message Context * @return application type of the message */ public static String getFixApplication(MessageContext msgCtx) { Map trpHeaders = (Map) msgCtx.getProperty(MessageContext.TRANSPORT_HEADERS); //try to get the application type from the transport headers String fixApplication = null; if (trpHeaders != null) { fixApplication = (String) trpHeaders.get(FIXConstants.FIX_MESSAGE_APPLICATION); } return fixApplication; } /** * Creates a Map of transport headers for a message * * @param serviceName name of the service to which the message belongs to * @param fixApplication FIX application type * @return a Map of transport headers */ public static Map<String, String> getTransportHeaders(String serviceName, String fixApplication) { Map<String, String> trpHeaders = new HashMap<String, String>(); trpHeaders.put(FIXConstants.FIX_MESSAGE_SERVICE, serviceName); trpHeaders.put(FIXConstants.FIX_MESSAGE_APPLICATION, fixApplication); return trpHeaders; } /** * Reads a FIX EPR and returns the host and port on a String array * * @param fixEPR a FIX EPR * @return an array of Strings containing addressing elements * @throws AxisFault on error */ public static String[] getSocketAddressElements(String fixEPR) throws AxisFault { int propPos = fixEPR.indexOf("?"); if (propPos != -1 && fixEPR.startsWith(FIXConstants.FIX_PREFIX)) { String address = fixEPR.substring(FIXConstants.FIX_PREFIX.length(), propPos); String[] socketAddressElemets = address.split(":"); if (socketAddressElemets.length == 2) { return socketAddressElemets; } } throw new AxisFault("Malformed FIX EPR: " + fixEPR); } /** * Reads the SOAP body of a message and attempts to retreive the application level * sequence number * * @param msgCtx Axis2 MessageContext * @return application level sequence number or -1 */ public static int getSequenceNumber(MessageContext msgCtx) { int seqNum; SOAPBody body = msgCtx.getEnvelope().getBody(); OMNamespace ns = getNamespaceOfFIXPayload(body); if (ns == null) { OMElement messageNode = body.getFirstChildWithName(new QName(FIXConstants.FIX_MESSAGE)); String value = messageNode.getAttributeValue(new QName(FIXConstants.FIX_MESSAGE_COUNTER)); if (value != null) { seqNum = Integer.parseInt(value); } else { seqNum = -1; } } else { seqNum = getSequenceNumber(body, ns); } return seqNum; } /** * Reads the SOAP body of a message and attempts to retreive the application level * sequence number * * @param body Body of the SOAP message * @param ns Namespace * @return application level sequence number or -1 */ private static int getSequenceNumber(SOAPBody body, OMNamespace ns) { OMElement messageNode = body.getFirstChildWithName(new QName(ns.getNamespaceURI(), FIXConstants.FIX_MESSAGE, ns.getPrefix())); String value = messageNode.getAttributeValue(new QName(ns.getNamespaceURI(), FIXConstants.FIX_MESSAGE_COUNTER, ns.getPrefix())); if (value != null) { return Integer.parseInt(value); } else { return -1; } } /** * Reads the SOAP body of a message and attempts to retreive the session identifier string * * @param msgCtx Axis2 MessageContext * @return a String uniquely identifying a session or null */ public static String getSourceSession(MessageContext msgCtx) { String srcSession; SOAPBody body = msgCtx.getEnvelope().getBody(); OMNamespace ns = getNamespaceOfFIXPayload(body); if (ns == null) { OMElement messageNode = body.getFirstChildWithName(new QName(FIXConstants.FIX_MESSAGE)); srcSession = messageNode.getAttributeValue(new QName( FIXConstants.FIX_MESSAGE_INCOMING_SESSION)); } else { srcSession = getSourceSession(body, ns); } return srcSession; } /** * Reads the SOAP body of a message and attempts to retreive the session identifier string * with a namesapce * * @param body Body of the SOAP message * @param ns Namespace * @return a String uniquely identifying a session or null */ private static String getSourceSession(SOAPBody body, OMNamespace ns) { OMElement messageNode = body.getFirstChildWithName(new QName(ns.getNamespaceURI(), FIXConstants.FIX_MESSAGE, ns.getPrefix())); return messageNode.getAttributeValue(new QName(ns.getNamespaceURI(), FIXConstants.FIX_MESSAGE_INCOMING_SESSION, ns.getPrefix())); } /** * Creates a text node within a CDATA section selectively by looking at the enclosing text. * @param soapFactory * @param field * @param text */ private static void createOMText(SOAPFactory soapFactory, OMElement field, String text) { if (text == null) { return; } if (text.indexOf('<') == -1 && text.indexOf('&') == -1) { soapFactory.createOMText(field, text); } else { soapFactory.createOMText(field, text, OMElement.CDATA_SECTION_NODE); } } /** * Read the FIX message payload and identify the namespace if exists * * @param fixBody FIX message payload * @return namespace as a OMNamespace */ public static OMNamespace getNamespaceOfFIXPayload(SOAPBody fixBody){ return fixBody.getFirstElementNS(); } }