and more in a single search tool across platforms. Read the announcement here. |
03/07/2023 11:23 AM - edited 03/07/2023 11:25 AM
Hello Saviynt Experts,
When I review SFTP Connector deployment instructions, it has this step:
Step 9: Use the following query in the job trigger
update EXTERNALCONNECTIONTYPE set IMPORTPARAMSMAP='jobtype:2,importtype:1,importtypeoptions:accounts' where connectiontype='JarConnector';
Looks this is not specifically apply to SFTP Connector, but it applies to custom connectors that use importaccount method based on JarConnector. Am I right?
if yes, what are other configuration steps before using createAccount/updateAccount of JarConnector?
The JarConnector in our instance does not convert the binding variables to actual values for our custom class method of createAccount. I think there are some missing pre-configuration steps for JarConnector itself. I AM NOT talking about the JarConnector based connection configuration though. I am talking about how to make JarConnector ready to use by Saviynt.
Solved! Go to Solution.
03/08/2023 01:15 AM
can you share config and logs
03/08/2023 04:06 AM - edited 03/08/2023 04:30 AM
Hello Rushikesh,
Thanks for your kind help, really appreciated. we are stuck at this point and impact to our project delivery plan. Please help on this issue as no many people have experience how to use this JarConnector
Here is our custom connector connection settings:
#Connection Type: JarConnector
#ConnectionJSON:
{
"url": "my.host.com",
"username": "User_Name",
"password": "PASSWORD"
}
#CreatAccountJSON: (tried different bindings with lower/upper case characters, none works out)
{
"fullyQualifiedClassName": "com.external.connector.AccountManager",
"methodName": "createAccount",
"arguments": {
"connect_url": "${connectionJSON.url}",
"connect_username": "${connectionJSON.username}",
"connect_password": "${ConnectionJSON.password}",
"accountId": "${users.username}",
"accountStatus": "${user.statuskey}",
"accountType": "hardcodedAccountType",
"accountLogin": "${accounts.accountName}"
}
}
Here is the argument print out method called by createAccount method:
public void printArgumentMapData(Map<String, Object> mapData) {
StringBuffer sb = new StringBuffer("ExternalConnector.printMapData: \r\n");
if(mapData == null || mapData.isEmpty()) {
sb.append("passed in map object is empty");
}else {
Iterator<String> keyIterator = mapData.keySet().iterator();
while(keyIterator != null && keyIterator.hasNext()) {
String key = keyIterator.next();
Object obj = mapData.get(key);
String objClassName = obj.getClass().getName();
String objValue = obj.toString();
sb.append("argumentName: ").append(key).append(" | ")
.append("argumentType: ").append(objClassName).append(" | ")
.append("argumentValue: ").append(objValue).append("\r\n");
}
}
System.out.println(sb.toString());
}
Here is the print output:
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"2023-03-04 03:10:02,537 [quartzScheduler_Worker-9] DEBUG println.PrintlnToLogger - Println :: ExternalConnector.1.0: Start to print passed in arguments map object of operation createAccount\r\n","stream":"stdout","time":"2023-03-04T03:10:02.537686297Z"}"
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"\n","stream":"stdout","time":"2023-03-04T03:10:02.537723496Z"}"
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"2023-03-04 03:10:02,537 [quartzScheduler_Worker-9] DEBUG println.PrintlnToLogger - Println :: ExternalConnector.printMapData: \r\n","stream":"stdout","time":"2023-03-04T03:10:02.537729189Z"}"
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"argumentName: connect_url | argumentType: java.lang.String | argumentValue: ${connectionJSON.url}\r\n","stream":"stdout","time":"2023-03-04T03:10:02.537733234Z"}"
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"argumentName: connect_username | argumentType: java.lang.String | argumentValue: ${connectionJSON.username}\r\n","stream":"stdout","time":"2023-03-04T03:10:02.537737183Z"}"
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"argumentName: connect_password | argumentType: java.lang.String | argumentValue: ${ConnectionJSON.password}\r\n","stream":"stdout","time":"2023-03-04T03:10:02.537741262Z"}"
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"argumentName: accountId | argumentType: java.lang.String | argumentValue: ${accountName}\r\n","stream":"stdout","time":"2023-03-04T03:10:02.53774543Z"}"
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"argumentName: accountStatus | argumentType: java.lang.String | argumentValue: ${user.statuskey}\r\n","stream":"stdout","time":"2023-03-04T03:10:02.537749358Z"}"
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"argumentName: accountType | argumentType: java.lang.String | argumentValue: hardcodedAccountType\r\n","stream":"stdout","time":"2023-03-04T03:10:02.537761534Z"}"
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"argumentName: accountLogin | argumentType: java.lang.String | argumentValue: ${accounts.accountName}\r\n","stream":"stdout","time":"2023-03-04T03:10:02.537765721Z"}"
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"\n","stream":"stdout","time":"2023-03-04T03:10:02.537769572Z"}"
"ecm-worker","2023-03-04T03:10:02.973+0000","{"log":"2023-03-04 03:10:02,537 [quartzScheduler_Worker-9] DEBUG println.PrintlnToLogger - Println :: ExternalConnector.1.0: End to print passed in arguments map object of operation createAccount\r\n","stream":"stdout","time":"2023-03-04T03:10:02.537773123Z"}"
Same behavior are in Version 2021 and Version 5.5 SP3
We have also opened ticket #1606984 on instance v2021 and #1603945 on instance version 5.5 SP3, but nobody can help us to figure out the root cause yet. it looks to me JarConnector Service did not convert the binding variables to actual values before it call the createAccount method.
Thanks,
03/08/2023 04:57 AM
Hi @alc
Can you please try the below connection json
{
"fullyQualifiedClassName": "com.sadinz.otmrelay.SaviyntInterface",
"methodName": "insertUser",
"arguments": {
"DBAAdminUsername": "${connectionJSON.username}",
"DBAAdminEncryptedPassword": "${connectionJSON.password}",
"serverBase": "${connectionJSON.url}",
"user_username": "${accounts}",
"user_password": "${connectionJSON.password}",
"firstName": "${users?.firstname}",
"lastName": "${users?.lastname}",
"email": "${users?.email}",
"domain":"${requestAccessAttributes.get('ID')}",
"role":"${requestAccessAttributes.get('ROLES')}"
}
}
Note: requestAccessAttributes is the Dynamic attribute values
Thanks
Darshan
03/08/2023 05:12 AM
Hello Darshan, Can you elaborate more about this?
I should put this JSON in CreateAccountJSON or CreateUserJSON? How to trigger it to be executed?
What should be ConnectionJSON for it?
Thanks
03/08/2023 05:17 AM
The above is create account json,
Connection json you can use it like below
{"url":"http://localurl:8080","username":"admin","password":"password"}
Thanks
03/08/2023 05:56 AM
Hello Darshan, I got this error with your JSON configuration. the class does not exist. I tried on version 2021.
"ecm-worker","2023-03-08T13:45:03.085+0000","{"log":"2023-03-08 13:45:02,393 [quartzScheduler_Worker-7] DEBUG provisoning.JarConnectorService - Error: java.lang.ClassNotFoundException: com.sadinz.otmrelay.SaviyntInterface\n","stream":"stdout","time":"2023-03-08T13:45:02.39400338Z"}"
03/08/2023 06:03 AM
Hi @alc
That was an example, please use the method you have defined in your java to pass it.
03/08/2023 06:14 AM - edited 03/08/2023 07:05 AM
Hello Darshan,
All other attributes are passed in correctly except dynamic attribute ID and ROLES. I have defined these two attribute on endpoint dynamic attributes. is that right? the account creation is triggered by a technical rule which should be able pick up the default value of the dynamic attribute, right?
"ecm-worker","2023-03-08T14:10:03.084+0000","{"log":"argumentName: domain | argumentType: java.lang.String | argumentValue: null\r\n","stream":"stdout","time":"2023-03-08T14:10:02.461218639Z"}"
"ecm-worker","2023-03-08T14:10:03.084+0000","{"log":"argumentName: role | argumentType: java.lang.String | argumentValue: null\r\n","stream":"stdout","time":"2023-03-08T14:10:02.461219314Z"}"
03/08/2023 10:42 AM
Hi @alc
Yes you are correct they are from DA however it is optional if you don't want it you can remove those.
This was a sample which we used for other connector so you can add as per you requirements
Thanks
Darshan
03/08/2023 10:56 AM - edited 03/08/2023 01:11 PM
Hello Darshan,
We do need the dynamic attributes, because we cannot utilize the user properties for this target application, we have to rely on dynamic attribute on account request form. if we do account request manually, the default values can pass to createAccount. but it will not pass when use role/rule assigned scenarios.
In addition once I put this "triggerrolename":"${tasks?.assignedFromRole?.role_name}" in the createAccount method, none of the arguments will be converted to its actual values. this is the behavior why I open this question topic. I cannot get it from Saviynt REST API either.
However, if I do a direct database search with following queries, I can find the role value:
select t.assignedFromRole from arstasks t where t.taskkey ='123'
where 123 is the task ID of the new account task generated from the role request.
Looks the role_name is not exposed via createAccountJSON or REST API.
03/08/2023 10:57 PM
Hi @alc
Okay, you can use the DA as per your requriements.
Now coming onto the variable ${tasks?.assignedFromRole?.role_name} this is exposed only in Rest connector ( rule_name is not exposed but role_name is exposed ) However if you are Jar connector you can try with this ${arsTasks.getassignedFromRole()}. ( In this role name is also not exposed )
Thanks
Darshan
03/09/2023 04:30 AM
Hello Darshan,
I just tried ${arsTasks.getassignedFromRole(), once add this into CreateAccountJSON, the original issue shows up again, none of the parameters will be able get actual values. the argument output is as attached screenshot.
We have to know either which rule or which role triggered the account creation, because several account attributes are determined by the role or rule information. Any idea for a solution? Since such information is in arstasks table, the last option is to use JDBC call to get it directly in Java code of my custom connector class. What do you think? Can I get arsTask.id from the CreateAccountJSON?
Thanks
03/09/2023 04:35 AM
Yes, even if one of the variable doesn't work then it will not pass it correctly, Task.id you can get it it is exposed as per documentation only
"taskid":"${arsTasks.getId()}"
03/09/2023 04:57 AM - edited 03/09/2023 04:59 AM
Hello Darshan,
I can get taskid as you instructed. What about password? Could you please let me know the correct syntax to get it from tasks? we have configured an application password policy which should generate a password for new account. Not sure there is any difference or not when account is created from rule/role assignment or from manual request though.
Thanks
03/09/2023 10:01 PM
It is there as per the documentation - https://docs.saviyntcloud.com/bundle/JAR-v2020x/page/Content/Understanding-the-Integration-between-E...
"${arsTasks.getPassword()}
Thanks
Darshan