Skip to Content
Author's profile photo Former Member

Using PI 7.3’s Directory API

Using PI 7.3’s Directory API

Directory API has been used by many companies to streamline processes and ease situations where manual configuration of Integration Directory objects is not the ideal solution, such as the updating of the communication channels after transport.  If a program can carry out this task, then it can minimize mistakes, speed up deployment and increase security.

Directory API has gone through different iterations, due to added functionalities and new objects introduced in newer releases.  The older version (XI 3.0, PI 7.0x, PI 7.1x) of the API can no longer be used with the newer versions of PI.  As the result, the development of the API has also changed.

The previous version of the API can be referenced in: Directory API Development

In this blog, I will introduce the basic development of using the PI 7.3x Directory API.  The example can be used as a template  to start a Directory API project, and hopefully overcome some of the initial hurdles.

Scenario:

The sample scenario is simply to get the number of Integrated Configuration objects, which was introduced in PI 7.1.

Pre-requisite:

The following roles must be added to the username executing the API:

  • SAP_XI_API_DISPLAY_J2EE
  • SAP_XI_API_DEVELOP_J2EE

Step-by-Step Guide

  1. Import the WSDL of the Directory API from the Enterprise Service Repository (ESR)

    The ESR contains the Service Interface of the API and using NWDS, we can import the WSDL of the service interface directly from the ESR.  (The NWDS version should at least match the PI versoin.)

    1. Before the import, verify the connection settings are correct:
      1. In NWDS’s main menu, go to Windows –> Preferences
        /wp-content/uploads/2012/10/pic1_146074.png
      2. In Preferences:  go to Web Services –> Enterprise Service Browser
        /wp-content/uploads/2012/10/pic2_146081.png
      3. Enter the appropriate server information
        /wp-content/uploads/2012/10/pic3_146082.png
    2. Create a Java project in NWDS:
      1. In NWDS menu:  File –> New –> Project
      2. Select: Java Project
      3. Enter a project name (In this example, the project name is “Demo_DirAPI”.)
    3. Import the Service Interface from the ESR:
      1. Right-click on the project name
      2. Select:  Import…
        /wp-content/uploads/2012/10/pic4_146083.png
      3. Select: Web services –> WSDL and click Next
        /wp-content/uploads/2012/10/pic5_146087.png
      4. Select option: Enterprise Service Repository and click Next
        /wp-content/uploads/2012/10/pic6_146088.png
      5. Enter logon information
        /wp-content/uploads/2012/10/pic7_146089.png
      6. Select the Service Interface in the ESR
        1. Navigate to; SAP BASIS 7.30 –> http://sap.com/xi/BASIS –> Folders –> Itegration Directory API
        2. Select the API by going to the appropriate folder and select the service interface:
          /wp-content/uploads/2012/10/pic8_146093.png
      7. You should see the WSDL imported under your project:
        /wp-content/uploads/2012/10/pic9_146094.png
  2. Generate the proxy from the imported WSDL
    1. Right-click on the WSDL and navigate to Web Serivices –> Generate Client:
      /wp-content/uploads/2012/10/pic10_146095.png
    2. Move the selector to “Develop client” and click Finish
      /wp-content/uploads/2012/10/pic11_146096.png
      If prompted, click on the default, “Update WSDL”:
      /wp-content/uploads/2012/10/pic12_146097.png
    3. You should see new packages generated:
      /wp-content/uploads/2012/10/pic13_146098.png
  3. Write the code
    1. Create a new package by right-click on: src, and select: New –> Package
      /wp-content/uploads/2012/10/pic14_146099.png
    2. Enter package name
      /wp-content/uploads/2012/10/pic15_146100.png
    3. Create a new class by right-click on the package and selct: New –> Class /wp-content/uploads/2012/10/pic16_146101.png
    4. Enter class name
      /wp-content/uploads/2012/10/pic17_146102.png
    5. Copy-n-paste the sample code:
      
      package com.demo.dirapi;
      
      import java.util.List;
      
      import javax.xml.ws.BindingProvider;
      
      import com.sap.xi.basis.IntegratedConfigurationIn;
      import com.sap.xi.basis.IntegratedConfigurationInService;
      import com.sap.xi.basis.IntegratedConfigurationQueryIn;
      import com.sap.xi.basis.IntegratedConfigurationQueryOut;
      import com.sap.xi.basis.MessageHeaderID;
      
      public class IntegratedConfiguration {
           private static String apiURL = "/IntegratedConfigurationInService/IntegratedConfigurationInImplBean?wsdl=binding&mode=ws_policy";
           private String serverPort = "usphlvm1426:50000";
           private String user = "demo";
           private String password = "abcd1234";
           private String url = new String();
           private IntegratedConfigurationIn port;
      
           public IntegratedConfiguration() {
                setURL(serverPort);
                try {
                     port = getPort();
                }
                catch (Exception e) {
                     e.printStackTrace();
                }
           }
      
           public List query() {
                IntegratedConfigurationQueryIn queryIn = new IntegratedConfigurationQueryIn();
                MessageHeaderID msgHdr = new MessageHeaderID();
                queryIn.setIntegratedConfigurationID(msgHdr);
                IntegratedConfigurationQueryOut queryOut = port.query(queryIn);
                List lMsgHdr = queryOut.getIntegratedConfigurationID();
                return lMsgHdr;
           }
      
           private void setURL(String serverPort) {
                if (serverPort == null)
                     return;
                else
                     this.url = this.url.concat("http://").concat(serverPort).concat(apiURL);
           }
      
           private IntegratedConfigurationIn getPort() throws Exception{
                IntegratedConfigurationIn port = null;
                try {
                     IntegratedConfigurationInService service = null;
      
                     service = new IntegratedConfigurationInService();
      
                     port = (IntegratedConfigurationIn) service.getIntegratedConfigurationIn_Port();
                    BindingProvider bp = (BindingProvider)port;
                    bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, user);
                    bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
                    if (url.length() != 0)
                         bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
                }
                catch (Exception ex){
                     ex.printStackTrace();
                }
                return port;
           }
      
           /**
            * @param args
            */
           public static void main(String[] args) {
                // TODO Auto-generated method stub
                IntegratedConfiguration test = new IntegratedConfiguration();
                List listMsgHdr = test.query();
                System.out.println("Done - number of configurations = " + listMsgHdr.size());
           }
      
      }
      

      Note:  The apiURL value can be obtained by going the the WSNavigator.

    6. The result:  Done – number of configurations = 27

Assigned Tags

      59 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      I followed the instructions and can run the code successfully from my local pc. I had been getting the wsdl in a different way and it was creating file names that were too long but your procedure fixed it.

      However, when I try to run in PI I get the following error which I believe is caused by the fact that the tmpUrl object is null.

      Caused by: java.lang.NullPointerException: while trying to invoke the method java.net.URL.getProtocol() of an object loaded from local variable 'tmpUrl'

      at com.sap.xi.basis.IntegratedConfigurationInService.<clinit>(IntegratedConfigurationInService.java:14)

      I am creating what appears to be a valid url for our system...see below...but it is not used because the static constructor is failing and I would only set the url after creating the port

      Here is the url:

      http://pollux.conocophillips.net:57100/IntegratedConfigurationInService/IntegratedConfigurationInImplBean?wsdl=binding&mode=ws_policy

      Author's profile photo Former Member
      Former Member

      @Larry Martin:

      Did you find a solution for you problem? I am running into the same error. On the local pc everything is working, but when I deploy the program as a web service (servlet) and a development component in combination with an enterprise application it leads to your mentioned error. It seems that the variable "port" is not filled/initialized.

      Thank you,

      Dennis

      Author's profile photo Former Member
      Former Member

      Thanks for the update William. The new API is much better. I've written a number of wrappers around it and hopefully someday it is cleaned up and robust enough to share.

      Hopefully PI 7.31 features get added to the Directory API too.

      -Manager Alert Rules (not just consumers)

      -Managing Alert Rules and Value Mapping in the Config Scenerios **

      Not specific to 7.31, but I'd also love to see a WhereUsedList service.

      **On that note, hopefully both of these object types get an 'Assign to Config Scenario' and 'Remove from Config Scenrio' option in the normal ID as well.

      Author's profile photo Former Member
      Former Member

      I'd like to add a caution that since the ConfigScenarioIn service does not support Value Mapping groups or Alert Rules, when using that service to change an existing config scenario, any Alert Rules and Value Mappings for it will be lost.

      Unfortunately it meant wasted effort for me as I had spent a good amount of time assigning Value Mapping Groups to Config Scenarios.

      Hopefully this is fixed in the next version.

      Author's profile photo Former Member
      Former Member

      We have also found that the Directory API does not support the Advanced Settings in Integrated Configurations for scenario-specific Staging and Logging.

      But even worse, is that when you update/change an Integrated Scenario using Directory API, if it had scenario-specific settings, they will be lost. This is dangerous as certain combinations of staging for EOIO messages can cause messages to get stuck.

      It seems there has not been much attention given to Directory API in the EHP1 update, leading to these gaps and issues, which frankly make it dangerous to use. Hopefully SAP plans to patch these gaps and hopefully avoid them again in the future.

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      There will be additional Directory API enhancements in PI 7.31 SP6, which is scheduled for beginning of Q1/2013.

      Author's profile photo Former Member
      Former Member

      Hi William,

      I'm trying to create a proxy for that API on ABAP side. But there is no service interface to be seen in ESR for any of the API Objects according to your topic f above.

      Do you know how to manage this?

      Thank you,

      Erik

      Author's profile photo Michal Krawczyk
      Michal Krawczyk

      hi Bill,

      with read operation the results are limited to 200 only

      is there a way to configure that somehow ? 🙂

      Thank you for any tips 🙂

      Regards,

      Michal Krawczyk

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Michal,

      I am not aware of a configuration parameter.  I don't have a PI system with more than 200 ICOs to test this out 🙁

      If I need to retrieve the info for all the ICOs, I normally use the QUERY operation to retrieve all instances of the ICOs (sender/receiver component/interface/namespace).  Then, I use the READ operation to retrieve the details each ones based on the QUERY results.

      Are you saying the QUERY operation is limited to 200?

      If it is the READ operation with the 200 limit, then maybe you can group only 200 for each READ at a time.

      If it is the QUERY operation with the 200 limit, then you can use a filter, e.g. = "A*" and go through the alphabet (it's case-sensitive, so you may have to go through the alphabet twice).

      Regards,

      William Li

      Author's profile photo Former Member
      Former Member

      I also do not have a PI system with more than 200 ICO's...yet. However, we use many of the other Directory API's and have never run into any sort of limit on the number of objects returned by the Query operation. We have more than 200 Configuration Scenarios, Communication Channels and Interface Determinations and have never seen a limit.

      Author's profile photo Michal Krawczyk
      Michal Krawczyk

      hi Larry,

      I even see this in wsnavigator when I run a query for all communication channels - only 200 is returned, do you have more over there when you search for all ?

      Thank you,

      Regards,

      Michal Krawczyk

      Author's profile photo Former Member
      Former Member

      Michal. We are not running our query in WSNavigator. We have written java classes that wrap each of the Directory API objects, such as Communication Channel, so we are running the query from our own java class and when we do that we do not see any limit.

      It would seem like the limit is in WSNavigator not in the actual API...which is actually a Web Service call.

      I have not used WSNavigator for this for a long time but I would bet there is some sort of configuration paramter that is limiting the number of responses. In fact, I am not aware of a way to limit the number fo objects returned from a Query call but I have not looked for one either so there could be an optional parameter.

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Michal,

      I just used wsnavigator to query communication channels and got 266 back.

      CommChan.png

      Default system configuration.

      Regards,

      William Li

      Author's profile photo Michal Krawczyk
      Michal Krawczyk

      Hi Guys,

      thank you both for your help 🙂

      what it turned out - we had exactly 200 channels 🙂

      Regards,

      Michal Krawczyk

      Author's profile photo Former Member
      Former Member

      Hi Bill,

      I'm following your earlier blogs on communication channel creation and trying to create SOAP receiver communication channel using Java-only PI 7.31 directory APIs. I have passed all the required parameters to the CommunicationChannelIn service, but it's throwing error - "Enter at least one object key for operation 'create'".

      When I tried to test the service through WS Navigator, it's giving exception - "Enter a value for attribute 'Transport Protocol Version'" which doesn't exists in case of SOAP adapter creation. I also tried with other communication channels but no luck so far.

      Can you please suggest me any work around or point out where I might me going wrong.

      Your expert advice and help will be highly appreciated.

      Regards,

      Yashu Vyas

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi,

      When running into such issues, one method I always use when creating an object is to look at an existing object and their values for the different fields.  You can use the "read" operation in WSNavigator to examine an existing receiver communication channel to determine the values you should use.

      Regards,

      William

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Yashu,

      Can you provide more information on what you are trying to create?  Give as much details as possible.

      Regards,

      William Li

      Author's profile photo Former Member
      Former Member

      Hi Bill,

      Thanks for all the support and help offered.

      We are facing following problems while trying to create communication channel through Dir API -


      In PI 7.0 Dir API's we had the following constructor -

      CommunicationChannelCreateChangeIn crtChan = new CommunicationChannelCreateChangeIn();


      and used the function 'crtChan.setCommunicationChannel(chans)' to associate the object 'chans' of type CommunicationChannelRestricted with 'crtChan', and created the communication channel using the below code -

      ConfigurationObjectModifyOut resp = port.create(crtChan);


      As we don't have any corresponding function in PI 7.31 Dir API's, we are not sure how to set the object of type RestrictedCommunicationChannelType on the object of class CommunicationChannelCreateChangeInType.


      We want to associate RestrictedCommunicationChannelType object with CommunicationChannelCreateChangeInType object to invoke the 'create' function of the class CommunicationChannelIn.


      Below is how we are trying to create the Communication Channel:


      CommunicationChannelIn port = (CommunicationChannelIn) service.getCommunicationChannelIn_Port();


      ConfigurationObjectModifyOutType resp = port.create(crtChan);


      We are getting the error 'Enter at least one object key for operation 'create''. We assume that it is because there is no 'set' method in the class CommunicationChannelCreateChangeInType

      to associate RestrictedCommunicationChannelType with it,

      Any help and pointers will be highly appreciated.

      Regards,

      Yashu

      Note : I'm trying to retrofit the java code mentioned in your earlier blog on communication channel creation.

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Yashu,

      Please don't provide me with the code, I will not be able to debug it for you.  Instead, I will use WSNavigator to create the comm chan.  If WSNavigator works, then I can use it to write the code.

      Please let me know the details of the comm chan you want to create.

      Regards,

      William

      Author's profile photo Former Member
      Former Member

      Hi Bill,

      We are trying to create a SOAP receiver communication channel through PI 7.31 Dir API. Please help us with that.

      Thanks a lot for your valuable time and help.

      Thanks & Regards,

      Yashu Vyas

      Author's profile photo Former Member
      Former Member

      Here is code to create a restricted CC from a noram CC.

      public RestrictedCommunicationChannel duplicateChannel(CommunicationChannel currentChannel) throws Exception {

        RestrictedCommunicationChannel newChannel = new RestrictedCommunicationChannel();

        newChannel.setCommunicationChannelID(currentChannel.getCommunicationChannelID());

        newChannel.setMasterLanguage(currentChannel.getMasterLanguage());

        ObjectAdministrativeData currentAdministrativeData = currentChannel.getAdministrativeData();

        if (currentAdministrativeData != null) {

         RestrictedObjectAdministrativeData newAdministrativeData = new RestrictedObjectAdministrativeData();

         newAdministrativeData.setResponsibleUserAccountID(currentAdministrativeData.getResponsibleUserAccountID());

         newAdministrativeData.setFolderPathID(currentAdministrativeData.getFolderPathID());

         newChannel.setAdministrativeData(newAdministrativeData);

        }

        List <LONGDescription> descriptions = currentChannel.getDescription();

        if ((descriptions != null) && (descriptions.size() > 0))

         for (int index = 0; index < descriptions.size(); index++)

          newChannel.getDescription().add(descriptions.get(index));

        newChannel.setAdapterMetadata(currentChannel.getAdapterMetadata());

        newChannel.setDirection(currentChannel.getDirection());

        newChannel.setTransportProtocol(currentChannel.getTransportProtocol());

        newChannel.setTransportProtocolVersion(currentChannel.getTransportProtocolVersion());

        newChannel.setMessageProtocol(currentChannel.getMessageProtocol());

        newChannel.setMessageProtocolVersion(currentChannel.getMessageProtocolVersion());

        newChannel.setAdapterEngineName(currentChannel.getAdapterEngineName());

        List <GenericProperty> genericProperties = currentChannel.getAdapterSpecificAttribute();

        if ((genericProperties != null) && (genericProperties.size() > 0))

         for (int index = 0; index < genericProperties.size(); index++)

          newChannel.getAdapterSpecificAttribute().add(genericProperties.get(index));

        List <GenericPropertyTable> adapterSpecificTableAttributes = currentChannel.getAdapterSpecificTableAttribute();

        if ((adapterSpecificTableAttributes != null) && (adapterSpecificTableAttributes.size() > 0))

         for (int index = 0; index < adapterSpecificTableAttributes.size(); index++)

          newChannel.getAdapterSpecificTableAttribute().add(adapterSpecificTableAttributes.get(index));

        newChannel.setModuleProcess(currentChannel.getModuleProcess());

        newChannel.setSenderIdentifier(currentChannel.getSenderIdentifier());

        newChannel.setReceiverIdentifier(currentChannel.getReceiverIdentifier());

        return newChannel;

      }


      Author's profile photo Former Member
      Former Member

      Hi Larry,

      It seems your utility is for duplicating an existing channel of type CommunicationChannel to create the CC of type RestrictedCommunicationChannel. However my requiement is to create the very first CC in the system using PI 7.31 API's.


      Our program doesn't have any information about any existing channel and as mentioned in my earlier query to Bill we are trying to associate RestrictedCommunicationChannelTypeobject with CommunicationChannelCreateChangeInType object to invoke the 'create' function of the classCommunicationChannelIn.


      Regards,

      Yashu Vyas

      Author's profile photo Former Member
      Former Member

      Vyas. We do not have anything to create a CC. Our code starts with the CC's we already have, lists them and updates them when requested.

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Yashu,

      I was able to create a receiver SOAP comm chan using WSNavigator.  The exported XML is below:  (you can copy it to a file)

      <CommunicationChannelCreateRequest>

        <CommunicationChannel>

          <MasterLanguage>EN</MasterLanguage>

          <CommunicationChannelID>

            <PartyID></PartyID>

            <ComponentID>BC1</ComponentID>

            <ChannelID>R_soap_test</ChannelID>

          </CommunicationChannelID>

          <AdapterMetadata>

            <Name>SOAP</Name>

            <Namespace>http://sap.com/xi/XI/System</Namespace>

            <SoftwareComponentVersionID>7e9a3ca7-82ab-11df-b3ad-f6750a424100</SoftwareComponentVersionID>

          </AdapterMetadata>

          <Direction>Receiver</Direction>

          <TransportProtocol>HTTP</TransportProtocol>

          <TransportProtocolVersion></TransportProtocolVersion>

          <MessageProtocol>SOAP</MessageProtocol>

          <MessageProtocolVersion></MessageProtocolVersion>

          <AdapterSpecificAttribute>

            <Name>XMBWS.TargetURL</Name>

            <Value>http://wsf.cdyne.com/WeatherWS/Weather.asmx</Value>

          </AdapterSpecificAttribute>

          <AdapterSpecificAttribute>

            <Name>XMBWS.ProxyHost</Name>

            <Value>proxy</Value>

          </AdapterSpecificAttribute>

          <AdapterSpecificAttribute>

            <Name>XMBWS.ProxyPort</Name>

            <Value>8080</Value>

          </AdapterSpecificAttribute>

          <AdapterSpecificAttribute>

            <Name>XMBWS.DefaultSOAPAction</Name>

            <Value>http://ws.cdyne.com/WeatherWS/GetCityWeatherByZIP</Value>

          </AdapterSpecificAttribute>

          <AdapterSpecificAttribute>

            <Name>useProxy</Name>

            <Value>1</Value>

          </AdapterSpecificAttribute>

        </CommunicationChannel>

      </CommunicationChannelCreateRequest>

      You can change the <ComponentID> to one that is available on your PI system and import the XML into WSNavigator to test.

      If it is successful, then these are the basic parameters to use.  If you need other attribute, e.g. proxy user and password, then you can use a READ operation to determine the names to use.

      Regards,

      William

      Author's profile photo Former Member
      Former Member

      Hi Bill,

      As suggested earlier we used READ operation and make it work to create CC through WSNavigator. However when we tried to do the same through our Java code using PI 7.31 DIr API it fails to create the same. That was the primary intent I wanted to share the code snippet with you as are not able to associate RestrictedCommunicationChannelType object with CommunicationChannelCreateChangeInType object to invoke the 'create' function of the class CommunicationChannelIn.

      We are getting the error 'Enter at least one object key for operation 'create''. We assume that it is because there is no 'set' method in the class CommunicationChannelCreateChangeInType to associate RestrictedCommunicationChannelType with it.

      It'll be great if you can throw some light on this aspect.

      Thanks & Regards,

      Yashu Vyas

      Author's profile photo Former Member
      Former Member

      Hi Bill,

      We fixed the issue and were able to create the communication channel through PI 7.31 Dir API utility.

      Thanks a lot for all your help and suggestions.

      Regards,

      Yashu Vyas

      Author's profile photo sateesh adma
      sateesh adma

      Hello Vyas,

      We are also getting exact same error for all the adapters .

      No transport protocol with name "File" and version "" exists for "Adapter Metadata File | http://sap.com/xi/XI/System (SAP BASIS 7.40)"

      Any help will be appreciated.

      Thanks,

      Sateesh Adma

      Author's profile photo Former Member
      Former Member

      Hi Bill,

      I have created a dirapi utility to make mass changes to pi communication channels (only) in PI 7.11 environment and it works great 🙂

      Now do I need to write the whole code again to be able to use this utility on PI 7.31?

      Vicky

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Vicky,

      You may not need to.  There are 2 sets of APIs in PI 7.31, one is for PI 7.11 and before.  The other is for PI 7.11 and after.  With PI 7.11, there were many enhancements in the ESR and ID, the older version can only handle those interfaces and configurations using the "classical" way, while the newer version can handle all.  Communication channels happens to be unchanged between the versions....I think.  So, you should be able to work with communication channels using both APIs.

      If you need to go to the new API, then you will need to re-write.

      Regards,

      William

      Author's profile photo Former Member
      Former Member

      Hi William,

      I have implemented the above code and was sucessfully able to retrieve the Number of ICO's and Number of Communication Channels . But my requiremnt is to get the Communication Channel names along with the Attributes. Could you please suggest as to what parameters should be used to get the Communication Channel names and List of attributes used in the Channel like user name , password etc instead of just getting the number , i need to get the names of the Channels as well.

      Thanks,

      Soundarya

      Author's profile photo Former Member
      Former Member

      The way to get the detail information on each object is to iterate througth the list of object, such as Commununications Channels and call the method to get the individual channel. Here is my overloaded method. I am using a log4j logger and have a standard method to log and check the returned message collection...which I will share if you need it.

      public CommunicationChannel returnChannel(String partyId, String componentId, String channelId) throws Exception {
        return returnChannel(partyId, componentId, channelId, Utility.MESSAGE_SEVERITY_ERROR);
      }

      public CommunicationChannel returnChannel(String partyId, String componentId, String channelId, String exceptionSeverity) throws Exception {
        CommunicationChannelID communicationChannelID = new CommunicationChannelID();
        if ((partyId != null) && (partyId.length() > 0)) communicationChannelID.setPartyID(partyId);
        if ((componentId != null) && (componentId.length() > 0)) communicationChannelID.setComponentID(componentId);
        communicationChannelID.setChannelID(channelId);
        return returnChannel(communicationChannelID);
      }

      public CommunicationChannel returnChannel(CommunicationChannelID communicationChannelID) throws Exception {
        return returnChannel(communicationChannelID, Utility.MESSAGE_SEVERITY_ERROR);
      }

      public CommunicationChannel returnChannel(CommunicationChannelID communicationChannelID, String exceptionSeverity) throws Exception {
        CommunicationChannel returnValue = null;
        try {
         CommunicationChannelReadIn returnChannelIn = new CommunicationChannelReadIn();
         returnChannelIn.getCommunicationChannelID().add(communicationChannelID);
         returnChannelIn.setReadContext(ReadContextCode.ACTIVE);
         Logger.getRootLogger().setLevel(Level.OFF);
         CommunicationChannelReadOut returnChannelOut = port.read(returnChannelIn);
         Logger.getRootLogger().setLevel(defaultLevel);
         LogMessageCollection messageCollection = returnChannelOut.getLogMessageCollection();
         integrationUtility.handleLogMessages(CLASS_NAME + " - Return Channel (" + communicationChannelID.getComponentID() + "/" +
           communicationChannelID.getChannelID() + ")", messageCollection, exceptionSeverity);
         try {
          returnValue = returnChannelOut.getCommunicationChannel().get(0);
         } catch (NullPointerException eNull) {
          logging.writeMessage("Returned Communication Channel is null for (" + communicationChannelID.getComponentID() + "/" +
            communicationChannelID.getChannelID() + ")", GLBLLogging.MSG_TYPE_DEBUG);
         }
         catch (IndexOutOfBoundsException eIndex) {
          logging.writeMessage("Returned Communication Channel Array had zero objects (" +
            communicationChannelID.getChannelID() + "/" + communicationChannelID.getComponentID() + ")",
            GLBLLogging.MSG_TYPE_DEBUG);
         }
        } catch (Exception e) {
         Logger.getRootLogger().setLevel(defaultLevel);
         String errorMessage = "PI Integration " + CLASS_NAME + " Return Channel failed = " + e.getMessage();
         logging.writeError(errorMessage, e);
         integrationUtility.sendNotification(Utility.ERROR_STATUS, "PI Integration " + CLASS_NAME + " Return Channel error", errorMessage);
         throw e;
        }
        return returnValue;
      }


      Author's profile photo Former Member
      Former Member

      Hi Martin,

      I tried using the above code you suggested but The Utility parameters in the above code are not identified in my editor and hence it shows error at those lines. I am looking for some code to read the channel names , its attributes etc using DIR API . Could you suggest any sample code to do so similar to the one suggested by William in this blog to get the number of ICO's. I am looking for such code to read the Channel name instead of the number of channels. I just wanted to understand the metod to be used to  get the channel name . Is it CommunicationChannelreadIn. If yes, what are the input parameters to it?

      Appreciate any quick responses.

      Thanks,

      Soundarya

      Author's profile photo Former Member
      Former Member

      The Utility class is my own, along with a few others. Here is my code for listing out all of the fields in a Communication Channel. In some places a subroutine is called but you will be able to see all of the fields.

      The way to determine what to do for any one type of object is to loook in the classes that were generated when you processed the WSDL file. They list all of the fields. Granted you have to sometimes go down a few levels to get to the things you can log but everything is there.

      public void logChannel(CommunicationChannel currentChannel) throws Exception {

        SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMM yyyy @ HH:mm:ss");

        CommunicationChannelID currentID = currentChannel.getCommunicationChannelID();

        logging.writeMessage("Communication Channel (" + currentID.getComponentID() + "/" +

          currentID.getChannelID() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        logging.writeMessage("   Master Language (" + currentChannel.getMasterLanguage() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        ObjectAdministrativeData administrativeData = currentChannel.getAdministrativeData();

        if (administrativeData != null) {

         logging.writeMessage("   Administrative Data - Responsible User Account ID (" +

           administrativeData.getResponsibleUserAccountID() +

           ") Folder Path ID (" + administrativeData.getFolderPathID() +

           ") Last Change User Account ID (" + administrativeData.getLastChangeUserAccountID() +

           ") Last Change Date Time (" +

           dateFormat.format(administrativeData.getLastChangeDateTime().toGregorianCalendar().getTime()) +

           ")", GLBLLogging.MSG_TYPE_DEBUG);

        }

        List <LONGDescription> descriptions = currentChannel.getDescription();

        integrationUtility.logDescription(descriptions);

        logging.writeMessage("   Communication Channel ID - Party ID (" + currentID.getPartyID() + ") Component ID (" +

          currentID.getComponentID() + ") Channel ID (" + currentID.getChannelID() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        DesignObjectID adapterMetadata = currentChannel.getAdapterMetadata();

        if (adapterMetadata != null) {

         logging.writeMessage("   Adapter Metadata - Name (" + adapterMetadata.getName() + ") Namespace (" +

           adapterMetadata.getNamespace() + ") Software Component Version ID (" +

           adapterMetadata.getSoftwareComponentVersionID() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        }

        logging.writeMessage("   Direction (" + currentChannel.getDirection() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        logging.writeMessage("   Transport Protocol (" + currentChannel.getTransportProtocol() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        logging.writeMessage("   Transport Protocol Version (" + currentChannel.getTransportProtocolVersion() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        logging.writeMessage("   Message Protocol (" + currentChannel.getMessageProtocol() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        logging.writeMessage("   Message Protocol Version (" + currentChannel.getMessageProtocolVersion() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        logging.writeMessage("   Adapter Engine Name (" + currentChannel.getAdapterEngineName() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        List <GenericProperty> genericProperties = currentChannel.getAdapterSpecificAttribute();

        integrationUtility.logGenericProperty("   ", "Adapter Specific Attribute", genericProperties);

        List <GenericPropertyTable> adapterSpecificTableAttributes = currentChannel.getAdapterSpecificTableAttribute();

        integrationUtility.logGenericPropertyTable("   ", "Adapter Specific Table Attribute", adapterSpecificTableAttributes);

        ModuleProcess moduleProcess = currentChannel.getModuleProcess();

        boolean moduleProcessHeader = false;

        if (moduleProcess != null) {

         List <ProcessStep> processSteps = moduleProcess.getProcessStep();

         if ((processSteps != null) && (processSteps.size() > 0)) for (int index = 0; index < processSteps.size(); index++) {

          if (moduleProcessHeader == false) {

           moduleProcessHeader = true;

           logging.writeMessage("   ModuleProcess", GLBLLogging.MSG_TYPE_DEBUG);

          }

          ProcessStep processStep = processSteps.get(index);

          logging.writeMessage("      Process Step - Module Name (" + processStep.getModuleName() + ") Module Type (" +

            processStep.getModuleType() + ") Parameter Group ID (" + processStep.getParameterGroupID() +

            ")", GLBLLogging.MSG_TYPE_DEBUG);

         }

         List <ParameterGroup> parameterGroups = moduleProcess.getParameterGroup();

         if ((parameterGroups != null) && (parameterGroups.size() > 0)) for (int index = 0; index < parameterGroups.size(); index++) {

          if (moduleProcessHeader == false) {

           moduleProcessHeader = true;

           logging.writeMessage("   ModuleProcess", GLBLLogging.MSG_TYPE_DEBUG);

          }

          ParameterGroup parameterGroup = parameterGroups.get(index);

          logging.writeMessage("      Parameter Group - Parameter Group ID (" + parameterGroup.getParameterGroupID() + ")",

            GLBLLogging.MSG_TYPE_DEBUG);

          List <RestrictedGenericProperty> parameters = parameterGroup.getParameter();

          if ((parameters != null) && (parameters.size() > 0)) for (int index1 = 0; index1 < parameters.size(); index1++) {

           RestrictedGenericProperty parameter = parameters.get(index1);

           logging.writeMessage("         Parameter - Name (" + parameter.getName() + ") Value (" +

             parameter.getValue() + ")", GLBLLogging.MSG_TYPE_DEBUG);

          }

         }

        }

        ChannelAdditionalIdentifier senderIdentifier = currentChannel.getSenderIdentifier();

        if (senderIdentifier != null) {

         logging.writeMessage("   Sender Identifier - Scheme ID (" + senderIdentifier.getSchemeID() + ") Scheme Agency ID (" +

           senderIdentifier.getSchemeAgencyID() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        }

        ChannelAdditionalIdentifier receiverIdentifier = currentChannel.getReceiverIdentifier();

        if (receiverIdentifier != null) {

         logging.writeMessage("   Receiver Identifier - Scheme ID (" + receiverIdentifier.getSchemeID() + ") Scheme Agency ID (" +

           receiverIdentifier.getSchemeAgencyID() + ")", GLBLLogging.MSG_TYPE_DEBUG);

        }

      }

      Author's profile photo Former Member
      Former Member

      Hi Martin,

      I am presently running the above code in NWDS in my system. It would be great if you could give the entire logic along with the utility class as i'm unable to connect to some of the term used in the above code while using in my nwds editor.

      As of now , the code that i'm using to get the communication channel number is as follows:

      1. import
        javax.xml.ws.BindingProvider;

      1. import
        org.apache.poi.xssf.usermodel.XSSFSheet;
      2. import
        org.apache.poi.xssf.usermodel.XSSFWorkbook;

      1. import
        com.sap.xi.basis.CommunicationChannelID;
      2. import
        com.sap.xi.basis.CommunicationChannelQueryIn;

      import com.sap.xi.basis.IntegratedConfigurationIn;

      import com.sap.xi.basis.IntegratedConfigurationInService;

      import com.sap.xi.basis.IntegratedConfigurationQueryIn;

      import com.sap.xi.basis.IntegratedConfigurationQueryOut;

      1. import
        com.sap.xi.basis.CommunicationChannelIn;
      2. import
        com.sap.xi.basis.CommunicationChannelInService;
      3. import
        com.sap.xi.basis.CommunicationChannelQueryOut;

      import com.sap.xi.basis.MessageHeaderID;

      import com.sap.xi.basis.global.LONGDescription;

      import java.io.File;

      import java.io.FileNotFoundException;

      1. import
        java.io.FileOutputStream;

      import java.io.IOException;

      import java.util.Date;

      import java.util.Map;

      import java.util.Set;

      import java.util.TreeMap;

      import org.apache.poi.hssf.usermodel.HSSFCell;

      import org.apache.poi.hssf.usermodel.HSSFCellStyle;

      import org.apache.poi.hssf.usermodel.HSSFDataFormat;

      import org.apache.poi.hssf.usermodel.HSSFRow;

      import org.apache.poi.hssf.usermodel.HSSFSheet;

      import org.apache.poi.hssf.usermodel.HSSFWorkbook;

      import org.apache.poi.hssf.util.HSSFColor;

      1. import
        org.apache.poi.ss.usermodel.Cell;
      2. import
        org.apache.poi.ss.usermodel.Row;

      import org.apache.poi.xssf.usermodel.XSSFSheet;

      import org.apache.poi.xssf.usermodel.XSSFWorkbook;

      public class
      CommunicationChannels {

           private static String apiURL = "/CommunicationChannelInService/CommunicationChannelInImplBean?wsdl=binding&mode=ws_policy";

           private String serverPort = "";

           private String user = "";

           private String password = "";

           private String url = new String();

           private
      CommunicationChannelIn
      port;

           public
      CommunicationChannels() {

              
      setURL(
      serverPort);

               try {

                    port = getPort();

              
      }

               catch (Exception e) {

                   
      e.printStackTrace();

              
      }

           }

           public List
      query() {

              
      CommunicationChannelQueryIn queryIn =
      new CommunicationChannelQueryIn();

              
      CommunicationChannelID msgHdr =
      new
      CommunicationChannelID();    

                queryIn.setCommunicationChannelID(msgHdr);

              
      CommunicationChannelQueryOut queryOut =
      port.query(queryIn);

              
      List lMsgHdr = queryOut.getCommunicationChannelID();

               return lMsgHdr;

              

           }

           private void setURL(String
      serverPort) {

               if (serverPort == null)

                    return;

               else

                    this.url = this.url.concat("http://").concat(serverPort).concat(apiURL);

           }

           private
      CommunicationChannelIn getPort()
      throws Exception{

              
      CommunicationChannelIn port =
      null;

               try {

                   
      CommunicationChannelInService service =
      null;

                   
      service =
      new CommunicationChannelInService();

                   
      port = (CommunicationChannelIn) service.getCommunicationChannelIn_Port();

                  
      BindingProvider bp = (BindingProvider)port;

                  
      bp.getRequestContext().put(BindingProvider.
      USERNAME_PROPERTY, user);

                  
      bp.getRequestContext().put(BindingProvider.
      PASSWORD_PROPERTY, password);

                   if (url.length() != 0)

                       
      bp.getRequestContext().put(BindingProvider.
      ENDPOINT_ADDRESS_PROPERTY, url);

              
      }

               catch (Exception ex){

                   
      ex.printStackTrace();

              
      }

               return port;

           }

           /**

            * @param args

            */

           public static void main(String[]
      args) {

               //TODO
      Auto-generated method stub

              
      CommunicationChannels test =
      new CommunicationChannels();

              
      List listMsgHdr = test.query();

              
      System.
      out.println("Done - number of communication channels = " +
      listMsgHdr.size());

             //Blank
      workbook

              
      XSSFWorkbook workbook =
      new XSSFWorkbook();

                //Create a
      blank sheet

              
      XSSFSheet sheet = workbook.createSheet(
      "Communication Channel ID's");

               //This
      data needs to be written (Object[])

              
      Map<String, Object[]> data =
      new TreeMap<String, Object[]>();

              
      data.put(
      "1", new Object[] {"S.no", "Comm
      Channel"
      , "Number"});

              
      data.put(
      "2", new Object[] {1, "number
      of Comm channels"
      ,+ listMsgHdr.size() });

             //Iterate
      over data and write to sheet

              
      Set<String> keyset = data.keySet();

               int rownum = 0;

               for (String key :
      keyset)

              
      {

              
      Row row = sheet.createRow(rownum++);

              
      Object [] objArr = data.get(key);

               int cellnum = 0;

               for (Object obj :
      objArr)

              
      {

              
      Cell cell = row.createCell(cellnum++);

               if(obj instanceof String)

              
      cell.setCellValue((String)obj);

               else if(obj instanceof Integer)

              
      cell.setCellValue((Integer)obj);

              
      }

              
      }

               try

          
          {

               //Write
      the workbook in file system

              
      FileOutputStream out =
      new FileOutputStream(new File("C:/Java/CommchannelList.xlsx"));

              
      workbook.write(out);

              
      out.close();

              
      System.
      out.println("Comm List written successfully on disk.");

              
      }

                catch (Exception e)

                {

              
      e.printStackTrace();

              
      }

           }

      }

      With the help of the above code i'm able to successfully populate an xls sheet with the number of Comm Channels but unable to read the Comm channel names and attributes.

      Could you please help me out as to at which place , the above method that you mentioned should be called? My requiremnt is to populate the xls with comm channel names and attributes.

      Could you please give methe end to end code along with the utility class that you are using as the above code that you mentioned has references to you own classes which i'm unaware of.How should this metho be called from the main method? The current channel is one of the parameters in this method, from where should this be passed?

      Aprreciate your response and looking forward for any quick help on the same.

      Regards,

      Soundarya

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Okay, here is the snippet of code to get the list of all comm chans and details.  You use query to get the list, then use read to retrieve the detailed info for each.

      public void getCommChanList() {

        CommunicationChannelQueryIn queryIn = new CommunicationChannelQueryIn();

        CommunicationChannelID id = new CommunicationChannelID();

        queryIn.setCommunicationChannelID(id);

        try {

         CommunicationChannelIn port = getPort();

         CommunicationChannelQueryOut queryOut = port.query(queryIn);

         List<CommunicationChannelID> ids = queryOut.getCommunicationChannelID();

         System.out.println(ids.size());

         for (int i=0; i<ids.size(); i++) {

          CommunicationChannel cc = read(ids.get(i), port);

          CommunicationChannelID ccid = cc.getCommunicationChannelID();

          String party = ccid.getPartyID();

          String component = ccid.getComponentID();

          String channel = ccid.getChannelID();

          String transport = cc.getTransportProtocol();

          String msgProtocol = cc.getMessageProtocol();

          DesignObjectID metadata = cc.getAdapterMetadata();

          String adapter = metadata.getName();

          System.out.println("\t" + i + ": " + party +"/" + component + "/" + channel + "\t" + adapter + "|" + transport + "|" + msgProtocol);

         }

        }

        catch (Exception e) {

        

        } 

      }

      public CommunicationChannel read(CommunicationChannelID id, CommunicationChannelIn port) {

        CommunicationChannel cc = null;

        CommunicationChannelReadIn readIn = new CommunicationChannelReadIn();

        ReadContextCode code = ReadContextCode.ACTIVE;

        readIn.setReadContext(code);

        readIn.getCommunicationChannelID().add(id);

       

        CommunicationChannelReadOut readOut = port.read(readIn);

        List<CommunicationChannel> ccList = readOut.getCommunicationChannel();

        for (int i=0; i<ccList.size(); i++) {

         cc = ccList.get(i);

        }

        return cc;

      }

      Author's profile photo Former Member
      Former Member

      Hi William Li,

      Above code works brilliantly.Could you please share code snippet for communication channel change/create as well .

      Thanks

      Regards

      Venkat

      Author's profile photo Former Member
      Former Member

      Venkat. I do not have create code but I do have c ode that will modify a Communication Channel. You have to create a Restricted one first and then modify the fields in the restricted object. We have some code that updates the password and it has some general methods. It is really too big to post here but I can email it.

      The code uses our own logging object and a few other things but you will be able to see how the restricted object is built, modified and saved in the directory.

      Author's profile photo Former Member
      Former Member

      Thanks Larry Martin.

      You can find my mail id  here .Please share that piece of code.

      >>You have to create a Restricted one first and then modify the fields in the restricted object.

      Are you going to create new channel with the existing channel details and then modify it  or just modify the existing channel and activate it ?

      Thanks

      Regards

      Venkat

      Author's profile photo Former Member
      Former Member

      Venkat. Your email shows as private.

      Author's profile photo Former Member
      Former Member

      Sorry,I made it public now

      Author's profile photo Former Member
      Former Member

      Hi Lary,

      I am also working on direcotry API, looking for the same code snippet for midifying the existing communication channels.... Could you please share that piece of code to me. so that i can try that one.

      Thanks in Advance.

      Regards,

      Srikanth Mavuri.

      Author's profile photo Former Member
      Former Member

      Hi Srikanth,

      As per SCN policies ,we shouldn't share our mail id or contact details here .We should make it public in our profile itself if you want to share it to others as I did above.

      Regards

      Venkat

      Author's profile photo sateesh adma
      sateesh adma

      Hello Venkat,

      Can you please share the code, we are trying to change connection parameters.

      Thanks,

      Sateesh

      Author's profile photo Former Member
      Former Member

      Thank you so much William.  The above code worked 🙂

      Author's profile photo Former Member
      Former Member

      Hi William,

      I have a question regarding the apiURL "CommunicationChannelInService/CommunicationChannelInImplBean?wsdl=binding&mode=ws_policy" restrcited to the PI version of the system. For eg. if i intend to use the above code for PI 7.11 Version , the same code which worked for 7.3 is not working for 7.1. Could you please tell me if it is a different aproach to be followed for 7.11 System? Except for the server port , all other details should be the same rite?

      But my code is not working for 7.11. When i run it in NWDS , it starts and says terminated without any errors. What could be the reason?

      Thanks,

      Soundarya

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi,

      The same steps should also work for 7.11, but will not work for 7.1.  7.1 has a different set of Directory API.

      Regards,

      William

      Author's profile photo Former Member
      Former Member

      Ok. Thank you.

      I am trying to use the API for Configuration Scenario objects to print the objects in the Configuration scenario using NWDS.I tried using CongigurationScenarioqueryIn but I'm stuck as to what parameters are to be used to fetch the objects.Is it possible to provide the sample code for this scenario. I need the sample code to fetch the Configuration Scenario objects like Configuration Scenario name Sender system , receiver sytem , sender and reciever communication channels , Receiver determination etc... Which method is to be used to fetch all these objects of a Configuration Scenario. It would be of great help if youc an provide me the sample code to fetch the same.

      Thanks,

      Soundarya

      Author's profile photo Former Member
      Former Member

      Soundarya. The way to find out how to get all of the fields and their detail content so you can list or display them is to look in the com.sap.xi.basis directory for the appropriate object, ConfigurationScenario, in this case. Many of the components are other types you need to look up to see their specific detail fields.

      Using this process you can get any of the component objects you need.

      Author's profile photo Former Member
      Former Member

      Hi William,

      First of all thank you for your great directory API Tutorials!

      Now to my problem:

      I followed your tutorial from above and the local client is working just fine!

      Now I tried to deploy this example as a Web Service (combination of EAR and DirectoryServletTool) on our Netweaver Application Server. I am using NWDS and one Software Component containing two Development Components.

      The error "JAX-WS deployable proxy is instantiated with 'new' instead of been injected. Cannot find WSDL URL for service [class com.sap.xi.basis.IntegratedConfigurationInService]" occures in the method "getPort".

      Can you give me a hint on how to resolve this issue?

      Thank you in advance!

      Regards,

      Dennis

      Author's profile photo Shiladitya Sarkar
      Shiladitya Sarkar

      Hi Dennis,

      Did you manage to get a solution for your problem. I'm trying to use the DirAPI from within a receiver java proxy and receiving the exact same error as described by you.

      Regards,

      Shiladitya

      Author's profile photo Gabriel Sagaya Paneer Selvam
      Gabriel Sagaya Paneer Selvam

      Hi William,

      I am trying to extract the entire Integrated Configuration object (ICO) names from Integration Directory API instead of total count of ICO objects. Could you please help me on that.

      Regards

      Gabriel

      Author's profile photo Raghu Vamseedhar Reddy Kadipi Reddy
      Raghu Vamseedhar Reddy Kadipi Reddy
      Author's profile photo Tiago Soares
      Tiago Soares

      Hi Ragbu.

      Is it possible to get, the object ID associated with a given Integrated Configuration via this service?

      I'm trying to get WSDL of a given ICO and only way that I can think of is via object ID. Is there any other way?

      Thanks

      Author's profile photo Frank Adams
      Frank Adams

      Hi,

      first of all: no, you cannot retrieve an ICO's object ID by using Directory API.

      But you can get the ICO WSDL by specifying the full ICO key, e.g.

      http://<your host>:<your_http_port>/dir/wsdl?ot=ic&senderParty=<ICO sender party>&senderService=<ICO sender service>&receiverParty=<ICO virtual receiver party>&receiverService=<ICO virtual receiver service>&interface=<ICO sender interface name>&interfaceNamespace=<ICO sender interface namespace>

      Please also check the various examples in http://<your host>:<your_http_port>/dir/wsdl.

      Further notes:

      - Just use empty string for empty key fields, e.g. for empty sender party: .... /dir/wsdl?ot=ic&senderParty=&senderService=<ICO sender service>&.....

      - You do not need to URL encode the namespace parameter, but it will also work with the encoded value

      Best regards,

      Frank

      Author's profile photo Tiago Soares
      Tiago Soares

      Thank you so much Frank.

      That worked perfectly... Fantastic stuff

      Author's profile photo Former Member
      Former Member

      You can get the list of ICO's using the most recent version of the Directory API's. We have an interface that is doing it every day in both single stack and dual stack. We are no 7.4 in both environments.

      Author's profile photo Fatih Eren
      Fatih Eren

      Hello William,

      can you say me how I get the ObjectID of the ICO with the Directory API?

       

       

      Author's profile photo Vijay Kamath
      Vijay Kamath

      Hi All,

      I am using directory API to update my REST receiver channel.  When I use this from SOAPUI, it works perfectly fine and I am able to change value of any field.  However when I try to do the same action using ABAP Program (using Consumer Proxy), I get the following error - 'Enter a value for attribute 'Transport Protocol Version'.

      I have not entered any value for this field in SOAP UI and in the ABAP program.  I have also validated with Adapter Metadata and the value is blank for this field.

      Appreciate if somebody can help me out with this.

       

       

      Author's profile photo p.bharat kharate
      p.bharat kharate

      Hello Everyone,

       

      I have followed the given steps and tried to execute the given program but It's giving me an error stating  "Exception in thread "main" java.lang.NoClassDefFoundError: com/sap/security/hardener/nw/facade/HardenerFacade". I tried to search for possible solution but I am not able to solve this issue. Please help me out with this issue.

      Refer the error thread snap attached below.

       It'll be really helpful if you provide your expertise to solve this issue.

       

      Thanks