View Javadoc

1   /*
2      Licensed under the Apache License, Version 2.0 (the "License");
3      you may not use this file except in compliance with the License.
4      You may obtain a copy of the License at
5   
6        http://www.apache.org/licenses/LICENSE-2.0
7   
8      Unless required by applicable law or agreed to in writing, software
9      distributed under the License is distributed on an "AS IS" BASIS,
10     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11     See the License for the specific language governing permissions and
12     limitations under the License.
13  */
14  package uk.nhs.interoperability.infrastructure;
15  
16  import java.util.HashMap;
17  import java.util.Map;
18  
19  import javax.xml.parsers.ParserConfigurationException;
20  import javax.xml.xpath.XPathConstants;
21  import javax.xml.xpath.XPathExpressionException;
22  
23  import org.w3c.dom.Document;
24  import org.w3c.dom.Node;
25  
26  import uk.nhs.interoperability.transport.ITKTransportProperties;
27  import uk.nhs.interoperability.util.Logger;
28  import uk.nhs.interoperability.util.xml.DomUtils;
29  import uk.nhs.interoperability.util.xml.XPaths;
30  
31  // TODO: Auto-generated Javadoc
32  /**
33   * The Class ITKMessagePropertiesImpl.
34   *
35   * @author Michael Odling-Smee
36   * @author Nicholas Jone
37   * @since 0.1
38   */
39  public class ITKMessagePropertiesImpl implements ITKMessageProperties {
40  	
41  
42  	/** The from address. */
43  	private ITKAddress fromAddress;
44  	
45  	/** The to address. */
46  	private ITKAddress toAddress;
47  	
48  	/** The audit identity. */
49  	private ITKIdentity auditIdentity ;
50  	
51  	/** The service id. */
52  	private String serviceId; 
53  	
54  	/** The business payload id. */
55  	private String businessPayloadId;
56  	
57  	/** The profile id. */
58  	private String profileId;
59  	
60  	/** The tracking id. */
61  	private String trackingId;
62  	
63  	/** The inbound transport properties. */
64  	private ITKTransportProperties inboundTransportProperties;
65  	
66  	//Create a map for handling specifications and make sure they are populated
67  	/** The handling specification. */
68  	private Map<String, String> handlingSpecification = new HashMap<String, String>();
69  
70  	/* (non-Javadoc)
71  	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#getTrackingId()
72  	 */
73  	public String getTrackingId() {
74  		return trackingId;
75  	}
76  
77  	/* (non-Javadoc)
78  	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#setTrackingId(java.lang.String)
79  	 */
80  	public void setTrackingId(String trackingId) {
81  		this.trackingId = trackingId;
82  	}
83  
84  	/* (non-Javadoc)
85  	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#getFromAddress()
86  	 */
87  	public ITKAddress getFromAddress() {
88  		return fromAddress;
89  	}
90  	
91  	/* (non-Javadoc)
92  	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#setFromAddress(uk.nhs.interoperability.infrastructure.ITKAddress)
93  	 */
94  	public void setFromAddress(ITKAddress fromAddress) {
95  		this.fromAddress = fromAddress;
96  	}
97  	
98  	/* (non-Javadoc)
99  	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#getToAddress()
100 	 */
101 	public ITKAddress getToAddress() {
102 		return toAddress;
103 	}
104 	
105 	/* (non-Javadoc)
106 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#setToAddress(uk.nhs.interoperability.infrastructure.ITKAddress)
107 	 */
108 	public void setToAddress(ITKAddress toAddress) {
109 		this.toAddress = toAddress;
110 	}
111 	
112 	/* (non-Javadoc)
113 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#getAuditIdentity()
114 	 */
115 	public ITKIdentity getAuditIdentity() {
116 		return auditIdentity;
117 	}
118 	
119 	/* (non-Javadoc)
120 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#setAuditIdentity(java.lang.String)
121 	 */
122 	public void setAuditIdentity(ITKIdentity auditIdentity) {
123 		this.auditIdentity = auditIdentity;
124 	}
125 	
126 	/* (non-Javadoc)
127 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#getServiceId()
128 	 */
129 	public String getServiceId() {
130 		return serviceId;
131 	}
132 	
133 	/* (non-Javadoc)
134 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#setServiceId(java.lang.String)
135 	 */
136 	public void setServiceId(String serviceId) {
137 		this.serviceId = serviceId;
138 	}
139 	
140 	/* (non-Javadoc)
141 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#getBusinessPayloadId()
142 	 */
143 	public String getBusinessPayloadId() {
144 		return businessPayloadId;
145 	}
146 	
147 	/* (non-Javadoc)
148 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#setBusinessPayloadId(java.lang.String)
149 	 */
150 	public void setBusinessPayloadId(String businessPayloadId) {
151 		this.businessPayloadId = businessPayloadId;
152 	}
153 	
154 	/* (non-Javadoc)
155 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#getProfileId()
156 	 */
157 	public String getProfileId() {
158 		return profileId;
159 	}
160 	
161 	/* (non-Javadoc)
162 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#setProfileId(java.lang.String)
163 	 */
164 	public void setProfileId(String profileId) {
165 		this.profileId = profileId;
166 	}
167 	
168 	/* (non-Javadoc)
169 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#getInboundTransportProperties()
170 	 */
171 	public ITKTransportProperties getInboundTransportProperties() {
172 		return inboundTransportProperties;
173 	}
174 
175 	/* (non-Javadoc)
176 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#setInboundTransportProperties(uk.nhs.interoperability.transport.ITKTransportProperties)
177 	 */
178 	public void setInboundTransportProperties(
179 			ITKTransportProperties inboundTransportProperties) {
180 		this.inboundTransportProperties = inboundTransportProperties;
181 	}
182 	
183 	/* (non-Javadoc)
184 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#getHandlingSpecifications()
185 	 */
186 	@Override
187 	public Map<String, String> getHandlingSpecifications() {
188 		return this.handlingSpecification;
189 	}
190 	
191 	/* (non-Javadoc)
192 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#addHandlingSpecification(java.lang.String, java.lang.String)
193 	 */
194 	@Override
195 	public void addHandlingSpecification(String key, String value) {
196 		this.handlingSpecification.put(key, value);
197 	}
198 	
199 	/* (non-Javadoc)
200 	 * @see uk.nhs.interoperability.infrastructure.ITKMessageProperties#getHandlingSpecification(java.lang.String)
201 	 */
202 	@Override
203 	public String getHandlingSpecification(String key) {
204 		return this.handlingSpecification != null ? this.handlingSpecification.get(key) : null;
205 	}
206 	
207 	/**
208 	 * Extract distribution envelope from soap.
209 	 *
210 	 * @param doc the doc
211 	 * @return the document
212 	 * @throws ITKMessagingException the iTK messaging exception
213 	 */
214 	public static Document extractDistributionEnvelopeFromSoap(Document doc) throws ITKMessagingException {
215 		try {
216 			return DomUtils.createDocumentFromNode((Node)XPaths.SOAP_BODY_CONTENT_XPATH.evaluate(doc, XPathConstants.NODE));
217 		} catch (XPathExpressionException e) {
218 			throw new ITKMessagingException(ITKMessagingException.PROCESSING_ERROR_NOT_RETRYABLE_CODE, "Could not extract values from request", e);
219 		} catch (ParserConfigurationException e) {
220 			throw new ITKMessagingException(ITKMessagingException.PROCESSING_ERROR_NOT_RETRYABLE_CODE, "XML parser configuration error", e);
221 		}
222 	}
223 
224 	/**
225 	 * Builds the.
226 	 *
227 	 * @param distributionEnvelope the distribution envelope
228 	 * @return the iTK message properties
229 	 * @throws ITKMessagingException the iTK messaging exception
230 	 */
231 	public static ITKMessageProperties build(Document distributionEnvelope) throws ITKMessagingException {
232 		//Construct an empty itkMessageProperties
233 		ITKMessagePropertiesImpl itkMessageProperties = new ITKMessagePropertiesImpl();
234 		
235 		try {
236 			
237 			
238 			
239 			Double payloadCount = (Double)XPaths.ITK_PAYLOAD_COUNT_XPATH.evaluate(distributionEnvelope, XPathConstants.NUMBER);
240 			Logger.debug("Number of payloads " + payloadCount);
241 			
242 			//For now throw an exception if we encounter anything other than a single payload
243 			//TODO - add support for multiple payloads
244 			if (payloadCount != 1) {
245 				throw new ITKMessagingException(itkMessageProperties, ITKMessagingException.PROCESSING_ERROR_NOT_RETRYABLE_CODE, "The ITK reference implementation currently only supports a single payload within a distribution envelope");
246 			}
247 			
248 			String itkService = XPaths.ITK_SERVICE_XPATH.evaluate(distributionEnvelope);
249 			Logger.debug("ITK service " + itkService);
250 			
251 			String itkAuditIdentityURI = XPaths.ITK_AUDIT_IDENTITY_URI_XPATH.evaluate(distributionEnvelope);
252 			String itkAuditIdentityType = XPaths.ITK_AUDIT_IDENTITY_TYPE_XPATH.evaluate(distributionEnvelope);
253 			Logger.debug("ITK audit identity " + itkAuditIdentityType + ":" + itkAuditIdentityURI);
254 			
255 			String itkFromAddress = XPaths.ITK_FROM_ADDRESS_XPATH.evaluate(distributionEnvelope);
256 			Logger.debug("ITK from address " + itkFromAddress);
257 			
258 			String itkToAddress = XPaths.ITK_FIRST_TO_ADDRESS_XPATH.evaluate(distributionEnvelope);
259 			Logger.debug("ITK to address " + itkToAddress);
260 			
261 			String itkTrackingId = XPaths.ITK_TRACKING_ID_XPATH.evaluate(distributionEnvelope);
262 			Logger.debug("ITK tracking id " + itkTrackingId);
263 			
264 			String itkProfileId = XPaths.ITK_PROFILE_ID_XPATH.evaluate(distributionEnvelope);
265 			Logger.debug("ITK profile id " + itkProfileId);
266 			
267 			String businessPayloadId = XPaths.ITK_FIRST_PAYLOAD_ID_XPATH.evaluate(distributionEnvelope);
268 			Logger.debug("ITK payload id " + businessPayloadId);
269 			
270 			String businessAckHandlingSpecification = XPaths.ITK_BUSINESS_ACK_HANDLING_SPECIFICATIONS_XPATH.evaluate(distributionEnvelope);
271 			Logger.debug("ITK businessAck handling specification " + businessAckHandlingSpecification);
272 			
273 			//DE = Payload properties (part of ITKMessageProperties API)
274 			itkMessageProperties.setBusinessPayloadId(businessPayloadId);
275 			itkMessageProperties.setToAddress(new ITKAddressImpl(itkToAddress));
276 			itkMessageProperties.setFromAddress(new ITKAddressImpl(itkFromAddress));
277 			itkMessageProperties.setServiceId(itkService);
278 			itkMessageProperties.setAuditIdentity(new ITKIdentityImpl(itkAuditIdentityURI, itkAuditIdentityType));
279 			itkMessageProperties.setProfileId(itkProfileId);
280 			itkMessageProperties.setTrackingId(itkTrackingId);
281 			itkMessageProperties.addHandlingSpecification(ITKMessageProperties.BUSINESS_ACK_HANDLING_SPECIFICATION_KEY, businessAckHandlingSpecification);
282 			//Also do we need to provide trackingId for any logging and correlation within Application?
283 			return itkMessageProperties;
284 			
285 		} catch (XPathExpressionException e) {
286 			throw new ITKMessagingException(itkMessageProperties, ITKMessagingException.PROCESSING_ERROR_NOT_RETRYABLE_CODE, "Could not extract values from request", e);
287 		}
288 	}
289 
290 }