package org.oliot.epcis.service.subscription; import java.io.DataOutputStream; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import javax.xml.bind.JAXB; import org.apache.log4j.Level; import org.bson.BsonDocument; import org.bson.BsonString; import org.oliot.epcis.configuration.Configuration; import org.oliot.epcis.service.query.mongodb.MongoQueryService; import org.oliot.model.epcis.EPCISQueryDocumentType; import org.oliot.model.epcis.ImplementationException; import org.oliot.model.epcis.QueryParameterException; import org.oliot.model.epcis.QueryResults; import org.oliot.model.epcis.QueryTooLargeException; import org.oliot.model.epcis.SubscriptionType; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.SchedulerException; import com.mongodb.client.MongoCollection; /** * Copyright (C) 2014-2016 Jaewook Byun * * This project is part of Oliot open source (http://oliot.org). Oliot EPCIS * v1.2.x is Java Web Service complying with Electronic Product Code Information * Service (EPCIS) v1.2. * * @author Jaewook Byun, Ph.D student * * Korea Advanced Institute of Science and Technology (KAIST) * * Real-time Embedded System Laboratory(RESL) * * bjw0829@kaist.ac.kr, bjw0829@gmail.com */ public class MongoSubscriptionTask implements Job { /** * Whenever execute method invoked according to the cron expression Query * the database and send the result to the destination. */ @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap map = context.getJobDetail().getJobDataMap(); BsonDocument jobData = (BsonDocument) map.get("jobData"); SubscriptionType s = new SubscriptionType(jobData); // InitialRecordTime limits recordTime if (s.getInitialRecordTime() != null) { try { s.getPollParameters().setGE_recordTime(s.getInitialRecordTime()); GregorianCalendar cal = new GregorianCalendar(); Date curTime = cal.getTime(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); s.setInitialRecordTime(sdf.format(curTime)); updateInitialRecordTime(s.getSubscriptionID(), s.getInitialRecordTime()); JobDetail detail = context.getJobDetail(); detail.getJobDataMap().put("jobData", SubscriptionType.asBsonDocument(s)); MongoSubscription.sched.addJob(detail, true, true); } catch (SchedulerException e) { e.printStackTrace(); } } MongoQueryService queryService = new MongoQueryService(); try { String pollResult; pollResult = queryService.poll(s.getPollParameters(), null, null, s.getSubscriptionID()); String resultString = ""; if (s.getPollParameters().getFormat() == null || s.getPollParameters().getFormat().equals("XML")) { EPCISQueryDocumentType resultXML = JAXB.unmarshal(new StringReader(pollResult), EPCISQueryDocumentType.class); if (resultXML != null && resultXML.getEPCISBody() != null && resultXML.getEPCISBody().getQueryTooLargeException() != null) { QueryTooLargeException e = resultXML.getEPCISBody().getQueryTooLargeException(); StringWriter sw = new StringWriter(); JAXB.marshal(e, sw); resultString = sw.toString(); } else if (resultXML != null && resultXML.getEPCISBody() != null && resultXML.getEPCISBody().getImplementationException() != null) { ImplementationException e = resultXML.getEPCISBody().getImplementationException(); StringWriter sw = new StringWriter(); JAXB.marshal(e, sw); resultString = sw.toString(); } else if (resultXML != null && resultXML.getEPCISBody() != null && resultXML.getEPCISBody().getQueryResults() != null && resultXML.getEPCISBody().getQueryResults().getResultsBody() != null) { List<Object> checkList = resultXML.getEPCISBody().getQueryResults().getResultsBody().getEventList() .getObjectEventOrAggregationEventOrQuantityEvent(); if (s.getReportIfEmpty() == false) { if (checkList == null || checkList.size() == 0) { // Do not report if reportIfEmpty is true return; } } QueryResults queryResults = new QueryResults(); queryResults.setQueryName(s.getPollParameters().getQueryName()); queryResults.setResultsBody(resultXML.getEPCISBody().getQueryResults().getResultsBody()); queryResults.setSubscriptionID(s.getSubscriptionID()); StringWriter sw = new StringWriter(); JAXB.marshal(queryResults, sw); resultString = sw.toString(); } } else { resultString = pollResult; } URL url = new URL(s.getDest()); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestProperty("Content-Length", "" + Integer.toString(resultString.getBytes().length)); conn.setRequestProperty("Content-Type", "application/xml; charset=utf-8"); DataOutputStream wr = new DataOutputStream(conn.getOutputStream()); wr.writeBytes(resultString); wr.flush(); wr.close(); int x = conn.getResponseCode(); System.out.println(x); conn.disconnect(); } catch (QueryParameterException e1) { Configuration.logger.log(Level.ERROR, e1.toString()); } catch (MalformedURLException e) { Configuration.logger.log(Level.ERROR, e.toString()); } catch (IOException e) { Configuration.logger.log(Level.ERROR, e.toString()); } catch (QueryTooLargeException e1) { Configuration.logger.log(Level.ERROR, e1.toString()); } } private void updateInitialRecordTime(String subscriptionID, String initialRecordTime) { MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("Subscription", BsonDocument.class); BsonDocument subscription = collection.find(new BsonDocument("subscriptionID", new BsonString(subscriptionID))) .first(); subscription.put("initialRecordTime", new BsonString(initialRecordTime)); if (subscription != null) { collection.findOneAndReplace(new BsonDocument("subscriptionID", new BsonString(subscriptionID)), subscription); } Configuration.logger.log(Level.INFO, "InitialRecordTime of Subscription ID: " + subscriptionID + " is updated to DB. "); } }