Skip to content
This repository has been archived by the owner on Sep 7, 2019. It is now read-only.

Soap Header Response Workflow #1659

Open
wants to merge 5 commits into
base: CONNECT_integration
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,7 @@ public void handleMessage(SoapMessage message) throws Fault {
@SuppressWarnings("unchecked")
public static void addResponseMessageIdToContext(Object port, Message currentMessage) {
try {
Client clientProxy = ClientProxy.getClient(port);

Map<String, Object> responseContext = clientProxy.getResponseContext();
String responseMsgId = (String) responseContext.get(NhincConstants.RESPONSE_MESSAGE_ID_KEY);
String responseMsgId = (String) getResponseContext(port).get(NhincConstants.RESPONSE_MESSAGE_ID_KEY);

if (responseMsgId != null && currentMessage != null) {

Expand All @@ -107,4 +104,13 @@ public static void addResponseMessageIdToContext(Object port, Message currentMes
LOG.warn("Exception ", e);
}
}

public static List<Header> getResponseHeaders(Object port) {
return (List<Header>) getResponseContext(port).get(Header.HEADER_LIST);
}

private static Map<String, Object> getResponseContext(Object port) {
Client clientProxy = ClientProxy.getClient(port);
return clientProxy.getResponseContext();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import org.apache.commons.collections.MapUtils;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.jaxws.context.WrappedMessageContext;
import org.apache.cxf.message.Message;
Expand All @@ -60,7 +61,8 @@ public abstract class BaseService {

private final AsyncMessageIdExtractor extractor = new AsyncMessageIdExtractor();
private static final Logger LOG = LoggerFactory.getLogger(BaseService.class);
private static HttpHeaderHelper headerHelper = new HttpHeaderHelper();
private static final HttpHeaderHelper headerHelper = new HttpHeaderHelper();
private static final ResponseHeaderHandler respHeaderHandler = new ResponseHeaderHandler();

protected AssertionType getAssertion(WebServiceContext context) {
return getAssertion(context, null);
Expand All @@ -84,6 +86,18 @@ protected AssertionType getAssertion(WebServiceContext context, AssertionType as

return assertion;
}

protected void addSoapHeaders(Object addHeaders, WebServiceContext context) {
List<Header> addHeadersList;

if(addHeaders != null && addHeaders instanceof List) {
addHeadersList = (List<Header>) addHeaders;
} else {
return;
}

respHeaderHandler.addResponseHeadersToContext(context, addHeadersList, NhincConstants.ALLOWABLE_OUTBOUND_RESPONSE_HEADERS);
}

//Extract custom http headers from message context.
private void handleHttpHeaders(AssertionType assertion, WebServiceContext context) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2009-2018, United States Government, as represented by the Secretary of Health and Human Services.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the United States Government nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE UNITED STATES GOVERNMENT BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package gov.hhs.fha.nhinc.messaging.server;

import gov.hhs.fha.nhinc.nhinclib.NhincConstants;
import gov.hhs.fha.nhinc.nhinclib.NullChecker;
import gov.hhs.fha.nhinc.properties.PropertyAccessException;
import gov.hhs.fha.nhinc.properties.PropertyAccessor;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.xml.ws.WebServiceContext;
import org.apache.cxf.headers.Header;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* @author jassmit
*/
public class ResponseHeaderHandler {

private static final Logger LOG = LoggerFactory.getLogger(ResponseHeaderHandler.class);

public void addResponseHeadersToContext(WebServiceContext context, List<Header> responseHeaders, String allowableProperty) {
List<Header> contextHeaders = (List<Header>) context.getMessageContext().get(Header.HEADER_LIST);
if(contextHeaders == null) {
contextHeaders = new ArrayList<>();
}

Set allowedHeaders = getAllowedHeaders(allowableProperty);
for(Header header : responseHeaders) {
if(allowedHeaders.contains(header.getName().getLocalPart())) {
header.setDirection(Header.Direction.DIRECTION_OUT);
contextHeaders.add(header);
}
}
}

private Set<String> getAllowedHeaders(String allowableProperty) {
Set allowedHeaders = new HashSet<>();
try {
allowedHeaders = getPropertyAccessor().getPropertySet(NhincConstants.GATEWAY_PROPERTY_FILE, allowableProperty);
} catch (PropertyAccessException ex) {
LOG.warn("Error accessing property file (} for property {}", NhincConstants.GATEWAY_PROPERTY_FILE, allowableProperty, ex);
}
return NullChecker.isNotNullish(allowedHeaders) ? allowedHeaders : new HashSet<>();
}

protected PropertyAccessor getPropertyAccessor() {
return PropertyAccessor.getInstance();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ public static EXCHANGE_TYPE getExchangeType(String value) {
public static final String GATEWAY_PROPERTY_FILE = "gateway";
public static final String SAML_PROPERTY_FILE = "saml";
public static final String HOME_COMMUNITY_ID_PROPERTY = "localHomeCommunityId";
public static final String ALLOWABLE_INBOUND_RESPONSE_HEADERS = "allowableInboundResponseHeaders";
public static final String ALLOWABLE_OUTBOUND_RESPONSE_HEADERS = "allowableOutboundResponseHeaders";
public static final String INTERNAL_CONNECTION_INFO = "InternalConnectionInfo2.xml";
public static final String DIRECTTESTING_FLAG = "DirectTesting";
public static final String MESSAGEMONITORING_DELAYINMINUTES = "MessageMonitoringDelayTime";
Expand Down Expand Up @@ -322,6 +324,7 @@ public static EXCHANGE_TYPE getExchangeType(String value) {
public static final String WS_SOAP_HEADER_MESSAGE_ID = "MessageID";
public static final String WS_SOAP_HEADER_MESSAGE_ID_PREFIX = "urn:uuid:";
public static final String WS_SOAP_TARGET_HOME_COMMUNITY_ID = "TargetHomeCommunityID";
public static final String SOAP_HEADERS_PROPERTY = "soapHeadersKey";
// Document Query Constants
public static final String ADAPTER_DOC_QUERY_SERVICE_NAME = "adapterdocquery";
public static final String ADAPTER_DOC_QUERY_SECURED_SERVICE_NAME = "adapterdocquerysecured";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,21 @@ public synchronized boolean getPropertyBoolean(String propertyFile, String prope

return propertyFileDAO.getPropertyBoolean(propertyFile, propertyName);
}

/**
* This will return a set of properties from a comma separated list in the property file.
*
* @param propertyFile
* @param propertyName
* @return
* @throws PropertyAccessException
*/
public synchronized Set<String> getPropertySet(String propertyFile, String propertyName) throws PropertyAccessException {
validateInput(propertyFile, propertyName);
loadPropertyFile(propertyFile);

return propertyFileDAO.getPropertySet(propertyFile, propertyName);
}

/**
* This will return the long value conversion of the property. If the property value cannot be converted to a long,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@

import gov.hhs.fha.nhinc.nhinclib.NullChecker;
import java.io.File;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.configuration.ConfigurationException;
Expand Down Expand Up @@ -71,6 +73,17 @@ public void loadPropertyFile(File propertyFile, String propertyFileName) throws
}
}

public Set getPropertySet(String propertyFileName, String propertyName) {
PropertiesConfiguration properties = propertyFilesHashmap.get(propertyFileName);
if (properties != null && properties.containsKey(propertyName)) {
List propertyValue = properties.getList(propertyName);
if(NullChecker.isNotNullish(propertyValue)) {
return new HashSet<>(propertyValue);
}
}
return Collections.emptySet();
}

public String getProperty(String propertyFileName, String propertyName) throws PropertyAccessException {
PropertiesConfiguration properties = propertyFilesHashmap.get(propertyFileName);
if (properties != null && properties.containsKey(propertyName)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ readHttpHeaders=false
# Sets outbound http connection value to "keep-alive", default property value is false ((For True, set to True or T).
connectionKeepAlive=false

# Allow for SOAP headers to be passed from NwHIN service to requesting adapter response message by adding header element names. Comma separated list.
!allowableInboundResponseHeaders=AccessDenial
# Allow for SOAP headers to be passed from responding adapter into NwHIN service response message by adding header element names. Comma separated list.
!allowableOutboundResponseHeaders=AccessDenial

# disable-cn-check should not be used for production; to enable-cn-check may required server-restart.
disableCNCheck=true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public AdhocQueryResponse respondingGatewayCrossGatewayQuerySecured(
AssertionType assertion = getAssertion(context, null);

return respondingGatewayCrossGatewayQuery(request.getAdhocQueryRequest(), assertion,
request.getNhinTargetCommunities());
request.getNhinTargetCommunities(), context);
}

/**
Expand All @@ -83,11 +83,11 @@ public AdhocQueryResponse respondingGatewayCrossGatewayQueryUnsecured(
RespondingGatewayCrossGatewayQueryRequestType request, WebServiceContext context) {

return respondingGatewayCrossGatewayQuery(request.getAdhocQueryRequest(), request.getAssertion(),
request.getNhinTargetCommunities());
request.getNhinTargetCommunities(), context);
}

private AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest request, AssertionType assertion,
NhinTargetCommunitiesType targets) {
NhinTargetCommunitiesType targets, WebServiceContext context) {

AdhocQueryResponse response = null;

Expand All @@ -99,7 +99,7 @@ private AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest
if (StringUtils.isBlank(targets.getUseSpecVersion())) {
targets.setUseSpecVersion("2.0");
}
response = outboundDocQuery.respondingGatewayCrossGatewayQuery(request, assertion, targets);
response = outboundDocQuery.respondingGatewayCrossGatewayQuery(request, assertion, targets, context);
} catch (Exception e) {
LOG.error("Failed to send request to Nwhin.", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ protected AssertionType getAssertion(WebServiceContext context, AssertionType oA
impl.respondingGatewayCrossGatewayQuerySecured(request, context);

verify(mockDQ).respondingGatewayCrossGatewayQuery(any(AdhocQueryRequest.class), any(AssertionType.class),
any(NhinTargetCommunitiesType.class));
any(NhinTargetCommunitiesType.class), any(WebServiceContext.class));
verify(target).setUseSpecVersion(eq("2.0"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import gov.hhs.fha.nhinc.common.nhinccommon.AssertionType;
import gov.hhs.fha.nhinc.common.nhinccommon.NhinTargetCommunitiesType;
import javax.xml.ws.WebServiceContext;
import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryRequest;
import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryResponse;

Expand All @@ -40,7 +41,7 @@ public class TestOutboundDocQuery implements OutboundDocQuery {

@Override
public AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest adhocQueryRequest,
AssertionType assertion, NhinTargetCommunitiesType targets) {
AssertionType assertion, NhinTargetCommunitiesType targets, WebServiceContext context) {
return new AdhocQueryResponse();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public AdhocQueryResponse respondingGatewayCrossGatewayQuerySecured(
AssertionType assertion = getAssertion(context, null);

return respondingGatewayCrossGatewayQuery(request.getAdhocQueryRequest(), assertion,
request.getNhinTargetCommunities());
request.getNhinTargetCommunities(), context);
}

/**
Expand All @@ -83,11 +83,11 @@ public AdhocQueryResponse respondingGatewayCrossGatewayQueryUnsecured(
RespondingGatewayCrossGatewayQueryRequestType request, WebServiceContext context) {

return respondingGatewayCrossGatewayQuery(request.getAdhocQueryRequest(), request.getAssertion(),
request.getNhinTargetCommunities());
request.getNhinTargetCommunities(), context);
}

private AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest request, AssertionType assertion,
NhinTargetCommunitiesType targets) {
NhinTargetCommunitiesType targets, WebServiceContext context) {

AdhocQueryResponse response = null;

Expand All @@ -99,7 +99,7 @@ private AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest
if (StringUtils.isBlank(targets.getUseSpecVersion())) {
targets.setUseSpecVersion("3.0");
}
response = outboundDocQuery.respondingGatewayCrossGatewayQuery(request, assertion, targets);
response = outboundDocQuery.respondingGatewayCrossGatewayQuery(request, assertion, targets, context);
} catch (Exception e) {
LOG.error("Failed to send request to Nwhin.", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
import gov.hhs.fha.nhinc.common.nhinccommon.AssertionType;
import gov.hhs.fha.nhinc.docquery.inbound.InboundDocQuery;
import gov.hhs.fha.nhinc.messaging.server.BaseService;
import gov.hhs.fha.nhinc.nhinclib.NhincConstants;
import gov.hhs.fha.nhinc.nhinclib.NhincConstants.UDDI_SPEC_VERSION;
import java.util.Properties;
import javax.xml.ws.WebServiceContext;
import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryRequest;
import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryResponse;
Expand All @@ -47,7 +49,12 @@ public AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest b
if (assertion != null) {
assertion.setImplementsSpecVersion(UDDI_SPEC_VERSION.SPEC_3_0.toString());
}

Properties webContextProperties = getWebContextProperties(context);

return inboundDocQuery.respondingGatewayCrossGatewayQuery(body, assertion, getWebContextProperties(context));
AdhocQueryResponse response = inboundDocQuery.respondingGatewayCrossGatewayQuery(body, assertion, webContextProperties);
addSoapHeaders(webContextProperties.get(NhincConstants.SOAP_HEADERS_PROPERTY), context);

return response;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ protected AssertionType getAssertion(WebServiceContext context, AssertionType oA
impl.respondingGatewayCrossGatewayQuerySecured(request, context);

verify(mockDQ).respondingGatewayCrossGatewayQuery(any(AdhocQueryRequest.class), any(AssertionType.class),
any(NhinTargetCommunitiesType.class));
any(NhinTargetCommunitiesType.class), any(WebServiceContext.class));
verify(target).setUseSpecVersion(eq("3.0"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import gov.hhs.fha.nhinc.common.nhinccommon.AssertionType;
import gov.hhs.fha.nhinc.common.nhinccommon.NhinTargetCommunitiesType;
import javax.xml.ws.WebServiceContext;
import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryRequest;
import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryResponse;

Expand All @@ -40,7 +41,7 @@ public class TestOutboundDocQuery implements OutboundDocQuery {

@Override
public AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest adhocQueryRequest,
AssertionType assertion, NhinTargetCommunitiesType targets) {
AssertionType assertion, NhinTargetCommunitiesType targets, WebServiceContext context) {
return new AdhocQueryResponse();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
package gov.hhs.fha.nhinc.docquery.adapter.proxy;

import gov.hhs.fha.nhinc.common.nhinccommon.AssertionType;
import java.util.Properties;
import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryRequest;
import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryResponse;

Expand All @@ -40,5 +41,5 @@ public interface AdapterDocQueryProxy {
* @param assertion Assertion received.
* @return AdhocQueryResponse.
*/
AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest msg, AssertionType assertion);
AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest msg, AssertionType assertion, Properties webContextProperties);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import gov.hhs.fha.nhinc.docquery.adapter.AdapterDocQueryOrchImpl;
import gov.hhs.fha.nhinc.docquery.aspect.AdhocQueryRequestDescriptionBuilder;
import gov.hhs.fha.nhinc.docquery.aspect.AdhocQueryResponseDescriptionBuilder;
import java.util.Properties;
import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryRequest;
import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryResponse;
import org.slf4j.Logger;
Expand All @@ -52,7 +53,7 @@ public class AdapterDocQueryProxyJavaImpl implements AdapterDocQueryProxy {
afterReturningBuilder = AdhocQueryResponseDescriptionBuilder.class, serviceType = "Document Query",
version = "")
@Override
public AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest msg, AssertionType assertion) {
public AdhocQueryResponse respondingGatewayCrossGatewayQuery(AdhocQueryRequest msg, AssertionType assertion, Properties webContextProperties) {
LOG.debug("Using Java Implementation for Adapter Doc Query Service");
return new AdapterDocQueryOrchImpl().respondingGatewayCrossGatewayQuery(msg, assertion);
}
Expand Down
Loading