package org.oliot.epcis.service.capture; import java.io.IOException; import java.io.InputStream; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.bind.JAXB; import org.apache.log4j.Level; import org.bson.BsonArray; import org.bson.BsonDocument; import org.bson.BsonInt64; import org.bson.BsonString; import org.oliot.epcis.configuration.Configuration; import org.oliot.epcis.service.subscription.TriggerEngine; import org.oliot.model.ale.ECReport; import org.oliot.model.ale.ECReportGroup; import org.oliot.model.ale.ECReportGroupList; import org.oliot.model.ale.ECReportGroupListMember; import org.oliot.model.ale.ECReportMemberField; import org.oliot.model.ale.ECReports; import org.oliot.model.ale.ECReportGroupListMemberExtension.FieldList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.ServletContextAware; import com.mongodb.client.MongoCollection; /** * Copyright (C) 2014 Jaewook Jack Byun * * This project is part of Oliot (oliot.org), pursuing the implementation of * Electronic Product Code Information Service(EPCIS) v1.1 specification in * EPCglobal. * [http://www.gs1.org/gsmp/kc/epcglobal/epcis/epcis_1_1-standard-20140520.pdf] * * * @author Jaewook Jack 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 */ @Controller @RequestMapping("/ALECapture") public class ALECapture implements ServletContextAware { @Autowired ServletContext servletContext; @RequestMapping public void post(HttpServletRequest request, HttpServletResponse response) { try { Configuration.logger.info(" ECReport Capture Started.... "); // Identifying what the event type is String eventType = request.getParameter("eventType"); // Default Event Type if (eventType == null) eventType = "ObjectEvent"; // Get ECReport InputStream is = request.getInputStream(); ECReports ecReports; if (Configuration.isCaptureVerfificationOn == true) { String xmlDocumentString = CaptureUtil.getXMLDocumentString(is); InputStream validateStream = CaptureUtil.getXMLDocumentInputStream(xmlDocumentString); boolean isValidated = CaptureUtil.validate(validateStream, Configuration.wsdlPath + "/EPCglobal-ale-1_1-ale.xsd"); if (isValidated == false) { Configuration.logger.info(" ECReport : Verification Failed "); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return; } InputStream ecReportStream = CaptureUtil.getXMLDocumentInputStream(xmlDocumentString); Configuration.logger.info(" ECReport : Validated "); ecReports = JAXB.unmarshal(ecReportStream, ECReports.class); } else { ecReports = JAXB.unmarshal(is, ECReports.class); } capture(ecReports, request); } catch (IOException e) { Configuration.logger.log(Level.ERROR, e.toString()); } } @Override public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } private boolean capture(ECReports ecReports, HttpServletRequest request) { // Event Time in timemillis , type long long eventTime = CaptureUtil.getEventTime(ecReports).toGregorianCalendar().getTimeInMillis(); // Event Time Zone String eventTimeZoneOffset = request.getParameter("eventTimeZoneOffset"); // Record Time : according to M5 GregorianCalendar recordTime = new GregorianCalendar(); long recordTimeMillis = recordTime.getTimeInMillis(); // Action String action = request.getParameter("action"); // Biz Step String bizStep = request.getParameter("bizStep"); // Disposition String disposition = request.getParameter("disposition"); // Read Point String readPoint = request.getParameter("readPoint"); // BizLocation String bizLocation = request.getParameter("bizLocation"); List<ECReport> ecReportList = ecReports.getReports().getReport(); for (int i = 0; i < ecReportList.size(); i++) { ECReport ecReport = ecReportList.get(i); if (ecReport.getGroup() == null) continue; List<ECReportGroup> ecReportGroups = ecReport.getGroup(); for (int j = 0; j < ecReportGroups.size(); j++) { ECReportGroup ecReportGroup = ecReportGroups.get(j); if (ecReportGroup.getGroupList() == null) continue; ECReportGroupList ecReportGroupList = ecReportGroup.getGroupList(); List<ECReportGroupListMember> members = ecReportGroupList.getMember(); for (int k = 0; k < members.size(); k++) { ECReportGroupListMember member = members.get(k); String epcString = member.getEpc().getValue(); if (member.getExtension() == null) continue; if (member.getExtension().getFieldList() == null) continue; FieldList fieldList = member.getExtension().getFieldList(); List<ECReportMemberField> fields = fieldList.getField(); Map<String, Object> extMap = new HashMap<String, Object>(); for (int l = 0; l < fields.size(); l++) { ECReportMemberField field = fields.get(l); String key = field.getName(); String value = field.getValue(); String[] valArr = value.split("\\^"); if (valArr.length != 2) { extMap.put(key, value); continue; } try { String type = valArr[1]; if (type.equals("int")) { extMap.put(key, Integer.parseInt(valArr[0])); } else if (type.equals("long")) { extMap.put(key, Long.parseLong(valArr[0])); } else if (type.equals("float")) { extMap.put(key, Float.parseFloat(valArr[0])); } else if (type.equals("double")) { extMap.put(key, Double.parseDouble(valArr[0])); } else if (type.equals("boolean")) { extMap.put(key, Boolean.parseBoolean(valArr[0])); } else { extMap.put(key, valArr[0]); } } catch (NumberFormatException e) { extMap.put(key, valArr[0]); } } BsonDocument dbo = new BsonDocument(); // EPC BsonArray epcList = new BsonArray(); BsonDocument epc = new BsonDocument(); epc.put("epc", new BsonString(epcString)); epcList.add(epc); dbo.put("epcList", epcList); dbo.put("eventTime", new BsonInt64(eventTime)); if (eventTimeZoneOffset == null) { dbo.put("eventTimeZoneOffset", new BsonString("+09:00")); } else { dbo.put("eventTimeZoneOffset", new BsonString(eventTimeZoneOffset)); } dbo.put("recordTime", new BsonInt64(recordTimeMillis)); if (action == null) { dbo.put("action", new BsonString("OBSERVE")); } else { dbo.put("action", new BsonString(action)); } if (bizStep != null) { dbo.put("bizStep", new BsonString(bizStep)); } if (disposition != null) { dbo.put("dispsition", new BsonString(disposition)); } if (readPoint != null) { dbo.put("readPoint", new BsonDocument("id", new BsonString(readPoint))); } if (bizLocation != null) { dbo.put("bizLocation", new BsonDocument("id", new BsonString(bizLocation))); } // Extension Field if (extMap.isEmpty() == false) { Iterator<String> keyIterator = extMap.keySet().iterator(); BsonDocument any = new BsonDocument(); any.put("@ale", new BsonString("http://" + request.getLocalAddr() + ":" + request.getLocalPort() + request.getContextPath() + "/schema/aleCapture.xsd")); while (keyIterator.hasNext()) { String key = keyIterator.next(); Object value = extMap.get(key); any.put("ale:" + key, new BsonString(value.toString())); } dbo.put("any", any); } MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("ObjectEvent", BsonDocument.class); if (Configuration.isTriggerSupported == true) { TriggerEngine.examineAndFire("ObjectEvent", dbo); } collection.insertOne(dbo); } } } return true; } }