package gov.nist.registry.ws;
import gov.nist.registry.common2.MetadataTypes;
import gov.nist.registry.common2.exception.ExceptionUtil;
import gov.nist.registry.common2.exception.MetadataException;
import gov.nist.registry.common2.exception.SchemaValidationException;
import gov.nist.registry.common2.exception.XdsException;
import gov.nist.registry.common2.exception.XdsFormatException;
import gov.nist.registry.common2.exception.XdsInternalException;
import gov.nist.registry.common2.registry.MetadataSupport;
import gov.nist.registry.common2.registry.RegistryUtility;
import gov.nist.registry.common2.registry.RetrieveMultipleResponse;
import gov.nist.registry.common2.registry.XdsCommon;
import gov.nist.registry.common2.service.AppendixV;
import gov.nist.registry.common2.util.PidHelper;
import gov.nist.registry.ws.config.Repository;
import gov.nist.registry.ws.serviceclasses.XdsService;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMText;
import org.apache.axis2.context.MessageContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openhealthtools.common.ihe.IheActor;
import org.openhealthtools.common.ws.server.IheHTTPServer;
import org.openhealthtools.openexchange.actorconfig.net.IConnectionDescription;
import org.openhealthtools.openexchange.audit.ActiveParticipant;
import org.openhealthtools.openexchange.audit.AuditCodeMappings;
import org.openhealthtools.openexchange.audit.IheAuditTrail;
import org.openhealthtools.openexchange.audit.ParticipantObject;
import org.openhealthtools.openexchange.config.PropertyFacade;
import org.openhealthtools.openexchange.utils.Pair;
import org.openhealthtools.openxds.XdsFactory;
import org.openhealthtools.openxds.log.LogMessage;
import org.openhealthtools.openxds.log.LoggerException;
import org.openhealthtools.openxds.repository.api.RepositoryException;
import org.openhealthtools.openxds.repository.api.RepositoryRequestContext;
import org.openhealthtools.openxds.repository.api.XdsRepositoryItem;
import org.openhealthtools.openxds.repository.api.XdsRepositoryService;
import org.openhealthtools.openxua.api.XuaException;
public class RetrieveDocumentSet extends XdsCommon {
ContentValidationService validater;
String registry_endpoint = null;
MessageContext messageContext;
boolean optimize = true;
IConnectionDescription connection = null;
/* The IHE Audit Trail for this actor. */
private IheAuditTrail auditLog = null;
private final static Log logger = LogFactory.getLog(RetrieveDocumentSet.class);
public RetrieveDocumentSet(LogMessage log_message, short xds_version, MessageContext messageContext) {
this.log_message = log_message;
this.messageContext = messageContext;
transaction_type = RET_transaction;
IheHTTPServer httpServer = (IheHTTPServer) messageContext.getTransportIn().getReceiver();
try {
IheActor actor = httpServer.getIheActor();
if (actor == null) {
throw new XdsInternalException("Cannot find XdsRepository actor configuration.");
}
connection = actor.getConnection();
if (connection == null) {
throw new XdsInternalException("Cannot find Server connection configuration.");
}
auditLog = actor.getAuditTrail();
init(new RetrieveMultipleResponse(), xds_version, messageContext);
}
catch (XdsInternalException e) {
logger.fatal(logger_exception_details(e));
response.add_error("XDSRepositoryError", e.getMessage(), ExceptionUtil.exception_details(e), log_message);
}
}
public OMElement retrieveDocumentSet(OMElement rds, ContentValidationService validater, boolean optimize, XdsService service) throws SchemaValidationException, XdsInternalException {
this.validater = validater;
this.optimize = optimize;
OMNamespace ns = rds.getNamespace();
String ns_uri = ns.getNamespaceURI();
if (ns_uri == null || !ns_uri.equals(MetadataSupport.xdsB.getNamespaceURI())) {
return service.start_up_error(rds, "RetrieveDocumentSet.java", AppendixV.REPOSITORY_ACTOR, "Invalid namespace on RetrieveDocumentSetRequest (" + ns_uri + ")", true);
}
try {
RegistryUtility.schema_validate_local(rds, MetadataTypes.METADATA_TYPE_RET);
} catch (Exception e) {
return service.start_up_error(rds, "RetrieveDocumentSet.java", AppendixV.REPOSITORY_ACTOR, "Schema validation errors:\n" + e.getMessage(), true);
}
ArrayList<OMElement> retrieve_documents = null;
// Call X-Service Provider Actor to validate X-User Assertion with X-Assertion Provider
try {
boolean validateUserAssertion = PropertyFacade.getBoolean("validate.userassertion");
if(validateUserAssertion){
SoapHeader header = new SoapHeader(messageContext);
boolean status = validateAssertion(header);
if (!status)
throw new XdsException("Invalid Identity Assertion");
}
retrieve_documents = retrieve_documents(rds);
}
catch (XdsFormatException e) {
response.add_error("XDSRepositoryError", "SOAP Format Error: " + e.getMessage(), RegistryUtility.exception_trace(e), log_message);
}
catch (MetadataException e) {
response.add_error("XDSRepositoryError", "Request Validation Error:\n " + e.getMessage(), RegistryUtility.exception_details(e), log_message);
}
catch (XdsException e) {
response.add_error("XDSRepositoryError", e.getMessage(), RegistryUtility.exception_details(e), log_message);
logger.fatal(logger_exception_details(e));
} catch (XuaException e) {
response.add_error("XDSRepositoryError", "XUA Error" + e.getMessage(), RegistryUtility.exception_details(e), log_message);
}
OMElement registry_response = null;
try {
registry_response = response.getResponse();
} catch (XdsInternalException e) {
logger.fatal(logger_exception_details(e));
try {
log_message.addErrorParam("Internal Error", "Error generating response from Ret.b");
}
catch (LoggerException e1) {
logger.fatal(logger_exception_details(e1));
}
}
//OMElement rdsr = MetadataSupport.om_factory.createOMElement("RetrieveDocumentSetResponse", MetadataSupport.xds_b);
//rdsr.addChild(registry_response);
if (retrieve_documents != null)
for (OMElement ret_doc : retrieve_documents)
registry_response.addChild(ret_doc);
this.log_response();
return response.getRoot();
}
ArrayList<OMElement> retrieve_documents(OMElement rds) throws MetadataException, XdsException {
ArrayList<OMElement> document_responses = new ArrayList<OMElement>();
ArrayList<Pair> doclist = new ArrayList<Pair>();
for (OMElement doc_request : MetadataSupport.childrenWithLocalName(rds, "DocumentRequest")) {
//HashMap<String, String> docMap = new HashMap<String, String>();
Pair doc = new Pair();
String rep_id = null;
String doc_id = null;
String home = null;
try {
rep_id = MetadataSupport.firstChildWithLocalName(doc_request, "RepositoryUniqueId").getText();
if (rep_id == null || rep_id.equals(""))
throw new Exception("");
}
catch (Exception e) {
throw new MetadataException("Cannot extract RepositoryUniqueId from DocumentRequest");
}
try {
doc_id = MetadataSupport.firstChildWithLocalName(doc_request, "DocumentUniqueId").getText();
if (doc_id == null || doc_id.equals("")) throw new Exception("");
}
catch (Exception e) {
throw new MetadataException("Cannot extract DocumentUniqueId from DocumentRequest");
}
OMElement home_ele = MetadataSupport.firstChildWithLocalName(doc_request, "HomeCommunityId");
if (home_ele != null)
home = home_ele.getText();
doc._first = doc_id;
doc._second = rep_id;
doclist.add(doc);
OMElement document_response = retrieve_document(rep_id, doc_id, home);
if (document_response != null)
document_responses.add(document_response);
}
auditLog(doclist, AuditCodeMappings.AuditTypeCodes.RetrieveDocumentSet);
return document_responses;
}
OMElement retrieve_document(String rep_id, String doc_id, String home) throws XdsException {
XdsRepositoryItem repositoryItem;
XdsRepositoryService rm = XdsFactory.getXdsRepositoryService();
if (!rep_id.equals(rm.getRepositoryUniqueId())) {
response.add_error(MetadataSupport.XDSRepositoryWrongRepositoryUniqueId, "Repository Unique ID in request " +
rep_id +
" does not match this repository's id " +
Repository.getRepositoryUniqueId(),
RegistryUtility.exception_details(null), log_message);
return null;
}
try {
RepositoryRequestContext context = new RepositoryRequestContext();
context.setConnection(connection);
repositoryItem = rm.getRepositoryItem(doc_id, context);
} catch (RepositoryException e) {
throw new XdsException("Cannot find repository item for document id, " + doc_id);
}
if (repositoryItem == null || repositoryItem.getDataHandler() == null)
throw new XdsException("Document is not found in Repository");
OMText t = MetadataSupport.om_factory.createOMText(repositoryItem.getDataHandler(), optimize);
if (logger.isDebugEnabled()) {
logger.debug("OPTIMIZE IS " + optimize);
}
t.setOptimize(optimize);
OMElement document_response = MetadataSupport.om_factory.createOMElement("DocumentResponse", MetadataSupport.xdsB);
if (home != null && !home.equals("")) {
OMElement home_ele = MetadataSupport.om_factory.createOMElement("HomeCommunityId", MetadataSupport.xdsB);
home_ele.addChild(MetadataSupport.om_factory.createOMText(home));
document_response.addChild(home_ele);
}
OMElement repid_ele = MetadataSupport.om_factory.createOMElement("RepositoryUniqueId", MetadataSupport.xdsB);
repid_ele.addChild(MetadataSupport.om_factory.createOMText(rep_id));
document_response.addChild(repid_ele);
OMElement docid_ele = MetadataSupport.om_factory.createOMElement("DocumentUniqueId", MetadataSupport.xdsB);
docid_ele.addChild(MetadataSupport.om_factory.createOMText(doc_id));
document_response.addChild(docid_ele);
OMElement mimetype_ele = MetadataSupport.om_factory.createOMElement("mimeType", MetadataSupport.xdsB);
mimetype_ele.addChild(MetadataSupport.om_factory.createOMText(repositoryItem.getMimeType()));
document_response.addChild(mimetype_ele);
OMElement document_ele = MetadataSupport.om_factory.createOMElement("Document", MetadataSupport.xdsB);
document_ele.addChild(t);
document_response.addChild(document_ele);
return document_response;
}
/**
* Audit Logging of Retrieve Document.
*
* @throws MetadataException
*/
private void auditLog(ArrayList<Pair> doclist, AuditCodeMappings.AuditTypeCodes eventTypeCode) throws MetadataException {
if (auditLog == null)
return;
String replyto = getMessageContext().getReplyTo().getAddress();
String remoteIP = (String) getMessageContext().getProperty(MessageContext.REMOTE_ADDR);
String localIP = (String) getMessageContext().getProperty(MessageContext.TRANSPORT_ADDR);
ActiveParticipant source = new ActiveParticipant();
source.setUserId(replyto);
// 'Retrieve Document Set' requires the altUserId of the source to be set to the Process
// ID of the JVM. TF6 vol 2b section 3.43.6.1.1
source.setAltUserId(PidHelper.getPid());
source.setAccessPointId(remoteIP);
ActiveParticipant dest = new ActiveParticipant();
dest.setAccessPointId(localIP);
//TODO: Needs to be improved
String userid = "http://" + connection.getHostname() + ":" + connection.getPort() + "/axis2/services/xdsrepositoryb";
dest.setUserId(userid);
//Document Info
Collection<ParticipantObject> docs = new ArrayList<ParticipantObject>();
for (Pair doc : doclist) {
ParticipantObject docObj = new ParticipantObject();
docObj.setId(doc._first.toString());
docObj.setDetail(new Pair("RepositoryUniqueId", doc._second.toString()));
docs.add(docObj);
}
//Finally Log it.
auditLog.logRepositoryQuery(source, dest, docs, eventTypeCode);
}
}