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

REST Account Import

JohnLawson
Regular Contributor
Regular Contributor

I'm trying to import accounts via REST but before it gets very far, I get:

Error - to Import Data correctly: No content to
map due to end-of-input at [Source: ; line: 1,
column: 0]

Does this have to do with the Connection JSON or the ImportUser JSON?

 

Here is the full stack:

2022-07-27T15:52:49.03442627Z stdout F com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
2022-07-27, 10:52 am
ecm-worker
2022-07-27T15:52:49.034435971Z stdout F at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
2022-07-27, 10:52 am
ecm-worker
2022-07-27T15:52:49.034438771Z stdout F at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:3854)
2022-07-27, 10:52 am
ecm-worker
2022-07-27T15:52:49.034449771Z stdout F at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3799)
2022-07-27, 10:52 am
ecm-worker
2022-07-27T15:52:49.034453271Z stdout F at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2877)
2022-07-27, 10:52 am
ecm-worker
2022-07-27T15:52:49.034457571Z stdout F at com.saviynt.provisoning.rest.RestProvisioningService.initializeConnectionForImport(RestProvisioningService.groovy:1863)
2022-07-27, 10:52 am
ecm-worker
2022-07-27T15:52:49.034462871Z stdout F at com.saviynt.provisoning.rest.RestProvisioningService.doImport(RestProvisioningService.groovy:121)
2022-07-27, 10:52 am
ecm-worker
2022-07-27T15:52:49.034467472Z stdout F at com.saviynt.ecm.integration.ExternalConnectionCallService.invokeExternalMethod(ExternalConnectionCallService.groovy:227)

 

16 REPLIES 16

sahajranajee
Saviynt Employee
Saviynt Employee

Hi @JohnLawson ,

Could you please share the import JSON being used?


Regards,
Sahaj Ranajee
Sr. Product Specialist

{
"accountParams": {
"connection": "acctAuth",
"processingType": "SequentialAndIterative",
"statusAndThresholdConfig": {
"statusColumn": "customproperty7",
"activeStatus": [
"true"
],
"deleteLinks": true,
"accountThresholdValue": 20,
"correlateInactiveAccounts": false,
"inactivateAccountsNotInFile": false,
"deleteAccEntForActiveAccounts": false
},
"call": {
"call1": {
    "callOrder": 0,
    "stageNumber": 0,
    "http": {
    "url": "https://XXXX/integrations/v1/Users?$top=500",
    "httpHeaders": {
    "Authorization": "${access_token}",
    "X-IN8-TENANT-PREFIX": "XXXX",
    "Ocp-Apim-Subscription-Key": "XXXX"
    },
    "httpMethod": "GET",
    "httpContentType": "application/json"
    },
    "makeProcessingStatus": true
},
"call2": {
    "callOrder": 1,
    "stageNumber": 1,
    "http": {
    "url": "${response?.headers?.Location?}",
    "httpHeaders": {
    "Authorization": "${access_token}",
	"X-IN8-TENANT-PREFIX": "XXX",
    "Ocp-Apim-Subscription-Key": "XXXXX"
    },
    "httpMethod": "GET",
    "httpContentType": "application/json"
    },
    "inputParams": {
    "dependentCall": true
    },
    "listField": "value",
    "keyField": "accountID",
    "nextApiKeyField": "accountID",
    "colsToPropsMap": {
    "status": "IsActive~#~bool",
    "accountID": "DisplayUserId~#~string",
    "validthrough": "EndDate~#~date"
    }
}
},

"pagination": {
    "offset": {
      "offsetParam": "Offset",
      "batchParam": "Max",
      "batchSize": 500,
      "totalCountPath": "total_count"
    },
    "nextUrl": {
      "nextUrlPath": "${response?.body?.size()>0?'https://XXX/integrations/v1/Users?$top=500&$skip=' + Math.addExact(total_count,500):null}"
    }
  }
}
}

The API is a bit weird in that a call has to be made first using the URI params, it then returns a Location header with the link for the next call that will then return the data.

Any thoughts?

What is end application name? 


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

It is a specialty software called InEight

rushikeshvartak
All-Star
All-Star

A simple fix could be Content-Type: application/json

"httpContentType":"application/json"


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

ranudeepreddy
New Contributor II
New Contributor II

Have you checked that are you using right Job?

Can you confirm that you didn't use this JSON in User Import/any thing?

Confirm that you are using this as Account Import JSON and running Account Import Job.

That was indeed part of the issue. I had it in the user import not account import.

JohnLawson
Regular Contributor
Regular Contributor

Now I am getting the following error:

DEBUG rest.RestProvisioningService  - Exception in persistAccounts try2 :
java.lang.NullPointerException: Cannot invoke method trim() on null object

Can you share accounimport json & api response


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

The accountimport json is in an above comment and here are the logs showing a 202 response:

DEBUG rest.RestProvisioningService  -
DEBUG rest.RestProvisioningService  - pullObjectsByRest - responseStatusCode ::202
DEBUG rest.RestProvisioningService  - Entered getResponseHeaders method
DEBUG rest.RestProvisioningService  - responseError : null
DEBUG rest.RestProvisioningService  - isAuthError: false
DEBUG rest.RestProvisioningService  - pullObjectsByRest - responseMap.size : 0
DEBUG rest.RestProvisioningService  - pullObjectsByRest - objectList.size : 1
DEBUG rest.RestProvisioningService  - Inside importAccountsFull:persistAccounts, pptTypeSep : ~#~
DEBUG rest.RestProvisioningService  - Exception in persistAccounts try2 :
stdout F java.lang.NullPointerException: Cannot invoke method trim() on null object
stdout F at com.saviynt.provisoning.rest.RestProvisioningService.persistAccounts(RestProvisioningService.groovy:4733)
stdout F at com.saviynt.provisoning.rest.RestProvisioningService.processAccountsByPagination(RestProvisioningService.groovy:4080)
stdout F at com.saviynt.provisoning.rest.RestProvisioningService.processAccounts(RestProvisioningService.groovy:3987)
stdout F at com.saviynt.provisoning.rest.RestProvisioningService$_processAccountsFinal_closure11_closure78.doCall(RestProvisioningService.groovy:1635)
stdout F at com.saviynt.provisoning.rest.RestProvisioningService$_processAccountsFinal_closure11.doCall(RestProvisioningService.groovy:1631)
stdout F at com.saviynt.provisoning.rest.RestProvisioningService.processAccountsFinal(RestProvisioningService.groovy:1630)
stdout F at com.saviynt.provisoning.rest.RestProvisioningService.processAccountsFullBySequentialAndIterative(RestProvisioningService.groovy:1592)
stdout F at com.saviynt.provisoning.rest.RestProvisioningService.importAccountsFull(RestProvisioningService.groovy:1423)
stdout F at com.saviynt.provisoning.rest.RestProvisioningService.doImport(RestProvisioningService.groovy:137)
stdout F at com.saviynt.ecm.integration.ExternalConnectionCallService.invokeExternalMethod(ExternalConnectionCallService.groovy:227)
stdout F at ApplicationDataImportJob.execute(ApplicationDataImportJob.groovy:206)
stdout F at org.quartz.core.JobRunShell.run(JobRunShell.java:199)

Add this is colsToPropsMap

"name": "DisplayUserId~#~string",


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

Still getting:
Error - to Import Data correctly: Cannot invoke
method trim() on null object

 

{
"accountParams": {
"connection": "acctAuth",
"processingType": "SequentialAndIterative",
"statusAndThresholdConfig": {
"statusColumn": "customproperty7",
"activeStatus": [
"true"
],
"deleteLinks": true,
"accountThresholdValue": 20,
"correlateInactiveAccounts": false,
"inactivateAccountsNotInFile": false,
"deleteAccEntForActiveAccounts": false
},
"call": {
"call1": {
    "callOrder": 0,
    "stageNumber": 0,
    "http": {
    "url": "https://XXXX/integrations/v1/Users?$top=500",
    "httpHeaders": {
    "Authorization": "${access_token}",
    "X-IN8-TENANT-PREFIX": "XXXX",
    "Ocp-Apim-Subscription-Key": "XXXX"
    },
    "httpMethod": "GET",
    "httpContentType": "application/json"
    },
    "makeProcessingStatus": true
},
"call2": {
    "callOrder": 1,
    "stageNumber": 1,
    "http": {
    "url": "${response?.headers?.Location?}",
    "httpHeaders": {
    "Authorization": "${access_token}",
	"X-IN8-TENANT-PREFIX": "XXX",
    "Ocp-Apim-Subscription-Key": "XXXXX"
    },
    "httpMethod": "GET",
    "httpContentType": "application/json"
    },
    "inputParams": {
    "dependentCall": true
    },
    "listField": "value",
    "keyField": "accountID",
    "nextApiKeyField": "accountID",
    "colsToPropsMap": {
   "name": "DisplayUserId~#~char",
    "accountID": "DisplayUserId~#~char"
    }
}
},

"pagination": {
    "offset": {
      "offsetParam": "Offset",
      "batchParam": "Max",
      "batchSize": 500,
      "totalCountPath": "total_count"
    },
    "nextUrl": {
      "nextUrlPath": "${response?.body?.size()>0?'https://XXX/integrations/v1/Users?$top=500&$skip=' + Math.addExact(total_count,500):null}"
    }
  }
}
}

 

 

This is changed

"name": "DisplayUserId~#~char",
"accountID": "DisplayUserId~#~char"

 


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

So I tried that but it still gave the trim error. Working backwards from that I hardcoded some values and removed the first call which seems to be the issue. I was able to get a success (but no accounts) using:


{
  "accountParams": {
    "connection": "userAuth",
    "processingType": "SequentialAndIterative",
    "statusAndThresholdConfig": {
      "statusColumn": "customproperty7",
      "activeStatus": [
        "true"
      ],
      "deleteLinks": true,
      "accountThresholdValue": 20,
      "correlateInactiveAccounts": false,
      "inactivateAccountsNotInFile": false,
      "deleteAccEntForActiveAccounts": false
    },
    "call": {
      "call1": {
        "callOrder": 1,
        "stageNumber": 1,
        "http": {
          "url": "https://XXX.hds.ineight.comXXX",
          "httpHeaders": {
            "Authorization": "Bearer XXX",
            "X-IN8-TENANT-PREFIX": "XXX",
            "Ocp-Apim-Subscription-Key": "XXX"
          },
          "httpMethod": "GET",
          "httpContentType": "application/json"
        },
        "inputParams": {
          "dependentCall": true
        },
        "listField": "value",
        "keyField": "accountID",
        "nextApiKeyField": "accountID",
        "colsToPropsMap": {
          "accountID": "SourceSystemId~#~char"
        }
      }
    }
  }
}

 

I can't figure out what is wrong with the first call that is causing the trim error. The only thing I can think would be ${response.headers.get('Location')} but I tried removing that and still got the trim error. Am I doing the 2 call format correctly?