Author : Colm Carew
Date : 2017-01-31
The Soap Router is an Application which as of writing this runs on Port 8085 and listens for Soap Messages (https://en.wikipedia.org/wiki/SOAP).
Currently deployed on ExtQA : https://qaextlb1.err/soap/
Will be deployed to ExteNet production : https://nocportal.extenetsystems.com/soap/
It basically listens for XML messages.
Once the message is received it compared against soap schemas which are stored in the MySQL database. If a match is found then the XML of the message will be sent onto the Soap Exchange and be tagged with the Customer the schema belongs to and the binding tag that is associated with the customer.
The Router also consumes a queue which is currently bound to the ebonding outbound exchange. If a message is received (the payload should be XML) on this queue then the Soap Router will look for the bound Customer, convert the message to a SoapMessage and send it to the associated customer endpoint.
The Soap Router is currently only being used a part of the eBonding Project : eBonding Project.
The Soap Router allows us to communicate with other vendors and systems that support Soap (Dev is required but the framework is in place).
A Soap Transmitter sends a message to our Soap Endpoint and our Soap Router receives it.
Our Soap Router creates a temporary callback queue (queue is destroyed as soon as the channel is closed) titled eBonding callback queue in the diagram above and we will use the message we get from this callback queue as the response we send back to the Customer. We also generate a Correlation ID in order to determine if the received message we get back on this queue is the one we care about (just in case another message makes it on the queue but we don't care about it). The Soap Router also consumes this queue.
The Soap Component then sends a message to the Soap Exchange and tags the message with the associated Customer tag. In the Customer domain of the Soap Router this is the exchangeTagName field and for now it will only ever be 'eBonding'.
As for the payload of the message we put on the exchange, the main payload is whatever XML we received from the Customer. Headers are also appended to the message. This is essentially metadata. For now the message headers are the customer name and whether or not the customer sent the correct HTTPS Basic Authentication values (a boolean true or false). Properties are also appended to the exchange methods. These properties are the reply queue name and the reply queue correlation ID which will be used in replying.
The appropriate queue (in this case the eBonding inbound queue) picks up the message. Processes it, generates the desired XML response string and replies to the temporary reply queue with the correlation ID.
The Soap Router receives a message on the callback queue then generates a Soap Message from the received XML and responds to the customer.
Some points to note here is that there are timeouts in place such that if the Soap Router does not get a response on it's callback queue with the correct correlation ID in a time set in the SoapConfig.groovy of the application then it will reply with a generic timeout soap message.
In the case of Outbound the Soap Router consumes the Soap Outbound Queue and binds the queue to the eBonding outbound exchange with the routing key 'soap'. Basically the Soap Outbound Queue waits for soap messages from eBonding only for now.
It obtains the customer from the message headers and tries to find that customer and their endpoint in the Soap Database. If it does it will post the message payload to that endpoint with the customer outbound credentials.
It will then log the response we get from the customer endpoint.
If we do not receive a response within a configurable number of seconds then the thread posting the message will timeout. This is incase the post does not finish successfully and keeps trying to post.
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Header/><SOAP-ENV:Body>
<m:processSync xmlns:m="http://eBonding/taservice/send"><?xml version="1.0"?>
<tML-TA:VerifyRepairCompletionRequest xsi:schemaLocation="http://www.ansi.org/tML/TA/tML-TAtML-TA.xsd" xmlns="http://www.ansi.org/tML/TA/tML-TA" xmlns:tML-TABase="http://www.ansi.org/tML/TA/tML-TABase" xmlns:tmlta="http://www.ansi.org/tML/TA/tML-TA" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tML-TA:RequestId>00000d0r000201728</tML-TA:RequestId>
<tML-TA:Customer>
<tML-TABase:UserId>EXT-M</tML-TABase:UserId>
<tML-TABase:ServiceProfile>service profile</tML-TABase:ServiceProfile>
</tML-TA:Customer>
<tML-TA:TargetObjectName>
<tML-TABase:DistinguishedName>
<tML-TABase:RDNSequenceItem>
<tML-TABase:Type>networkID</tML-TABase:Type>
<tML-TABase:Assertion>EXT</tML-TABase:Assertion>
</tML-TABase:RDNSequenceItem>
<tML-TABase:RDNSequenceItem>
<tML-TABase:Type>accountName</tML-TABase:Type>
<tML-TABase:Assertion>EXT-M</tML-TABase:Assertion>
</tML-TABase:RDNSequenceItem>
<tML-TABase:RDNSequenceItem>
<tML-TABase:Type>troubleReportID</tML-TABase:Type>
<tML-TABase:Assertion>464043</tML-TABase:Assertion>
</tML-TABase:RDNSequenceItem>
</tML-TABase:DistinguishedName>
</tML-TA:TargetObjectName>
<tML-TA:TroubleReportId>464043</tML-TA:TroubleReportId>
<tML-TA:CloseOutVerification>1</tML-TA:CloseOutVerification>
<tML-TA:VerificationRemarks>
<tML-TABase:AdditionalTroubleInfoItem>1484842269 ns2691 Submitted Accept Ready To Close </tML-TABase:AdditionalTroubleInfoItem>
</tML-TA:VerificationRemarks>
<tML-TA:TroubleClearancePerson>
<tML-TABase:Name>ATT EMNRC</tML-TABase:Name>
<tML-TABase:Phone>8882966381</tML-TABase:Phone>
</tML-TA:TroubleClearancePerson>
</tML-TA:VerifyRepairCompletionRequest></m:processSync></SOAP-ENV:Body></SOAP-ENV:Envelope>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header>
<wsse:Security env:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">MIIGezCCBWOgAwIB==</wsse:BinarySecurityToken>
</wsse:Security>
</env:Header>
<env:Body>
<n1:processSyncResponse xmlns:n1="http://eBonding/taservice/send"><![CDATA[<?xml version="1.0" encoding="UTF-8"?><tML-TA:VerifyRepairCompletionResponse xmlns:tML-TA="http://www.ansi.org/tML/TA/tML-TA" xmlns:tML-TABase="http://www.ansi.org/tML/TA/tML-TABase" xmlns="http://www.ansi.org/tML/TA/tML-TA" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tML-TA:RequestId>00000d0r000201728</tML-TA:RequestId>
<tML-TA:TargetObjectName>
<tML-TABase:DistinguishedName>
<tML-TABase:RDNSequenceItem>
<tML-TABase:Type>networkID</tML-TABase:Type>
<tML-TABase:Assertion>EXT</tML-TABase:Assertion>
</tML-TABase:RDNSequenceItem>
<tML-TABase:RDNSequenceItem>
<tML-TABase:Type>accountName</tML-TABase:Type>
<tML-TABase:Assertion>EXT-M</tML-TABase:Assertion>
</tML-TABase:RDNSequenceItem>
<tML-TABase:RDNSequenceItem>
<tML-TABase:Type>serviceID</tML-TABase:Type>
<tML-TABase:Assertion></tML-TABase:Assertion>
</tML-TABase:RDNSequenceItem>
<tML-TABase:RDNSequenceItem>
<tML-TABase:Type>troubleReportID</tML-TABase:Type>
<tML-TABase:Assertion>464043</tML-TABase:Assertion>
</tML-TABase:RDNSequenceItem>
</tML-TABase:DistinguishedName>
</tML-TA:TargetObjectName>
<tML-TABase:Exception>
<tML-TABase:NotFound>
<tML-TABase:ExceptionList>
<tML-TABase:Tag>TroubleReportID</tML-TABase:Tag>
<tML-TABase:Value>464043</tML-TABase:Value>
<tML-TABase:Signature>
<tML-TABase:Note>No ticket found for trouble report ID: 464043</tML-TABase:Note>
</tML-TABase:Signature>
</tML-TABase:ExceptionList>
</tML-TABase:NotFound>
</tML-TABase:Exception></tML-TA:VerifyRepairCompletionResponse>]]></n1:processSyncResponse>
</env:Body>
</env:Envelope>
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:java="http://eBonding/taservice/notify"> <soapenv:Header/> <soapenv:Body> <java:notify soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><?xml version="1.0" encoding="UTF-8"?><AttributeValueChangeNotification xmlns="http://www.ansi.org/tML/TA/tML-TA" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tML-TA="http://www.ansi.org/tML/TA/tML-TA" xmlns:tML-TABase="http://www.ansi.org/tML/TA/tML-TABase" xsi:schemaLocation="http://www.ansi.org/tML/TA/tML-TAtML-TA.xsd"> <tML-TA:NotificationId>84</tML-TA:NotificationId> <tML-TA:EventTime>2017-01-20T07:40:10Z</tML-TA:EventTime> <tML-TA:TargetObjectName>
<tML-TABase:DistinguishedName>
<tML-TABase:RDNSequenceItem>
<tML-TABase:Type>networkID</tML-TABase:Type>
<tML-TABase:Assertion>EXT</tML-TABase:Assertion>
</tML-TABase:RDNSequenceItem>
<tML-TABase:RDNSequenceItem>
<tML-TABase:Type>accountName</tML-TABase:Type>
<tML-TABase:Assertion>EXT-M</tML-TABase:Assertion>
</tML-TABase:RDNSequenceItem>
<tML-TABase:RDNSequenceItem>
<tML-TABase:Type>serviceID</tML-TABase:Type>
<tML-TABase:Assertion>(SW-NV-LVSTRI-00176) - (LSVGNV01) - (ATT) - (01)</tML-TABase:Assertion>
</tML-TABase:RDNSequenceItem>
<tML-TABase:RDNSequenceItem>
<tML-TABase:Type>troubleReportID</tML-TABase:Type>
<tML-TABase:Assertion>486033</tML-TABase:Assertion>
</tML-TABase:RDNSequenceItem>
</tML-TABase:DistinguishedName>
</tML-TA:TargetObjectName> <EventData> <tML-TABase:TroubleReportId>486033</tML-TABase:TroubleReportId> <tML-TABase:AgentContactPerson> <tML-TABase:Number>+1 886 892 5327</tML-TABase:Number> <tML-TABase:Name>ExteNet NOC</tML-TABase:Name> <tML-TABase:Phone>+1 886 892 5327</tML-TABase:Phone> <tML-TABase:Loc> <tML-TABase:CivicAddress>3030 Warrenville Road</tML-TABase:CivicAddress> <tML-TABase:City>Lisle</tML-TABase:City> <tML-TABase:State>IL</tML-TABase:State> <tML-TABase:Zip>60532</tML-TABase:Zip> </tML-TABase:Loc> <tML-TABase:Email>noc@extenetsystems.com</tML-TABase:Email> </tML-TABase:AgentContactPerson> <tML-TABase:AdditionalTroubleStatusInfo>
<tML-TABase:AdditionalTroubleStatusInfoItem>carrier_update has been updated to be : TEST WITH AT</tML-TABase:AdditionalTroubleStatusInfoItem>
</tML-TABase:AdditionalTroubleStatusInfo>
<tML-TABase:TroubleReportStatusTime>2017-01-20T07:40:10Z</tML-TABase:TroubleReportStatusTime> </EventData> </AttributeValueChangeNotification></java:notify> </soapenv:Body> </soapenv:Envelope>
As with all the grails config files it is located at '/usr/local/grails' and is called SoapConfig.groovy.
numberOfTriesBeforeFail is the number of times the bootstrap tried to connect to RabbitMQ before giving up and closing the app (doesn't stop the app process though).
numberOfSecondsBetweeTries is the number of seconds it waits between each try.
numberOfSecondsToWaitForRabbitReconnect is the number of seconds the App waits to reconnect to RabbitMQ if RabbitMQ connection is lost. Note this will continue forever until app is shutdown or Rabbit comes back onlines
rabbitmq {
credentials{
username='admin'
password='admin'
host='localhost'
virtualHost='admin'
}
queues {
//Incoming Message
//Outgoing Message
soapOutboundQueue='soap_outbound_queue'
}
exchanges {
//Incoming Message
soapExchangeName='soap_exchange_topic'
//Outgoing Message
ebondingOutboundExchange='eBonding_outbound_exchange_topic'
}
tags {
ebondingTag='eBonding'
soapTag='soap'
}
bindings {
//In the Form "QUEUEMAME::EXCHANGENAME::TAG"
//Incoming Message
//Outgoing Message
soapBinding="${queues.soapOutboundQueue}::${exchanges.ebondingOutboundExchange}::${tags.soapTag}"
}
consumer {
name='soap_component'
}
numberOfTriesBeforeFail = 5
numberOfSecondsBetweeTries = 30
numberOfSecondsToWaitForRabbitReconnect = 30
}
numberOfInboundThreads - this is the number of inbound threads i.e. Incoming Soap Message Receiver Worker Threads
numberOfOutboundThreads - this is the number of outbound worker threads
nameOfInboundMessageThreads - name template of the worker threads
nameOfOutboundMessageThreads - name template of the outbound threads
numberOfSecondsToWait - number of seconds to wait for a response to an incoming message before timing out the thread and responding with a timeout message
numberOfSecondsToWaitBeforeTimeoutForOutbound - number of seconds to wait before timing out an outbound thread. Use case here is a seriously slow connection when posting a message to an endpoint and we do not want the outbound thread to hang
threadmanager {
numberOfInboundThreads = 10
numberOfOutboundThreads = 2
nameOfInboundMessageThreads='InBoundSoapMsgHandler'
nameOfOutboundMessageThreads='OutBoundSoapMsgHandler'
numberOfSecondsToWait = 30
numberOfSecondsToWaitBeforeTimeoutForOutbound = 20
}
Self explanatory
dataSource.pooled=true dataSource.driverClassName="com.mysql.jdbc.Driver" dataSource.dialect="org.hibernate.dialect.MySQL5InnoDBDialect" dataSource.url="jdbc:mysql://localhost/soap?useUnicode=yes&characterEncoding=UTF-8" dataSource.username="root" dataSource.password="PASSWORD"