Bloomberg Data License web services access from Powershell - powershell

I have a X509 certificate (e.g. C:\Cert\BBcert.pl2) and a password (e.g. "XYZ") with which I should use to authenticate and the DLWS here https://service.bloomberg.com/assets/dl/dlws.wsdl
I can use a SOAP GUI client to connect and do some queries but how do I go about using the certificate, password and link above in powershell so I can send some queries?
If anyone has used the Bloomberg Data License Web Services and can provide a complete example how to fetch some pricing data?

Start with:
curl --cert .\BloombergDLWS.p12:MyP#$$w0rd -H "Content-Type: text/xml;charset=utf-8" -H 'SOAPAction: \"submitGetDataRequest\"' -d "#submitGetDataRequest.xml" --request-target 'https://dlws.bloomberg.com/dlps' --url 'https://dlws.bloomberg.com/dlps'
Three notes about the CURL command:
The request-target flag is necessary. Otherwise it sends POST /dlps HTTP/1.1 instead of POST /dlps HTTP/1.1 and results in a 502 BAD GATEWAY error.
Escape the SOAPAction quotes, otherwise you get Failed to convert request to BAS: Failed to find action index for SOAP action 'submitGetDataRequest' when converting SOAP request for service ID 125322
Read the SOAP envelope XML from a file. Inline XML, besides vastly inflating the command length, generated a ParseError even though I had copied it in carefully as one line.
Where submitGetDataRequest.xml contains
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://services.bloomberg.com/datalicense/dlws/ps/20071001">
<soapenv:Header/>
<soapenv:Body>
<ns:submitGetDataRequest>
<ns:headers>
<ns:secmaster>true</ns:secmaster>
</ns:headers>
<ns:fields>
<ns:field>NAME</ns:field>
<ns:field>TICKER</ns:field>
<ns:field>CPN</ns:field>
<ns:field>MATURITY</ns:field>
<ns:field>ID_BB_GLOBAL</ns:field>
</ns:fields>
<ns:instruments>
<ns:instrument>
<ns:id>912810CY2</ns:id>
<ns:type>CUSIP</ns:type>
</ns:instrument>
</ns:instruments>
</ns:submitGetDataRequest>
</soapenv:Body>
</soapenv:Envelope>
This returns a response that doesn't contain the data you want, but it does include a responseId code to use in a second request.
<?xml version="1.0" encoding="UTF-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<dlws:submitGetDataResponse xmlns='http://services.bloomberg.com/datalicense/dlws/ps/20071001'
xmlns:dlws="http://services.bloomberg.com/datalicense/dlws/ps/20071001"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<dlws:statusCode>
<dlws:code>0</dlws:code>
<dlws:description>Success</dlws:description>
</dlws:statusCode>
<dlws:requestId>01234567-89AB-CDEF-0123-456789ABCDEF</dlws:requestId>
<dlws:responseId>ABCDEF0123-4567890AB</dlws:responseId>
</dlws:submitGetDataResponse>
</soap:Body>
</soap:Envelope>
You must insert the responseId code into another request like so (saved as retrieveGetDataResponse.xml):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://services.bloomberg.com/datalicense/dlws/ps/20071001">
<soapenv:Header/>
<soapenv:Body>
<ns:retrieveGetDataRequest>
<ns:responseId>ABCDEF0123-4567890AB</ns:responseId>
</ns:retrieveGetDataRequest>
</soapenv:Body>
</soapenv:Envelope>
Wait a few minutes, then submit the final request, saving your data as DataResponse.xml:
curl --cert .\BloombergDLWS.p12:MyP#$$w0rd -H "Content-Type: text/xml;charset=utf-8" -H 'SOAPAction: \"retrieveGetDataResponse\"' -d "#retrieveGetDataResponse.xml" --request-target 'https://dlws.bloomberg.com/dlps' --url 'https://dlws.bloomberg.com/dlps' -o DataResponse.xml
Submitting this request too soon will return a result that basically says it's not ready, try again later.

Related

gSOAP: How to use SOAP instead of POST for specific service/schema

First off, let me apologize, because I don't know much about SOAP and most of what I'm saying is probably nonsense.
I upgraded some client-side code that was generated using gSoap 2.8.4 to gSoap 2.8.93
As far as I can tell, the program only sends one request to the server. Previously this request was wrapped in
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="bmf.gv.at:pkt/PKTSoap" xmlns:ns1="bmf.gv.at:pkt" xmlns:ns3="bmf.gv.at:pkt/PKTSoap12">
<SOAP-ENV:Body>
...
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
However with the code generated by the new version this envelope is missing. I understand that this is because the request is generated as a REST request instead of a SOAP one. I've found threads that talk about the //gsoap directive for the service setting the method-protocol to SOAP instead of POST, but I can only find these directives for requests to the sub-services /PKTSoap and /PKTSoap12, not to the root service bmf.gv.at:pkt, to which the request is sent. In fact that is not even called a service in the code, it's called a schema. And the requests to it are called top-level root elements of the schema. They are all automatically generated as REST requests.
My question is how can I instruct gSoap to generate all requests as SOAP1.1 requests? Any help whatsoever is greatly appreciated.
WSDL: https://pastebin.com/bmC8Hx6M
typemap.dat is the default one with the following appended:
ns1 = "bmf.gv.at:pkt"
ns2 = "bmf.gv.at:pkt/PKTSoap"
ns3 = "bmf.gv.at:pkt/PKTSoap12"
And I use the following commands to generate:
wsdl2h.exe -c -g -N ns %1.wsdl
soapcpp2.exe -c -C -I./import -1 %1.h
It is not clear from your question which request messages do not include the envelope.
Here is a quick way to test the generated source code, to verify that the SOAP1.1 envelope and body are included (I've used C++ here):
wsdl2h -L -g -N ns service.wsdl
soapcpp2 -1 -C -I import service.h
A small demo client, to test the request message:
#include "soapH.h"
#include "PKTSoap.nsmap"
int main()
{
struct soap *soap = soap_new1(SOAP_XML_INDENT);
_ns1__DatenpoolkontoErzeugen req;
_ns1__Verarbeitung res;
req.soap_default(soap);
soap_call___ns2__PKTDatenpoolkontoErzeugen(soap, "http://", NULL, &req, res);
}
Compiled with:
c++ -o service service.cpp soapC.cpp soapClient.cpp stdsoap2.cpp
Then run:
$ ./service
POST / HTTP/1.1
Host:
User-Agent: gSOAP/2.8
Content-Type: text/xml; charset=utf-8
Content-Length: 526
Connection: close
SOAPAction: "bmf.gv.at:pkt/PKTDatenpoolkontoErzeugen"
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="bmf.gv.at:pkt/PKTSoap" xmlns:ns1="bmf.gv.at:pkt" xmlns:ns3="bmf.gv.at:pkt/PKTSoap12">
<SOAP-ENV:Body>
<ns1:DatenpoolkontoErzeugen>
<ns1:Absender xsi:nil="true"/>
</ns1:DatenpoolkontoErzeugen>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This shows that bmf.gv.at:pkt requests are sent exactly as specified in the WSDL.

Call server-signing service with Base64 encoded certificate in DSS

I need to execute tok:sign request of DSS with a given certificate instead of an alias.
<alias>certificate</alias>
I tried to replace below one with a base64 string, but got following error in log.
INFO | http-nio-8080-exec-3 |
o.a.cxf.services.SoapSignatureTokenConnection.FAULT_OUT | FAULT_OUT
Sample, original SOAP request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tok="http://token.dss.esig.europa.eu/">
<soapenv:Header/>
<soapenv:Body>
<tok:sign>
<toBeSigned>
<bytes>wFNeS+K3n/2TKRMFQ2v4iTFOSj+uwF7P/Lt98xrZ5Ro=</bytes>
</toBeSigned>
<digestAlgorithm>SHA256</digestAlgorithm>
<alias>certificate</alias>
</tok:sign>
</soapenv:Body>
</soapenv:Envelope>
I already added certificate to cacerts file, but unable to retrieve with getKeys SOAP request. Or on the other way, how could I add a new p12 to server-side to make it available by an alias?
p12 file is configurable in dss.properties file, base64 directly in request isn't supported:
Server signing token
dss.server.signing.keystore.type = PKCS12
dss.server.signing.keystore.filename = user_a_rsa.p12
dss.server.signing.keystore.password = password
In case of demo-webapp root of dss-demonstrations repository has to be rebuilt(mvn clean install) to put a new signing certificate to webapp.

create soap request string with xmlbeans and axis2

i have a web service client which uses axis2 1.6.1, xmlbeans. It works fine.
Now, i want to create a string of soap request message (not only a xml string but also a soap string) from request object.
Please help.
(using jaxb or cxf are not options for this project)
Ok, i worked it out. After you have xmlbean object, just do string concatenate between soap envelope and xmlObject.toXML().
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.qwest.com/XMLSchema" >
<soapenv:Header/>
<soapenv:Body>
+ xmlObject.toXML()
+ </soapenv:Body>
</soapenv:Envelope>

SOAP endpoint in WSO2 APIM fails with null pointer exception

I'm trying to add a SOAP API to APIM 1.10.0.
First, I'll try to test the SOAP service itself, using the following CURL. The service should return weather conditions of a given city/country:
curl -X POST -T soap.xml -H "Content-Type: text/xml" \
"http://www.webservicex.net/globalweather.asmx"
Providing the following soap.xml:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetWeather xmlns="http://www.webserviceX.NET">
<CityName>Eilat</CityName>
<CountryName>Israel</CountryName>
</GetWeather>
</soap:Body>
</soap:Envelope>
I receive a sensible response!
Now I introduce this service to APIM, as follows:
- Add new API
- I have a SOAP endpoint
- WSDL URL: http://www.webservicex.net/globalweather.asmx?wsdl
- Start Creating
- Name: eilat
- Context: /eilat
- Version: 1.0.0
- WSDL: http://www.webservicex.net/globalweather.asmx?wsdl [tested ok]
- Production Endpoint: http://www.webservicex.net/globalweather.asmx [valid]
- Tier Availability: Unlimited
I subscribe to this API, and try the following CURL
curl -H "Authorization: Bearer <my-key>" -X POST -T soap.xml \
-H "Content-Type: text/xml" http://localhost:8280/eilat/1.0.0
I get the following reply:
<faultstring>unknown</faultstring>
Trying the same in SOAP UI, I get:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>unknown</faultstring>
<detail/>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
With #status#: HTTP 1.1/500 Internal Server Error
Looking at the logs:
1) http_access_2016-01-17.log
127.0.0.1 - - [17/Jan/2016:16:53:34 +0200]
"POST /eilat/1.0.0 HTTP/1.1" - 482 "-"
"curl/7.19.7 (x86_64-redhat-linux-gnu)
libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
2) wso2-apigw-errors.log
2016-01-17 16:53:34,364 [-] [PassThroughMessageProcessor-374]
ERROR ServerWorker Error processing
POST reguest for :
/eilat/1.0.0. Error detail: null. java.lang.NullPointerException
3) wso2carbon.log
INFO {org.apache.synapse.rest.API} -
Initializing API: admin--eilat:v1.0.0 {org.apache.synapse.rest.API}
INFO {org.wso2.carbon.core.services.util.CarbonAuthenticationUtil} -
'admin#carbon.super [-1234]' logged in at [2016-01-17 16:52:51,282+0200]
{org.wso2.carbon.core.services.util.CarbonAuthenticationUtil}
ERROR {org.apache.synapse.transport.passthru.ServerWorker} -
Error processing POST reguest for : /eilat/1.0.0.
Error detail: null.
{org.apache.synapse.transport.passthru.ServerWorker}
java.lang.NullPointerException
Looking at the API again, I see that WSDL URL is changed from the URL I provided, to the following:
/registry/resource/_system/governance/apimgt/applicationdata/wsdls/admin--eilat1.0.0.wsdl
I guess this is normal behavior.
Question is - why the Null Pointer Exception?
Error was caused due to a custom authentication plugin handler.
Removing this handler from the chain of handlers solved the problem.

Setting Schema Structure for Proxy Service(CFX) exposed using Mule ESB

I am very new to Mule ESB. I want to expose a Mule flow as an WebService to an external applicaton. How to set the request(payload) structure in the wsdl exposed by mule?
Am using CFX for it.
Currently my request while loading WSDL in SoapUI looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sup="http://support.cxf.module.mule.org/">
<soapenv:Header/>
<soapenv:Body>
<sup:invoke>
<sup:arg0>?</sup:arg0>
</sup:invoke>
</soapenv:Body>
</soapenv:Envelope>
Actual request expected to be is as follows:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://pcom.orga.com/pc/webservices/messages/v1">
<soapenv:Header/>
<soapenv:Body>
<v1:searchOfferRequest>
<searchInput>
<status>RELEASED</status>
</searchInput>
</v1:searchOfferRequest>
</soapenv:Body>
</soapenv:Envelope>
Have a look at Mule documentation for exposing a SOAP service in Mule, specifically look for the section "Creating a WSDL First JAX-WS Service" which has an example of what you are looking for.
HTH