1

I'm trying to integrate my rails app with a Sql Server Reports Services (SSRS) using Savon 2.11.1. I'm using the ReportServicesExecution2005 WSDL. The problem I have is that I have to add a session_id to the soap header after the client has been instantiated. This is because the session_id is generated by SSRS after the client makes a call to load_report.

client = Savon.client(wsdl: "https://somewsdl.asmx?wsdl", basic_auth: ["user", "pass"])

this call returns the session_id in the response:

response = client.call(:load_report, message: {report: "path/to/report"} ) 

the soap header needs to contain the session_id in the client when this call is made:

client.call(:set_execution_parameters, message: { report: "path/to/report", parameters: params  }  )

Tried this but it didn't work:

client.call(:set_execution_parameters, soap_header: {"session_id" => @session_id}, message: { report: "path/to/report", parameters: params  }  ) 

I get the following error:

(soap:Client) The session identifier is missing. A session identifier is required for this operation. ---> Microsoft.ReportingServices.Diagnostics.Utilities.MissingSessionIdException: The session identifier is missing. A session identifier is required for this operation.

Thanks for the help an advance.

user2967603
  • 139
  • 12

2 Answers2

0

You should use the soap_header hash to pass session id like

response = client.call(:set_execution_parameters, :soap_header => { :session_id => sid })

Cheers

Abid Iqbal
  • 753
  • 8
  • 22
  • This only sets the soap_header in locals and Savon passes globals in client.rd. I'm still getting the same error and session_id is still blank in the soap_header when I try your solution. – user2967603 Aug 03 '16 at 20:00
0

The solution I found(while clunky) was to create a new client via Savon and pass the existing client values plus the new execution_id/session_Id into the constructor. This did the trick. Code example below.

Initial Savon Client:

@exeClient = Savon.client(wsdl: "some_wsdl.asmx?wsdl", basic_auth: ["user", "pass"], 
convert_request_keys_to: :camelcase, soap_header: {"execution_id" => ""} ) 

call load_report to get execution_id:

@data = @exeClient.call(:load_report, message: {report: "/path/to/report"} )

Access execution_id:

@report = @data.to_hash

@execution_id = @report[:load_report_response][:execution_info][:execution_id]

Create new client that has access to run the report via the execution_id:

@newClient = Savon.client(wsdl: "/path/to/report/wsdl", basic_auth: ["user", "pass"], 
 :soap_header => {:"tns:TrustedUserHeader" => {"tns:UserName"=> "" , "tns:UserToken" => ""},  :"tns:ExecutionHeader" => {"tns:ExecutionID" => @execution_id}}) 

Create Params Hash:

param1 = { :Parameter_value =>{
    :"Name" => "nameOfParam",
    :"Value" => current_user.company_id
  }
}

Call setExecutionParameters:

response =  @newClient.call(:set_execution_parameters, message: { "Parameters" => param1} )

Now it works. Note that its important how you specify namespaces with Savon. If you don't do it correctly, the namespace will not be specified on some tags; which will make the soap call fail.

user2967603
  • 139
  • 12
  • I also want to point out that the "TrustedUserHeader" and all sub tags were requires to make this work regardless if they were blank or not. – user2967603 Aug 15 '16 at 20:00