Accessing UKMS by using Java API. Multiple values implementation.
Introduction
As already mentioned in 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. |
Prerequisites
We have similar prerequisites as in 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.
Solution
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.
1. Create Message Mapping for MT_SAPMaterial and MT_NONSAPMaterial.
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.

3. Map the messages just one to one. The mapping of fields Material_ID to Material_Code is of our main interest here.
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:
To access classes from Java API first define it as used archive on tab Functions for your mapping:
Add the following imports to your UDF:
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.
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:
If no key/value maintained the resulting XML will contain empty XML element for target identifier without any target value (like <TargetID .../>).
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.
Example: DEMO : MATERIAL_ID : SAP : 123 : MATERIAL_CODE : NONSAP
So now the complete UDF code:
=================================================================================
/* 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.*/
// Constants
final String DELIM = " : ";
// Adjust according to your party
final String DEFAULT_PARTY = "";
// Adjust according to your BS name
final String DEFAULT_SERVICE = "YOUR_INTEGRATION_SERVER";
// Adjust according to your RCV RFC channel
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 = "";
// Variables
HashMap hm = new HashMap();
String[] keys = new String[srcValue.length];
AbstractTrace trace = container.getTrace();
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++) {
// Create source and target identifiers
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, "");
// Add mapping request
keyMapping.addMapping(context[0], sourceIdentifier, targetIdentifier);
// Create mapping key and put it into string array
keys[i] = context[0] + DELIM + srcScheme[0] + DELIM + srcAgency[0] + DELIM +
srcValue[i] + DELIM + tgtScheme[0] + DELIM + tgtAgency[0];
// Trace mapping request
trace.addInfo("Mapping request added for:" + keys[i]);
} // End for
// Trace request RFC XML
trace.addInfo("Request RFC XML: " + keyMapping.toRfcXml().toString());
// Execute
keyMapping.execute();
// Retrieve results
Iterator iter = keyMapping.getResultIterator();
Mapping mappingResult;
while (iter.hasNext()) {
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());
}
// Get values by associated keys and put them into ResultList
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());
}
=================================================================================
6. Map Material_ID to the Material_Code by using getUKMSValue UDF in the following way:
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.
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.
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’s it, we have developed reusable UDF to access UKMS in single RFC call with multiple values implementation!
Summary of the Part 2
UKMS provides Java API containing relevant classes and the methods to access RFC-enabled functional modules. Based on this functionality the user defined functions can be implemented to access UKMS key mappings during the mapping runtime on PI. Furthermore also custom developed Java API is possible (suppose that you would like to access UKMS tables via custom developed RFCs and would like to integrate alerting for missing UKMS key mappings…) to get the full control of what is going on.