Announcing the Saviynt Knowledge Exchange unifying the Saviynt forums, documentation, training,
and more in a single search tool across platforms. Read the announcement here.

What Pre Configuration steps are needed for JarConnector to work?

alc
Regular Contributor
Regular Contributor

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.

15 REPLIES 15

rushikeshvartak
All-Star
All-Star

can you share config and logs


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

alc
Regular Contributor
Regular Contributor

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,

 

 

Darshanjain
Saviynt Employee
Saviynt Employee

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

alc
Regular Contributor
Regular Contributor

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

Darshanjain
Saviynt Employee
Saviynt Employee

The above  is create account json,

Connection json you can use it like below

{"url":"http://localurl:8080","username":"admin","password":"password"}

 

Thanks

alc
Regular Contributor
Regular Contributor

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"}"

Darshanjain
Saviynt Employee
Saviynt Employee

Hi @alc 

That was an example, please use the method you have defined  in your java to pass it.

alc
Regular Contributor
Regular Contributor

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"}"

 

dynamicAttributes.jpg

Darshanjain
Saviynt Employee
Saviynt Employee

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

 

alc
Regular Contributor
Regular Contributor

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.

Darshanjain
Saviynt Employee
Saviynt Employee

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

 

alc
Regular Contributor
Regular Contributor

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

 

 

Darshanjain
Saviynt Employee
Saviynt Employee

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()}"

 

alc
Regular Contributor
Regular Contributor

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

Darshanjain
Saviynt Employee
Saviynt Employee

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