package com.sap.hana.cloud.samples.weatherapp.api;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import com.sap.core.connectivity.api.http.HttpDestination;
@Path("/weather")
@Produces({ MediaType.APPLICATION_JSON })
public class WeatherService
{
private static final int COPY_CONTENT_BUFFER_SIZE = 1024;
@GET
@Path("/")
@Produces({ MediaType.APPLICATION_JSON })
public Response getWeatherInformation(@QueryParam(value = "id") String id, @QueryParam(value = "q") String q)
{
HttpClient httpClient = null;
HttpGet httpGet = null;
String msgBody = null;
try
{
// Get HTTP destination
Context ctx = new InitialContext();
HttpDestination destination = (HttpDestination) ctx.lookup("java:comp/env/" + "openweathermap-destination");
// Create HTTP client
httpClient = destination.createHttpClient();
final String baseURL = destination.getURI().toString();
String destinationURL = null;
if (id != null && id.trim().length() > 0) // id takes precedence
{
destinationURL = MessageFormat.format("{0}&id={1}&units=metric", baseURL, id);
}
else
{
destinationURL = MessageFormat.format("{0}&q={1}&units=metric", baseURL, q);
}
// Execute HTTP request
httpGet = new HttpGet(destinationURL);
HttpResponse httpResponse = httpClient.execute(httpGet);
// Check response status code
int statusCode = httpResponse.getStatusLine().getStatusCode();
// copy content from the incoming response to the outgoing response
HttpEntity entity = null;
if (httpResponse != null)
{
entity = httpResponse.getEntity();
}
msgBody = getResponseBodyasString(entity);
if (statusCode == HttpServletResponse.SC_OK)
{
return Response.ok(msgBody).build();
}
else
{
return Response.status(statusCode).entity(msgBody).build();
}
}
catch (RuntimeException e)
{
// In case of an unexpected exception we abort the HTTP request
// in order to shut down the underlying connection immediately.
if (httpGet != null)
{
httpGet.abort();
}
// unexpected runtime error
String errorMessage = "'Houston, we have a problem!' : "
+ e.getMessage()
+ ". See logs for details.";
msgBody = errorMessage;
}
catch (NamingException e)
{
// Lookup of destination failed
String errorMessage = "Lookup of destination failed with reason: "
+ e.getMessage()
+ ". See "
+ "logs for details. Hint: Make sure to have the destination "
+ "[openweathermap-destination]" + " configured.";
msgBody = errorMessage;
}
catch (Exception e)
{
// Connectivity operation failed
String errorMessage = "Connectivity operation failed with reason: "
+ e.getMessage()
+ ". See "
+ "logs for details. Hint: Make sure to have an HTTP proxy configured in your "
+ "local Eclipse environment in case your environment uses "
+ "an HTTP proxy for the outbound Internet "
+ "communication.";
msgBody = errorMessage;
}
finally
{
// When HttpClient instance is no longer needed, shut down the connection manager to ensure immediate
// deallocation of all system resources
if (httpClient != null)
{
httpClient.getConnectionManager().shutdown();
}
}
// if we end up here something went really bad
return Response.serverError().build();
}
/**
* Extracts the response body from the specified {@link HttpEntity} and returns it as a UTF-8 encoded String.
*
* @param entity The {@link HttpEntity} to extract the message body from
* @return The UTF-8 encoded String representation of the message body
* @throws
*/
static String getResponseBodyasString(HttpEntity entity) throws Exception
{
String retVal = null;
if (entity != null)
{
InputStream instream = entity.getContent();
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
try
{
byte[] buffer = new byte[COPY_CONTENT_BUFFER_SIZE];
int len;
while ((len = instream.read(buffer)) != -1)
{
outstream.write(buffer, 0, len);
}
}
catch (IOException e)
{
// In case of an IOException the connection will be released
// back to the connection manager automatically
throw e;
}
finally
{
// Closing the input stream will trigger connection release
try
{
instream.close();
}
catch (Exception e)
{
// Ignore
}
}
retVal = outstream.toString("UTF-8");
}
return retVal;
}
}