Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

<h2 style="font-size: 20px; color: #225a8d; font-family: Arial">Accessing UKMS by using Java API. Multiple values implementation.</h2>

Introduction

As already mentioned in Part 1  (Accessing UKMS from message mappings (single value implementation) - Part 1) of this blog, there is more than one way to access UKMS from PI. In addition to the ABAP OO interface and RFC-enabled function module also standard Java API called “UnifiedKeyMappingService“ is provided as PI content in SAP Basis SWCV:

Since the standard Java API was not available in SAP Basis component on PI 7.1 at the moment of writing this blog, you have to import archive with UKMS classes from PI 7.0 or define usage dependency between SWCVs if you are on PI 7.1. The Java-centric approach for accessing UKMS mentioned below has been tested on PI 7.0 SP16 and PI 7.1 SP6 and SP7.

Note: Recently UKMS provides also classes to run an ABAP mapping for connecting UKMS to PI. Please refer for details to appropriate help.sap.com documentation for SAP PI 7.1 EHP1.

<h3 style="color: #225a8d; font-family: Arial"><br />Prerequisites</h3>

We have similar prerequisites as in Part 1  (Accessing UKMS from message mappings (single value implementation) - Part 1) of this blog and want map fictitious SAP material ID to the non-SAP material code during the mapping runtime. The difference is that our source message contains lots of material IDs from source system, so we would like to boost the mapping performance and access UKMS via single RFC call by using Java API “UnifiedKeyMappingService”, which should be available at the time of mapping implementation in your SWCV.

RFC receiver communication channel has been configured in Integration Directory to access UKMS. UKMS is configured in the ABAP stack and the following key-value-pairs have been maintained in UKMS:

All required objects (DTs and MTs) are created in ESR. The MT_SAPMaterial is used in outbound message:

The inbound message is based on the MT_NONSAPMaterial:

Now let us begin with the part, which should make the hearts of Java funs beat faster.

<h3 style="color: #225a8d; font-family: Arial"><br />Solution</h3><p style="font-family: Arial">In order to access UKMS mappings from message mapping we will create an UDF. Within this UDF we will use classes provided in Java API, execute the RFC call and provide response values within ResultList object. To make UDF reusable we will parameterize the mapping and provide required parameters as mapping inbound parameters.</p><p style="font-family: Arial">1. Create Message Mapping for MT_SAPMaterial and MT_NONSAPMaterial.</p><p style="font-family: Arial">2. Select the tab “Signature” and insert import parameter for receiver RFC channel required to access UKMS functional module as well as import parameters for context, schemeIDs and schemeAgencyIDs.</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251936572/map_params.png|height=108|alt=image|width=542|s...!</p><p style="font-family: Arial">3. Map the messages just one to one. The mapping of fields Material_ID to Material_Code is of our main interest here.</p><p style="font-family: Arial">4. Open the mapping of those fields and create a new UDF getUKMSValues with an execution type “All Values of Queue” and the following signature variables:</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251936572/func_params.png|height=298|alt=image|width=373|...! </p><p style="font-family: Arial">To access classes from Java API first define it as used archive on tab Functions for your mapping:</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251936572/used_arch.png|height=267|alt=image|width=335|sr...! </p><p style="font-family: Arial">Add the following imports to your UDF: </p><p>!https://weblogs.sdn.sap.com/weblogs/images/251936572/imports.png|height=188|alt=image|width=220|src=...! </p><p style="font-family: Arial">5. Now, when the general conditions are in place let us write the code. We will use the class com.sap.basis.ukm.GetKeyMapping for reading key mappings. Internally this class makes use of the same RFC UKM_GET_KEY_MAPPINGS we already used in Part 1. As you know (this blog assumes that you already have basic understanding of UKMS) the Core Component Type Identifier CCT:Identifier is applied to identify UKMS key within the context. The schemeID represents object type and the schemeAgencyID represents the business system. Within the Java API the class com.sap.basis.ukm.Identifier provides required methods for generating CCT:Identifiers. <br />To add a single mapping request the addMapping() method from GetKeyMapping class can be used, which requires context, source identifier with source value (in other words the source key) and target identifier as input parameters. The key mapping result contains context, source identifier with source value and target identifier with mapped target value, the structure looks like: </p><p>!https://weblogs.sdn.sap.com/weblogs/images/251936572/rfc_response.png|height=254|alt=image|width=576...! </p><p style="font-family: Arial">If no key/value maintained the resulting XML will contain empty XML element for target identifier without any target value (like <TargetID .../>).</p><p style="font-family: Arial">As the above mentioned RFC does not consider by responding the sequence of mapping requests, the HashMap object from java.util is used to map certain keys to associated values and get later those values by keys. The HashMap objects keys are constructed from context, source schemeID, source schemeAgencyID, source value, target schemeID and target schemeAgencyID separated by delimiter. <br />Example: DEMO : MATERIAL_ID : SAP : 123 : MATERIAL_CODE : NONSAP</p><p style="font-family: Arial">So now the complete UDF code: <br />================================================================================= </p><pre style="font-family: Arial"><pre style="color: green; font-family: Arial">/* UKMS lookup as a multiple value implementation based on Java API for Unified Key Mapping Version 1.0.

Set the trace level to info in order to see mapping request keys as well as request rfc xml.*/</pre>

<pre style="color: green; font-family: Arial">// Constants</pre>final String DELIM = " : ";

<br /><pre style="color: green; font-family: Arial">// Adjust according to your party</pre>final String DEFAULT_PARTY = "";<br /><pre style="color: green; font-family: Arial">// Adjust according to your BS name</pre>final String DEFAULT_SERVICE = "YOUR_INTEGRATION_SERVER";

<br /><pre style="color: green; font-family: Arial">// Adjust according to your RCV RFC channel</pre>final String DEFAULT_CHANNEL = "YOUR_RFC_CC";

final String SOURCE_SCHEME_VERSION_ID = "";

final String SOURCE_SCHEME_AGENCY_SCHEME_ID = "";

final String SOURCE_SCHEME_AGENCY_SCHEME_AGENCY_ID = "";

final String TARGET_SCHEME_VERSION_ID = "";

final String TARGET_SCHEME_AGENCY_SCHEME_ID = "";

final String TARGET_SCHEME_AGENCY_SCHEME_AGENCY_ID = "";

<pre style="color: green; font-family: Arial">// Variables</pre>HashMap hm = new HashMap();

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

AbstractTrace trace = container.getTrace();

try {

<pre style="color: green; font-family: Arial">// Create GetKeyMapping</pre>GetKeyMapping keyMapping = new GetKeyMapping(trace, DEFAULT_PARTY,

  DEFAULT_SERVICE, DEFAULT_CHANNEL);

<pre style="color: green; font-family: Arial">// Create identifiers, add mapping request and save key for every source value</pre>    for (int i = 0; i < srcValue.length; i++) {

     <pre style="color: green; font-family: Arial">     // Create source and target identifiers</pre>     Identifier sourceIdentifier = new Identifier(srcScheme[0],

       SOURCE_SCHEME_VERSION_ID, srcAgency[0],

       SOURCE_SCHEME_AGENCY_SCHEME_ID,

       SOURCE_SCHEME_AGENCY_SCHEME_AGENCY_ID,

       srcValue[i]);

     Identifier targetIdentifier = new Identifier(tgtScheme[0],

       TARGET_SCHEME_VERSION_ID, tgtAgency[0],

       TARGET_SCHEME_AGENCY_SCHEME_ID,

       TARGET_SCHEME_AGENCY_SCHEME_AGENCY_ID, "");

<pre style="color: green; font-family: Arial">     // Add mapping request</pre>     keyMapping.addMapping(context[0], sourceIdentifier, targetIdentifier); 

<pre style="color: green; font-family: Arial">      // Create mapping key and put it into string array</pre>     keys[i] = context[0] +  DELIM + srcScheme[0] + DELIM + srcAgency[0] + DELIM +

        srcValue[i] + DELIM + tgtScheme[0] + DELIM + tgtAgency[0];

<pre style="color: green; font-family: Arial">      // Trace mapping request</pre>     trace.addInfo("Mapping request added for:" + keys[i]);

       } // End for

<pre style="color: green; font-family: Arial">// Trace request RFC XML</pre>trace.addInfo("Request RFC XML: " + keyMapping.toRfcXml().toString());

<pre style="color: green; font-family: Arial">// Execute</pre>keyMapping.execute();

<pre style="color: green; font-family: Arial">// Retrieve results</pre>Iterator iter = keyMapping.getResultIterator();

Mapping mappingResult;

while (iter.hasNext()) {

     mappingResult = (Mapping) iter.next();

<pre style="color: green; font-family: Arial"> // Build key</pre>  String myKey = mappingResult.getMainContextID() + DELIM +

                     mappingResult.getSource().getSchemeID() + DELIM +

     mappingResult.getSource().getSchemeAgencyID() + DELIM +

     mappingResult.getSource().getValue() + DELIM +

     mappingResult.getTarget().getSchemeID() + DELIM +

     mappingResult.getTarget().getSchemeAgencyID();

<pre style="color: green; font-family: Arial">// Put key and value into HashMap</pre>hm.put(myKey, mappingResult.getTarget().getValue());

}

<pre style="color: green; font-family: Arial">// Get values by associated keys and put them into ResultList</pre>for(int i = 0; i < keys.length; i++)

     result.addValue((String)hm.get(keys[i]));

} catch (Exception e) {

throw new RuntimeException("Exception occurred: " + e.getMessage());

}

</pre><p style="font-family: Arial">================================================================================= </p><p style="font-family: Arial">6. Map Material_ID to the Material_Code by using getUKMSValue UDF in the following way: </p><p>!https://weblogs.sdn.sap.com/weblogs/images/251936572/udf_mapp.png|height=324|alt=image|width=485|src...! </p><p style="font-family: Arial">Map constants to the appropriate mapping parameters created in the step 1. Don’t forget to set the context of Material_ID to the root node MT_SAPMaterial to get all values from complete queue and use SplitByValue standard function to ensure, that context changes separate Material_Code values. </p><p style="font-family: Arial">7. Now test the mapping by initializing mapping parameters on “Test” tab according to key-value-pairs maintained in UKMS. Select for mm_rfc_channel parameter valid RFC receiver channel from ID. </p><p>!https://weblogs.sdn.sap.com/weblogs/images/251936572/test_params.png|height=173|alt=image|width=299|...! </p><p style="font-family: Arial">Create input message with several Material_ID values, set trace level to “Info” or higher and execute the test. Every single mapping request as well as RFC input structure is traced. That’sit, we have developed reusable UDF to access UKMS in single RFC call with multiple values implementation! </p><p>!https://weblogs.sdn.sap.com/weblogs/images/251936572/traces.png|height=343|alt=image|width=601|src=h...!</body>

1 Comment