package eu.ehri.project.indexing.source.impl; import com.fasterxml.jackson.databind.JsonNode; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; import eu.ehri.project.indexing.source.Source; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.InputStream; import java.net.URI; import java.util.Properties; /** * Fetch JSON from a web resource. It must accept and * return MediaType application/json. */ public class WebJsonSource implements Source<JsonNode> { private static final Client client = Client.create(); private final URI url; private ClientResponse response = null; private InputStreamJsonSource ios = null; private final Properties headers; private boolean finished = false; public WebJsonSource(URI url, Properties headers) { this.url = url; this.headers = headers; } public void close() throws SourceException { if (!finished) { if (ios != null) { ios.close(); ios = null; } if (response != null) { response.close(); response = null; } finished = true; } } @Override public Iterable<JsonNode> iterable() throws SourceException { response = getResponse(); checkResponse(response); InputStream entityInputStream = response.getEntityInputStream(); if (entityInputStream == null) { throw new SourceException("Entity stream is null for url: " + url); } ios = new InputStreamJsonSource(entityInputStream); return ios.iterable(); } @Override public boolean isFinished() { return finished; } private ClientResponse getResponse() throws SourceException { try { WebResource.Builder rsc = client.resource(url) .accept(MediaType.APPLICATION_JSON) .type(MediaType.APPLICATION_JSON); for (String header : headers.stringPropertyNames()) { rsc = rsc.header(header, headers.getProperty(header)); } return rsc.get(ClientResponse.class); } catch (Exception e) { throw new SourceException( "Error accessing web resource: '" + url + "': \n" + e.getMessage(), e); } } /** * Check a REST API response is good. * * @param response The response object to check */ private void checkResponse(ClientResponse response) throws SourceException { if (response.getStatus() != Response.Status.OK.getStatusCode()) { throw new SourceException( "Unexpected response from web resource: '" + url + "': " + response.getStatus()); } } }