My colleague had a problem in trying to access a SOAP web service. Specifically, he needed to provide extended SOAP headers in regards to the security requirements, a SAML assertion in this case, and the standard Informatica Web Transformation wasn't doing much for him.
We discovered that this is quite easy to accomplish by way of a Java Transformation instead. So here's how we did it.
In informatica, create the Java Transformation. The below illustration depicts it between two other transformations, and we can see how the input and output values are transferred between them.
Please pardon the use of the Danish language; I hope the gist of it will suffice.
The below picture further illustrates the input and output ports of the Java transformation. These exact names are immediately available to us from the Java code we write.
Now, let's add the Java-code specific to the task of calling a SOAP web-service with headers and all.
We have multiple tabs available on the transformation - I used only the 'On Input Row' and 'Import Packages'.
In 'Import Packages', specify the Java imports required to perform the task. For my use-case, these were sufficient:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
Given these imports, we can go ahead and add the Java code in the 'On Input Row' tab. Please forgive the wall of text; I felt it was important to include the complete SOAP request, headers and body and all, for the sake of completeness.
try {
logInfo("Sending soap request");
String FagsystemNavn = fagsystemnavn_Input;
String KundeNummer = kundenummer_Input;
String MeddelelseTypeNummer = meddelelsetypenummer_Input;
String KanalTypeNummer = kanaltypenummer_Input;
Integer currentTimeInSeconds = (int) (System.currentTimeMillis() / 1000);
String MeddelelseBatchId = currentTimeInSeconds.toString();
String soapTemplate = "<soapenv:Envelope
xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"
xmlns:ns=\"http://skat.dk/begrebsmodel/2009/01/15/\">\n"
+ " <soapenv:Header>\n"
+ " <wsse:Security soapenv:mustUnderstand=\"1\"
xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/
oasis-200401-wss-wssecurity-secext-1.0.xsd\">\n"
+ " <Assertion AssertionID=\"d913c046fddbca7a55fca34caf18cafa\"
IssueInstant=\"2007-05-14T11:45:21.835Z\" Issuer=\"test.unsigned\"
MajorVersion=\"1\" MinorVersion=\"1\"
xmlns=\"urn:oasis:names:tc:SAML:1.0:assertion\"
xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\"
xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\">\n"
+ " <Conditions NotBefore=\"2007-05-14T11:43:21.834Z\"
NotOnOrAfter=\"2112-05-14T11:43:21.834Z\"/>\n"
+ " <AuthenticationStatement
AuthenticationInstant=\"2007-05-14T11:45:21.834Z\"
AuthenticationMethod=\"urn:oasis:names:tc:SAML:1.0:am:unspecified\">\n"
+ " <Subject>\n"
+ " <NameIdentifier Format=\"urn:oasis:names:
tc:SAML:1.1:nameid-format:unspecified\"
NameQualifier=\"skat\">skatGuid=wEFI04,ou=skatEmployee,ou=internal,
ou=entities,dc=skat,dc=dk</NameIdentifier>\n"
+ " <SubjectConfirmation>\n"
+ " <ConfirmationMethod>urn:oasis:names:
tc:SAML:1.0:cm:sender-vouches</ConfirmationMethod>\n"
+ " </SubjectConfirmation>\n" + "
</Subject>\n"
+ " </AuthenticationStatement>\n" + "
<AttributeStatement>\n"
+ " <Subject>\n"
+ " <NameIdentifier
Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\"
NameQualifier=\"skat\">skatGuid=wEFI04,ou=skatEmployee,ou=internal,
ou=entities,dc=skat,dc=dk</NameIdentifier>\n"
+ " <SubjectConfirmation>\n"
+ " <ConfirmationMethod>urn:oasis:names:
tc:SAML:1.0:cm:sender-vouches</ConfirmationMethod>\n"
+ " </SubjectConfirmation>\n" + "
</Subject>\n"
+ " <Attribute AttributeName=\"Groups\"
AttributeNamespace=\"urn:bea:security:saml:groups\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"
+ " <AttributeValue>
PRIMARY_IDENTITY_skatGuid=14a2d120-bbda-4b62-aa27-1bbd8751f47f,
ou=skatSystem,ou=internal,ou=entities,dc=skat,dc=dk</AttributeValue>\n"
+ " <AttributeValue>AUTH_LEVEL_6</AttributeValue>\n"
+ " <AttributeValue>EFISagsbehandlerPRG</AttributeValue>\n"
+ " </Attribute>\n" + " </AttributeStatement>\n"
+ " </Assertion>\n" + " </wsse:Security>\n" +
" </soapenv:Header>\n"
+ " <soapenv:Body>\n" + "
<ns:MeddelelseMultiSend_I>\n" +
" <ns:Kontekst>\n"
+ " <tsk:HovedOplysninger
xmlns:tsk=\"http://skat.dk/begrebsmodel/xml/schemas/kontekst/2007/05/31/\">\n"
+ " <tsk:TransaktionsID>A12345678ZZ</tsk:TransaktionsID>\n"
+ " <tsk:TransaktionsTid>2010-10-14T13:30:47</tsk:TransaktionsTid>\n"
+ " </tsk:HovedOplysninger>\n" + " </ns:Kontekst>\n"
+ " <ns:FagsystemNavn>${FagsystemNavn}</ns:FagsystemNavn>\n"
+ " <ns:MeddelelseBatchID>${MeddelelseBatchId}</ns:MeddelelseBatchID>\n"
+ " <ns:Meddelelser>\n" + " <ns:Meddelelse>\n"
+ " <ns:MeddelelseIndhold>\n" + "\n"
+ " <ns:DIASMeddelelseAnmodningSambeskatningStruktur>\n"
+ " <ns:Aktør>\n"
+ " <ns:VirksomhedNavnFirmaNavn>Et_Aktø
r_Firmanavn</ns:VirksomhedNavnFirmaNavn>\n"
+ " <ns:VirksomhedCVRNummer>12345677
</ns:VirksomhedCVRNummer>\n"
+ " </ns:Aktør>\n" + "
<ns:SelskabListe>\n"
+ " <ns:Selskab>\n"
+ " <ns:VirksomhedNavnFirmaNavn>Et_Selskab_Firmanavn1
</ns:VirksomhedNavnFirmaNavn>\n"
+ " <ns:VirksomhedCVRNummer>11111111
</ns:VirksomhedCVRNummer>\n"
+ " </ns:Selskab>\n" + "
<ns:Selskab>\n"
+ " <ns:VirksomhedNavnFirmaNavn>
Et_Selskab_Firmanavn2</ns:VirksomhedNavnFirmaNavn>\n"
+ " <ns:VirksomhedCVRNummer>22222222
</ns:VirksomhedCVRNummer>\n"
+ " </ns:Selskab>\n" + "
<ns:Selskab>\n"
+ " <ns:VirksomhedNavnFirmaNavn>Et_Selskab_Firmanavn3
</ns:VirksomhedNavnFirmaNavn>\n"
+ " <ns:VirksomhedCVRNummer>33333333
</ns:VirksomhedCVRNummer>\n"
+ " </ns:Selskab>\n" + "
</ns:SelskabListe>\n"
+ " <ns:SelskabSambeskatningÆndringStartDato>2014-04-11
</ns:SelskabSambeskatningÆndringStartDato>\n"
+ " </ns:DIASMeddelelseAnmodningSambeskatningStruktur>\n" + "\n"
+ " </ns:MeddelelseIndhold>\n"
+ " <ns:MeddelelseTypeNummer>${MeddelelseTypeNummer}
</ns:MeddelelseTypeNummer>\n"
+ " <ns:MeddelelseAfsenderReference>99</ns:MeddelelseAfsenderReference>\n"
+ " <ns:KundeNummer>${KundeNummer}</ns:KundeNummer>\n"
+ " <ns:MeddelelseOprettetAfMedarbejder>w95641
</ns:MeddelelseOprettetAfMedarbejder>\n"
+ " <ns:KanalTypeNummer>${KanalTypeNummer}
</ns:KanalTypeNummer>\n"
+ " <ns:KanalAdresseStruktur>\n" + "
<ns:AdresseValg>\n"
+ " <ns:EmailAdresseStruktur>\n" + "
<ns:EmailAdresse>\n"
+ " <ns:EmailAdresseEmail>finn.danvar@skat.dk</ns:EmailAdresseEmail>\n"
+ " </ns:EmailAdresse>\n" + " </ns:EmailAdresseStruktur>\n"
+ "<!--\n" + " <ns:TelefonNummerStruktur>\n"
+ " <ns:TelefonNummerStruktur>\n"
+ " <ns:TelefonNummer>81615902</ns:TelefonNummer>\n"
+ " </ns:TelefonNummerStruktur>\n"
+ " </ns:TelefonNummerStruktur>\n" +
"-->\n" + " </ns:AdresseValg>\n"
+ " </ns:KanalAdresseStruktur>\n"
+ " <ns:MeddelelseTypeSkalIKommunikationMappe>
true</ns:MeddelelseTypeSkalIKommunikationMappe>\n"
+ " <ns:Filer/>\n" + "
</ns:Meddelelse>\n" + " </ns:Meddelelser>\n"
+ " </ns:MeddelelseMultiSend_I>\n" + "
</soapenv:Body>\n" + "</soapenv:Envelope>";
String soapMessage = soapTemplate.replace("${FagsystemNavn}", FagsystemNavn)
.replace("${MeddelelseBatchId}", MeddelelseBatchId)
.replace("${MeddelelseTypeNummer}",
MeddelelseTypeNummer).replace("${KundeNummer}", KundeNummer)
.replace("${KanalTypeNummer}", KanalTypeNummer);
URL url = new URL("http://the-url-to-your-soap-service");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml");
connection.setReadTimeout(5000);
OutputStream out = connection.getOutputStream();
Writer wout = new OutputStreamWriter(out);
wout.write(soapMessage);
wout.close();
InputStreamReader isr = null;
if (connection.getResponseCode() <= 400) {
isr = new InputStreamReader(connection.getInputStream());
} else {
isr = new InputStreamReader(connection.getErrorStream());
}
BufferedReader in = new BufferedReader(isr);
StringBuffer responseSoapMessage = new StringBuffer();
String inputLine = in.readLine();
while (inputLine != null) {
responseSoapMessage.append(inputLine);
inputLine = in.readLine();
}
in.close();
System.out.println("responseSoapMessage" + responseSoapMessage.toString());
int webServiceKaldSucces_Output;
if (responseSoapMessage.toString().contains(
"<n1:AdvisNummer>1001</n1:AdvisNummer>
<n1:AdvisTekst>Request with 1 messages was acknowledged</n1:AdvisTekst>")) {
webServiceKaldSucces_Output = 1;
logInfo("Soap request - succes");
} else {
webServiceKaldSucces_Output = 0;
logInfo("Soap request - error");
}
generateRow();
}
catch (Exception ex)
{
logError(ex.getMessage());
}
The above code pieces a SOAP-request together, replacing specific values within it with the input-port values. Then, by way of a standard Java HttpURLConnection
, it fires off the request, and reads the response into a StringBuilder
object. For our use-case, we report success or failure by looking for a particular piece of String
-value, we had no need to parse the response further.
Do note the call to 'generateRow()
', this is required by Informatica to populate the output value(s).
Also note the calls to logInfo(message)
and logError(message)
, respectively, these enable logging into the Informatica Session log. So by all means, go crazy with them, you can never have enough logging.
Hope it helps!