@Override public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { JsonAdapter<Object> adapter = moshi.adapter(genericType); BufferedSource source = Okio.buffer(Okio.source(entityStream)); if (!source.request(1)) { throw new NoContentException("Stream is empty"); } return adapter.fromJson(source); // Note: we do not close the InputStream per the interface documentation. }
/** * Reads entity of given type from response. Returns null when the response has a zero-length content. * * @param response * service response * @param responseType * expected response type * @return the response entity * @throws RestException */ private <RES> RES readEntity(final Response response, final Class<RES> responseType) throws RestException { boolean buffered = false; try { buffered = response.bufferEntity(); return response.readEntity(responseType); } catch (final ProcessingException ex) { if (response.getStatus() == Response.Status.NO_CONTENT.getStatusCode() || ex.getCause() instanceof NoContentException) { return null; } else { if ((response.getStatusInfo().getFamily() == Response.Status.Family.CLIENT_ERROR) || (response.getStatusInfo().getFamily() == Response.Status.Family.SERVER_ERROR)) { return null; // Ignore content interpretation errors if status is an error already } final String body = buffered ? " '" + response.readEntity(String.class) + "' of type '" + response.getMediaType() + "'" : ""; throw new RestException("Could not interpret the response body" + body, ex); } } }
@Test public void emptyReadThrows() throws IOException { Buffer data = new Buffer(); Class<Object> type = (Class) String.class; try { reader.readFrom(type, type, new Annotation[0], APPLICATION_JSON_TYPE, new MultivaluedHashMap<>(), data.inputStream()); fail(); } catch (NoContentException ignored) { } }
/** * Checks whether given exception is a {@link ProcessingException} that wraps a message body reader * {@link NoContentException}. * @param exception Exception to check * @return <code>true</code> if given it a no content exception */ protected static boolean isNoContentException(Exception exception) { if (exception != null && exception instanceof ProcessingException && exception.getCause() != null) { return exception.getCause() instanceof NoContentException; } return false; }
@Override public T readFrom(Class<T> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { try (Reader entityReader = new InputStreamReader(entityStream, Charsets.UTF_8)) { String entity = CharStreams.toString(entityReader); if (entity == null || entity.isEmpty()) { throw new NoContentException("failed to deserialize JSON entity: " + "empty/null entity stream"); } return JsonUtils.toObject(JsonUtils.parseJsonString(entity), type); } catch (IllegalArgumentException | JsonParseException e) { // produce a 400 http response throw new WebApplicationException(e, Response.status(Status.BAD_REQUEST).entity(new ErrorType(e)).build()); } }
/** * calls IOFabric Controller endpoind and returns Json result * * @param command - endpoint to be called * @param queryParams - query string parameters * @param postParams - post parameters * @return result in Json format * @throws Exception */ public JsonObject doCommand(String command, Map<String, Object> queryParams, Map<String, Object> postParams) throws Exception { if (!controllerUrl.toLowerCase().startsWith("https")) throw new Exception("unable to connect over non-secure connection"); JsonObject result = null; StringBuilder uri = new StringBuilder(controllerUrl); uri.append("instance/") .append(command) .append("/id/").append(instanceId) .append("/token/").append(accessToken); if (queryParams != null) queryParams.entrySet().forEach(entry -> { uri.append("/").append(entry.getKey()) .append("/").append(entry.getValue()); }); List<NameValuePair> postData = new ArrayList<NameValuePair>(); if (postParams != null) postParams.entrySet().forEach(entry -> { String value = entry.getValue().toString(); if (value == null) value = ""; postData.add(new BasicNameValuePair(entry.getKey(), value)); }); try { initialize(); RequestConfig config = getRequestConfig(); HttpPost post = new HttpPost(uri.toString()); post.setConfig(config); post.setEntity(new UrlEncodedFormEntity(postData)); CloseableHttpResponse response = client.execute(post); if (response.getStatusLine().getStatusCode() == 403){ throw new ForbiddenException(); } else if (response.getStatusLine().getStatusCode() == 204){ throw new NoContentException(""); } BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8")); result = Json.createReader(in).readObject(); } catch (Exception e) { throw e; } return result; }