package gov.samhsa.acs.pep;
import static gov.samhsa.acs.audit.AcsAuditVerb.DIRECT_EMAIL_SEND_REQUEST;
import static gov.samhsa.acs.audit.AcsAuditVerb.DIRECT_EMAIL_SEND_RESPONSE;
import static gov.samhsa.acs.audit.AcsAuditVerb.DIRECT_EMAIL_SEND_RESPONSE_ERROR_CONSENT;
import static gov.samhsa.acs.audit.AcsAuditVerb.DIRECT_EMAIL_SEND_RESPONSE_ERROR_SYSTEM;
import static gov.samhsa.acs.audit.AcsAuditVerb.REGISTRY_STORED_QUERY_REQUEST;
import static gov.samhsa.acs.audit.AcsAuditVerb.REGISTRY_STORED_QUERY_RESPONSE;
import static gov.samhsa.acs.audit.AcsAuditVerb.REGISTRY_STORED_QUERY_RESPONSE_ERROR_CONSENT;
import static gov.samhsa.acs.audit.AcsAuditVerb.REGISTRY_STORED_QUERY_RESPONSE_ERROR_SYSTEM;
import static gov.samhsa.acs.audit.AcsAuditVerb.RETRIEVE_DOCUMENT_SET_REQUEST;
import static gov.samhsa.acs.audit.AcsAuditVerb.RETRIEVE_DOCUMENT_SET_RESPONSE;
import static gov.samhsa.acs.audit.AcsAuditVerb.RETRIEVE_DOCUMENT_SET_RESPONSE_ERROR_CONSENT;
import static gov.samhsa.acs.audit.AcsAuditVerb.RETRIEVE_DOCUMENT_SET_RESPONSE_ERROR_SYSTEM;
import static gov.samhsa.acs.audit.AcsPredicateKey.INTERMEDIARY_SUBJECT_NPI;
import static gov.samhsa.acs.audit.AcsPredicateKey.PATIENT_UNIQUE_ID;
import static gov.samhsa.acs.audit.AcsPredicateKey.PURPOSE_OF_USE;
import static gov.samhsa.acs.audit.AcsPredicateKey.RECIPIENT_SUBJECT_NPI;
import static gov.samhsa.acs.audit.AcsPredicateKey.REQUEST_BODY;
import static gov.samhsa.acs.audit.AcsPredicateKey.RESPONSE_BODY;
import gov.samhsa.acs.audit.AuditService;
import gov.samhsa.acs.audit.AuditVerb;
import gov.samhsa.acs.audit.PredicateKey;
import gov.samhsa.acs.brms.domain.SubjectPurposeOfUse;
import gov.samhsa.acs.brms.domain.XacmlResult;
import gov.samhsa.acs.common.dto.XacmlRequest;
import gov.samhsa.acs.common.dto.XacmlResponse;
import gov.samhsa.acs.common.log.AcsLogger;
import gov.samhsa.acs.common.log.AcsLoggerFactory;
import gov.samhsa.acs.common.tool.SimpleMarshaller;
import gov.samhsa.acs.common.tool.exception.SimpleMarshallerException;
import gov.samhsa.acs.common.validation.exception.XmlDocumentReadFailureException;
import gov.samhsa.acs.contexthandler.ContextHandler;
import gov.samhsa.acs.contexthandler.exception.NoPolicyFoundException;
import gov.samhsa.acs.contexthandler.exception.PolicyProviderException;
import gov.samhsa.acs.dss.ws.schema.DSSRequest;
import gov.samhsa.acs.dss.ws.schema.DSSRequestForDirect;
import gov.samhsa.acs.dss.ws.schema.DSSResponse;
import gov.samhsa.acs.dss.ws.schema.DSSResponseForDirect;
import gov.samhsa.acs.dss.wsclient.DSSWebServiceClient;
import gov.samhsa.acs.pep.aspect.AspectUtils;
import gov.samhsa.acs.pep.exception.InconsistentPatientUniqueIdException;
import gov.samhsa.acs.pep.exception.MissingParameterException;
import gov.samhsa.acs.pep.exception.MultipleRepositoryIdException;
import gov.samhsa.acs.pep.exception.NoDocumentFoundException;
import gov.samhsa.acs.pep.exception.UnsupportedFormatCodeException;
import gov.samhsa.acs.pep.exception.UnsupportedResponseOptionTypeException;
import gov.samhsa.acs.pep.saml.SamlTokenParser;
import gov.samhsa.acs.pep.saml.exception.SamlTokenParserException;
import gov.samhsa.acs.pep.saml.exception.SamlTokenPrincipalException;
import gov.samhsa.acs.xdsb.common.XdsbErrorFactory;
import gov.samhsa.acs.xdsb.registry.wsclient.adapter.XdsbRegistryAdapter;
import gov.samhsa.acs.xdsb.registry.wsclient.exception.XdsbRegistryAdapterException;
import gov.samhsa.acs.xdsb.repository.wsclient.adapter.XdsbRepositoryAdapter;
import gov.samhsa.acs.xdsb.repository.wsclient.exception.XdsbRepositoryAdapterException;
import gov.samhsa.ds4ppilot.schema.pep.DirectEmailSendRequest;
import gov.samhsa.ds4ppilot.schema.pep.DirectEmailSendResponse;
import ihe.iti.xds_b._2007.RetrieveDocumentSetRequest;
import ihe.iti.xds_b._2007.RetrieveDocumentSetRequest.DocumentRequest;
import ihe.iti.xds_b._2007.RetrieveDocumentSetResponse;
import ihe.iti.xds_b._2007.RetrieveDocumentSetResponse.DocumentResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.UUID;
import javax.annotation.Resource;
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;
import org.apache.wss4j.common.principal.SAMLTokenPrincipal;
import org.springframework.util.Assert;
import ch.qos.logback.audit.AuditException;
/**
* The Class PolicyEnforcementPointImpl.
*/
public class PolicyEnforcementPointImpl implements PolicyEnforcementPoint {
// Constants
/** The Constant PERMIT. */
public static final String PERMIT = "PERMIT";
/** The Constant SUPPORTED_ADHOCQUERY_RESPONSE_TYPE. */
public static final String SUPPORTED_ADHOCQUERY_RESPONSE_TYPE = "LeafClass";
/** The Constant URN_RESOURCE_ID. */
public static final String URN_RESOURCE_ID = "urn:oasis:names:tc:xacml:1.0:resource:resource-id";
/** The Constant URN_INTERMEDIARY_SUBJECT. */
public static final String URN_INTERMEDIARY_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject";
/** The Constant URN_RECIPIENT_SUBJECT. */
public static final String URN_RECIPIENT_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject";
/** The Constant URN_PURPOSE_OF_USE. */
public static final String URN_PURPOSE_OF_USE = "urn:oasis:names:tc:xspa:1.0:subject:purposeofuse";
/** The logger. */
private final AcsLogger logger = AcsLoggerFactory
.getLogger(this.getClass());
// Services
/** The xdsb registry. */
private final XdsbRegistryAdapter xdsbRegistry;
/** The xdsb repository. */
private final XdsbRepositoryAdapter xdsbRepository;
/** The xdsb error factory. */
private final XdsbErrorFactory xdsbErrorFactory;
/** The context handler. */
private final ContextHandler contextHandler;
/** The document segmentation. */
private final DSSWebServiceClient documentSegmentation;
/** The marshaller. */
private final SimpleMarshaller marshaller;
/** The context. */
@Resource
private final WebServiceContext context;
/** The saml token parser. */
private SamlTokenParser samlTokenParser;
/** The data handler to bytes converter. */
private final DataHandlerToBytesConverter dataHandlerToBytesConverter;
/** The audit service. */
private final AuditService auditService;
/** The aspect utils. */
private final AspectUtils aspectUtils;
/** The is audit failure by pass. */
private final boolean isAuditFailureByPass;
/**
* Instantiates a new policy enforcement point impl.
*
* @param isAuditFailureByPass
* the is audit failure by pass
* @param xdsbRegistry
* the xdsb registry
* @param xdsbRepository
* the xdsb repository
* @param xdsbErrorFactory
* the xdsb error factory
* @param contextHandler
* the context handler
* @param documentSegmentation
* the document segmentation
* @param marshaller
* the marshaller
* @param context
* the context
* @param parser
* the parser
* @param dataHandlerToBytesConverter
* the data handler to bytes converter
* @param auditService
* the audit service
* @param aspectUtils
* the aspect utils
*/
public PolicyEnforcementPointImpl(boolean isAuditFailureByPass,
XdsbRegistryAdapter xdsbRegistry,
XdsbRepositoryAdapter xdsbRepository,
XdsbErrorFactory xdsbErrorFactory, ContextHandler contextHandler,
DSSWebServiceClient documentSegmentation,
SimpleMarshaller marshaller, WebServiceContext context,
SamlTokenParser parser,
DataHandlerToBytesConverter dataHandlerToBytesConverter,
AuditService auditService, AspectUtils aspectUtils) {
super();
this.isAuditFailureByPass = isAuditFailureByPass;
this.xdsbRegistry = xdsbRegistry;
this.xdsbRepository = xdsbRepository;
this.xdsbErrorFactory = xdsbErrorFactory;
this.contextHandler = contextHandler;
this.documentSegmentation = documentSegmentation;
this.marshaller = marshaller;
this.context = context;
this.samlTokenParser = parser;
if (this.samlTokenParser == null) {
this.samlTokenParser = new SamlTokenParser();
}
this.dataHandlerToBytesConverter = dataHandlerToBytesConverter;
this.auditService = auditService;
this.aspectUtils = aspectUtils;
}
/*
* (non-Javadoc)
*
* @see gov.samhsa.acs.pep.PolicyEnforcementPoint#directEmailSend(gov.samhsa
* .ds4ppilot.schema.pep.DirectEmailSendRequest)
*/
@Override
public DirectEmailSendResponse directEmailSend(DirectEmailSendRequest input) {
final DirectEmailSendResponse response = new DirectEmailSendResponse();
XacmlRequest xacmlRequest = null;
String resourceId = null;
String intermediarySubject = null;
String purposeOfUse = null;
String recipientSubject = null;
final String messageId = createMessageId();
final String INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR";
final String NO_POLICY = "NO_POLICY";
PolicyEnforcementPointResponseStatus pepResponseStatus = PolicyEnforcementPointResponseStatus.SUCCESS;
try {
// logging DirectEmailSendRequest
logger.debug(messageId, aspectUtils.getInXMLFormat(input));
final SAMLTokenPrincipal samlTokenPrincipal = getUserPrincipal(messageId);
resourceId = parseSamlToken(samlTokenPrincipal, URN_RESOURCE_ID,
messageId);
intermediarySubject = parseSamlToken(samlTokenPrincipal,
URN_INTERMEDIARY_SUBJECT, messageId);
purposeOfUse = parseSamlToken(samlTokenPrincipal,
URN_PURPOSE_OF_USE, messageId);
recipientSubject = parseSamlToken(samlTokenPrincipal,
URN_RECIPIENT_SUBJECT, messageId);
xacmlRequest = setXacmlRequest(resourceId, purposeOfUse,
intermediarySubject, recipientSubject, messageId);
// logging XacmlRequest
logger.debug(messageId, aspectUtils.getInXMLFormat(xacmlRequest));
// Audit incoming retrieveDocumentSetRequest
auditRequest(input, xacmlRequest);
// Enforce policy
final XacmlResponse xacmlResponse = contextHandler
.enforcePolicy(xacmlRequest);
// logging xacmlResponse
logger.debug(messageId, aspectUtils.getInXMLFormat(xacmlResponse));
if (PERMIT.equals(xacmlResponse.getPdpDecision())) {
response.setPdpDecision(PERMIT);
final String originalC32 = input.getC32();
byte[] processedPayload;
final XacmlResult xacmlResult = createXacmlResult(xacmlRequest,
xacmlResponse);
final String xacmlResultString = marshaller
.marshal(xacmlResult);
final String xdsDocumentEntryUniqueId = "";
// packageAsXdm = input.getPackageAsXdm()
final boolean packageAsXdm = true;
final DSSRequestForDirect request = new DSSRequestForDirect();
request.setDocumentXml(originalC32);
request.setEnforcementPoliciesXml(xacmlResultString);
request.setAudited(true);
request.setAuditFailureByPass(isAuditFailureByPass);
request.setPackageAsXdm(packageAsXdm);
request.setRecipientEmailAddress(input.getRecipientEmail());
request.setSenderEmailAddress(input.getSenderEmail());
request.setXdsDocumentEntryUniqueId(xdsDocumentEntryUniqueId);
final DSSResponseForDirect segmentDocumentResponse = documentSegmentation
.segmentDocumentForDirect(request);
processedPayload = dataHandlerToBytesConverter
.toByteArray(segmentDocumentResponse
.getDocumentPayloadRawData());
response.setMaskedDocument(segmentDocumentResponse
.getSegmentedDocumentXml());
response.setFilteredStreamBody(processedPayload);
} else {
handlePDPDeny(messageId, xacmlRequest, xacmlResponse);
}
// Handle errors
} catch (final SamlTokenPrincipalException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(
messageId,
"SAMLTokenPrincipal cannot be retrieved from WebServiceContext.",
e);
response.setPdpDecision(INTERNAL_SERVER_ERROR);
} catch (final SamlTokenParserException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "SamlTokenParser failed.", e);
response.setPdpDecision(INTERNAL_SERVER_ERROR);
} catch (final AuditException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "AuditService failed.", e);
response.setPdpDecision(INTERNAL_SERVER_ERROR);
} catch (final NoPolicyFoundException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_CONSENT;
logger.info(messageId, e.getMessage());
logger.debug(messageId, e.getMessage(), e);
response.setPdpDecision(NO_POLICY);
} catch (final PolicyProviderException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "PolicyProvider failed.", e);
response.setPdpDecision(INTERNAL_SERVER_ERROR);
}
// TODO (BU)
/*
* catch (final InvalidSegmentedClinicalDocumentException e) {
* pepResponseStatus =
* PolicyEnforcementPointResponseStatus.ERROR_SYSTEM; final
* StringBuilder errorBuilder = new StringBuilder(); errorBuilder
* .append
* ("Schema validation failed: Invalid document after segmentation: ");
* errorBuilder.append(e.getMessage()); errorBuilder.append(".");
* logger.debug(messageId, errorBuilder.toString(), e);
* logger.error(messageId, errorBuilder.toString());
* response.setPdpDecision(INTERNAL_SERVER_ERROR); }
*/
catch (final XmlDocumentReadFailureException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
final StringBuilder errorBuilder = new StringBuilder();
errorBuilder
.append("Schema validation failed: Unable to load schema: ");
errorBuilder.append(e.getMessage());
errorBuilder.append(".");
logger.error(messageId, errorBuilder.toString(), e);
response.setPdpDecision(INTERNAL_SERVER_ERROR);
} catch (final IOException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "DataHandlerToBytesConverter failed.", e);
response.setPdpDecision(INTERNAL_SERVER_ERROR);
} catch (final SimpleMarshallerException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "SimpleMarshaller failed.", e);
response.setPdpDecision(INTERNAL_SERVER_ERROR);
} catch (final Throwable t) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId,
"Unexpected exception occured in PolicyEnforcementPoint.",
t);
response.setPdpDecision(INTERNAL_SERVER_ERROR);
} finally {
// Audit response
try {
if (xacmlRequest == null) {
xacmlRequest = setXacmlRequestIfNull(resourceId, messageId);
}
auditResponse(response, xacmlRequest, pepResponseStatus);
} catch (final Throwable e) {
logger.error(messageId, "Cannot audit the response.", e);
response.setPdpDecision(INTERNAL_SERVER_ERROR);
}
}
Assert.notNull(response.getPdpDecision());
return response;
}
/*
* (non-Javadoc)
*
* @see gov.samhsa.acs.pep.PolicyEnforcementPoint#registryStoredQuery(oasis
* .names.tc.ebxml_regrep.xsd.query._3.AdhocQueryRequest)
*/
@Override
public AdhocQueryResponse registryStoredQuery(AdhocQueryRequest req) {
AdhocQueryResponse response = null;
XacmlRequest xacmlRequest = null;
String resourceId = null;
String intermediarySubject = null;
String purposeOfUse = null;
String recipientSubject = null;
final String messageId = createMessageId();
PolicyEnforcementPointResponseStatus pepResponseStatus = PolicyEnforcementPointResponseStatus.SUCCESS;
try {
// logging AdhocQueryRequest
logger.debug(messageId, aspectUtils.getInXMLFormat(req));
final SAMLTokenPrincipal samlTokenPrincipal = getUserPrincipal(messageId);
resourceId = parseSamlToken(samlTokenPrincipal, URN_RESOURCE_ID,
messageId);
intermediarySubject = parseSamlToken(samlTokenPrincipal,
URN_INTERMEDIARY_SUBJECT, messageId);
purposeOfUse = parseSamlToken(samlTokenPrincipal,
URN_PURPOSE_OF_USE, messageId);
recipientSubject = parseSamlToken(samlTokenPrincipal,
URN_RECIPIENT_SUBJECT, messageId);
xacmlRequest = setXacmlRequest(resourceId, purposeOfUse,
intermediarySubject, recipientSubject, messageId);
// logging XacmlRequest
logger.debug(messageId, aspectUtils.getInXMLFormat(xacmlRequest));
// Audit incoming registryStoredQueryRequest
auditRequest(req, xacmlRequest);
// Validate input parameters
validateAdhocQueryRequest(req, messageId);
// Validate format code (only '2.16.840.1.113883.10.20.1^^HITSP' is
// supported)
final String formatCode = xdsbRegistry.extractFormatCode(req);
validateFormatCode(formatCode, messageId);
// Validate response option type (only 'LeafClass' is supported,
// because PEP requires metadata for filtering query response)
validateResponseOptionType(req, messageId);
// The patient id in $XDSDocumentEntryPatientId
final String patientUniqueId = xdsbRegistry.extractPatientId(req);
validatePatientUniqueIdConsistency(patientUniqueId,
xacmlRequest.getPatientUniqueId(), messageId);
// Enforce policy
final XacmlResponse xacmlResponse = contextHandler
.enforcePolicy(xacmlRequest);
// logging xacmlResponse
logger.info(messageId,
"PDP Decision : " + xacmlResponse.getPdpDecision());
logger.debug(messageId, aspectUtils.getInXMLFormat(xacmlResponse));
// If PDP returns PERMIT
if (PERMIT.equals(xacmlResponse.getPdpDecision())) {
// Search for clinical documents of the patient
response = xdsbRegistry.registryStoredQuery(req,
intermediarySubject, messageId);
// logging AdhocQueryResponse
logger.debug(messageId, aspectUtils.getInXMLFormat(response));
// If the response returns empty, it means either there are no
// documents found or they are filtered out by the authorId
// (intermediaryNPI)
validateResponse(response, patientUniqueId,
intermediarySubject, messageId);
} else {
// PDP did not return PERMIT
handlePDPDeny(messageId, xacmlRequest, xacmlResponse);
}
// Handle Errors
} catch (final SamlTokenPrincipalException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(
messageId,
"SAMLTokenPrincipal cannot be retrieved from WebServiceContext.",
e);
response = xdsbErrorFactory
.errorAdhocQueryResponseInternalServerError();
} catch (final SamlTokenParserException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "SamlTokenParser failed.", e);
response = xdsbErrorFactory
.errorAdhocQueryResponseInternalServerError();
} catch (final AuditException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "AuditService failed.", e);
response = xdsbErrorFactory
.errorAdhocQueryResponseInternalServerError();
} catch (final XdsbRegistryAdapterException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "XdsbRegistryAdapter failed.", e);
response = xdsbErrorFactory
.errorAdhocQueryResponseRegistryNotAvailable();
} catch (final MissingParameterException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.info(messageId, e.getMessage());
logger.debug(messageId, e.getMessage(), e);
response = xdsbErrorFactory
.errorAdhocQueryResponseMissingParameters();
} catch (final UnsupportedFormatCodeException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.info(messageId, e.getMessage());
logger.debug(messageId, e.getMessage(), e);
response = xdsbErrorFactory
.errorAdhocQueryResponseConstructByErrorMessage(e
.getMessage());
} catch (final UnsupportedResponseOptionTypeException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.info(messageId, e.getMessage());
logger.debug(messageId, e.getMessage(), e);
response = xdsbErrorFactory
.errorAdhocQueryResponseConstructByErrorMessage(e
.getMessage());
} catch (final InconsistentPatientUniqueIdException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.info(messageId, e.getMessage());
logger.debug(messageId, e.getMessage(), e);
response = xdsbErrorFactory
.errorAdhocQueryResponseConstructByErrorMessage(e
.getMessage());
} catch (final NoPolicyFoundException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_CONSENT;
logger.info(messageId, e.getMessage());
logger.debug(messageId, e.getMessage(), e);
response = xdsbErrorFactory
.errorAdhocQueryResponseConstructByErrorMessage(e
.getMessage());
} catch (final PolicyProviderException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "PolicyProvider failed.", e);
response = xdsbErrorFactory
.errorAdhocQueryResponseInternalServerError();
} catch (final NoDocumentFoundException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.info(messageId, e.getMessage());
logger.debug(messageId, e.getMessage(), e);
response = xdsbErrorFactory
.errorAdhocQueryResponseConstructByErrorMessage(e
.getMessage());
} catch (final Throwable t) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId,
"Unexpected exception occured in PolicyEnforcementPoint.",
t);
response = xdsbErrorFactory
.errorAdhocQueryResponseInternalServerError();
} finally {
// Audit response
try {
if (xacmlRequest == null) {
xacmlRequest = setXacmlRequestIfNull(resourceId, messageId);
}
auditResponse(response, xacmlRequest, pepResponseStatus);
} catch (final Throwable e) {
logger.error(messageId, "Cannot audit the response.", e);
response = xdsbErrorFactory
.errorAdhocQueryResponseInternalServerError();
}
}
Assert.notNull(response, "The response cannot be null.");
return response;
}
/*
* (non-Javadoc)
*
* @see gov.samhsa.acs.pep.PolicyEnforcementPoint#retrieveDocumentSet(ihe
* .iti.xds_b._2007.RetrieveDocumentSetRequest)
*/
@Override
public RetrieveDocumentSetResponse retrieveDocumentSet(
RetrieveDocumentSetRequest input) {
RetrieveDocumentSetResponse response = null;
XacmlRequest xacmlRequest = null;
String resourceId = null;
String intermediarySubject = null;
String purposeOfUse = null;
String recipientSubject = null;
final String messageId = createMessageId();
PolicyEnforcementPointResponseStatus pepResponseStatus = PolicyEnforcementPointResponseStatus.SUCCESS;
try {
// logging RetrieveDocumentSetRequest
logger.debug(messageId, aspectUtils.getInXMLFormat(input));
final SAMLTokenPrincipal samlTokenPrincipal = getUserPrincipal(messageId);
resourceId = parseSamlToken(samlTokenPrincipal, URN_RESOURCE_ID,
messageId);
intermediarySubject = parseSamlToken(samlTokenPrincipal,
URN_INTERMEDIARY_SUBJECT, messageId);
purposeOfUse = parseSamlToken(samlTokenPrincipal,
URN_PURPOSE_OF_USE, messageId);
recipientSubject = parseSamlToken(samlTokenPrincipal,
URN_RECIPIENT_SUBJECT, messageId);
xacmlRequest = setXacmlRequest(resourceId, purposeOfUse,
intermediarySubject, recipientSubject, messageId);
// logging XacmlRequest
logger.debug(messageId, aspectUtils.getInXMLFormat(xacmlRequest));
// Audit incoming retrieveDocumentSetRequest
auditRequest(input, xacmlRequest);
// Validate request (check for multiple repository ids)
validateRetrieveDocumentSetRequest(input, messageId);
// Enforce policy
final XacmlResponse xacmlResponse = contextHandler
.enforcePolicy(xacmlRequest);
// logging xacmlResponse
logger.debug(messageId, aspectUtils.getInXMLFormat(xacmlResponse));
// If PDP returns PERMIT
if (PERMIT.equals(xacmlResponse.getPdpDecision())) {
// Retrieve documents
response = xdsbRepository.retrieveDocumentSet(input,
xacmlRequest.getPatientId(),
xacmlRequest.getIntermediarySubjectNPI());
// logging RetrieveDocumentSetResponse
logger.debug(messageId, aspectUtils.getInXMLFormat(response));
// Validate response
validateRetrieveDocumentSetResponse(response, messageId);
// Start segmentation
segmentResponse(response, messageId, xacmlRequest,
xacmlResponse);
} else {
// PDP did not return PERMIT
handlePDPDeny(messageId, xacmlRequest, xacmlResponse);
}
// Handle errors
} catch (final SamlTokenPrincipalException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(
messageId,
"SAMLTokenPrincipal cannot be retrieved from WebServiceContext.",
e);
response = xdsbErrorFactory
.errorRetrieveDocumentSetInternalServerError();
} catch (final SamlTokenParserException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "SamlTokenParser failed.", e);
response = xdsbErrorFactory
.errorRetrieveDocumentSetInternalServerError();
} catch (final AuditException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "AuditService failed.", e);
response = xdsbErrorFactory
.errorRetrieveDocumentSetInternalServerError();
} catch (final MultipleRepositoryIdException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.info(messageId, e.getMessage());
logger.debug(messageId, e.getMessage(), e);
response = xdsbErrorFactory
.errorRetrieveDocumentSetResponseConstructByErrorMessage(e
.getMessage());
} catch (final NoPolicyFoundException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_CONSENT;
logger.info(messageId, e.getMessage());
logger.debug(messageId, e.getMessage(), e);
response = xdsbErrorFactory
.errorRetrieveDocumentSetResponseConstructByErrorMessage(e
.getMessage());
} catch (final PolicyProviderException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "PolicyProvider failed.", e);
response = xdsbErrorFactory
.errorRetrieveDocumentSetInternalServerError();
} catch (final XdsbRepositoryAdapterException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "XdsbRepositoryAdapter failed.", e);
response = xdsbErrorFactory
.errorRetrieveDocumentSetResponseRepositoryNotAvailable();
} catch (final NoDocumentFoundException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.info(messageId, e.getMessage());
logger.debug(messageId, e.getMessage(), e);
response = xdsbErrorFactory
.errorRetrieveDocumentSetResponseNotExistsOrAccessible(input);
} catch (final SimpleMarshallerException e) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId, "SimpleMarshaller failed.", e);
response = xdsbErrorFactory
.errorRetrieveDocumentSetInternalServerError();
} catch (final Throwable t) {
pepResponseStatus = PolicyEnforcementPointResponseStatus.ERROR_SYSTEM;
logger.error(messageId,
"Unexpected exception occured in PolicyEnforcementPoint.",
t);
response = xdsbErrorFactory
.errorRetrieveDocumentSetInternalServerError();
} finally {
// Audit response
try {
if (xacmlRequest == null) {
xacmlRequest = setXacmlRequestIfNull(resourceId, messageId);
}
auditResponse(response, xacmlRequest, pepResponseStatus);
} catch (final Throwable e) {
logger.error(messageId, "Cannot audit the response.", e);
response = xdsbErrorFactory
.errorRetrieveDocumentSetInternalServerError();
}
}
Assert.notNull(response, "The response cannot be null.");
return response;
}
/**
* Sets the xacml request.
*
* @param resourceId
* the resource id
* @param purposeOfUse
* the purpose of use
* @param intermediarySubject
* the intermediary subject
* @param recipientSubject
* the recipient subject
* @param messageId
* the message id
* @return the xacml request
*/
public XacmlRequest setXacmlRequest(String resourceId, String purposeOfUse,
String intermediarySubject, String recipientSubject,
String messageId) {
final XacmlRequest xacmlRequest = new XacmlRequest();
String homeCommunityId = "";
String patientId = "";
// Sample resourceId:
// "d3bb3930-7241-11e3-b4f7-00155d3a2124^^^&2.16.840.1.113883.4.357&ISO"
final StringTokenizer tokenizer = new StringTokenizer(resourceId, "&");
patientId = tokenizer.nextToken().replace("^^^", "");
homeCommunityId = tokenizer.nextToken();
xacmlRequest.setHomeCommunityId(homeCommunityId);
xacmlRequest.setIntermediarySubjectNPI(intermediarySubject);
xacmlRequest.setMessageId(messageId);
xacmlRequest.setPurposeOfUse(purposeOfUse);
xacmlRequest.setRecipientSubjectNPI(recipientSubject);
xacmlRequest.setPatientId(patientId);
xacmlRequest.setPatientUniqueId("'" + resourceId + "'");
return xacmlRequest;
}
/**
* Sets the xacml request if null.
*
* @param resourceId
* the resource id
* @param messageId
* the message id
* @return the xacml request
*/
public XacmlRequest setXacmlRequestIfNull(String resourceId,
final String messageId) {
final XacmlRequest xacmlRequest = new XacmlRequest();
xacmlRequest.setMessageId(messageId);
xacmlRequest.setPatientId(resourceId);
return xacmlRequest;
}
/**
* Validate adhoc query request.
*
* @param req
* the req
* @param messageId
* the message id
* @return true, if successful
* @throws XdsbRegistryAdapterException
* the xdsb registry adapter exception
* @throws MissingParameterException
* the missing parameter exception
*/
boolean validateAdhocQueryRequest(AdhocQueryRequest req, String messageId)
throws XdsbRegistryAdapterException, MissingParameterException {
String formatCode = null;
String pid = null;
String status = null;
try {
formatCode = xdsbRegistry.extractFormatCode(req);
pid = xdsbRegistry.extractPatientId(req);
status = xdsbRegistry.extractDocumentEntryStatus(req);
} catch (final Throwable t) {
logger.error(messageId, t.getMessage());
final String errMsg = "XdsbRegistryAdapter failed while trying to extract formatCode, patientId or documentEntryStatus from AdhocQueryRequest.";
logger.error(messageId, errMsg);
throw new XdsbRegistryAdapterException(errMsg);
}
final boolean valid = isNotNull(formatCode) && isNotNull(pid)
&& isNotNull(status);
if (!valid) {
final String errMsg = "Missing required parameters in AdhocQueryRequest.";
logger.debug(messageId, errMsg);
throw new MissingParameterException(errMsg);
}
return valid;
}
/**
* Audit request.
*
* @param request
* the request
* @param xacmlRequest
* the xacml request
* @throws AuditException
* the audit exception
*/
private void auditRequest(Object request, XacmlRequest xacmlRequest)
throws AuditException {
AuditVerb requestType = null;
if (request instanceof AdhocQueryRequest) {
requestType = REGISTRY_STORED_QUERY_REQUEST;
} else if (request instanceof RetrieveDocumentSetRequest) {
requestType = RETRIEVE_DOCUMENT_SET_REQUEST;
} else if (request instanceof DirectEmailSendRequest) {
requestType = DIRECT_EMAIL_SEND_REQUEST;
} else {
final StringBuilder builder = new StringBuilder();
builder.append("Invalid request type: ");
builder.append(request.getClass().getName());
builder.append(": This request cannot be audited by Policy Enforcement Point.");
final String errMsg = builder.toString();
logger.error(xacmlRequest.getMessageId(), errMsg);
throw new AuditException(errMsg);
}
final Map<PredicateKey, String> predicateMap = auditService
.createPredicateMap();
predicateMap.put(INTERMEDIARY_SUBJECT_NPI,
xacmlRequest.getIntermediarySubjectNPI());
predicateMap.put(RECIPIENT_SUBJECT_NPI,
xacmlRequest.getRecipientSubjectNPI());
predicateMap.put(PATIENT_UNIQUE_ID, xacmlRequest.getPatientUniqueId());
predicateMap.put(PURPOSE_OF_USE, xacmlRequest.getPurposeOfUse());
try {
predicateMap.put(REQUEST_BODY, marshaller.marshal(request));
} catch (final SimpleMarshallerException e) {
logger.error(xacmlRequest.getMessageId(), e.getMessage());
logger.error(xacmlRequest.getMessageId(),
"SimpleMarshaller failed during auditing.");
throw new AuditException(e.getMessage(), e);
}
auditService.audit(this, xacmlRequest.getMessageId(), requestType,
xacmlRequest.getPatientId(), predicateMap);
}
/**
* Audit response.
*
* @param response
* the response
* @param xacmlRequest
* the xacml request
* @param pepResponseStatus
* the pep response status
* @throws SimpleMarshallerException
* the simple marshaller exception
* @throws AuditException
* the audit exception
*/
private void auditResponse(Object response, XacmlRequest xacmlRequest,
PolicyEnforcementPointResponseStatus pepResponseStatus)
throws SimpleMarshallerException, AuditException {
final AuditVerb auditVerb = resolveResponseAuditVerb(response,
pepResponseStatus);
Assert.notNull(auditVerb,
"Cannot resolve AuditVerb; it cannot be null.");
final Map<PredicateKey, String> predicateMap = auditService
.createPredicateMap();
predicateMap.put(RESPONSE_BODY, marshaller.marshal(response));
auditService.audit(this, xacmlRequest.getMessageId(), auditVerb,
xacmlRequest.getPatientId(), predicateMap);
}
/**
* Creates the message id.
*
* @return the string
*/
private String createMessageId() {
return UUID.randomUUID().toString();
}
/**
* Sets the xacml result.
*
* @param xacmlRequest
* the xacml request
* @param xacmlResponse
* the xacml response
* @return the xacml result
*/
private XacmlResult createXacmlResult(XacmlRequest xacmlRequest,
XacmlResponse xacmlResponse) {
final XacmlResult xacmlResult = new XacmlResult();
xacmlResult.setHomeCommunityId(xacmlRequest.getHomeCommunityId());
xacmlResult.setMessageId(xacmlRequest.getMessageId());
xacmlResult.setPdpDecision(xacmlResponse.getPdpDecision());
xacmlResult.setPdpObligations(xacmlResponse.getPdpObligation());
xacmlResult.setSubjectPurposeOfUse(SubjectPurposeOfUse
.fromAbbreviation(xacmlRequest.getPurposeOfUse()));
xacmlResult.setPatientId(xacmlRequest.getPatientId());
return xacmlResult;
}
/**
* Gets the user principal.
*
* @param messageId
* the message id
* @return the user principal
* @throws SamlTokenPrincipalException
* the saml token principal exception
*/
private SAMLTokenPrincipal getUserPrincipal(String messageId)
throws SamlTokenPrincipalException {
try {
final SAMLTokenPrincipal samlTokenPrincipal = (SAMLTokenPrincipal) context
.getUserPrincipal();
return samlTokenPrincipal;
} catch (final Throwable t) {
logger.error(messageId, t.getMessage());
throw new SamlTokenPrincipalException(t);
}
}
/**
* Handle pdp deny.
*
* @param messageId
* the message id
* @param xacmlRequest
* the xacml request
* @param xacmlResponse
* the xacml response
* @throws NoPolicyFoundException
* the no policy found exception
*/
private void handlePDPDeny(final String messageId,
XacmlRequest xacmlRequest, XacmlResponse xacmlResponse)
throws NoPolicyFoundException {
// Log PDP decision
final StringBuilder logMsg = new StringBuilder();
logMsg.append("PDP did not return ");
logMsg.append(PERMIT);
logMsg.append(". PDP decision:");
logMsg.append(xacmlResponse.getPdpDecision());
logMsg.append(".");
logger.info(messageId, logMsg.toString());
// Throw NoPolicyFoundException.
final StringBuilder noConsentsFoundErrorStringBuilder = new StringBuilder();
noConsentsFoundErrorStringBuilder
.append("No consents found for patient ");
noConsentsFoundErrorStringBuilder.append(xacmlRequest
.getPatientUniqueId());
noConsentsFoundErrorStringBuilder.append(".");
final String errMsg = noConsentsFoundErrorStringBuilder.toString();
logger.error(messageId, errMsg);
throw new NoPolicyFoundException(errMsg);
}
/**
* Handle xml validation error.
*
* @param documentResponse
* the document response
* @param removeList
* the remove list
* @param errorMap
* the error map
* @param xdsDocumentEntryUniqueId
* the xds document entry unique id
*/
private void handleXmlValidationError(DocumentResponse documentResponse,
List<DocumentResponse> removeList, Map<String, String> errorMap,
String xdsDocumentEntryUniqueId) {
final StringBuilder builder = new StringBuilder();
builder.append("Document validation error occured for documentUniqueId='");
builder.append(xdsDocumentEntryUniqueId);
builder.append("'. Please contact to system administrator if this error persists.");
errorMap.put(xdsDocumentEntryUniqueId, builder.toString());
removeList.add(documentResponse);
}
/**
* Checks if is not null.
*
* @param s
* the s
* @return true, if is not null
*/
private boolean isNotNull(String s) {
return s != null && !"".equals(s);
}
/**
* Parses the saml token.
*
* @param samlTokenPrincipal
* the saml token principal
* @param urn
* the urn
* @param messageId
* the message id
* @return the string
* @throws SamlTokenParserException
* the saml token parser exception
*/
private String parseSamlToken(SAMLTokenPrincipal samlTokenPrincipal,
String urn, String messageId) throws SamlTokenParserException {
String tokenValue = null;
try {
tokenValue = samlTokenParser.parse(samlTokenPrincipal.getToken(),
urn);
} catch (final Throwable t) {
logger.error(messageId, t.getMessage());
throw new SamlTokenParserException(t.getMessage(), t);
}
return tokenValue;
}
/**
* Resolve response audit verb.
*
* @param response
* the response
* @param pepResponseStatus
* the pep response status
* @return the audit verb
*/
private AuditVerb resolveResponseAuditVerb(Object response,
PolicyEnforcementPointResponseStatus pepResponseStatus) {
AuditVerb auditVerb = null;
if (response instanceof AdhocQueryResponse) {
switch (pepResponseStatus) {
case ERROR_CONSENT:
auditVerb = REGISTRY_STORED_QUERY_RESPONSE_ERROR_CONSENT;
break;
case ERROR_SYSTEM:
auditVerb = REGISTRY_STORED_QUERY_RESPONSE_ERROR_SYSTEM;
break;
case SUCCESS:
auditVerb = REGISTRY_STORED_QUERY_RESPONSE;
break;
default:
auditVerb = null;
break;
}
} else if (response instanceof RetrieveDocumentSetResponse) {
switch (pepResponseStatus) {
case ERROR_CONSENT:
auditVerb = RETRIEVE_DOCUMENT_SET_RESPONSE_ERROR_CONSENT;
break;
case ERROR_SYSTEM:
auditVerb = RETRIEVE_DOCUMENT_SET_RESPONSE_ERROR_SYSTEM;
break;
case SUCCESS:
auditVerb = RETRIEVE_DOCUMENT_SET_RESPONSE;
break;
default:
auditVerb = null;
break;
}
} else if (response instanceof DirectEmailSendResponse) {
switch (pepResponseStatus) {
case ERROR_CONSENT:
auditVerb = DIRECT_EMAIL_SEND_RESPONSE_ERROR_CONSENT;
break;
case ERROR_SYSTEM:
auditVerb = DIRECT_EMAIL_SEND_RESPONSE_ERROR_SYSTEM;
break;
case SUCCESS:
auditVerb = DIRECT_EMAIL_SEND_RESPONSE;
break;
default:
auditVerb = null;
break;
}
} else {
auditVerb = null;
}
return auditVerb;
}
/**
* Segment response.
*
* @param response
* the response
* @param messageId
* the message id
* @param xacmlRequest
* the xacml request
* @param xacmlResponse
* the xacml response
* @throws SimpleMarshallerException
* the simple marshaller exception
* @throws AuditException
* the audit exception
*/
private void segmentResponse(RetrieveDocumentSetResponse response,
final String messageId, XacmlRequest xacmlRequest,
XacmlResponse xacmlResponse) throws SimpleMarshallerException,
AuditException {
final XacmlResult xacmlResult = createXacmlResult(xacmlRequest,
xacmlResponse);
final String enforcementPolicies = marshaller.marshal(xacmlResult);
final Map<String, String> errorMap = new HashMap<String, String>();
final List<DocumentResponse> removeList = new LinkedList<DocumentResponse>();
for (final DocumentResponse documentResponse : response
.getDocumentResponse()) {
final String document = new String(documentResponse.getDocument());
final String xdsDocumentEntryUniqueId = documentResponse
.getDocumentUniqueId();
DSSResponse segmentDocumentResponse = null;
final DSSRequest request = new DSSRequest();
request.setDocumentXml(document);
request.setEnforcementPoliciesXml(enforcementPolicies);
request.setAudited(true);
request.setAuditFailureByPass(isAuditFailureByPass);
// TODO (BU)
try {
segmentDocumentResponse = documentSegmentation
.segmentDocument(request);
}
/*
* catch (final InvalidSegmentedClinicalDocumentException e) { final
* StringBuilder errorBuilder = new StringBuilder(); errorBuilder
* .append
* ("Schema validation failed: Invalid document after segmentation: "
* ); errorBuilder.append(e.getMessage()); errorBuilder.append(".");
* logger.debug(messageId, errorBuilder.toString(), e);
* logger.error(messageId, errorBuilder.toString());
* handleXmlValidationError(documentResponse, removeList, errorMap,
* xdsDocumentEntryUniqueId); } catch (final
* XmlDocumentReadFailureException e) { final StringBuilder
* errorBuilder = new StringBuilder(); errorBuilder
* .append("Schema validation failed: Unable to load schema: ");
* errorBuilder.append(e.getMessage()); errorBuilder.append(".");
* logger.error(messageId, errorBuilder.toString(), e);
* handleXmlValidationError(documentResponse, removeList, errorMap,
* xdsDocumentEntryUniqueId); }
*/
catch (final Exception e) {
logger.error(messageId, "Error in segmentation", e);
handleXmlValidationError(documentResponse, removeList,
errorMap, xdsDocumentEntryUniqueId);
}
if (segmentDocumentResponse != null) {
documentResponse.setDocument(segmentDocumentResponse
.getSegmentedDocumentXml().getBytes());
}
// logging SegmentDocumentResponse
logger.debug(messageId,
aspectUtils.getInXMLFormat(segmentDocumentResponse));
}
// If there are any document failed schema validation
if (removeList.size() > 0) {
// Remove invalid document
response.getDocumentResponse().removeAll(removeList);
// Add proper error message in the response, and return it
xdsbErrorFactory.errorRetrieveDocumentSetResponseSchemaValidation(
response, errorMap);
}
}
/**
* Validate format code.
*
* @param formatCode
* the format code
* @param messageId
* the message id
* @return true, if successful
* @throws UnsupportedFormatCodeException
* the unsupported format code exception
*/
private boolean validateFormatCode(String formatCode, String messageId)
throws UnsupportedFormatCodeException {
final boolean valid = XdsbRegistryAdapter.FORMAT_CODE_CLINICAL_DOCUMENT
.equals(formatCode);
if (!valid) {
final StringBuilder builder = new StringBuilder();
builder.append(formatCode);
builder.append(" format code is not supported by Policy Enforcement Point.");
builder.append(" The only supported format code is ");
builder.append(XdsbRegistryAdapter.FORMAT_CODE_CLINICAL_DOCUMENT);
builder.append(".");
final String errMsg = builder.toString();
logger.debug(messageId, errMsg);
throw new UnsupportedFormatCodeException(errMsg);
}
return valid;
}
/**
* Validate patient unique id consistency.
*
* @param patientUniqueIdFromRequest
* the patient unique id from request
* @param patientUniqueIdFromSaml
* the patient unique id from saml
* @param messageId
* the message id
* @return true, if successful
* @throws InconsistentPatientUniqueIdException
* the inconsistent patient unique id exception
*/
private boolean validatePatientUniqueIdConsistency(
String patientUniqueIdFromRequest, String patientUniqueIdFromSaml,
String messageId) throws InconsistentPatientUniqueIdException {
final boolean valid = patientUniqueIdFromRequest
.equals(patientUniqueIdFromSaml);
if (!valid) {
final StringBuilder builder = new StringBuilder();
builder.append("The document entry patient id in $XDSDocumentEntryPatientId (");
builder.append(patientUniqueIdFromRequest);
builder.append(") does not match the patient unique id (");
builder.append(patientUniqueIdFromSaml);
builder.append(") generated from SAML header.");
final String errMsg = builder.toString();
logger.debug(messageId, errMsg);
throw new InconsistentPatientUniqueIdException(errMsg);
}
return valid;
}
/**
* Validate response.
*
* @param response
* the response
* @param patientUniqueId
* the patient unique id
* @param intermediarySubject
* the intermediary subject
* @param messageId
* the message id
* @return true, if successful
* @throws NoDocumentFoundException
* the no document found exception
*/
private boolean validateResponse(AdhocQueryResponse response,
String patientUniqueId, String intermediarySubject, String messageId)
throws NoDocumentFoundException {
final boolean emptyResponse = (response.getRegistryObjectList()
.getIdentifiable() == null || response.getRegistryObjectList()
.getIdentifiable().size() == 0)
&& (response.getResponseSlotList() == null || response
.getResponseSlotList().getSlot().size() == 0)
&& (response.getRegistryErrorList() == null || response
.getRegistryErrorList().getRegistryError().size() == 0);
if (emptyResponse) {
final StringBuilder builder = new StringBuilder();
builder.append("No documents found for patient ");
builder.append(patientUniqueId);
builder.append(" authored by ");
builder.append(intermediarySubject);
builder.append(".");
final String errMsg = builder.toString();
logger.error(messageId, errMsg);
throw new NoDocumentFoundException(errMsg);
}
return !emptyResponse;
}
/**
* Validate response option type.
*
* @param req
* the req
* @param messageId
* the message id
* @return true, if successful
* @throws XdsbRegistryAdapterException
* the xdsb registry adapter exception
* @throws UnsupportedResponseOptionTypeException
* the unsupported response option type exception
*/
private boolean validateResponseOptionType(AdhocQueryRequest req,
String messageId) throws XdsbRegistryAdapterException,
UnsupportedResponseOptionTypeException {
boolean valid;
try {
valid = SUPPORTED_ADHOCQUERY_RESPONSE_TYPE.equals(xdsbRegistry
.extractResponseOptionReturnType(req));
} catch (final Throwable t) {
logger.error(messageId, t.getMessage());
final String errMsg = "XdsbRegistryAdapter failed while extracting AdhocQuery ResponseOptionType.";
logger.error(messageId, errMsg);
throw new XdsbRegistryAdapterException(errMsg);
}
if (!valid) {
final StringBuilder builder = new StringBuilder();
builder.append("Policy Enforcement Point only supports '");
builder.append(SUPPORTED_ADHOCQUERY_RESPONSE_TYPE);
builder.append("' response option return type.");
final String errMsg = builder.toString();
logger.debug(messageId, errMsg);
throw new UnsupportedResponseOptionTypeException(errMsg);
}
return valid;
}
/**
* Validate retrieve document set request.
*
* @param input
* the input
* @param messageId
* the message id
* @return true, if successful
* @throws MultipleRepositoryIdException
* the multiple repository id exception
*/
private boolean validateRetrieveDocumentSetRequest(
RetrieveDocumentSetRequest input, String messageId)
throws MultipleRepositoryIdException {
String firstRepositoryId = null;
Assert.notEmpty(input.getDocumentRequest());
for (final DocumentRequest docReq : input.getDocumentRequest()) {
// Capture the first document request's repository id
if (firstRepositoryId == null) {
firstRepositoryId = docReq.getRepositoryUniqueId();
}
// Check if rest of the repository ids are same
if (!firstRepositoryId.equals(docReq.getRepositoryUniqueId())) {
final String errMsg = "All repository ids in RetrieveDocumentSetRequest need to be same.";
logger.debug(messageId, errMsg);
throw new MultipleRepositoryIdException(errMsg);
}
}
return true;
}
/**
* Validate retrieve document set response.
*
* @param response
* the response
* @param messageId
* the message id
* @return true, if successful
* @throws NoDocumentFoundException
* the no document found exception
*/
private boolean validateRetrieveDocumentSetResponse(
RetrieveDocumentSetResponse response, final String messageId)
throws NoDocumentFoundException {
if (response.getDocumentResponse() == null
|| response.getDocumentResponse().size() == 0) {
if (response.getRegistryResponse().getRegistryErrorList()
.getRegistryError().size() > 0) {
final String errMsg = "No document found in XDS.b repository. XDS.b returns an error response.";
logger.debug(messageId, errMsg);
throw new NoDocumentFoundException(errMsg);
}
}
return true;
}
}