Walking through an Integration Activity in User Application – Part 3

Walking through an Integration Activity in User Application – Part 3

In the previous article in this series I worked through the pre-activity of the Integration Activity action. Who would have thought so much work goes on, in such detail in the pre-activity, before we even start actually doing anything with it.

I think the core takeaway, which was buried in the previous argument is to realize that a lot of the User Application internals and workflow related things in particular were designed as almost standalone objects that need data to be passed from one to another. Thus we often have to copy data from one object (the Start_form) to another (the flowdata XML object or the SOAP XML input document) which if you keep this in mind, makes troubleshooting easier, since when the data you expect is missing, oh ya, I forgot to copy it springs to mind. But also reminds you of where to look. You can use an Action from the palette to copy and manipulate data (Mapping, which is an action you drop on the workflow screen, which is different than the Map buttons in the Pre or Post Activity of actions). Alternatively, so actions require that you do the copying in the pre or post activity.

I did not discuss the post activity issue on this one, but if your SOAP document sends a response to the request, you can use XPATH to select the parts you want and copy into flowdata to use later. Again that model of you have to copy the things you want, or else you won't get them.

In the previous article, we saw how the Source Expression column (Look in Data Item Mappings view to see it, right click on any action in the workflow, and select Show Data Item Mappings) is first evaluated for all the items in the list, then the Target expression (labeled Web Services Input Field in the GUI, but called target expression in the logs) is evaluated. A reminder that we used ECMA in the Source expressions, but we used XPATH in the target and the User Application knew how to generate the ECMA to enact the XPATH. In some ways that is a nice convenience function, but in other ways it removes a level of control. On the whole, XPATH is flexible enough do what I need, so I am ok with it.

Finally, we get a SOAP document rendered, with our data copied in, that can be passed INTO the Integration Activity itself. This was all mapping the deck chairs till now.

2016-06-28 15:37:36,435 [pool-4-thread-10] DEBUG com.novell.soa.af.impl.activity.IntegrationActivity- [RBPM] Input: <?xml version="1.0" encoding="UTF-8"?><Envelope _serverUrl_="https://corp-idmadm101.acme.org:8443/IDMProv/role/service" _userid_="CN=uaadmin,OU=admins,OU=services,O=acme">
<Body>
<createRoleRequest>
<role>
<container/>
<description/>
<name/>
<roleCategoryKeys>
<categorykey>
<categoryKey/>
</categorykey>
</roleCategoryKeys>
<roleLevel/>
<systemRole>false</systemRole>
</role>
</createRoleRequest>
</Body>
</Envelope>



It is a bit annoying since it displays it without the whitespace formatting, you know the tabs and so on that make XML look like XML, so it is sometimes hard to see errors due to incorrect nesting.

But we can see that beyond the systemRole node with a value of false, and the XML attributes of the Envelope node, I basically got nothing copied. As noted in the previous article that was because I had forget ten to do a Map All, on the Start activities Post Activity page, to copy all the Form Data into the flowdata object, so I had nothing to work with. Thus we know it will fail, since the data is bad, but in fact it fails for a different initial reason.


2016-06-28 15:37:36,726 [http-bio-8443-exec-6] ERROR com.novell.common.auth.JAASManager- [RBPM] Login failed for user: CN=uaadmin,OU=admins,OU=services,O=acme
Domain: corp-idmadm101.acme.org Bad Set-Cookie header: JSESSIONID=88837751D29C8B46FFF2CF9D6559BD59; Path=/IDMProv/; Secure; HttpOnly
No '=' found for token starting at position 69
java.net.ProtocolException: Missing WWW-Authenticate header
at com.sssw.b2b.ee.httpclient.AuthorizationModule.responsePhase2Handler(AuthorizationModule.java:314)
at com.sssw.b2b.ee.httpclient.HTTPResponse.handleResponse(HTTPResponse.java:661)
at com.sssw.b2b.ee.httpclient.HTTPResponse.getStatusCode(HTTPResponse.java:168)
at com.sssw.b2b.rt.util.GNVURLReadWrite.httpPutOrPost(GNVURLReadWrite.java:463)
at com.sssw.b2b.rt.util.GNVURLReadWrite.httpPost(GNVURLReadWrite.java:405)
at com.sssw.b2b.rt.util.GNVURLReadWrite.putOrPostURL(GNVURLReadWrite.java:761)
at com.sssw.b2b.rt.util.GNVURLReadWrite.postURL(GNVURLReadWrite.java:734)
at com.sssw.b2b.rt.action.GNVDocIOAction.evaluateXMLAction(GNVDocIOAction.java:539)
at com.sssw.b2b.rt.action.GNVDocIOAction.apply(GNVDocIOAction.java:448)
at com.sssw.b2b.rt.action.GNVActionList.apply(GNVActionList.java:209)
at com.sssw.b2b.rt.action.GNVTryAction.apply(GNVTryAction.java:324)
at com.sssw.b2b.rt.action.GNVActionList.apply(GNVActionList.java:209)
at com.sssw.b2b.rt.action.GNVActionModel.apply(GNVActionModel.java:177)
at com.sssw.b2b.rt.GNVActionComponent.execute(GNVActionComponent.java:439)
at com.sssw.b2b.rt.service.GNVServiceComponent.execute(GNVServiceComponent.java:186)
at com.novell.soa.af.impl.activity.IntegrationActivity.executeComponent(IntegrationActivity.java:667)
at com.novell.soa.af.impl.activity.IntegrationActivity.execute(IntegrationActivity.java:481)
at com.novell.soa.af.impl.activity.IntegrationActivity.process(IntegrationActivity.java:311)
at com.novell.soa.af.impl.activity.ActivityNode.notifyArrive(ActivityNode.java:206)
at com.novell.soa.af.impl.activity.IntegrationActivity.notifyArrive(IntegrationActivity.java:277)
at com.novell.soa.af.impl.core.ProcessImpl.startActivity(ProcessImpl.java:1697)
at com.novell.soa.af.impl.core.ProcessImpl.forward(ProcessImpl.java:1594)
at com.novell.soa.af.impl.activity.ActivityNode.forward(ActivityNode.java:265)
at com.novell.soa.af.impl.activity.ActivityNode.forward(ActivityNode.java:240)
at com.novell.soa.af.impl.activity.StartActivity.process(StartActivity.java:94)
at com.novell.soa.af.impl.activity.ActivityNode.notifyArrive(ActivityNode.java:206)
at com.novell.soa.af.impl.activity.RunnableActivity.run(RunnableActivity.java:50)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
++++++ Tue Jun 28 15:37:36 EDT 2016 USER LOG FROM GEN_V1_CORP-IDMDEV_UserApplication_Create Role_Activity
------ com.sssw.b2b.rt.GNVException: rt001801:Document I/O error: Missing WWW-Authenticate header;
---> nested java.net.ProtocolException: Missing WWW-Authenticate header


When I first troubleshooted (troubleshot? Trebuchet shot?) the issue, I assumed my Missing WWW-Authenticate header was because I forgot to map it. But in fact it was not. However, I did grab some trace that was helpful to show what properly Mapping the data from the Form to the flowdata would look like during the Start activity.


2016-06-28 15:50:51,047 [http-bio-8443-exec-10] TRACE com.novell.soa.af.impl.link.Link- [RBPM] Link() FORWARD[Start, Activity]
2016-06-28 15:50:51,065 [http-bio-8443-exec-10] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating target expression: wi.createXPath("flow-data/Start/request_form/roleDescription").setValue("Testing Role creation")


The Target Expression in the GUI is written as XPATH, and that is 'rendered' as ECMA of flowdata.get('Start/request_form/roleContainer') a convenience for sure, but again one I wonder if it would be possible to override for complicated cases.

Later in the flow, you can see that when I actually remembered to properly map the data, that in fact I get a SOAP document that looks much better.

And you can see later, when it renders the SOAP the values copied in properly:


2016-06-28 15:50:51,203 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: CN=uaadmin,OU=admins,OU=services,O=acme
2016-06-28 15:50:51,203 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating source expression: flowdata.get('Start/request_form/roleContainer')
2016-06-28 15:50:51,204 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: BizUnit
2016-06-28 15:50:51,205 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating source expression: flowdata.get('Start/request_form/roleDescription')
2016-06-28 15:50:51,205 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: Testing Role creation
2016-06-28 15:50:51,205 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating source expression: flowdata.get('Start/request_form/roleName')
2016-06-28 15:50:51,206 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: BU-Testing
2016-06-28 15:50:51,206 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating source expression: flowdata.get('Start/request_form/roleCategory')
2016-06-28 15:50:51,206 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: BizUnit
2016-06-28 15:50:51,206 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating source expression: flowdata.get('Start/request_form/roleLevel')
2016-06-28 15:50:51,206 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: 30
2016-06-28 15:50:51,206 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating source expression: 'false'
2016-06-28 15:50:51,207 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: false



Above you can see the Source Expressions in the pre-activity mapping executing and looking like good values, well at least those that can be displayed as text.
2016-06-28 15:50:51,207 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating target expression: Input.createXPath('Envelope/@_serverUrl_').setValue("https://corp-idmadm101.acme.org:8443/IDMProv/role/service")
2016-06-28 15:50:51,208 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: com.novell.soa.script.mozilla.javascript.Undefined@1b36f5f6
2016-06-28 15:50:51,208 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating target expression: Input.createXPath('Envelope/@_userid_').setValue("CN=uaadmin,OU=admins,OU=services,O=acme")
2016-06-28 15:50:51,208 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: com.novell.soa.script.mozilla.javascript.Undefined@1b36f5f6
2016-06-28 15:50:51,208 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating target expression: Input.createXPath('Envelope/Body/createRoleRequest/role/container').setValue("BizUnit")
2016-06-28 15:50:51,209 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: com.novell.soa.script.mozilla.javascript.Undefined@1b36f5f6
2016-06-28 15:50:51,209 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating target expression: Input.createXPath('Envelope/Body/createRoleRequest/role/description').setValue("Testing Role creation")
2016-06-28 15:50:51,210 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: com.novell.soa.script.mozilla.javascript.Undefined@1b36f5f6
2016-06-28 15:50:51,210 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating target expression: Input.createXPath('Envelope/Body/createRoleRequest/role/name').setValue("BU-Testing")
2016-06-28 15:50:51,210 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: com.novell.soa.script.mozilla.javascript.Undefined@1b36f5f6
2016-06-28 15:50:51,210 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating target expression: Input.createXPath('Envelope/Body/createRoleRequest/role/roleCategoryKeys/categorykey/categoryKey').setValue("BizUnit")
2016-06-28 15:50:51,211 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: com.novell.soa.script.mozilla.javascript.Undefined@1b36f5f6
2016-06-28 15:50:51,211 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating target expression: Input.createXPath('Envelope/Body/createRoleRequest/role/roleLevel').setValue("30")
2016-06-28 15:50:51,211 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: com.novell.soa.script.mozilla.javascript.Undefined@1b36f5f6
2016-06-28 15:50:51,212 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating target expression: Input.createXPath('Envelope/Body/createRoleRequest/role/systemRole').setValue("false")
2016-06-28 15:50:51,212 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: com.novell.soa.script.mozilla.javascript.Undefined@1b36f5f6




All the target expressions look good. The mapping gets converted to XPATH commands of where to set the values via ECMA.


2016-06-28 15:50:51,212 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.activity.IntegrationActivity- [RBPM] Input: <?xml version="1.0" encoding="UTF-8"?><Envelope _serverUrl_="https://corp-idmadm101.acme.org:8443/IDMProv/role/service" _userid_="CN=uaadmin,OU=admins,OU
=services,O=acme">
<Body>
<createRoleRequest>
<role>
<container>BizUnit</container>
<description>Testing Role creation</description>
<name>BU-Testing</name>
<roleCategoryKeys>
<categorykey>
<categoryKey>BizUnit</categoryKey>
</categorykey>
</roleCategoryKeys>
<roleLevel>30</roleLevel>
<systemRole>false</systemRole>
</role>
</createRoleRequest>
</Body>
</Envelope>


Here my SOAP has values finally, and I have the username and URL in the Envelope node, but I get the same error. That is because while this was actually a problem, the first one to show up is actually the authentication issue, which is obvious by the absence of the password in that same node, in hindsight. Just as on the <Envelope> node, there is a _serverUrl_ and _userid_ XML attribute, there should have been a _password_ one as well.

So thus our authentication will of course fail since we send in a URL (correct), username (correct), and no password so that is not going to work.


2016-06-28 15:50:51,107 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating source expression: GCV.getValueForNamedPassword('service-account-pwd')
2016-06-28 15:50:51,108 [pool-4-thread-1] TRACE com.novell.soa.af.impl.scripting.GCVScript- [RBPM] Calling extended operation (GetDriverGCVResponse) lCtx.extendedOperation(new GetDriverGCVRequest(cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme, service-account-pwd));
2016-06-28 15:50:51,141 [pool-4-thread-1] TRACE com.novell.soa.af.impl.scripting.GCVScript- [RBPM] GCV definition is: null
2016-06-28 15:50:51,141 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: null


The issue is that for a Named Password, even if it is a password-ref GCV type, while in the engine, a GCV token will return the password value, in the User Application you need to use a different ECMA function. So instead of GCV.get() you need to use GCV.getValueForNamedPassword(). As a final twist, you actually need a GCV set on the User Application driver, named allow-fetch-named-passwords explicitly enabled to true. You can read more about this in the docs, which has a complete example GCV you can add.

https://www.netiq.com/documentation/idm45/agpro/data/bu5sikg.html

My recollection is that the latest User App packaged drivers include this GCV already, you just need to make sure it is set to true. Alas, you then apparently need to restart the User App driver, but also the User Application web application which is where the users notice the issue.

Now as it happens, my issue was not that GCV missing, but rather for some reason I was sure that I had set the Named Password, but I had not. Thus I had to fix the GCV values and named password values on my driver for it to actually succeed at getting the value out of it.

You can see the difference between when the GCV.get() command works, vs null, below.


2016-06-28 15:50:51,141 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating source expression: GCV.get('UAProvURL') + '/role/service'
2016-06-28 15:50:51,142 [pool-4-thread-1] TRACE com.novell.soa.af.impl.scripting.GCVScript- [RBPM] Calling extended operation (GetDriverGCVResponse) lCtx.extendedOperation(new GetDriverGCVRequest(cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme, UAProvURL));
2016-06-28 15:50:51,168 [pool-4-thread-1] TRACE com.novell.soa.af.impl.scripting.GCVScript- [RBPM] GCV definition is: <?xml version="1.0" encoding="UTF-8"?><nds dtdversion="4.0" ndsversion="8.x">
<source>
<product edition="Advanced" version="4.5.3.0">DirXML</product>
<contact>NetIQ Corporation</contact>
</source>
<output>
<status level="success">Global Configuration Values<configuration-values>
<definitions>
<definition display-name="User Application Provisioning Services URL" name="UAProvURL" type="string">
<value xml:space="preserve">https://corp-idmadm101.acme.org:8443/IDMProv</value>
</definition>
</definitions>
</configuration-values>
</status>
</output>
</nds>
2016-06-28 15:50:51,171 [pool-4-thread-1] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: https://corp-idmadm101.acme.org:8443/IDMProv/role/service



It looks like the User App injects a query into the driver, to get the GCV value, which is kind of interesting. I wish I had remembered to look at the User App driver log, with level 3 enabled, at the time this ran, so I could see if it really injected into the driver, or is just the engine returns the value in this XDS like format. I am curious, and in case anyone happens to know, please post a comment.


2016-06-28 16:05:40,385 [pool-4-thread-2] TRACE com.novell.soa.af.impl.scripting.GCVScript- [RBPM] service-account-pwd
2016-06-28 16:05:40,386 [pool-4-thread-2] TRACE com.novell.soa.af.impl.scripting.GCVScript- [RBPM] Calling extended operation (GetNamedPasswordResponse) lCtx.extendedOperation(new GetNamedPasswordRequest(cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme, service-account-pwd));
2016-06-28 16:05:40,448 [pool-4-thread-2] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: P@ssw0rd1


Now you can see the successful result above. It was able to request the value of the named password. The ECMA call is a smiden misleading, since it is really the GCV name, which is a password-ref, which specifies the actual named password holding the value, but that is how it is named.

Now that we have the surrounding components working, we get a rendered SOAP document that is starting to look better. We have the URL, Username, and password in the <Envelope> node properly. It looks like we sent in most of the data. Hopefully it will work this time.

2016-06-28 16:05:40,508 [pool-4-thread-2] DEBUG com.novell.soa.af.impl.activity.IntegrationActivity- [RBPM] Input: <?xml version="1.0" encoding="UTF-8"?><Envelope _password_="P@ssw0rd1" _serverUrl_="https://corp-idmadm101.acme.org:8443/IDMProv/role/service" _userid_="CN=uaadmin,OU=admins,OU=services,O=acme">
<Body>
<createRoleRequest>
<role>
<container>BizUnit</container>
<description>Testing Role creatoon</description>
<name>BU-Testing</name>
<roleCategoryKeys>
<categorykey>
<categoryKey>BizUnit</categoryKey>
</categorykey>
</roleCategoryKeys>
<roleLevel>30</roleLevel>
<systemRole>false</systemRole>
</role>
</createRoleRequest>
</Body>
</Envelope>



But that did not work. I had sent in the <container> node, which allows you to create the Role in a container underneath the Level10, Level20, or Level30 containers. I was sending BizUnit, and that failed, so I tried sending in OU=BizUnit but failed as well. That seems unlikely, what could it be, my kingdom for an informative error message!

2016-06-28 16:20:57,950 [http-bio-8443-exec-9] ERROR com.novell.idm.nrf.service.RoleManagerService- [RBPM] [Create_Role_Failure] Initiated by cn=uaadmin,ou=admins,ou=system,o=acme, Role DN: cn=BU-Testing,OU=BizUnit,cn=Level30,cn=RoleDefs,cn=RoleConfig,cn=AppConfig,cn=
UserApplication,cn=dset,ou=idm,ou=system,o=acme, Error Message: Ldap error creating object: cn=BU-Testing,OU=BizUnit,cn=Level30,cn=RoleDefs,cn=RoleConfig,cn=AppConfig,cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme. Error: javax.naming.NameNotFoundException: [LDAP:
error code 32 - NDS error: no such entry (-601)]; remaining name 'cn=BU-Testing,OU=BizUnit,cn=Level30,cn=RoleDefs,cn=RoleConfig,cn=AppConfig,cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme'
2016-06-28 16:20:57,952 [http-bio-8443-exec-9] INFO com.novell.idm.nrf.soap.ws.role.impl.RoleServiceSkeletonImpl- [RBPM] DAL communication error.
com.novell.idm.nrf.exception.NrfException: DAL communication error.


Oh look, there it is. This error is actually informative, if you take a moment to read it, it tells you what you need to know. When you get an eDirectory -601 error then it means there is an object not found. If so, what could be wrong? Well it tells you the DN it cannot find.

cn=BU-Testing,OU=BizUnit,cn=Level30,cn=RoleDefs,cn=RoleConfig,cn=AppConfig,cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme


Look at that and do you see the issue? As I look at it now, it is even more obvious. The container objects under the AppConfig container, are actually named CN=, not OU=. I think I am just used to using OU objects, since they feel more useful than a CN= container. But in this case, it literally is meant to be a container, thus the container class, and the naming of cn= in use.

Once I changed that it stopped with that error, but still, getting an error I thought we got rid of before, the WWW-Authenicate error. Why is it back now? I thought that giving it the password was the issue. But in fact it was not the entire issue. It helped that I knew how the authentication was done, but I am not sure I have seen it documented, rather I have inferred from experience with the product.

What happens, if you dig in deep enough, is that inside the Integration Activity tokens are used to copy the values from the XPATH of Envelope/@_URL_ into a variable and so on for password and userid as well. Then the values are stripped from the XML, so that the user name and password are not sent in the clear in the document, rather it is just a mechanism to get the data into the activity.

Then if you dig in deeper, buried in the Execute action inside the Integration Activity and then as one of the Headers (Authentication obviously enough), it looks like:
"Basic " + java.lang.String(Packages.org.apache.commons.codec.binary.Base64().encodeBase64(java.lang.String(_userid_+":"+_password_).getBytes("UTF-8")),"UTF-8")


Ok, that looks good, it is doing Basic header Authentication. That is the string "Basic: " then the username:password base base 64 encoded. Looks good, why is it not working? I do NOT know how to enable debugging of an Integration Activity at this level, so I copied that code into Description, to see if it worked, and it did. It needed a little bit of modification to work though.

"Basic " + java.lang.String(Packages.org.apache.commons.codec.binary.Base64().encodeBase64(java.lang.String(GCV.get('service-account-dn')+":"+GCV.getValueForNamedPassword('service-account-pwd')).getBytes("UTF-8")),"UTF-8")


What I realized as I watched that trace out was that I was passing in a full LDAP DN. When for Basic Authentication it REALLY wants just username:password, not full LDAP DN:password.

Once I changed to a passing in username like 'uaadmin' and not a full LDAP DN it worked:

2016-06-29 10:54:01,883 [pool-5-thread-10] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: com.novell.soa.script.mozilla.javascript.Undefined@599cdaa9
2016-06-29 10:54:01,884 [pool-5-thread-10] DEBUG com.novell.soa.af.impl.activity.IntegrationActivity- [RBPM] Input: <?xml version="1.0" encoding="UTF-8"?><Envelope _password_="P@ssw0rd1" _serverUrl_="https://corp-idmadm101.acme.org:8443/IDMProv/role/service" _userid_="uaadmin">
<Body>
<createRoleRequest>
<role>
<container>cn=BizUnit</container>
<description>Testing Role creatoon</description>
<name>BU-Testing</name>
<roleCategoryKeys>
<categorykey>
<categoryKey>BizUnit</categoryKey>
</categorykey>
</roleCategoryKeys>
<roleLevel>30</roleLevel>
<systemRole>false</systemRole>
</role>
</createRoleRequest>
</Body>
</Envelope>


You can see that the userid is now uuadmin, a simple CN, which works. The password is there. The URL is there. All looks good. The XML of the request looks good. Got container correct as cn=BizUnit and all the rest look good.

2016-06-29 10:54:02,157 [http-bio-8443-exec-2] INFO com.novell.pwdmgt.util.PasswordHelper- [RBPM] [Login_Success] uaadmin successfully logged in.

I logged in properly this time, yay!

2016-06-29 10:54:02,239 [http-bio-8443-exec-2] DEBUG com.novell.soa.util.CacheUtil- [RBPM] Object was found in cache: IDM_ACTIVATION_INFORMATION cache holder: AdvancedEdition
2016-06-29 10:54:02,239 [http-bio-8443-exec-2] DEBUG com.novell.soa.util.CacheUtil- [RBPM] Object RETRIEVED from cache: IDM_ACTIVATION_INFORMATION from cache holder: AdvancedEdition



I find it interesting that it checks the license before running, but ok. I would think if you got this far already, the license should have been well and truly validated already, but I guess you never know.


2016-06-29 10:54:02,331 [http-bio-8443-exec-2] INFO  com.novell.idm.nrf.service.RoleManagerService- [RBPM] [Create_Role] Initiated by cn=uaadmin,ou=admins,ou=system,o=acme, Role DN: cn=BU-Testing,cn=BizUnit,cn=Level30,cn=RoleDefs,cn=RoleConfig,cn=AppConfig,cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme


We see that the role request is submitted, the Create_Role code is running. Amusingly, after that dance with full DN vs simple name, we see it is still initated by the full LDAP DN. This makes me think, that there might be a case where SOAP calls could fail.

If you had two users, Role Administrators, same naming attribute value (say both ProvAdmin) but in different containers, so legal in eDirectory, this might cause an issue. In the GUI at the web interface level, if you logged in as ProvAdmin, and the search returned two users, you would get a prompt asking you which one. Now that was in the Pre-IDM 4.5/IDM Home days before OSP got stuck in the middle. I do wonder what would happen in this case, if you tried to make a SOAP call. Either it would fail, or only the first object returned (likely by create date order) would be able to login and the second would not.

Regardless, we get a successful response document back:

2016-06-29 10:54:02,343 [http-bio-8443-exec-2] DEBUG com.novell.soa.ws.impl.xml.OutputStreamImpl- <SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'><SOAP-ENV:Body><ns1:createRoleResponse xmlns="http://www.novell.com/role/service" xmlns:ns1="http://www.novell.com/role/service"><result><dn>cn=BU-Testing,cn=BizUnit,cn=Level30,cn=RoleDefs,cn=RoleConfig,cn=AppConfig,cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme</dn></result></ns1:createRoleResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
2016-06-29 10:54:02,347 [pool-5-thread-10] DEBUG com.novell.soa.af.impl.activity.IntegrationActivity- [RBPM] execute completed (pool-5-thread-10), retry count = 0 processing number = 0
2016-06-29 10:54:02,348 [pool-5-thread-10] DEBUG com.novell.soa.af.impl.activity.IntegrationActivity- [RBPM] Output: <?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:createRoleResponse xmlns:ns1="http://www.novell.com/role/service" xmlns="http://www.novell.com/role/service">
<result>
<dn>cn=BU-Testing,cn=BizUnit,cn=Level30,cn=RoleDefs,cn=RoleConfig,cn=AppConfig,cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme</dn>
</result>
</ns1:createRoleResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>



Let me grab that and reformat it for you. One thing I note is that the Integration Activity trace sometimes looses whitespace formatting.


<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:createRoleResponse xmlns:ns1="http://www.novell.com/role/service" xmlns="http://www.novell.com/role/service">
<result>
<dn>cn=BU-Testing,cn=BizUnit,cn=Level30,cn=RoleDefs,cn=RoleConfig,cn=AppConfig,cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme</dn>
</result>
</ns1:createRoleResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>



Thus our createRoleResponse document has the DN of the Role created, which is nice confirmation, if we wanted to use the value somewhere. If you did, the createRoleResponse/result/dn/text() can be grabbed in the Post Activity mapping if you wanted, to return the DN of the Role you created to be used later in the workflow.

2016-06-29 10:54:02,363 [pool-5-thread-10] INFO  com.novell.soa.af.impl.LogEvent- [RBPM] [Workflow_Forwarded] Initiated by System, Process ID: 1285cd3e273c4e5bb2c0e5f5e4f4d7df, Process Name: cn=Create Role,cn=RequestDefs,cn=AppConfig,cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme:61, Activity: Activity, Recipient: cn=uaadmin,ou=admins,ou=system,o=acme
2016-06-29 10:54:02,370 [pool-5-thread-10] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] evaluating to string: flowdata.get('IDM_COMPLETED_APPROVAL_STATUS')
2016-06-29 10:54:02,371 [pool-5-thread-10] DEBUG com.novell.soa.af.impl.core.DataItemEvaluator- [RBPM] result: approved
2016-06-29 10:54:02,386 [pool-5-thread-10] INFO com.novell.soa.af.impl.LogEvent- [RBPM] [Workflow_Ended] Initiated by System, Process ID: 1285cd3e273c4e5bb2c0e5f5e4f4d7df, Process Name: cn=Create Role,cn=RequestDefs,cn=AppConfig,cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme:61, Activity: Finish, Recipient: cn=uaadmin,ou=admins,ou=system,o=acme
2016-06-29 10:54:02,931 [http-bio-8443-exec-4] TRACE com.novell.soa.common.i18n.BestLocaleServletFilter- [RBPM] Using Resource-Group[base-resgrp] with bestLocale[en_US] for /IDMProv/UIQuery

Finally some cleanup, as we see the final step in our workflow process, to completion, and default to Approved, since this was a workflow recall that did the Integration Activity.

DISCLAIMER:

Some content on Community Tips & Information pages is not officially supported by Micro Focus. Please refer to our Terms of Use for more detail.
Comments
The reason for GCV.getValueForNamedPassword, is that it needs to use the ldap extensions to do this, and not just an normal ldap call.
Top Contributors
Version history
Revision #:
1 of 1
Last update:
‎2016-12-05 20:22
Updated by:
 
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.