WebService After Rule Error

Hi Team,

I am trying to call IDN API from webservices after rule to generate access token using client credentials. I am getting below error. Below are the method and error details,

API URL: https://tenantNAME.api.identitynow.com/oauth/token?grant_type=client_credentials&client_id=clientID&client_secret=clientSecret
Method: POST.

{
   "exception":{
      "stacktrace":"java.security.PrivilegedActionException: org.apache.bsf.BSFException: The application script threw an exception: java.net.SocketTimeoutException: Read timed out BSF info: SOURCENAME at line: 0 column: columnNo\n\tat java.base\/java.security.AccessController.doPrivileged(Native Method)\n\tat org.apache.bsf.BSFManager.eval(BSFManager.java:442)\n\tat sailpoint.server.BSFRuleRunner.eval(BSFRuleRunner.java:233)\n\tat sailpoint.server.BSFRuleRunner.runRule(BSFRuleRunner.java:203)\n\tat sailpoint.server.InternalContext.runRule(InternalContext.java:1229)\n\tat sailpoint.server.InternalContext.runRule(InternalContext.java:1201)\n\tat sailpoint.connector.DefaultConnectorServices.runRule(DefaultConnectorServices.java:96)\n\tat sailpoint.connector.DefaultConnectorServices.runRule(DefaultConnectorServices.java:126)\n\tat sailpoint.connector.CollectorServices.runRule(CollectorServices.java:1003)\n\tat sailpoint.connector.webservices.v2.RequestOrchestratorV2.handleAfterOperationRule(RequestOrchestratorV2.java:651)\n\tat sailpoint.connector.webservices.v2.RequestOrchestratorV2.processAfterRequest(RequestOrchestratorV2.java:457)\n\tat connector.sdk.webservices.ExecutionMediator.processEndpoint(ExecutionMediator.java:669)\n\tat connector.sdk.webservices.ExecutionMediator.process(ExecutionMediator.java:349)\n\tat sailpoint.connector.webservices.v2.WebServiceFacadeV2.addRemoveEntitlement(WebServiceFacadeV2.java:1277)\n\tat sailpoint.connector.webservices.v2.WebServiceFacadeV2.create(WebServiceFacadeV2.java:1006)\n\tat sailpoint.connector.webservices.v2.WebServiceFacadeV2.provision(WebServiceFacadeV2.java:474)\n\tat sailpoint.connector.webservices.WebServicesConnector.provision(WebServicesConnector.java:111)\n\tat sailpoint.connector.ConnectorProxy.provision(ConnectorProxy.java:1116)\n\tat com.sailpoint.ccg.cloud.container.Container.provision(Container.java:310)\n\tat com.sailpoint.ccg.cloud.container.ContainerIntegration.provision(ContainerIntegration.java:156)\n\tat com.sailpoint.ccg.handler.ProvisionHandler.invoke(ProvisionHandler.java:190)\n\tat sailpoint.gateway.accessiq.CcgPipelineMessageHandler.handleMessage(CcgPipelineMessageHandler.java:26)\n\tat com.sailpoint.pipeline.server.PipelineServer$InboundQueueListener$MessageHandler.run(PipelineServer.java:369)\n\tat java.base\/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)\n\tat java.base\/java.util.concurrent.FutureTask.run(FutureTask.java:264)\n\tat java.base\/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\n\tat java.base\/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\n\tat java.base\/java.lang.Thread.run(Thread.java:829)\nCaused by: org.apache.bsf.BSFException: The application script threw an exception: java.net.SocketTimeoutException: Read timed out BSF info: SOURCENAME at line: 0 column: columnNo\n\tat bsh.util.BeanShellBSFEngine.eval(BeanShellBSFEngine.java:193)\n\tat org.apache.bsf.BSFManager$5.run(BSFManager.java:445)\n\t... 28 more\n",
      "exception_class":"java.security.PrivilegedActionException"
   },
   "stack":"ccg",
   "pod":"stg02-apsoutheast2",
   "connector-logging":"146",
   "Operation":"Create",
   "clusterId":"38",
   "buildNumber":"771",
   "apiUsername":"eddd751d-dac3-4e4e-afb4-24175b47f961",
   "orgType":"staging",
   "file":"BSFManager.java",
   "encryption":"1266",
   "messageType":"provision",
   "connector-bundle-identityiq":"174",
   "line_number":451,
   "@version":1,
   "CB_version":"608",
   "logger_name":"org.apache.bsf.BSFManager",
   "mantis-client":"1266",
   "class":"org.apache.bsf.BSFManager",
   "ParentOperation":"ProvisioningOperation",
   "clientId":"123",
   "request_milliseconds":"3912",
   "source_host":"7371f0355d90",
   "method":"eval",
   "org":"tenantORG",
   "level":"ERROR",
   "IdentityIQ":"8.0 Build 2f61d76cf47-20220429-140148",
   "message":"Exception: ",
   "pipeline":"1266",
   "@timestamp":"2022-10-17T15:50:14.856Z",
   "NativeIdentity":"***",
   "thread_name":"pool-5-thread-8",
   "metrics":"1266",
   "region":"ap-southeast",
   "AppType":"Web Services",
   "Application":"NAME [source]",
   "request_id":"*************************",
   "CB_Type":"connector-bundle-webservices",
   "queue":"stg02-apsoutheast2-tenantORG-cluster-38",
   "SCIM Common":"8.0 Build 00b1f252d1b-20200225-190809"
}

Can someone please take a look at this?

Thanks,
Abhinov

I see there is a socketTimeoutException. Can you confirm that the VA can reach https://tenantname.api.identitynow.com/oauth/token? You can try logging into your VA and send a curl request with your client credentials to see if you can get a token.

You can use custom auth here instead of writing rule.
I believe standard client credentials also works fine without any customization. Not sure why you are going for cuztomization altogether.

Your Java socket is timing out (throws java.net.SocketTimeoutException: Connection timed out) means that it takes too long to get respond from other device and your request expires before getting response.

You can effectively handle it from client side by define a connection timeout and later handle it by using a try/catch/finally block. You can use the connect(SocketAddress endpoint, int timeout) method and set the timeout parameter:

Socket socket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(host, port);
socket.connect(socketAddress, 12000); //12000 are milli seconds

From server side you can use the setSoTimeout(int timeout) method to set a timeout value. The timeout value defines how long the ServerSocket.accept() method will block:

ServerSocket serverSocket = new new ServerSocket(port);
serverSocket.setSoTimeout(12000);

So to avoid this exception in another way, you should keep the connection be alive using the method Socket.setKeepAlive() method although possibly you have not used the method setTimeout() , meaning asking the socket to unlimited block to receive.