Announcing the SAVIYNT KNOWLEDGE EXCHANGE unifying the Saviynt forums, documentation, training, and more in a single search tool across platforms. Click HERE to read the Announcement.

Custom Action External Jar in User Update Rule

gaurav007
New Contributor II
New Contributor II

Hello,

I have a usecase in which I have to use the custom action functionality in user update rule, now I have created a user update rule(which is working I verified it), and a JAR with the custom action functionality.

Whenever I make changes in the user Identity, user update rule is triggered but the Custom Action is not working, the logs doesn't show that the JAR got executed. i have used the class name as -  com.saviynt.custom.UserPreprocessValidator.validator.CustomActionClass and method name as - CustomMethod, but it doesn't work.

gaurav007_0-1679908370827.png

 

I have used the same JAR, same Class name and same Method name and tried to execute JAR through the External JAR Job. it got executed and got the expected response/result.

Can you advise what I might be missing here?

12 REPLIES 12

nimitdave
Saviynt Employee
Saviynt Employee

@gaurav007 , Pls can you check the logs for the case when user update rule will be invoked.

gaurav007
New Contributor II
New Contributor II

I am getting this type of error in log. please check below logs for the reference but same JAR is working with the JOB.

Thanks for the help in advance.

[29###CustomMethod###77###com.saviynt.custom.UserPreprocessValidator.validator.CustomActionClass:[Gaurav_Test]]\n","stream":"stdout","time":"2023-03-28T06:22:29.934992194Z"}"
"ecm-worker","2023-03-28T06:22:30.759+00:00","{"log":"2023-03-28 06:22:29,934 [quartzScheduler_Worker-6] DEBUG changeaction.UserChangeActionService - Calling customAction, keysarr - [29, CustomMethod, 77, com.saviynt.custom.UserPreprocessValidator.validator.CustomActionClass]\n","stream":"stdout","time":"2023-03-28T06:22:29.9350244Z"}"
"ecm-worker","2023-03-28T06:22:30.759+00:00","{"log":"2023-03-28 06:22:29,934 [quartzScheduler_Worker-6] DEBUG changeaction.UserChangeActionService - class: com.saviynt.custom.UserPreprocessValidator.validator.CustomActionClass, method: CustomMethod\n","stream":"stdout","time":"2023-03-28T06:22:29.935033499Z"}"
"ecm-worker","2023-03-28T06:22:30.759+00:00","{"log":"2023-03-28 06:22:29,935 [quartzScheduler_Worker-6] DEBUG changeaction.UserChangeActionService - Custom Action -\u003e Class Name : com.saviynt.custom.UserPreprocessValidator.validator.CustomActionClass\n","stream":"stdout","time":"2023-03-28T06:22:29.935043525Z"}"
"ecm-worker","2023-03-28T06:22:30.759+00:00","{"log":"2023-03-28 06:22:29,935 [quartzScheduler_Worker-6] DEBUG changeaction.UserChangeActionService - Custom Action -\u003e Method Name : CustomMethod\n","stream":"stdout","time":"2023-03-28T06:22:29.935048248Z"}"
"ecm-worker","2023-03-28T06:22:30.759+00:00","{"log":"2023-03-28 06:22:29,944 [quartzScheduler_Worker-2] DEBUG changeaction.UserChangeActionService - Lets Invoke Class Namecom.saviynt.custom.UserPreprocessValidator.validator.CustomActionClass method CustomMethod\n","stream":"stdout","time":"2023-03-28T06:22:29.944713602Z"}"
"ecm-worker","2023-03-28T06:22:30.759+00:00","{"log":"2023-03-28 06:22:29,944 [quartzScheduler_Worker-6] DEBUG changeaction.UserChangeActionService - Lets Invoke Class Namecom.saviynt.custom.UserPreprocessValidator.validator.CustomActionClass method CustomMethod\n","stream":"stdout","time":"2023-03-28T06:22:29.944841261Z"}"
"ecm-worker","2023-03-28T06:22:30.759+00:00","{"log":"2023-03-28 06:22:29,946 [quartzScheduler_Worker-2] ERROR changeaction.UserChangeActionService - Error: \n","stream":"stdout","time":"2023-03-28T06:22:29.947071308Z"}"
"ecm-worker","2023-03-28T06:22:30.759+00:00","{"log":"java.lang.NoSuchMethodException: com.saviynt.custom.UserPreprocessValidator.validator.CustomActionClass.CustomMethod(java.lang.String)\n","stream":"stdout","time":"2023-03-28T06:22:29.947089146Z"}"

 

nimitdave
Saviynt Employee
Saviynt Employee

If possible please share the jar or the method CustomMethod.

It should be like this or similar

public void customMethod(String userJson)

gaurav007
New Contributor II
New Contributor II

Please check and advise what I might be missing.

package com.saviynt.custom.UserPreprocessValidator.validator;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

import com.google.gson.Gson;

public class CustomActionClass {

public CustomActionClass() {

}

public void CustomMethod() {

String accessToken = null;
try {
URL url = new URL("URL");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);

String requestBody = "{\"username\": \"username\", \"password\": \"password\"}";
byte[] input = requestBody.getBytes(StandardCharsets.UTF_8);
OutputStream os = conn.getOutputStream();
os.write(input, 0, input.length);

if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));

String output;
StringBuilder responseBuilder = new StringBuilder();
while ((output = br.readLine()) != null) {
responseBuilder.append(output);
}
Gson gson = new Gson();
TokendataResponse response = gson.fromJson(responseBuilder.toString(), TokendataResponse.class);

accessToken = response.getAccessToken();
System.out.println("token---------->" + accessToken);
} catch (Exception e) {
e.printStackTrace();
}
//return accessToken;

List<String> username = null;
try {
URL url = new URL("URL");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
conn.setDoOutput(true);
String requestBody = "{\"filtercriteria\":{\"customproperty1\":\"Term\"}}";
byte[] input = requestBody.getBytes(StandardCharsets.UTF_8);
OutputStream os = conn.getOutputStream();
os.write(input, 0, input.length);

if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
StringBuilder responseBuilder = new StringBuilder();
while ((output = br.readLine()) != null) {
responseBuilder.append(output);
}

Gson gson = new Gson();
UserListResponse response = gson.fromJson(responseBuilder.toString(), UserListResponse.class);
List<Userlist> users = response.getUserlist();
username = users.stream().map(Userlist::getUsername).collect(Collectors.toList());
} catch (Exception e) {
e.printStackTrace();
}
for (String usernames : username) {
try {
System.out.println("API Calling for" + usernames);
URL url = new URL("URL");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
conn.setDoOutput(true);
String requestBody = "{\"analyticsname\":\"UserCustomAnalytics\",\"attributes\":{\"username\":"
+ usernames + "}}";
byte[] input = requestBody.getBytes(StandardCharsets.UTF_8);
OutputStream os = conn.getOutputStream();
os.write(input, 0, input.length);
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}

BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
StringBuilder responseBuilder = new StringBuilder();
while ((output = br.readLine()) != null) {
responseBuilder.append(output);
}

} catch (Exception e) {
e.printStackTrace();
}

}
}


}

nimitdave
Saviynt Employee
Saviynt Employee

Please try once by Changing the method definition to public void CustomMethod(String userJSON)

userJSON is the json of the user for which rule is invoked.

try with below method once:

public void customMethod(String userJson) {
System.out.println("userJson data : " + userJson);
}

09
New Contributor III
New Contributor III

Could you please share product documentation link about void method and what data it sends.  I tried searching but didnt found any.   

the solutions you provided is working. However, wondering is this documented or not?

rahul_p
Regular Contributor II
Regular Contributor II

Hello @nimitdave ,

Can you please tell me where are these System.out.println logs getting printed?

I am checking at Admin=>Admin Function => Log Viewer, but its not there.

Regards,

Rahul

petra_bremer
New Contributor III
New Contributor III

Does anyone here have a tip? I can't find the System.out output in the log either.

Regards

Petra

rahul_p
Regular Contributor II
Regular Contributor II

Hi @petra_bremer ,

You can refer below url and 2nd question in that has answer for you:

 https://forums.saviynt.com/t5/identity-governance/how-to-build-develop-custom-java-jar-solution/m-p/...

Thanks,

Rahul

petra_bremer
New Contributor III
New Contributor III

Thank you - really good and helpful summary !!!

yogesh
Regular Contributor III
Regular Contributor III

This information should be in the documentation but documentation only contains extremely basic information only.

I have given feedback on documentation that it should specify what arguments can be passed to the custom method. "userJson" is mentioned nowhere in the documentation.

Similarly it is not mentioned what saviynt expects the custom method to return or should it be just void.

Please can you add this information to the documentation itself? It would be better to have this information there than hunting random forum posts.

gaurav007
New Contributor II
New Contributor II

Thanks. It's Working now