package gov.nist.registry.ws.serviceclasses;
import gov.nist.registry.common2.exception.MetadataValidationException;
import gov.nist.registry.common2.exception.XdsInternalException;
import gov.nist.registry.common2.exception.XdsValidationException;
import gov.nist.registry.common2.exception.XdsWSException;
import gov.nist.registry.common2.registry.AdhocQueryResponse;
import gov.nist.registry.common2.registry.Metadata;
import gov.nist.registry.common2.registry.MetadataSupport;
import gov.nist.registry.common2.registry.RegistryErrorList;
import gov.nist.registry.common2.registry.RegistryResponse;
import gov.nist.registry.common2.registry.Response;
import gov.nist.registry.common2.registry.RetrieveDocumentSetResponse;
import gov.nist.registry.common2.registry.XdsCommon;
import gov.nist.registry.common2.service.AppendixV;
import gov.nist.registry.common2.soap.Soap;
import gov.nist.registry.common2.xca.HomeAttribute;
import gov.nist.registry.ws.AdhocQueryRequest;
import gov.nist.registry.ws.ContentValidationService;
import gov.nist.registry.ws.RetrieveDocumentSet;
import java.util.List;
import org.apache.axiom.om.OMElement;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openhealthtools.common.ihe.IheActor;
import org.openhealthtools.common.utils.ConnectionUtil;
import org.openhealthtools.common.ws.server.IheHTTPServer;
import org.openhealthtools.openexchange.actorconfig.net.IConnectionDescription;
import org.openhealthtools.openexchange.config.PropertyFacade;
import org.openhealthtools.openxds.log.LoggerException;
import org.openhealthtools.openxds.xca.api.XcaRG;
public abstract class RGAbstract extends XdsService implements ContentValidationService {
private final static Log logger = LogFactory.getLog(RGAbstract.class);
boolean optimize = true;
static String homeProperty;
String home;
static {
homeProperty = PropertyFacade.getString("home.community.id");
}
IConnectionDescription connection = null;
IConnectionDescription registryClientConnection = null;
IConnectionDescription repositoryClientConnection = null;
abstract public boolean runContentValidationService(Metadata request, Response response);
abstract public OMElement AdhocQueryRequest(OMElement ahqr);
abstract protected void validateWS() throws XdsWSException;
abstract protected void validateQueryTransaction(OMElement sor) throws XdsValidationException, MetadataValidationException, XdsInternalException;
abstract protected void validateRetrieveTransaction(OMElement sor) throws XdsValidationException;
abstract protected String getQueryTransactionName();
abstract protected String getRetTransactionName();
public RGAbstract() {
home = homeProperty; // allows sub-classes to override
IheHTTPServer httpServer = (IheHTTPServer)getMessageContext().getTransportIn().getReceiver();
try {
IheActor actor = httpServer.getIheActor();
if (actor == null) {
throw new XdsInternalException("Cannot find XcaRG actor configuration.");
}
connection = actor.getConnection();
if (connection == null) {
throw new XdsInternalException("Cannot find XcaRG connection configuration.");
}
registryClientConnection = ((XcaRG)actor).getRegistryClientConnection();
if (registryClientConnection == null) {
throw new XdsInternalException("Cannot find XcaRG XdsRegistryClient connection configuration.");
}
repositoryClientConnection = ((XcaRG)actor).getRepositoryClientConnection();
if (repositoryClientConnection == null) {
throw new XdsInternalException("Cannot find XcaRG XdsRepositoryClient connection configuration.");
}
} catch (XdsInternalException e) {
logger.fatal("Internal Error getting XcaRG actor configuration: " + e.getMessage());
}
}
protected void setHome(String home) {
this.home = home;
}
public String getServiceName() { return "RG"; }
public void setOptimize(boolean opt) { this.optimize = opt; }
public OMElement AdhocQueryRequest(OMElement ahqr, String profile_name, String service_name) {
try {
OMElement startup_error = beginTransaction(getQueryTransactionName(), ahqr, AppendixV.REGISTRY_ACTOR);
if (startup_error != null)
return startup_error;
log_message.setTestMessage(getQueryTransactionName());
OMElement ahq = MetadataSupport.firstChildWithLocalName(ahqr, "AdhocQuery") ;
if (ahq == null) {
endTransaction(false);
return this.start_up_error(ahqr, null, REGISTRY_ACTOR, profile_name + " only accepts Stored Query - AdhocQuery element not found");
}
validateWS();
validateQueryTransaction(ahqr);
RegistryErrorList rel = new RegistryErrorList(RegistryErrorList.version_3, true /* log */);
rel.setIsRG();
AdhocQueryRequest a = new AdhocQueryRequest(log_message, getMessageContext(), isSecure(), XdsCommon.xds_b );
a.setServiceName(service_name);
a.setIsRG();
if (a.requiresHomeInXGQ(ahqr)) {
String home = a.getHome(ahqr);
if (home == null || home.equals("")) {
rel.add_error(MetadataSupport.XDSStoredQueryMissingParam,
"homeCommunityId is missing but is required on this type of Stored Query when used in XCA",
"RGAbstract.java", log_message);
OMElement response = new AdhocQueryResponse(Response.version_3, rel).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
}
}
/*OMElement result = a.adhocQueryRequest(ahqr);
setHomeOnSQResponse(result, home);
endTransaction(a.getStatus());
return result;*/
Protocol protocol = ConnectionUtil.getProtocol(registryClientConnection);
String epr = ConnectionUtil.getTransactionEndpoint(registryClientConnection);
Soap soap = new Soap();
soap.soapCall(ahqr, protocol, epr, false, true, true, "urn:ihe:iti:2007:RegistryStoredQuery", null);
OMElement result = soap.getResult();
return processRegResult(result);
}
catch (Exception e) {
return endTransaction(ahqr, e, AppendixV.REGISTRY_ACTOR, "");
}
}
public OMElement RetrieveDocumentSetRequest(OMElement rdsr) {
try {
OMElement startup_error = beginTransaction(getRetTransactionName(), rdsr, AppendixV.REPOSITORY_ACTOR);
if (startup_error != null)
return startup_error;
log_message.setTestMessage(getRetTransactionName());
validateWS();
validateRetrieveTransaction(rdsr);
RegistryErrorList rel = new RegistryErrorList(RegistryErrorList.version_3, true /* log */);
verifyHomeOnRetrieve(rdsr, rel, home);
if (rel.has_errors()) {
rel.setIsRG();
OMElement response = new RetrieveDocumentSetResponse(new RegistryResponse(RegistryErrorList.version_3, rel)).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
}
// RetrieveDocumentSet s = new RetrieveDocumentSet(log_message, XdsCommon.xds_b, getMessageContext());
// s.setIsXCA();
// System.out.println("RBAbstract:Retrieve(): optimize is " + optimize);
// OMElement result = s.retrieveDocumentSet(rdsr, this, optimize /* optimize */, this);
// setHomeOnRetResponse(result);
// log_message.addOtherParam("Result", result.toString());
// endTransaction(s.getStatus());
Protocol protocol = ConnectionUtil.getProtocol(repositoryClientConnection);
String epr = ConnectionUtil.getTransactionEndpoint(repositoryClientConnection);
Soap soap = new Soap();
soap.soapCall(rdsr, protocol, epr, true, true, true, "urn:ihe:iti:2007:RetrieveDocumentSet", null);
OMElement result = soap.getResult();
return processResult(result);
} catch (Exception e) {
return endTransaction(rdsr, e, AppendixV.REPOSITORY_ACTOR, "");
}
}
private OMElement processResult(OMElement result) throws XdsInternalException, LoggerException {
RegistryErrorList rel = new RegistryErrorList(RegistryErrorList.version_3, true /* log */);
rel.setIsRG();
if (result == null) {
rel.add_error(MetadataSupport.XDSRepositoryError, "Null response message from Repository", "RGAbstract.java", log_message);
OMElement response = new RetrieveDocumentSetResponse(new RegistryResponse(RegistryErrorList.version_3, rel)).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
}
OMElement rr = MetadataSupport.firstChildWithLocalName(result, "RegistryResponse");
if (rr == null) {
rel.add_error(MetadataSupport.XDSRepositoryError, "Null RegistryResponse from Repository", "RGAbstract.java", log_message);
OMElement response = new RetrieveDocumentSetResponse(new RegistryResponse(RegistryErrorList.version_3, rel)).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
}
String status = rr.getAttributeValue(MetadataSupport.status_qname);
if (status == null) {
rel.add_error(MetadataSupport.XDSRepositoryError, "Null status from Repository", "RGAbstract.java", log_message);
OMElement response = new RetrieveDocumentSetResponse(new RegistryResponse(RegistryErrorList.version_3, rel)).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
}
if ( !status.equals(MetadataSupport.response_status_type_namespace + "Success")) {
OMElement registry_error_list = MetadataSupport.firstChildWithLocalName(result, "RegistryErrorList");
rel.addRegistryErrorList(registry_error_list, log_message);
OMElement response = new RetrieveDocumentSetResponse(new RegistryResponse(RegistryErrorList.version_3, rel)).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
} else {
setHomeOnRetResponse(result);
log_message.addOtherParam("Result", result.toString());
log_message.setPass(true);
endTransaction(true);
return result;
}
}
private OMElement processRegResult(OMElement result) throws XdsInternalException, LoggerException {
RegistryErrorList rel = new RegistryErrorList(RegistryErrorList.version_3, true /* log */);
rel.setIsRG();
if (result == null) {
rel.add_error(MetadataSupport.XDSRegistryError, "Null response message from Registry", "RGAbstract.java", log_message);
OMElement response = new RetrieveDocumentSetResponse(new RegistryResponse(RegistryErrorList.version_3, rel)).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
}
OMElement rol = MetadataSupport.firstChildWithLocalName(result, "RegistryObjectList");
if (rol == null) {
rel.add_error(MetadataSupport.XDSRegistryError, "Null RegistryObjectList from Registry", "RGAbstract.java", log_message);
OMElement response = new RetrieveDocumentSetResponse(new RegistryResponse(RegistryErrorList.version_3, rel)).getResponse();
result.getFirstElement();
addOther("Response", response.toString());
endTransaction(false);
return response;
}
String status = result.getAttributeValue(MetadataSupport.status_qname);
if (status == null) {
rel.add_error(MetadataSupport.XDSRegistryError, "Null status from Registry", "RGAbstract.java", log_message);
OMElement response = new RetrieveDocumentSetResponse(new RegistryResponse(RegistryErrorList.version_3, rel)).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
}
if ( !status.equals(MetadataSupport.response_status_type_namespace + "Success")) {
OMElement registry_error_list = MetadataSupport.firstChildWithLocalName(result, "RegistryErrorList");
rel.addRegistryErrorList(registry_error_list, log_message);
OMElement response = new RetrieveDocumentSetResponse(new RegistryResponse(RegistryErrorList.version_3, rel)).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
} else {
setHomeOnSQResponse(result, home);
log_message.addOtherParam("Result", result.toString());
log_message.setPass(true);
endTransaction(true);
return result;
}
}
protected void verifyHomeOnRetrieve(OMElement rdsr, RegistryErrorList rel, String home) {
List<OMElement> doc_requests = MetadataSupport.decendentsWithLocalName(rdsr, "DocumentRequest");
for (OMElement doc_request : doc_requests) {
OMElement home_att_ele = MetadataSupport.firstChildWithLocalName(doc_request, "HomeCommunityId");
if (home_att_ele == null) {
rel.add_error(MetadataSupport.XDSMissingHomeCommunityId, "homeCommunityId missing or empty" , null, log_message);
continue;
}
String home_att = home_att_ele.getText();
if (home_att == null || home_att.equals(""))
rel.add_error(MetadataSupport.XDSMissingHomeCommunityId, "homeCommunityId missing or empty" , null, log_message);
else if ( !home_att.equals(home))
rel.add_error(MetadataSupport.XDSUnknownCommunity, "Do not understand homeCommunityId " + home_att , null, log_message);
}
}
public OMElement AdhocQueryRequestTooManyDocs(OMElement ahqr, String profile_name, String service_name) {
try {
OMElement startup_error = beginTransaction(service_name, ahqr, AppendixV.REGISTRY_ACTOR);
if (startup_error != null)
return startup_error;
log_message.setTestMessage(service_name);
OMElement ahq = MetadataSupport.firstChildWithLocalName(ahqr, "AdhocQuery") ;
if (ahq == null) {
endTransaction(false);
return this.start_up_error(ahqr, null, REGISTRY_ACTOR, profile_name + " only accepts Stored Query - AdhocQuery element not found");
}
OMElement respOption = MetadataSupport.firstChildWithLocalName(ahqr, "ResponseOption");
if (respOption == null) {
endTransaction(false);
return this.start_up_error(ahqr, null, REGISTRY_ACTOR, profile_name + " ResponseOption element missing");
}
String returnType = respOption.getAttributeValue(MetadataSupport.return_type_qname);
if ( !returnType.equals("LeafClass")) {
endTransaction(false);
return this.start_up_error(ahqr, null, REGISTRY_ACTOR, profile_name + " This endpoint only accepts LeafClass returnType requests");
}
RegistryErrorList rel = new RegistryErrorList(RegistryErrorList.version_3, true /* log */);
rel.setIsRG();
rel.add_error(MetadataSupport.XDSTooManyResults,
"Too many documents were requested",
"RGAbstract.java", log_message);
OMElement response = new AdhocQueryResponse(Response.version_3, rel).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
}
catch (Exception e) {
return endTransaction(ahqr, e, AppendixV.REPOSITORY_ACTOR, "");
}
}
public OMElement AdhocQueryRequestForceError(OMElement ahqr, String profile_name, String service_name, String errorCode, String errorMessage) {
try {
OMElement startup_error = beginTransaction(service_name, ahqr, AppendixV.REGISTRY_ACTOR);
if (startup_error != null)
return startup_error;
log_message.setTestMessage(service_name);
OMElement ahq = MetadataSupport.firstChildWithLocalName(ahqr, "AdhocQuery") ;
if (ahq == null) {
endTransaction(false);
return this.start_up_error(ahqr, null, REGISTRY_ACTOR, profile_name + " only accepts Stored Query - AdhocQuery element not found");
}
OMElement respOption = MetadataSupport.firstChildWithLocalName(ahqr, "ResponseOption");
if (respOption == null) {
endTransaction(false);
return this.start_up_error(ahqr, null, REGISTRY_ACTOR, profile_name + " ResponseOption element missing");
}
String returnType = respOption.getAttributeValue(MetadataSupport.return_type_qname);
if ( !returnType.equals("LeafClass")) {
endTransaction(false);
return this.start_up_error(ahqr, null, REGISTRY_ACTOR, profile_name + " This endpoint only accepts LeafClass returnType requests");
}
RegistryErrorList rel = new RegistryErrorList(RegistryErrorList.version_3, true /* log */);
rel.setIsRG();
rel.add_error(errorCode,
errorMessage,
"RGAbstract.java", log_message);
OMElement response = new AdhocQueryResponse(Response.version_3, rel).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
}
catch (Exception e) {
return endTransaction(ahqr, e, AppendixV.REPOSITORY_ACTOR, "");
}
}
public OMElement RetrieveDocumentForceError(OMElement rdsr, String errorCode, String errorMessage) {
try {
OMElement startup_error = beginTransaction(getRetTransactionName(), rdsr, AppendixV.REPOSITORY_ACTOR);
if (startup_error != null)
return startup_error;
log_message.setTestMessage(getRetTransactionName());
validateWS();
// validateRetrieveTransaction(rdsr);
RegistryErrorList rel = new RegistryErrorList(RegistryErrorList.version_3, true /* log */);
// verifyHomeOnRetrieve(rdsr, rel, home);
rel.add_error(errorCode,
errorMessage,
"RGAbstract.java", log_message);
if (rel.has_errors()) {
rel.setIsRG();
OMElement response = new RetrieveDocumentSetResponse(new RegistryResponse(RegistryErrorList.version_3, rel)).getResponse();
addOther("Response", response.toString());
endTransaction(false);
return response;
}
RetrieveDocumentSet s = new RetrieveDocumentSet(log_message, XdsCommon.xds_b, getMessageContext());
s.setIsRG();
if (logger.isDebugEnabled()) {
logger.debug("RBAbstract:Retrieve(): optimize is " + optimize);
}
OMElement result = s.retrieveDocumentSet(rdsr, this, optimize /* optimize */, this);
setHomeOnRetResponse(result);
log_message.addOtherParam("Result", result.toString());
endTransaction(s.getStatus());
return result;
} catch (Exception e) {
return endTransaction(rdsr, e, AppendixV.REPOSITORY_ACTOR, "");
}
}
void setHomeOnSQResponse(OMElement root, String home) {
HomeAttribute homeAtt = new HomeAttribute(home);
homeAtt.set(root);
}
void setHomeOnRetResponse(OMElement result) {
List<OMElement> doc_responses = MetadataSupport.decendentsWithLocalName(result, "DocumentResponse");
for (OMElement doc_response : doc_responses) {
if (MetadataSupport.firstChildWithLocalName(doc_response, MetadataSupport.home_community_id_qname.getLocalPart()) == null) {
OMElement hci = MetadataSupport.om_factory.createOMElement(MetadataSupport.home_community_id_qname);
hci.setText(home);
doc_response.getFirstElement().insertSiblingBefore(hci);
}
}
}
}