package com.sap.research.fiware.ngsi10.simple;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;
import noNamespace.ContextElementResponseList;
import noNamespace.EntityId;
import noNamespace.NotifyContextRequest;
import noNamespace.NotifyContextRequestDocument;
import noNamespace.NotifyContextResponseDocument;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.xmlbeans.XmlException;
import com.sap.research.fiware.ngsi10.simple.exceptions.BadRequestException;
import com.sap.research.fiware.ngsi10.simple.exceptions.ServerConnectionException;
import com.sap.research.fiware.ngsi10.simple.subscriptionmanagement.Subscription;
import com.sap.research.fiware.ngsi10.simple.wrappers.EntityIdWrapper;
/**
* Connects to a context notification endpoint and sends a notification there
*
*
*
*/
public class NotifyContextClient {
private static final Logger LOG = Logger.getLogger(NotifyContextClient.class.getName());
private Subscription subscription;
private NotifyContextRequest request;
private NotifyContextRequestDocument requestDoc;
/**
* @param subscription
* the subscription that triggered the context notification
*/
public NotifyContextClient(Subscription subscription) {
this.subscription = subscription;
}
public void sendNotification() throws ServerConnectionException {
try {
LOG.info("Trying to client for subscription " + subscription.getInfo());
sendNotificationWithoutErrorHandling();
LOG.info("Successfully notified client for subscription " + subscription.getInfo());
} catch (Exception e) {
throw new ServerConnectionException(e);
}
}
/**
* sends the notification
*
* @throws ServerConnectionException
* the endpoint is unreachable or sent an unappropriate response
* @throws IOException
* @throws ClientProtocolException
* @throws BadRequestException
* @throws XmlException
*/
public void sendNotificationWithoutErrorHandling()
throws ClientProtocolException, IOException, BadRequestException, XmlException {
prepareNGSIResponse();
writeRequestedContextElements();
HttpPost post = prepareHTTPResponse();
createResponseBody(post);
sendQuery(post);
}
private void writeRequestedContextElements() {
ContextElementResponseList contextElementResponseList = request.addNewContextResponseList();
EntityId[] entityIDs = unwrapEntityIDs(subscription.getEntityIDs());
String[] contextAttributes = subscription.getAttributes();
ContextElementResponseListHelper contextElementResponseListHelper = new ContextElementResponseListHelper(contextElementResponseList, entityIDs, contextAttributes);
contextElementResponseListHelper.write();
}
private EntityId[] unwrapEntityIDs(EntityIdWrapper[] entityIDWrappers) {
EntityId[] entityIDs = new EntityId[entityIDWrappers.length];
for(int i = 0; i<entityIDWrappers.length; i++) {
entityIDs[i] = entityIDWrappers[i].getEntityId();
}
return entityIDs;
}
private void prepareNGSIResponse() {
requestDoc = NotifyContextRequestDocument.Factory.newInstance();
request = requestDoc.addNewNotifyContextRequest();
String subscriptionID = subscription.getSubscriptionID();
request.setSubscriptionId(subscriptionID);
request.setOriginator(subscriptionID);
}
private void sendQuery(HttpPost post) throws IOException,
ClientProtocolException, XmlException, BadRequestException {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse httpresponse = httpclient.execute(post);
InputStream input = httpresponse.getEntity().getContent();
NotifyContextResponseDocument responseDocument = NotifyContextResponseDocument.Factory.parse(input);
if (!responseDocument.validate())
throw new BadRequestException("Response from NGSI server is not valid");
}
private void createResponseBody(HttpPost post)
throws UnsupportedEncodingException {
StringEntity entity = new StringEntity("<xml-fragment>" + requestDoc.xmlText() + "</xml-fragment>");
post.setEntity(entity);
}
private HttpPost prepareHTTPResponse() {
HttpPost post = new HttpPost();
post.addHeader("Content-Type", "application/xml");
post.setURI(subscription.getReference());
return post;
}
}