Skip to content
This repository has been archived by the owner on Aug 13, 2020. It is now read-only.

Commit

Permalink
Merge pull request #81 from CJSCommonPlatform/rest-sender
Browse files Browse the repository at this point in the history
Add support for POSTs in REST client
  • Loading branch information
mapingo committed May 31, 2016
2 parents acb93e8 + d717eeb commit 59489d2
Show file tree
Hide file tree
Showing 17 changed files with 447 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
public class EndpointDefinition {

private final String baseURi;
private final String baseUri;
private final String path;
private final Set<String> pathParams;
private final Set<QueryParam> queryParams;
Expand All @@ -22,7 +22,7 @@ public class EndpointDefinition {
*/
public EndpointDefinition(final String baseUri, final String path, final Set<String> pathParams,
final Set<QueryParam> queryParams) {
this.baseURi = baseUri;
this.baseUri = baseUri;
this.path = path;
this.pathParams = pathParams;
this.queryParams = queryParams;
Expand All @@ -33,8 +33,8 @@ public EndpointDefinition(final String baseUri, final String path, final Set<Str
*
* @return the base URI
*/
public String getBaseURi() {
return baseURi;
public String getBaseUri() {
return baseUri;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
package uk.gov.justice.services.clients.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.lang.String.format;
import static java.util.stream.Collectors.toSet;
import static javax.ws.rs.client.Entity.entity;
import static javax.ws.rs.core.Response.Status.ACCEPTED;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static javax.ws.rs.core.Response.Status.OK;
import static uk.gov.justice.services.messaging.JsonEnvelope.METADATA;
import static uk.gov.justice.services.messaging.JsonObjectMetadata.ID;
import static uk.gov.justice.services.messaging.JsonObjects.createObjectBuilder;
import static uk.gov.justice.services.messaging.JsonObjects.createObjectBuilderWithFilter;
import static uk.gov.justice.services.messaging.logging.JsonEnvelopeLoggerHelper.toEnvelopeTraceString;
import static uk.gov.justice.services.messaging.logging.LoggerUtils.trace;
import static uk.gov.justice.services.messaging.logging.ResponseLoggerHelper.toResponseTrace;

import uk.gov.justice.services.common.converter.StringToJsonObjectConverter;
import uk.gov.justice.services.core.enveloper.Enveloper;
import uk.gov.justice.services.messaging.JsonEnvelope;
import uk.gov.justice.services.messaging.JsonObjectEnvelopeConverter;
import uk.gov.justice.services.messaging.JsonObjects;
import uk.gov.justice.services.messaging.Metadata;

import java.util.Set;

import javax.inject.Inject;
import javax.json.JsonObject;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.Invocation.Builder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import static java.lang.String.format;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static javax.ws.rs.core.Response.Status.OK;
import static uk.gov.justice.services.messaging.JsonEnvelope.METADATA;
import static uk.gov.justice.services.messaging.JsonObjectMetadata.ID;
import static uk.gov.justice.services.messaging.JsonObjects.createObjectBuilder;
import static uk.gov.justice.services.messaging.logging.JsonEnvelopeLoggerHelper.toEnvelopeTraceString;
import static uk.gov.justice.services.messaging.logging.LoggerUtils.trace;
import static uk.gov.justice.services.messaging.logging.ResponseLoggerHelper.toResponseTrace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Helper service for processing requests for generating REST clients.
Expand All @@ -47,19 +53,71 @@ public class RestClientProcessor {
Enveloper enveloper;

/**
* Make a request using the envelope provided to a specified endpoint.
* Make a GET request using the envelope provided to a specified endpoint.
*
* @param definition the endpoint definition
* @param envelope the envelope containing the payload and/or parameters to pass in the
* request
* @return the response from that the endpoint returned for this request
*/
public JsonEnvelope request(final EndpointDefinition definition, final JsonEnvelope envelope) {
public JsonEnvelope get(final EndpointDefinition definition, final JsonEnvelope envelope) {

final WebTarget target = createWebTarget(definition, envelope);

final Builder builder = target.request(format(MEDIA_TYPE_PATTERN, envelope.metadata().name()));

trace(LOGGER, () -> String.format("Sending GET request to %s using message: %s", target.getUri().toString(), toEnvelopeTraceString(envelope)));

final Response response = builder.get();

trace(LOGGER, () -> String.format("Sent GET request %s and received: %s", envelope.metadata().id().toString(), toResponseTrace(response)));

final int status = response.getStatus();
if (status == NOT_FOUND.getStatusCode()) {
return enveloper.withMetadataFrom(envelope, envelope.metadata().name()).apply(null);
} else if (status != OK.getStatusCode()) {
throw new RuntimeException(format("GET request %s failed; expected 200 but got %s with reason \"%s\"",
envelope.metadata().id().toString(), status,
response.getStatusInfo().getReasonPhrase()));
}

final JsonObject responseAsJsonObject = stringToJsonObjectConverter.convert(response.readEntity(String.class));

return jsonObjectEnvelopeConverter.asEnvelope(addMetadataIfMissing(responseAsJsonObject, envelope.metadata(), response.getHeaderString(CPPID)));
}

/**
* Make a POST request using the envelope provided to a specified endpoint.
*
* @param definition the endpoint definition
* @param envelope the envelope containing the payload and/or parameters to pass in the request
*/
public void post(final EndpointDefinition definition, final JsonEnvelope envelope) {
final WebTarget target = createWebTarget(definition, envelope);

final Builder builder = target.request(format(MEDIA_TYPE_PATTERN, envelope.metadata().name()));

trace(LOGGER, () -> String.format("Sending POST request to %s using message: %s", target.getUri().toString(), toEnvelopeTraceString(envelope)));

final JsonObject requestBody = stripParamsFromPayload(definition, envelope);
final Response response = builder.post(entity(requestBody.toString(), format(MEDIA_TYPE_PATTERN, envelope.metadata().name())));

trace(LOGGER, () -> String.format("Sent POST request %s and received: %s", envelope.metadata().id().toString(), toResponseTrace(response)));

final int status = response.getStatus();
if (status != ACCEPTED.getStatusCode()) {
throw new RuntimeException(format("POST request %s failed; expected 202 response but got %s with reason \"%s\"",
envelope.metadata().id().toString(), status,
response.getStatusInfo().getReasonPhrase()));
}
}

private WebTarget createWebTarget(final EndpointDefinition definition, final JsonEnvelope envelope) {
final JsonObject payload = envelope.payloadAsJsonObject();
final Client client = ClientBuilder.newClient();

WebTarget target = client
.target(definition.getBaseURi())
.target(definition.getBaseUri())
.path(definition.getPath());

for (String pathParam : definition.getPathParams()) {
Expand All @@ -76,36 +134,24 @@ public JsonEnvelope request(final EndpointDefinition definition, final JsonEnvel
target = target.queryParam(paramName, payload.getString(paramName));
}
}
return target;
}

final Invocation.Builder builder = target.request(format(MEDIA_TYPE_PATTERN, envelope.metadata().name()));

final WebTarget finalTarget = target;
trace(LOGGER, () -> String.format("Sending REST request to %s using message: %s", finalTarget.getUri().toString(),
toEnvelopeTraceString(envelope)));

final Response response = builder.get();

trace(LOGGER, () -> String.format("REST response for %s received: %s", envelope.metadata().id().toString(), toResponseTrace(response)));

final int status = response.getStatus();
if (status == NOT_FOUND.getStatusCode()) {
return enveloper.withMetadataFrom(envelope, envelope.metadata().name()).apply(null);
} else if (status != OK.getStatusCode()) {
throw new RuntimeException(format("Request Failed with code %s and reason \"%s\"", status,
response.getStatusInfo().getReasonPhrase()));
}

final JsonObject responseAsJsonObject = stringToJsonObjectConverter.convert(response.readEntity(String.class));

return jsonObjectEnvelopeConverter.asEnvelope(addMetadataIfMissing(responseAsJsonObject, envelope.metadata(), response.getHeaderString(CPPID)));
private JsonObject stripParamsFromPayload(final EndpointDefinition definition, final JsonEnvelope envelope) {
final JsonObject payload = envelope.payloadAsJsonObject();
final Set<String> pathParams = definition.getPathParams();
final Set<String> queryParams = definition.getQueryParams().stream()
.map(QueryParam::getName)
.collect(toSet());
return createObjectBuilderWithFilter(payload, (fieldName) -> !pathParams.contains(fieldName) && !queryParams.contains(fieldName)).build();
}

private JsonObject addMetadataIfMissing(final JsonObject responseAsJsonObject, final Metadata requestMetadata, final String cppId) {
if (responseAsJsonObject.containsKey(METADATA)) {
return responseAsJsonObject;
}

final JsonObject metadata = JsonObjects.createObjectBuilderWithFilter(requestMetadata.asJsonObject(), x -> !ID.equals(x))
final JsonObject metadata = createObjectBuilderWithFilter(requestMetadata.asJsonObject(), x -> !ID.equals(x))
.add(ID, cppId)
.build();

Expand Down
Loading

0 comments on commit 59489d2

Please sign in to comment.