[SalesForce] Invoking SAP SOAP Webservice from Salesforce(Callout)

We have integration from Salesforce to SAP PI where salesforce invokes Soap web service exposed by SAP PI. We received wsdl provided by SAP PI and Apex was generated out of it. Please help in the following two issues that we are facing while connecting to sap pi:

  1. How do we provide the credentials(Username, password of SAP PI system) while invoking it from Salesforce? The same were provided as part of Request properties in SOAPUI
  2. How do we attach a file while invoking the service? In Soapui it was given under Attachments header.

Please find below the generated Apex from the wsdl that we received:

//Generated by wsdl2apex

public class PIService {
    public class DT_SFDC_FIC_Report_Req {
        public PIService.inputdoc_element inputdoc;
        private String[] inputdoc_type_info = new String[]{'inputdoc','http://salesforce.com/FIC',null,'1','1','false'};
        private String[] apex_schema_type_info = new String[]{'http://salesforce.com/FIC','false','false'};
        private String[] field_order_type_info = new String[]{'inputdoc'};
    }
    public class category_element {
        public PIService.attribute_element[] attribute;
        public String name;
        private String[] attribute_type_info = new String[]{'attribute','http://salesforce.com/FIC',null,'0','-1','false'};
        private String[] name_att_info = new String[]{'name'};
        private String[] apex_schema_type_info = new String[]{'http://salesforce.com/FIC','false','false'};
        private String[] field_order_type_info = new String[]{'attribute'};
    }
    public class inputdoc_element {
        public PIService.category_element[] category;
        public String location;
        public String title;
        public String file;
        public String mimetype;
        public String createdby;
        public String created;
        public String modified;
        public String description;
        public String correlationid;
        public String source;
        public String Assigned_to_Group;
        public String appuserid;
        public String apppwd;
        public String siteid;
        public String type_x;
        public String action;
        private String[] category_type_info = new String[]{'category','http://salesforce.com/FIC',null,'0','-1','false'};
        private String[] location_type_info = new String[]{'location','http://salesforce.com/FIC',null,'1','1','false'};
        private String[] title_type_info = new String[]{'title','http://salesforce.com/FIC',null,'1','1','false'};
        private String[] file_type_info = new String[]{'file','http://salesforce.com/FIC',null,'1','1','false'};
        private String[] mimetype_type_info = new String[]{'mimetype','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] createdby_type_info = new String[]{'createdby','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] created_type_info = new String[]{'created','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] modified_type_info = new String[]{'modified','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] description_type_info = new String[]{'description','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] correlationid_type_info = new String[]{'correlationid','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] source_type_info = new String[]{'source','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] Assigned_to_Group_type_info = new String[]{'Assigned_to_Group','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] appuserid_type_info = new String[]{'appuserid','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] apppwd_type_info = new String[]{'apppwd','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] siteid_type_info = new String[]{'siteid','http://salesforce.com/FIC',null,'1','1','false'};
        private String[] type_x_att_info = new String[]{'type'};
        private String[] action_att_info = new String[]{'action'};
        private String[] apex_schema_type_info = new String[]{'http://salesforce.com/FIC','false','false'};
        private String[] field_order_type_info = new String[]{'category','location','title','file','mimetype','createdby','created','modified','description','correlationid','source','Assigned_to_Group','appuserid','apppwd','siteid'};
    }
    public class message_element {
        public PIService.node_element node;
        public String statuscode;
        public String statusmessage;
        public String correlationid;
        private String[] node_type_info = new String[]{'node','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] statuscode_type_info = new String[]{'statuscode','http://salesforce.com/FIC',null,'1','1','false'};
        private String[] statusmessage_type_info = new String[]{'statusmessage','http://salesforce.com/FIC',null,'1','1','false'};
        private String[] correlationid_type_info = new String[]{'correlationid','http://salesforce.com/FIC',null,'1','1','false'};
        private String[] apex_schema_type_info = new String[]{'http://salesforce.com/FIC','false','false'};
        private String[] field_order_type_info = new String[]{'node','statuscode','statusmessage','correlationid'};
    }
    public class item_element {
        public String name;
        private String[] name_att_info = new String[]{'name'};
        private String[] apex_schema_type_info = new String[]{'http://salesforce.com/FIC','false','false'};
        private String[] field_order_type_info = new String[]{};
    }
    public class attribute_element {
        public String name;
        private String[] name_att_info = new String[]{'name'};
        private String[] apex_schema_type_info = new String[]{'http://salesforce.com/FIC','false','false'};
        private String[] field_order_type_info = new String[]{};
    }
    public class DT_SFDC_FIC_Report_Resp {
        public PIService.message_element message;
        private String[] message_type_info = new String[]{'message','http://salesforce.com/FIC',null,'1','1','false'};
        private String[] apex_schema_type_info = new String[]{'http://salesforce.com/FIC','false','false'};
        private String[] field_order_type_info = new String[]{'message'};
    }
    public class node_element {
        public PIService.category_element[] category;
        public String location;
        public String title;
        public String file;
        public String mimetype;
        public String createdby;
        public String created;
        public String modified;
        public String description;
        public String objectid;
        public String type_x;
        public String action;
        private String[] category_type_info = new String[]{'category','http://salesforce.com/FIC',null,'0','-1','false'};
        private String[] location_type_info = new String[]{'location','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] title_type_info = new String[]{'title','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] file_type_info = new String[]{'file','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] mimetype_type_info = new String[]{'mimetype','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] createdby_type_info = new String[]{'createdby','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] created_type_info = new String[]{'created','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] modified_type_info = new String[]{'modified','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] description_type_info = new String[]{'description','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] objectid_type_info = new String[]{'objectid','http://salesforce.com/FIC',null,'0','1','false'};
        private String[] type_x_att_info = new String[]{'type'};
        private String[] action_att_info = new String[]{'action'};
        private String[] apex_schema_type_info = new String[]{'http://salesforce.com/FIC','false','false'};
        private String[] field_order_type_info = new String[]{'category','location','title','file','mimetype','createdby','created','modified','description','objectid'};
    }
    public class HTTPS_Port {
        public String endpoint_x = 'XXX Endpoint';
        public Map<String,String> inputHttpHeaders_x;
        public Map<String,String> outputHttpHeaders_x;
        public String clientCertName_x;
        public String clientCert_x;
        public String clientCertPasswd_x;
        public Integer timeout_x;
        private String[] ns_map_type_info = new String[]{'http://salesforce.com/FIC', 'PIService'};
        public PIService.message_element SI_SFDC_FIC_Report_OB(PIService.inputdoc_element inputdoc) {
            PIService.DT_SFDC_FIC_Report_Req request_x = new PIService.DT_SFDC_FIC_Report_Req();
            request_x.inputdoc = inputdoc;
            PIService.DT_SFDC_FIC_Report_Resp response_x;
            Map<String, PIService.DT_SFDC_FIC_Report_Resp> response_map_x = new Map<String, PIService.DT_SFDC_FIC_Report_Resp>();
            response_map_x.put('response_x', response_x);
            WebServiceCallout.invoke(
              this,
              request_x,
              response_map_x,
              new String[]{endpoint_x,
              'http://sap.com/xi/WebService/soap1.1',
              'http://salesforce.com/FIC',
              'MT_SFDC_FIC_Report_Req',
              'http://salesforce.com/FIC',
              'MT_SFDC_FIC_Report_Resp',
              'PIService.DT_SFDC_FIC_Report_Resp'}
            );
            response_x = response_map_x.get('response_x');
            return response_x.message;
        }
    }
}

From SOAPUi, the service invokation was successful, PFB the screenshot:

enter image description here

As you see from the above image,

  1. The SAP PI credentials were given under Request properties(highlighted in the screenshot)
  2. A pdf is attached under Attchments(next to Headers)(highlighted in the screenshot). The service takes pdf Attachment as input.
  3. Expecting a Certificate is provided to Salesforce by PI
    How do we write code for above 3 points while writing callout in Salesforce.

Please let us know how to include code for the above 3 points in the below code for making successful callout:

PIService.HTTPS_Port service = new PIService.HTTPS_Port();
PIService.inputdoc_element input = new PIService.inputdoc_element();
PIService.message_element response = new PIService.message_element();
service.inputHttpHeaders_x = new Map<String,String>();
String username = 'SapPIUsername';
String password = 'SapPIPassword';  
Blob headerValue = Blob.valueOf(username + ':' + password);
String authorizationHeader = 'BASIC ' +EncodingUtil.base64Encode(headerValue);
service.inputHttpHeaders_x.put('Authorization',authorizationHeader);
input.siteid='1171';
input.title='abc.pdf';
input.file='abcd.pdf';
input.correlationid='33';
input.mimetype='application/pdf';
input.source='SFDC';
response = service.SI_SFDC_FIC_Report_OB(input);
System.debug(response);

Thanks a lot.

Best Answer

The SAP PI credentials were given under Request properties

This would be flowing through to the Authorization HTTP header. You can do this via the inputHttpHeaders_x on the service proxy class. See Using Basic Authentication with Web Services

A pdf is attached under Attchments(next to Headers)(highlighted in the screenshot). The service takes pdf Attachment as input.

SOAP API would be adding the file as a MIME-based attachment. See Attachments and Inline Files. As far as I know there is no native support for this via wsdl2apex and the corresponding WebServiceCallout.invoke method.

You will need to resort to doing a raw HTTP request from Apex and manually encoding the Content-Type, boundary, etc... This is no easy task in Apex because it doesn't have native support for encoding multipart requests. I'm currently working on a post about a similar challenge that I'll try and remember to like from here when it is complete. You can manually build out the multipart/form-data POST body in Apex by carefully handling the Base64 padding characters. See Steps required to support POSTing multipart/form-data Content-Type from Apex

Expecting a Certificate is provided to Salesforce by PI

See Using Certificates with SOAP Services

Related Topic