SK SKYVVA Documentation

68.2 How to pass raw data to custom class for processing with custom code?

Learning Objective:- This unit describes:-

1. How to pass raw data to a custom class (Message Creation) for processing?

Our Skyvva Tool supports XML, CSV, and JSON file formats by default. However, if you have complex XML, JSON, or other raw data structures that our tool cannot read in your payload, you will need to use a custom class to build your logic and read your raw data structure to create the SKYVVA Message yourself.

Here is a sample payload in a data format that our standard cannot read:


status: success code: '200' message: completed data:

2. The procedure to pass raw data to a custom class (Message Creation) for processing with custom code:-

The procedure is given below with an example:-

2.1. Create MetaData, Repository and Message Type:-
2.2. Create Integration:-
2.3. Create custom class :

public with sharing class RawDataCustomProcessing extends AbstractIntegrationV3 {

List lines{get;set;}

Map mapParentIntfMsg = new Map();

public override IServicesUtil.IMessageResult createMessage(AbstractIntegrationV3.DtoRequestBody dtoRequestBody,

AbstractIntegrationV3.DtoStructure dtoStr){

AbstractIntegrationV3.DtoInterface dtoIntfStructure = getInterfaceStructure();

// custom transaction

if(String.isBlank(dtoRequestBody.transactionId))dtoRequestBody.transactionId='YAML-Data-'+System.now().getTime();

// parse yaml payload to map// here using your own logic

Map dataAsMap = doParse(dtoRequestBody.payload);

System.debug('>>dataAsMap: '+dataAsMap);

// i know exactly my data contain data node as array //{"NodeX":[{},{}]} List rootData = (List)dataAsMap.get(dtoIntfStructure.sourceObject); for (Object nodeRoot : rootData) {

// create mesage from root createMsg((Map)nodeRoot,dtoIntfStructure,true,1,dtoRequestBody.transactionId,null); } return super.msgResult; }

// overide create message logic public override IMessage__c invokeNewMessage( String rootId, String parentId, String transId, Boolean hasChild, Integer lv, String hPath, Boolean isRoot, Interfaces__c mInft, Map idata ){

// just using skyvva default message setting IMessage__c msg=super.invokeNewMessage(rootId,parentId,transId,hasChild,lv,hPath,isRoot,mInft,idata); msg.Name='IM#YAML-Data-'+System.now().getTime()+'---'+indexMsg; return msg; }

// hierarchy message creation void createMsg(Map objectX,AbstractIntegrationV3.DtoInterface dtoIntfStructure,Boolean isRoot,Integer level,String transactionId,IMessage__c rootMsg){ Map idata = new Map(); for (String field : objectX.keySet()) { Object valueX=objectX.get(field);

// ignore array or object, ingore childen datas if(valueX instanceof List || valueX instanceof Map)continue; idata.put(field,valueX+''); //string,string }

// System.debug('>>createMsg>idata: '+JSON.serializePretty(idata));

// get parent message if current creation is child IMessage__c parentMsg=mapParentIntfMsg.get(dtoIntfStructure.parentIntfId);

// current message, invoke create message setting IMessage__c msg = invokeNewMessage(rootMsg?.External_Id2__c,parentMsg?.External_Id2__c,transactionId,false,level,null,isRoot,super.mIntf.get(dtoIntfStructure.intfId),idata);

// save parent interface to message mapParentIntfMsg.put(dtoIntfStructure.intfId,msg);

// if current is root levelt then set it to children if(isRoot)rootMsg=msg; else {

// mark parent and grand parent as has child rootMsg.HasChild__c=true; parentMsg.HasChild__c=true; }

// create children message for(AbstractIntegrationV3.DtoInterface tmp : dtoIntfStructure.child){

// System.debug('>>createMsg>tmp.sourceObject: '+tmp.sourceObject); Object obj = objectX.get(tmp.sourceObject); if(obj==null){ // ingore case for (String field : objectX.keySet()) {

// find child node if(tmp.sourceObject.equalsIgnoreCase(field)){ obj = objectX.get(field); } } }

// System.debug('>>createMsg>obj: '+obj); // child message if(obj instanceof Map){ createMsg((Map)obj,tmp,false,level+1,transactionId,rootMsg); }

// child message array else if(obj instanceof List){ List lstObj = (List) obj; for(Object obj1 : lstObj){ createMsg((Map)obj1,tmp,false,level+1,transactionId,rootMsg); } } } }

// logic parsing raw data --------------satrt

Map doParse(String yamlString){ Map yamlMap = new Map(); lines=yamlString.split('\n'); while (!lines.isEmpty()){ readByLine(lines.remove(0),yamlMap); } return yamlMap; }

void readByLine(String line,Map result){ if (String.isBlank(line.trim()))return; if(!line.contains(':'))return; String[] parts = line.split(':',2); String name = parts[0].trim(); name=name.removeStart('- '); String value = parts[1].trim(); if (String.isNotBlank(value)) { result.put(name.removeStart('- '), value); } else if(!lines.isEmpty() && isElement(lines.get(0))) { Integer indexOfNextLevel=getIndexOfElement(lines.get(0)); List> children=new List>(); Map child;

// read children Integer nextLvl=indexOfNextLevel; while(!lines.isEmpty() && getIndexOfElement(lines.get(0))==nextLvl){ if(isElement(lines.get(0))){ child=new Map(); children.add(child); } readByLine(lines.remove(0),child); } result.put(name,children); } } Boolean isElement(String nextLine){ return String.isNotBlank(nextLine) && nextLine.trim().startsWith('-'); } Integer getIndexOfElement(String nextLine){ Integer level = 0; while (nextLine.substring(level,level+1) == ' ' || nextLine.substring(level,level+1)=='-') { level += 1; } return level; } // logic parsing raw data --------------end---------------- }

  • Copy and paste this code into the custom class. This example code will enable the reading of the data structure.
2.4. Create Interface:
  •  In the Runtime Configuration Section of the Interface page we need to select two things which are shown in the picture given below:-
  • To enable custom processing, check the 'Custom Processing' option. Once you have checked this option, you will be able to use a custom class for this interface. A custom Apex class is required to handle the specific processing for this interface.
  • You also need to enter the custom processing class that you have created with the logic mentioned above.
  • In the Custom Processing section, you need to select the block that you want to custom
  • Select 'Message Creation' on "Custom Block to replace the SKYVVA Block". This is the block that you need to customize.
2.5. Do Mapping:
2.6. Call via V4/integrate
  • After calling V4/integrate, it will read raw data and create the message.
Open this article in the interactive viewer →