Message Detail using XML file with a custom processor
This provides an example of enabling MessageDetail for a Custom InboundInterface with a processor.
Create an inbound interface with Custom format.
Provide processor name in Processor tab which will do all the inbound data handling.
Since this is a custom interface(for XMLs) we need to create new MessageQueue, MessageSource and MessageSourcePoll configuration. This is detailed under Integration -> Message and Message Queues.
External reference configuration for the queue + interface combination will be like below. (New queue in above step is created with name inbox/XML for ProgressiveRetailer enterprise)
#* Ref Type,* External Value, Local Value, DescriptionPLT.MessageDetail:Enable,100~inbox/XML~ProgressiveRetailer~PTA.TestXML_ORDER_IB~1.0,AllRecords,Message Detail enabledforall recordsThe sample XML file with 2 records that will be processed is as below:
<?xmlversion="1.0"encoding="UTF-8"standalone="yes"?><Orders><Order><BUYING_ENT>ProgressiveRetailer</BUYING_ENT><SELLING_ENT>ProgressiveRetailer</SELLING_ENT><ORDER_NUMBER>test12</ORDER_NUMBER><CURRENCY>USD</CURRENCY><BUYING_ORG>SouthRegion</BUYING_ORG><SELLING_ORG>WestRegion</SELLING_ORG><ITEM_NAME>158126</ITEM_NAME><SHIPPED_QUANTITY>10.0</SHIPPED_QUANTITY><UOM>EACH</UOM><UNIT_PRICE>100.0</UNIT_PRICE></Order><Order><BUYING_ENT>ProgressiveRetailer</BUYING_ENT><SELLING_ENT>ProgressiveRetailer</SELLING_ENT><ORDER_NUMBER>test13</ORDER_NUMBER><CURRENCY>USD</CURRENCY><BUYING_ORG>SouthRegion</BUYING_ORG><SELLING_ORG>WestRegion</SELLING_ORG><ITEM_NAME>213705</ITEM_NAME><SHIPPED_QUANTITY>10.0</SHIPPED_QUANTITY><UOM>EACH</UOM><UNIT_PRICE>100.0</UNIT_PRICE></Order></Orders>Sample code to Create and Save message detail records for both Success and error scenarios is as below. Raw data is formed while iterating the file and saved. After the DB write operation, the error and success records and fetched and message detail is created. Save is done in the finally block so that even when there are exceptions message detail is updated and saved. XSD is used for marshalling and un-marshalling the data.
// InitializationsList<MessageDetail> messageDetails =newArrayList<>();objmesDetailServiceImpl =newMessageDetailServiceImpl();TaskResult result =null;ModelDataService mds = Services.get(ModelDataService.class);com.onenetwork.platform.data.model.ModelList<Order> modelListMsg =null;mapTxnNoRawData =newHashMap<String, JSONArray>();List<Order> alstOrders =newArrayList<Order>();Order order =null;OrderLineItem orderLineItem =null;intcounter;// Iterating through file recordstry{JAXBContext jaxbContext = JAXBContext.newInstance(Orders.class);Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();Marshaller jaxbMarshaller = jaxbContext.createMarshaller();jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);Orders ordersToMarshall =newOrders();Orders orders = (Orders) jaxbUnmarshaller.unmarshal(message.readPayload());for(inti =0; i < orders.getOrder().size(); i++) {order =newOrder();orderLineItem =newOrderLineItem();/*Logic to create Order jaxb from the unmarshalled object*/// Adding order to listalstOrders.add(order);// Forming raw data, by marshalling Orders objectordersToMarshall.getOrder().add(orders.getOrder().get(i));StringWriter sw =newStringWriter();jaxbMarshaller.marshal(ordersToMarshall, sw);ordersToMarshall.getOrder().clear();JSONArray arr =newJSONArray();arr.put(sw.toString());mapTxnNoRawData.put(order.getOrderNumber(), arr);order =null;orderLineItem =null;}modelListMsg =newcom.onenetwork.platform.data.model.ModelList<Order>();modelListMsg.setCustomModelName(Order.STANDARD_MODEL_NAME);modelListMsg.setValueChainId(pltUserContext.getValueChainId());modelListMsg.setActionName("PLT.InsertOrUpdate");modelListMsg.getModels().addAll(alstOrders);String strProcessingErrors ="";intcounter =0;com.onenetwork.platform.data.model.ModelList<Order> modelList = mds.write(modelListMsg, pltUserContext);for(inti =0; i < modelListMsg.getModels().size(); i++) {strProcessingErrors =null;for(intj =0; j < modelList.getErrors().size(); j++) {if(modelListMsg.getModels().get(i).getOrderNumber().equals(modelList.getModels().get(j).getOrderNumber())) {strProcessingErrors = modelList.getErrors().get(j).toString();break;}}counter++;objmesDetailServiceImpl.createMessageDetail(""+ counter,strProcessingErrors,modelListMsg.getModels().get(i).getOrderNumber(),modelListMsg.getModels().get(i).getModelType().toString(),mapTxnNoRawData.get(modelListMsg.getModels().get(i).getOrderNumber()).toString(),message,messageDetails,pltUserContext);}}catch(Exception e) {if(modelListMsg !=null&& modelListMsg.getModels().size() >0) {updateMessgeDetailsWithError(messageDetails, modelListMsg, e.toString(), message, pltUserContext);}result = TaskResult.FAIL;thrownewRuntimeException("Exception while processing Order(s).. "+ e.getMessage());}finally{TransactionSupport.callWithNewTransaction(newjava.util.concurrent.Callable<Object>() {@OverridepublicObject call()throwsException {objmesDetailServiceImpl.saveMessageDetails(messageDetails, pltUserContext);returnnull;}});if(result ==null) {result = TaskResult.SUCCEED;}}privatevoidupdateMessgeDetailsWithError(List<MessageDetail> messageDetails,ModelList<Order> modelListMsg,String error,Message message,PlatformUserContext pltUserContext) {for(inti =0; i < modelListMsg.getModels().size(); i++) {objmesDetailServiceImpl.createMessageDetail(""+ i +1,error,modelListMsg.getModels().get(i).getOrderNumber(),modelListMsg.getModels().get(i).getModelType().toString(),mapTxnNoRawData.get(modelListMsg.getModels().get(i).getOrderNumber()).toString(),message,messageDetails,pltUserContext);}}MessageDetailReport when added to the UIMM will be visible on UI under Message Queues menu (MessageQueues-Order-XML)
Actual MessgeDetail report will look like: