package org.atomnuke.pubsub.eventlet;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import javax.ws.rs.core.Response;
import javax.xml.datatype.DatatypeConfigurationException;
import net.jps.jx.JsonReader;
import net.jps.jx.JsonWriter;
import net.jps.jx.JxFactory;
import net.jps.jx.jackson.JacksonJxFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.atomnuke.atom.model.Category;
import org.atomnuke.atom.model.Entry;
import org.atomnuke.pubsub.api.type.SubscriptionCategory;
import org.atomnuke.pubsub.api.type.SubscriptionContent;
import org.atomnuke.pubsub.api.type.SubscriptionDocument;
import org.atomnuke.sink.eps.eventlet.AtomEventlet;
import org.atomnuke.sink.eps.eventlet.AtomEventletException;
import org.atomnuke.task.context.AtomTaskContext;
import org.atomnuke.lifecycle.InitializationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author zinic
*/
public class SubscriptionEventlet implements AtomEventlet {
private static final Logger LOG = LoggerFactory.getLogger(SubscriptionEventlet.class);
private static final JxFactory JX_FACTORY;
static {
JxFactory jsonFactory = null;
try {
jsonFactory = new JacksonJxFactory();
} catch (DatatypeConfigurationException configurationException) {
LOG.error(configurationException.getMessage(), configurationException);
}
JX_FACTORY = jsonFactory;
}
private final JsonReader<SubscriptionContent> contentReader = JX_FACTORY.newReader(SubscriptionContent.class);
private final JsonWriter<SubscriptionDocument> documentWriter = JX_FACTORY.newWriter(SubscriptionDocument.class);
private final String subscriptionId, callbackUrl;
private final HttpClient httpClient;
public SubscriptionEventlet(HttpClient httpClient, String subscriptionId, String callbackUrl) {
this.httpClient = httpClient;
this.subscriptionId = subscriptionId;
this.callbackUrl = callbackUrl;
}
@Override
public void entry(Entry entry) throws AtomEventletException {
if (!entry.content().type().equalsIgnoreCase("application/json")) {
return;
}
SubscriptionContent content;
try {
content = contentReader.read(new ByteArrayInputStream(entry.content().toString().getBytes()));
} catch (Exception ex) {
LOG.warn("Unable to parse event content JSON: " + ex.getMessage());
return;
}
final SubscriptionDocument payload = new SubscriptionDocument();
payload.setId(subscriptionId);
payload.setCallback(callbackUrl);
payload.setContent(content);
for (Category entryCategory : entry.categories()) {
final SubscriptionCategory subscriptionCategory = new SubscriptionCategory();
subscriptionCategory.setScheme(entryCategory.scheme());
subscriptionCategory.setTerm(entryCategory.term());
payload.addCategory(subscriptionCategory);
}
final HttpPost webhookPost = new HttpPost(callbackUrl);
try {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
documentWriter.write(payload, baos);
webhookPost.setHeader("Content-Type", "application/json");
webhookPost.setEntity(new ByteArrayEntity(baos.toByteArray()));
final HttpResponse webhookResponse = httpClient.execute(webhookPost);
if (webhookResponse == null || webhookResponse.getStatusLine() == null) {
LOG.error("Failed to get a response from the webhook endpoint.");
}
if (webhookResponse.getStatusLine().getStatusCode() != Response.Status.ACCEPTED.getStatusCode()) {
LOG.error("Potential error with webhook client. Recieved the following: " + webhookResponse.getStatusLine().toString());
}
} catch (Exception ex) {
LOG.error(ex.getMessage(), ex);
} finally {
webhookPost.releaseConnection();
}
}
@Override
public void init(AtomTaskContext contextObject) throws InitializationException {
}
@Override
public void destroy() {
}
}