Thursday, August 2, 2012

Making an RFC call from a UDF in PI - For UKMS


You need to import the following in your java
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.helpers.DefaultHandler;

import com.kerry.pi.ukm.Customizing;
import com.kerry.pi.ukm.RFCAdapterException;
import com.sap.aii.af.service.api.Payload;
import com.sap.aii.mapping.api.AbstractTrace;
import com.sap.aii.mapping.api.StreamTransformationException;
import com.sap.aii.mapping.lookup.Channel;
import com.sap.aii.mapping.lookup.LookupException;
import com.sap.aii.mapping.lookup.LookupService;
import com.sap.aii.mapping.lookup.RfcAccessor;

import com.sap.aii.mapping.lookup.XmlPayload;

import com.sap.aii.mappingtool.tf.rt.Container;
import com.sap.aii.mappingtool.tf.rt.GlobalContainer;
import com.sap.aii.mappingtool.tf.rt.ResultList;
import com.sap.basis.ukm.GetKeyMapping;
import com.sap.basis.ukm.Identifier;
import com.sap.basis.ukm.XmlHelper;
import com.sap.basis.ukm.datatypes.Mapping;

public class UKMSUDF {

public void rfcUKMS(String[] context, String[] srcScheme,
            String[] srcAgency, String[] srcValue, String[] tgtScheme,
            String[] tgtAgency, Channel channel, String[] alert, int OPTION,
            ResultList result, Container container)
            throws StreamTransformationException {

        AbstractTrace trace = container.getTrace();

        trace.addWarning("Stage:rfcUKMS:0");
        String NameChannel = "";
        String Party = "";
        String Service = "";

        if (OPTION == 1) {
            NameChannel = DEFAULT_CHANNEL1;
            Party = DEFAULT_PARTY1;
            Service = DEFAULT_SERVICE1;
        } else {
            NameChannel = DEFAULT_CHANNEL2;
            Party = DEFAULT_PARTY2;
            Service = DEFAULT_SERVICE2;

        }

        // Constants
        final String DELIM = " : ";
        // party1
        final String DEFAULT_PARTY = Party;
        final String DEFAULT_SERVICE = Service;
        final String DEFAULT_CHANNEL = NameChannel;
        final String SOURCE_SCHEME_VERSION_ID = "";
        final String SOURCE_SCHEME_AGENCY_SCHEME_ID = "";
        final String SOURCE_SCHEME_AGENCY_SCHEME_AGENCY_ID = "ZZZ";
        final String TARGET_SCHEME_VERSION_ID = "";
        final String TARGET_SCHEME_AGENCY_SCHEME_ID = "";
        final String TARGET_SCHEME_AGENCY_SCHEME_AGENCY_ID = "ZZZ";

        // Variables
        HashMap hm = new HashMap();
        HashMap hm2 = new HashMap();

        String[] keys = new String[srcValue.length];

        if (srcValue.length == 0)
            return;

        try {
            // Create GetKeyMapping
            GetKeyMapping keyMapping = new GetKeyMapping(trace, DEFAULT_PARTY,
                    DEFAULT_SERVICE, DEFAULT_CHANNEL);

            // Create identifiers, add mapping request and save key for every
            // source value
            for (int i = 0; i < srcValue.length; i++) {
                    if (OPTION==2 && srcValue[i].length() <= 5) srcValue[i] = srcValue[i].replace('*','x');

                // Create source and target identifiers
                Identifier sourceIdentifier = new Identifier(srcScheme[i],
                        SOURCE_SCHEME_VERSION_ID, srcAgency[i],
                        SOURCE_SCHEME_AGENCY_SCHEME_ID,
                        SOURCE_SCHEME_AGENCY_SCHEME_AGENCY_ID, srcValue[i]);
                Identifier targetIdentifier = new Identifier(tgtScheme[i],
                        TARGET_SCHEME_VERSION_ID, tgtAgency[i],
                        TARGET_SCHEME_AGENCY_SCHEME_ID,
                        TARGET_SCHEME_AGENCY_SCHEME_AGENCY_ID, "");

                // Add mapping request
                keyMapping.addMapping(context[i], sourceIdentifier,
                        targetIdentifier);

                // Create mapping key and put it into string array
                keys[i] = context[i] + DELIM + srcScheme[i] + DELIM
                        + srcAgency[i] + DELIM + srcValue[i] + DELIM
                        + tgtScheme[i] + DELIM + tgtAgency[i];

                // Trace mapping request
                trace.addWarning("Mapping request added for:" + keys[i]);

            } // End for

            // Trace request RFC XML
            trace.addWarning("Request RFC XML: "
                    + keyMapping.toRfcXml().toString());

            // Execute
            keyMapping.execute();

            // Retrieve results
            Iterator iter = keyMapping.getResultIterator();
            if (iter == null) {
                return;
            }



if (OPTION==2) {
           
            Node n = keyMapping.getResult();
            NodeList children = n.getChildNodes();
            if( children != null ) {
              for( int i = 0; i < children.getLength(); i++ ) {
                Node childNode = children.item( i );

                // here would be a good place to put your application logic
                // and do something base upon node type
               
                Node n1 = childNode;
                NodeList children1 = n1.getChildNodes();
                if( children1 != null ) {
                    String key = "";
                  for( int i1 = 0; i1 < children1.getLength(); i1++ ) {
                     
                    Node childNode1 = children1.item( i1 );

                    // here would be a good place to put your application logic
                    // and do something base upon node type
                    NodeList childNodes;
                    StringBuffer contents = new StringBuffer();
                   
                    childNodes =  childNode1.getChildNodes();
                    for(int i2=0; i2 < childNodes.getLength(); i2++ )
                    {
                      if( childNodes.item(i2).getNodeType() == Node.TEXT_NODE )
                      {
                    contents.append(childNodes.item(i2).getNodeValue());
                      }
                    }
                  
                    if (i1 % 2 == 0) { key = contents.toString(); }
                    else { key =  key.substring(key.indexOf(":")); hm2.put(key,contents.toString());  trace.addInfo( "adding hm2 => " + key + ":" + contents.toString() ); key ="";   }
                  }
                }
              }
            }
            }

            Mapping mappingResult;

            int countResult = 0;
            while (iter.hasNext()) {
                countResult++;
                mappingResult = (Mapping) iter.next();

                // Build key
                String myKey = mappingResult.getMainContextID() + DELIM
                        + mappingResult.getSource().getSchemeID() + DELIM
                        + mappingResult.getSource().getSchemeAgencyID() + DELIM
                        + mappingResult.getSource().getValue() + DELIM
                        + mappingResult.getTarget().getSchemeID() + DELIM
                        + mappingResult.getTarget().getSchemeAgencyID();

                // Put key and value into HashMap
                hm.put(myKey, mappingResult.getTarget().getValue());

            //    if (OPTION==2) { result.addValue((String) mappingResult.getTarget().getValue());  trace.addInfo((String) mappingResult.getTarget().getValue()); }
            }

            // Get values by associated keys and put them into ResultList

                   
            int iResult = 0;
           

            for (int i = 0; i < keys.length; i++) {
                    if (OPTION==2) { result.addValue((String) hm2.get((String) srcValue[i].substring(1))); trace.addInfo("returned"+srcValue[i].substring(1)); }

                trace.addInfo("Comparing result: " + srcValue.length + "-"
                        + countResult);
                // Throw an exception if keys[i] != countResult
                if (srcValue.length != countResult) {
                    throw new RuntimeException("Multiple Mappings for "
                            + keys[i]);
                }
                trace.addWarning("Key returned: " + hm.get(keys[i]));
                trace.addInfo("Alert: " + alert[i]);

                String returnValue = "";

                if (OPTION == 1) {
                    returnValue = (String) hm.get(keys[i]);

                    // throw an exception if the alert is set to Y and the
                    // source
                    // value is not blank and UKMS target value is blank
                    if (returnValue.length() == 0 && srcValue[i].length() > 0
                            && alert[i] != null && alert[i].compareTo("Y") == 0)
                        throw new RuntimeException(
                                "UKMS value Returned blank : " + keys[i]);
                    // Throw Exception if the return value is blank and the
                    // alert is
                    // set
                    trace.addWarning("Adding value to resultset");
                    result.addValue(returnValue);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("Exception occurred: " + e.getMessage());
        }
    }// end method

    public void getUKMSValues(String[] ricef, String[] sourceSystem,
            String[] targetSystem, String[] fieldName, String[] qualf,
            String[] value, ResultList result, Channel channel,
            Container container) throws StreamTransformationException { // Retrieve
                                                                        // the
                                                                        // Context,
                                                                        // SrcScheme,SrcAgency,
                                                                        // TgtScheme,
                                                                        // TgtAgency,
                                                                        // Alert
        // Enable tracing



        AbstractTrace trace = container.getTrace();
    java.util.Date date= new java.util.Date();
        trace.addInfo((new Timestamp(date.getTime()).toString()));


        GlobalContainer globalContainer;
        Boolean isRecoverable = true;
        InputStream ist = null;
        Document document = null;
        Node rootNode = null;
        // Alert variables
        RfcAccessor RFCAccessor;
        final String FunctionModule = "Z_FM_MAP_GET_UKMS_CUST";

        final String FunctionModuleNamespace = "urn:sap-com:document:sap:rfc:functions";
        trace.addInfo (""+ricef.length+"-"+sourceSystem.length+"-"+targetSystem.length+""+fieldName.length+"-"+qualf.length+"-"+value.length);
       
       
       
        XmlPayload RFCResult;
        LookupException le;
        String[] context = new String[value.length];
        String[] srcScheme = new String[value.length];
        String[] srcAgency = new String[value.length];
        String[] tgtScheme = new String[value.length];
        String[] tgtAgency = new String[value.length];
        String[] hasAlert = new String[value.length];
        String[] qua = new String[value.length];
       
        if (qualf.length != value.length) {
            for (int g=0; g< value.length ; g++){
                qua[g]=qualf[0];
            }
           
        }else qua = qualf;
       
        globalContainer = container.getGlobalContainer();
        // Channel rfcChannel =
        // globalContainer.getInputParameters().getChannel("rfc_channel");

        RFCAccessor = LookupService.getRfcAccessor(channel);
        NodeList ctCustomizingNodes ;

      try {

        //for (int i = 0; i < value.length; i++) {

            trace.addInfo("Loop Starts here: " + value.length);
            StringBuffer tmpStr = new StringBuffer();
            tmpStr.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><ns0:");
            tmpStr.append(FunctionModule);
            tmpStr.append(" xmlns:ns0=\"");
            tmpStr.append(FunctionModuleNamespace);
            tmpStr.append("\">");
            tmpStr.append("<RICEFW>");
            tmpStr.append(ricef[0]);
            tmpStr.append("</RICEFW>");
            tmpStr.append("<SOURCE>");
            tmpStr.append(sourceSystem[0]);
            tmpStr.append("</SOURCE>");
            tmpStr.append("<TARGET>");
            tmpStr.append(targetSystem[0]);
            tmpStr.append("</TARGET>");
            tmpStr.append("<FIELD>");
            tmpStr.append(fieldName[0]);
            tmpStr.append("</FIELD>");
            tmpStr.append("</ns0:");
            tmpStr.append(FunctionModule);
            tmpStr.append(">");
            String FunctionModuleXML = tmpStr.toString();
           
//            String FunctionModuleXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ns0:"
//                    + FunctionModule
//                    + " xmlns:ns0=\""
//                    + FunctionModuleNamespace
//                    + "\">"
//                    + "<RICEFW>"
//                    + ricef[0]
//                    + "</RICEFW>"
//                    + "<SOURCE>"
//                    + sourceSystem[0]
//                    + "</SOURCE>"
//                    + "<TARGET>" + targetSystem[0] + "</TARGET>"
//                    // + "<QUALF>"
//                    // + qualf[i]
//                    // + "</QUALF>"
//                    + "<FIELD>" + fieldName[0] + "</FIELD>" + "";
//
//            FunctionModuleXML = FunctionModuleXML + "" + "</ns0:"
//                    + FunctionModule + ">";

           

                trace.addWarning("RFC call1 " + FunctionModuleXML);
                // Create an XML input stream that represents the RFC request
                // message.
                InputStream is = new ByteArrayInputStream(
                        FunctionModuleXML.getBytes());

                // Create the XML Payload
                XmlPayload payload = LookupService.getXmlPayload(is);

                // Execute the lookup.
                // if (i > 0)
                RFCResult = RFCAccessor.call(payload);

            trace.addWarning("Call made to retrieve customizing");
            // PARSE THE RETURN xml
            //try {
                DocumentBuilderFactory factory = DocumentBuilderFactory
                        .newInstance();
                if (factory == null) {
                    throw new Exception(
                            "DocumentBuilderFactory factory is null");
                }

                DocumentBuilder builder = factory.newDocumentBuilder();
                if (builder == null) {
                    throw new Exception("DocumentBuilder builder is null");
                }

                document = builder.parse(RFCResult.getContent());
                if (document == null) {
                    trace.addInfo("Document is null");
                    throw new Exception("Document document is null");
                }

            // Customizing retrieved into XML and parsed into document and
            // nodelist

           

           
         //} // end for loop
        Element docEle = document.getDocumentElement();
        ctCustomizingNodes = docEle.getElementsByTagName("item");
        // This should only have 1 customizing returned.
        for (int i = 0; i < value.length; i++) {
            // RETURN an error if customizing has more than 1 entry
            trace.addWarning("Customizing returned : "
                    + ctCustomizingNodes.getLength());
            for (int k = 0; k < ctCustomizingNodes.getLength(); k++) {
                String cont = "";
                String sa = "";
                String ss = "";
                String ta = "";
                String ts = "";
                String alert = "";
                String qual="";
               
                NodeList nl = ctCustomizingNodes.item(k).getChildNodes();
                for (int j = 0; j < nl.getLength(); j++) {
                   
                    Node node = nl.item(j);
                          if (node.getNodeName().compareTo("QUALIFIER") == 0) {
                          qual = node.getFirstChild().getNodeValue();
                            trace.addInfo("QUALIFIER" + qual);
                        }
                        if (node.getNodeName().compareTo("CONTEXT") == 0) {
                            cont = node.getFirstChild().getNodeValue();
                            trace.addInfo("CONTEXT" + cont);
                        }
                        if (node.getNodeName().compareTo("SOURCE_AGENCY") == 0) {
                            sa = node.getFirstChild().getNodeValue();
                            trace.addInfo("SOURCE_AGENCY" + sa);
                        }

                        if (node.getNodeName().compareTo("SOURCE_SCHEME") == 0) {
                            ss = node.getFirstChild().getNodeValue();
                            trace.addInfo("SOURCE_SCHEME" + ss);
                        }
                        if (node.getNodeName().compareTo("TARGET_AGENCY") == 0) {
                            ta = node.getFirstChild().getNodeValue();
                            trace.addInfo("TARGET_AGENCY" + ta);
                        }
                        if (node.getNodeName().compareTo("TARGET_SCHEME") == 0) {
                            ts = node.getFirstChild().getNodeValue();
                            trace.addInfo("TARGET_SCHEME" + ts);
                        }
                        if (node.getNodeName().compareTo("ALERT") == 0) {
                            alert = node.getFirstChild().getNodeValue();
                            trace.addInfo("ALERT" + alert);
                        }
                   
            } // end J
                trace.addInfo("each qualifier:" +qua[i]);
                if (qual.compareTo(qua[i])==0) {
                    trace.addInfo("Found qualifer " + qual);
                    context[i] = cont;
                    srcAgency[i] = sa;
                    srcScheme[i] = ss;
                    tgtAgency[i] = ta;
                    tgtScheme[i] = ts;
                    hasAlert[i] = alert;
                   
                   
                }
        } // end K

        }// end i
       
          } catch (Throwable t) {
                trace.addWarning("Exception " + t.getMessage());
        }
        // Make rfc call to retrieve UKMS.
        trace.addInfo(channel.toString());
    trace.addWarning(channel.toString());
        trace.addInfo((new Timestamp(date.getTime()).toString()));
        rfcUKMS(context, srcScheme, srcAgency, value, tgtScheme, tgtAgency,
                channel, hasAlert, 1, result, container);
        trace.addInfo((new Timestamp(date.getTime()).toString()));

    } // end method

}