protected void streamOperationOutcome(
      BaseServerResponseException theE,
      RestfulServer theServer,
      EncodingEnum theEncodingNotNull,
      HttpServletResponse theResponse,
      RequestDetails theRequest)
      throws IOException {
    theResponse.setStatus(theE.getStatusCode());

    theServer.addHeadersToResponse(theResponse);

    if (theE.getOperationOutcome() != null) {
      theResponse.setContentType(theEncodingNotNull.getResourceContentType());
      IParser parser = theEncodingNotNull.newParser(theServer.getFhirContext());
      parser.setPrettyPrint(RestfulServerUtils.prettyPrintResponse(theServer, theRequest));
      Writer writer = theResponse.getWriter();
      try {
        parser.encodeResourceToWriter(theE.getOperationOutcome(), writer);
      } finally {
        writer.close();
      }
    } else {
      theResponse.setContentType(Constants.CT_TEXT);
      Writer writer = theResponse.getWriter();
      try {
        writer.append(theE.getMessage());
      } finally {
        writer.close();
      }
    }
  }
Example #2
0
 @Override
 public Bundle invokeClient(
     String theResponseMimeType,
     Reader theResponseReader,
     int theResponseStatusCode,
     Map<String, List<String>> theHeaders)
     throws IOException, BaseServerResponseException {
   EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
   if (respType == null) {
     throw NonFhirResponseException.newInstance(
         theResponseStatusCode, theResponseMimeType, theResponseReader);
   }
   IParser parser = respType.newParser(myContext);
   return parser.parseBundle(myType, theResponseReader);
 }
  @Test
  public void testView() {

    ExtPatient src = new ExtPatient();
    src.addIdentifier("urn:sys", "id1");
    src.addIdentifier("urn:sys", "id2");
    src.getExt().setValue(100);
    src.getModExt().setValue(200);

    String enc = ourCtx.newXmlParser().encodeResourceToString(src);
    IParser parser = ourCtx.newXmlParser();
    Patient nonExt = parser.parseResource(Patient.class, enc);

    assertEquals(Patient.class, nonExt.getClass());
    assertEquals("urn:sys", nonExt.getIdentifier().get(0).getSystem().getValueAsString());
    assertEquals("id1", nonExt.getIdentifier().get(0).getValue().getValue());
    assertEquals("urn:sys", nonExt.getIdentifier().get(1).getSystem().getValueAsString());
    assertEquals("id2", nonExt.getIdentifier().get(1).getValue().getValueAsString());

    List<ExtensionDt> ext = nonExt.getUndeclaredExtensionsByUrl("urn:ext");
    assertEquals(1, ext.size());
    assertEquals("urn:ext", ext.get(0).getUrlAsString());
    assertEquals(IntegerDt.class, ext.get(0).getValueAsPrimitive().getClass());
    assertEquals("100", ext.get(0).getValueAsPrimitive().getValueAsString());

    List<ExtensionDt> modExt = nonExt.getUndeclaredExtensionsByUrl("urn:modExt");
    assertEquals(1, modExt.size());
    assertEquals("urn:modExt", modExt.get(0).getUrlAsString());
    assertEquals(IntegerDt.class, modExt.get(0).getValueAsPrimitive().getClass());
    assertEquals("200", modExt.get(0).getValueAsPrimitive().getValueAsString());

    ExtPatient va = ourCtx.newViewGenerator().newView(nonExt, ExtPatient.class);
    assertEquals("urn:sys", va.getIdentifier().get(0).getSystem().getValueAsString());
    assertEquals("id1", va.getIdentifier().get(0).getValue().getValue());
    assertEquals("urn:sys", va.getIdentifier().get(1).getSystem().getValueAsString());
    assertEquals("id2", va.getIdentifier().get(1).getValue().getValueAsString());
    assertEquals(100, va.getExt().getValue().intValue());
    assertEquals(200, va.getModExt().getValue().intValue());
    assertEquals(0, va.getAllUndeclaredExtensions().size());
  }
  @Test
  public void testModelExtension() throws DataFormatException {
    MyOrganization org = new MyOrganization();
    org.getName().setValue("org0");

    MyPatient patient = new MyPatient();
    patient.addIdentifier("foo", "bar");
    patient.getManagingOrganization().setResource(org);

    IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
    String str = p.encodeResourceToString(patient);

    ourLog.info(str);

    MyPatient parsed = ourCtx.newXmlParser().parseResource(MyPatient.class, str);
    assertEquals("foo", parsed.getIdentifierFirstRep().getSystem().getValueAsString());

    //		assertEquals(MyOrganization.class,
    // parsed.getManagingOrganization().getResource().getClass());
    //		MyOrganization parsedOrg = (MyOrganization) parsed.getManagingOrganization().getResource();
    //		assertEquals("arg0", parsedOrg.getName().getValue());
  }
Example #5
0
    @Override
    public T invokeClient(
        String theResponseMimeType,
        Reader theResponseReader,
        int theResponseStatusCode,
        Map<String, List<String>> theHeaders)
        throws IOException, BaseServerResponseException {
      EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
      if (respType == null) {
        throw NonFhirResponseException.newInstance(
            theResponseStatusCode, theResponseMimeType, theResponseReader);
      }
      IParser parser = respType.newParser(myContext);
      T retVal = parser.parseResource(myType, theResponseReader);

      if (myId != null) {
        retVal.setId(myId);
      }

      MethodUtil.parseClientRequestResourceHeaders(theHeaders, retVal);

      return retVal;
    }
Example #6
0
    @Override
    public OperationOutcome invokeClient(
        String theResponseMimeType,
        Reader theResponseReader,
        int theResponseStatusCode,
        Map<String, List<String>> theHeaders)
        throws IOException, BaseServerResponseException {
      EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
      if (respType == null) {
        return null;
      }
      IParser parser = respType.newParser(myContext);
      OperationOutcome retVal;
      try {
        retVal = parser.parseResource(OperationOutcome.class, theResponseReader);
      } catch (DataFormatException e) {
        ourLog.warn("Failed to parse OperationOutcome response", e);
        return null;
      }
      MethodUtil.parseClientRequestResourceHeaders(theHeaders, retVal);

      return retVal;
    }
Example #7
0
 /**
  * This method is called for nested bundles (e.g. if we received a transaction with an entry that
  * was a GET search, this method is called on the bundle for the search result, that will be
  * placed in the outer bundle). This method applies the _summary and _content parameters to the
  * output of that bundle.
  *
  * <p>TODO: This isn't the most efficient way of doing this.. hopefully we can come up with
  * something better in the future.
  */
 private IBaseResource filterNestedBundle(
     RequestDetails theRequestDetails, IBaseResource theResource) {
   IParser p = getContext().newJsonParser();
   RestfulServerUtils.configureResponseParser(theRequestDetails, p);
   return p.parseResource(theResource.getClass(), p.encodeResourceToString(theResource));
 }
  @Override
  public Object invokeClient(
      String theResponseMimeType,
      Reader theResponseReader,
      int theResponseStatusCode,
      Map<String, List<String>> theHeaders)
      throws IOException {
    IParser parser =
        createAppropriateParserForParsingResponse(
            theResponseMimeType, theResponseReader, theResponseStatusCode);

    switch (getReturnType()) {
      case BUNDLE:
        {
          Bundle bundle;
          if (myResourceType != null) {
            bundle = parser.parseBundle(myResourceType, theResponseReader);
          } else {
            bundle = parser.parseBundle(theResponseReader);
          }
          switch (getMethodReturnType()) {
            case BUNDLE:
              return bundle;
            case LIST_OF_RESOURCES:
              List<IResource> listOfResources;
              if (myResourceListCollectionType != null) {
                listOfResources = new ArrayList<IResource>();
                for (IResource next : bundle.toListOfResources()) {
                  if (!myResourceListCollectionType.isAssignableFrom(next.getClass())) {
                    ourLog.debug(
                        "Not returning resource of type {} because it is not a subclass or instance of {}",
                        next.getClass(),
                        myResourceListCollectionType);
                    continue;
                  }
                  listOfResources.add(next);
                }
              } else {
                listOfResources = bundle.toListOfResources();
              }
              return listOfResources;
            case RESOURCE:
              List<IResource> list = bundle.toListOfResources();
              if (list.size() == 0) {
                return null;
              } else if (list.size() == 1) {
                return list.get(0);
              } else {
                throw new InvalidResponseException(
                    theResponseStatusCode,
                    "FHIR server call returned a bundle with multiple resources, but this method is only able to returns one.");
              }
            case BUNDLE_PROVIDER:
              throw new IllegalStateException(
                  "Return type of "
                      + IBundleProvider.class.getSimpleName()
                      + " is not supported in clients");
          }
          break;
        }
      case RESOURCE:
        {
          IResource resource;
          if (myResourceType != null) {
            resource = parser.parseResource(myResourceType, theResponseReader);
          } else {
            resource = parser.parseResource(theResponseReader);
          }

          MethodUtil.parseClientRequestResourceHeaders(null, theHeaders, resource);

          switch (getMethodReturnType()) {
            case BUNDLE:
              return Bundle.withSingleResource(resource);
            case LIST_OF_RESOURCES:
              return Collections.singletonList(resource);
            case RESOURCE:
              return resource;
            case BUNDLE_PROVIDER:
              throw new IllegalStateException(
                  "Return type of "
                      + IBundleProvider.class.getSimpleName()
                      + " is not supported in clients");
          }
          break;
        }
    }

    throw new IllegalStateException("Should not get here!");
  }
Example #9
0
  <T> T invokeClient(
      FhirContext theContext,
      IClientResponseHandler<T> binding,
      BaseHttpClientInvocation clientInvocation,
      EncodingEnum theEncoding,
      Boolean thePrettyPrint,
      boolean theLogRequestAndResponse) {

    if (!myDontValidateConformance) {
      myFactory.validateServerBaseIfConfiguredToDoSo(myUrlBase, myClient, this);
    }

    // TODO: handle non 2xx status codes by throwing the correct exception,
    // and ensure it's passed upwards
    HttpRequestBase httpRequest;
    HttpResponse response;
    try {
      Map<String, List<String>> params = createExtraParams();

      if (theEncoding == EncodingEnum.XML) {
        params.put(Constants.PARAM_FORMAT, Collections.singletonList("xml"));
      } else if (theEncoding == EncodingEnum.JSON) {
        params.put(Constants.PARAM_FORMAT, Collections.singletonList("json"));
      }

      if (thePrettyPrint == Boolean.TRUE) {
        params.put(
            Constants.PARAM_PRETTY, Collections.singletonList(Constants.PARAM_PRETTY_VALUE_TRUE));
      }

      EncodingEnum encoding = getEncoding();
      if (theEncoding != null) {
        encoding = theEncoding;
      }

      httpRequest = clientInvocation.asHttpRequest(myUrlBase, params, encoding, thePrettyPrint);

      if (theLogRequestAndResponse) {
        ourLog.info("Client invoking: {}", httpRequest);
        if (httpRequest instanceof HttpEntityEnclosingRequest) {
          HttpEntity entity = ((HttpEntityEnclosingRequest) httpRequest).getEntity();
          if (entity.isRepeatable()) {
            String content = IOUtils.toString(entity.getContent());
            ourLog.info("Client request body: {}", content);
          }
        }
      }

      for (IClientInterceptor nextInterceptor : myInterceptors) {
        nextInterceptor.interceptRequest(httpRequest);
      }

      response = myClient.execute(httpRequest);

      for (IClientInterceptor nextInterceptor : myInterceptors) {
        nextInterceptor.interceptResponse(response);
      }

    } catch (DataFormatException e) {
      throw new FhirClientConnectionException(e);
    } catch (IOException e) {
      throw new FhirClientConnectionException(e);
    }

    try {
      String mimeType;
      if (Constants.STATUS_HTTP_204_NO_CONTENT == response.getStatusLine().getStatusCode()) {
        mimeType = null;
      } else {
        ContentType ct = ContentType.get(response.getEntity());
        mimeType = ct != null ? ct.getMimeType() : null;
      }

      Map<String, List<String>> headers = new HashMap<String, List<String>>();
      if (response.getAllHeaders() != null) {
        for (Header next : response.getAllHeaders()) {
          String name = next.getName().toLowerCase();
          List<String> list = headers.get(name);
          if (list == null) {
            list = new ArrayList<String>();
            headers.put(name, list);
          }
          list.add(next.getValue());
        }
      }

      if (response.getStatusLine().getStatusCode() < 200
          || response.getStatusLine().getStatusCode() > 299) {
        String body = null;
        Reader reader = null;
        try {
          reader = createReaderFromResponse(response);
          body = IOUtils.toString(reader);
        } catch (Exception e) {
          ourLog.debug("Failed to read input stream", e);
        } finally {
          IOUtils.closeQuietly(reader);
        }

        String message =
            "HTTP "
                + response.getStatusLine().getStatusCode()
                + " "
                + response.getStatusLine().getReasonPhrase();
        BaseOperationOutcome oo = null;
        if (Constants.CT_TEXT.equals(mimeType)) {
          message = message + ": " + body;
        } else {
          EncodingEnum enc = EncodingEnum.forContentType(mimeType);
          if (enc != null) {
            IParser p = enc.newParser(theContext);
            try {
              // TODO: handle if something other than OO comes back
              oo = (BaseOperationOutcome) p.parseResource(body);
              if (oo.getIssueFirstRep().getDetailsElement().isEmpty() == false) {
                message = message + ": " + oo.getIssueFirstRep().getDetailsElement().getValue();
              }
            } catch (Exception e) {
              ourLog.debug("Failed to process OperationOutcome response");
            }
          }
        }

        keepResponseAndLogIt(theLogRequestAndResponse, response, body);

        BaseServerResponseException exception =
            BaseServerResponseException.newInstance(
                response.getStatusLine().getStatusCode(), message);
        exception.setOperationOutcome(oo);

        if (body != null) {
          exception.setResponseBody(body);
        }

        throw exception;
      }
      if (binding instanceof IClientResponseHandlerHandlesBinary) {
        IClientResponseHandlerHandlesBinary<T> handlesBinary =
            (IClientResponseHandlerHandlesBinary<T>) binding;
        if (handlesBinary.isBinary()) {
          InputStream reader = response.getEntity().getContent();
          try {

            if (ourLog.isTraceEnabled() || myKeepResponses || theLogRequestAndResponse) {
              byte[] responseBytes = IOUtils.toByteArray(reader);
              if (myKeepResponses) {
                myLastResponse = response;
                myLastResponseBody = null;
              }
              String message =
                  "HTTP "
                      + response.getStatusLine().getStatusCode()
                      + " "
                      + response.getStatusLine().getReasonPhrase();
              if (theLogRequestAndResponse) {
                ourLog.info("Client response: {} - {} bytes", message, responseBytes.length);
              } else {
                ourLog.trace("Client response: {} - {} bytes", message, responseBytes.length);
              }
              reader = new ByteArrayInputStream(responseBytes);
            }

            return handlesBinary.invokeClient(
                mimeType, reader, response.getStatusLine().getStatusCode(), headers);
          } finally {
            IOUtils.closeQuietly(reader);
          }
        }
      }

      Reader reader = createReaderFromResponse(response);

      if (ourLog.isTraceEnabled() || myKeepResponses || theLogRequestAndResponse) {
        String responseString = IOUtils.toString(reader);
        keepResponseAndLogIt(theLogRequestAndResponse, response, responseString);
        reader = new StringReader(responseString);
      }

      try {
        return binding.invokeClient(
            mimeType, reader, response.getStatusLine().getStatusCode(), headers);
      } finally {
        IOUtils.closeQuietly(reader);
      }

    } catch (IllegalStateException e) {
      throw new FhirClientConnectionException(e);
    } catch (IOException e) {
      throw new FhirClientConnectionException(e);
    } finally {
      if (response instanceof CloseableHttpResponse) {
        try {
          ((CloseableHttpResponse) response).close();
        } catch (IOException e) {
          ourLog.debug("Failed to close response", e);
        }
      }
    }
  }