-
Notifications
You must be signed in to change notification settings - Fork 3
Http Callout Local Example
This sample uses the Vault Java SDK HttpService and JsonService interfaces to implement this functionality. These services are available for making HTTP Callouts from within the Vault Java SDK.
For full details on the interfaces and methods used, please review the Javadocs.
This example only operates on the vSDK Http Doctype document in the draft state.
The vSDKLocalHttpCalloutAction document action and vSDKHttpCallouts user-defined class demonstrate how to use an HTTP Callout to make Vault API call within a single local vault.
The example prompts the user for a new owner, viewer, and editor and those roles are updated. Once updated, an HTTP Callout is made to retrieve document actions and then initiate the document's workflow.
- The vSDKLocalHttpCalloutAction - takes user input from the
vSDK User Input Objectand sets new roles on a document. Once the roles have been modified, an HTTP Callout is made to initiate a workflow against the new owner.- A User Action Prompt is utilized to allow the user to input new data.
- This new data is used to assign the new users to relevant roles on the document.
- Once assigned, the HTTP Callout functionality starts a document workflow.
- The vSDKHttpCallouts contains the
localGetLifecycleActionsandlocalStartDocWorkflowmethods to start a local HTTP Callout.
The vSDKLocalHttpCalloutAction Document Action prompts the user for input of new users that should be assigned to various roles on the document.
After DocumentRoleService#batchUpdateDocumentRolesruns successfully (the new roles have been assigned), then the local HTTP Callout vSDKHttpCallouts.localGetLifecycleActions is made to retrieve the document's lifecycle actions and then initiate a workflow.
@DocumentActionInfo(label="SDK: Local Http Callout", user_input_object="vsdk_user_input_object__c", user_input_object_type="")
public class vSDKLocalHttpCalloutAction implements DocumentAction {
public void execute(DocumentActionContext documentActionContext) {
...
if (documentRoleUpdates.size() > 0) {
docRoleService.batchUpdateDocumentRoles(documentRoleUpdates)
.rollbackOnErrors()
.execute();
logService.info("Document Role update successful.");
//Delete temporary user input record
recordService.batchDeleteRecords(VaultCollections.asList(inputRecord)).rollbackOnErrors().execute();
//Loop through all documents and initiate the APR Document workflow for the new owner (manager) of the record.
for (DocumentVersion docVersion : docVersionList) {
String version_id = docVersion.getValue("id", ValueType.STRING) + "_" +
docVersion.getValue("major_version_number__v", ValueType.NUMBER).toString() + "_" +
docVersion.getValue("minor_version_number__v", ValueType.NUMBER).toString();
vSDKHttpCallouts.localGetLifecycleActions(version_id, userToRoleMap.get(OWNER), params);
}
}
}Now that user roles have been updated and a new owner exists, the vSDKHttpCallouts.localGetLifecycleActions directly initiates an HttpService callout against the local target vault.
This is done with httpService.newLocalHttpRequest(). The method creates a connection using the user that runs the Vault API call.
HttpRequest request = httpService.newLocalHttpRequest()Alternatively, you can create a local Connection record that will always use the specificed Authorized Connection User to make the local callout.
The method makes a Vault API call against https://developer.veevavault.com/api/19.1/#retrieve-user-actions to determine the name of the required Document Lifecycle Action.
The HttpRequest object works similar to other Java based HTTP request libraries. We can set the method, path, header, and body.
Here we use the current document's ID, major version, and minor version to initiate the Vault API call.
For our path, we only have to append the API portion after the DNS - e.g., /api/v19.1/objects/documents/{docId}/versions/{major_version}/{minor_version}/lifecycle_actions. The full DNS name is included by default when you create the request against the Connection record.
/**
* Runs against a local API connection to locate and verify the correct document workflow.
* This is necessary so that the proper workflow is started when this method is used.
* See https://developer.veevavault.com/api/19.1/#retrieve-user-actions for details
*
* @param versionId of the document
* @param userId of the document owner
* @param params for API input
*/
public static void localGetLifecycleActions(String versionId, String userId, Map<String,String> params) {
LogService logService = ServiceLocator.locate(LogService.class);
HttpService httpService = ServiceLocator.locate(HttpService.class);
String[] version_id = StringUtils.split(versionId, "_");
//A `newLocalHttpRequest` is an Http Callout against the same vault (local) using the user that initiated the SDK code.
//The user must have access to the action being performed or the Vault API will return an access error.
HttpRequest request = httpService.newLocalHttpRequest()
.setMethod(HttpMethod.GET)
.appendPath("/api/v19.1/objects/documents/" + version_id[0] + "/versions/" + version_id[1] + "/" + version_id[2] + "/lifecycle_actions");
...
}The HttpRequest is now setup and ready to be sent to the source vault. With the /api/v19.1/objects/documents/{docId}/versions/{major_version}/{minor_version}/lifecycle_actions endpoint, we want to receive JSON data back so you send the request with the HttpResponseBodyValueType.JSONDATA parameter value.
When the HttpRequest response from the local vault is received, it can be parsed through using the JsonService class.
The response values are used to determine if the required Document Lifecycle Action was located on the current document state and if it was, then initiate the workflow.
- First, the response is parsed into a
JsonDataobject - From the response, the
getJsonObject()will get the response as a parseableJsonObject- Here the
getValuemethod can be used to retrieveresponseStatus,responseDetails, andlifecycleActions
- Here the
- The
lifecycleActionselement is an array of JSON data. This is parsed into aJsonArrayobject.- Each lifecycle action is returned as an element of the array and must be parsed into a
JsonObject. - Individual fields can then be retrieved from each
JsonObjectthat is in theJsonArray.
- Each lifecycle action is returned as an element of the array and must be parsed into a
public static void localGetLifecycleActions(String versionId, String userId, Map<String,String> params) {
...
httpService.send(request, HttpResponseBodyValueType.JSONDATA)
.onSuccess(httpResponse -> {
int responseCode = httpResponse.getHttpStatusCode();
logService.info("RESPONSE: " + responseCode);
logService.info("RESPONSE: " + httpResponse.getResponseBody());
JsonData response = httpResponse.getResponseBody();
if (response.isValidJson()) {
String responseStatus = response.getJsonObject().getValue("responseStatus", JsonValueType.STRING);
if (responseStatus.equals("SUCCESS")) {
logService.info("Verifying Lifecycle Actions for document - " + String.join("_", version_id));
JsonArray lifecycleActions = response.getJsonObject().getValue("lifecycle_actions__v", JsonValueType.ARRAY);
for (int count = 0; count < lifecycleActions.getSize(); count++) {
JsonObject action = lifecycleActions.getValue(count, JsonValueType.OBJECT);
String actionLabel = action.getValue("label__v", JsonValueType.STRING);
//If the correct action label is located, initiate `localStartDocWorkflow` to start the document workflow.
if (actionLabel.contains("Start HTTP Workflow")) {
logService.info("Located the workflow action '{}'", actionLabel);
String actionName = action.getValue("name__v", JsonValueType.STRING);
vSDKHttpCallouts.localStartDocWorkflow(versionId, userId, params, actionName);
}
}
}
...
}
})
.onError(httpOperationError -> {
int responseCode = httpOperationError.getHttpResponse().getHttpStatusCode();
logService.info("RESPONSE: " + responseCode);
logService.info(httpOperationError.getMessage());
logService.info(httpOperationError.getHttpResponse().getResponseBody());
})
.execute();
}If the vSDKHttpCallouts.localGetLifecycleActions determines that the current document state has an action called Start HTTP Workflow, then we can initiate the workflow with vSDKHttpCallouts.localStartDocWorkflow
public static void localGetLifecycleActions(String versionId, String userId, Map<String,String> params) {
...
JsonArray lifecycleActions = response.getJsonObject().getValue("lifecycle_actions__v", JsonValueType.ARRAY);
for (int count = 0; count < lifecycleActions.getSize(); count++) {
JsonObject action = lifecycleActions.getValue(count, JsonValueType.OBJECT);
String actionLabel = action.getValue("label__v", JsonValueType.STRING);
//If the correct action label is located, initiate `localStartDocWorkflow` to start the document workflow.
if (actionLabel.contains("Start HTTP Workflow")) {
logService.info("Located the workflow action '{}'", actionLabel);
String actionName = action.getValue("name__v", JsonValueType.STRING);
vSDKHttpCallouts.localStartDocWorkflow(versionId, userId, params, actionName);
}
}
...The vSDKHttpCallouts.localStartDocWorkflow uses the https://developer.veevavault.com/api/19.1/#initiate-user-action API to start the workflow.
As with the previous HTTP Callout, this uses the current document's ID, major version, and minor version to initiate the Vault API call against a HttpService.newLocalHttpRequest() connection. The code then uses the new owner from the role change as the workflows Approver and appends any additional body parameters.
/**
* Runs against a local API connection to initiate a document workflow
* The workflow is initiated for the "userId" which is the owner of the document.
* See https://developer.veevavault.com/api/19.1/#initiate-user-action for details.
*
* @param versionId of the document
* @param userId of the document owner
* @param params for API input
* @param action starts the document workflow
*/
public static void localStartDocWorkflow(String versionId, String userId, Map<String,String> params, String action) {
LogService logService = ServiceLocator.locate(LogService.class);
HttpService httpService = ServiceLocator.locate(HttpService.class);
String[] version_id = StringUtils.split(versionId, "_");
//A `newLocalHttpRequest` is an Http Callout against the same vault (local) using the user that initiated the SDK code.
//The user must have access to the action being performed or the Vault API will return an access error.
HttpRequest request = httpService.newLocalHttpRequest()
.setMethod(HttpMethod.PUT)
.appendPath("/api/v19.1/objects/documents/" + version_id[0] + "/versions/" + version_id[1] + "/" + version_id[2] + "/lifecycle_actions/" + action)
.setBodyParam("Approver", "user:" + userId);
for (String key : params.keySet()) {
request.setBodyParam(key,params.get(key));
}
...As with the previous method, a Json Data response is received and then processed for the JsonData, JsonObject, and JsonArray classes.
public static void localStartDocWorkflow(String versionId, String userId, Map<String,String> params, String action) {
...
httpService.send(request, HttpResponseBodyValueType.JSONDATA)
.onSuccess(httpResponse -> {
int responseCode = httpResponse.getHttpStatusCode();
logService.info("RESPONSE: " + responseCode);
logService.info("RESPONSE: " + httpResponse.getResponseBody());
JsonData response = httpResponse.getResponseBody();
//This API call just initiates a workflow. Log success or errors messages depending on the results of the call.
if (response.isValidJson()) {
String responseStatus = response.getJsonObject().getValue("responseStatus", JsonValueType.STRING);
if (responseStatus.equals("SUCCESS")) {
logService.info("Starting HTTP Workflow for document - " + String.join("_", version_id));
}
...
}
})
.onError(httpOperationError -> {
int responseCode = httpOperationError.getHttpResponse().getHttpStatusCode();
logService.info("RESPONSE: " + responseCode);
logService.info(httpOperationError.getMessage());
logService.info(httpOperationError.getHttpResponse().getResponseBody());
})
.execute();
...
}