Copy URL endpoint
The purpose of the Copy URL endpoint is to copy an existing service instance and create a new service instance. AMS passes both the original service instance and the new service instance to the service's Copy URL. This is to enable the app developer the flexibility of storing or copying information (such as record definition) from the original service instance with the new service instance.
Note: If a Copy URL is not provided, AMS will treat copy as create, and call the app's Create URL instead.
Workflow
The following diagram illustrates the process of copying a service.
Service Copy URL endpoint
AMS calls the service's Copy URL endpoint with the following request.
Service URL
<service-baseUrl><service-copyUrl>
Request Method
POST
Request Header
Authorization: Bearer <JWT>
Content-Type=application/json
Bearer Token
JWT claims
When AMS is making the request to the App, the key and value pairs bear the following meanings:
Key | Value Definition | Context |
---|---|---|
iss
|
The issuer of the token. | Issuer is AMS |
sub
|
The subject of the token. | Set to the app's associated product uuid. |
aud
|
The audience of the token. | The App's Token Key. |
exp
|
The date and time the token will expire, expressed as a Unix timestamp. Must be after the current date/time. | Set to 60 seconds after the JWT was created. |
iat
|
The date and time the JWT was issued, expressed as a Unix timestamp. | Set to the current time. |
jti
|
The unique identifier for the JWT token. | Set to a random UUID |
o.a.p.ctenantId
|
The tenant Id. | Set to the id of the tenant as identified by the product |
o.a.p.cproductUUID
|
The product UUID. | Set to the product's UUID. |
o.a.p.cproductName
|
The product name. | Set to the product's name. |
o.a.p.csourceRequest
|
The source of the request. | Set to the product's UUID. |
o.a.p.cdestinationId
|
The destination Id. | Set to the app's token key (found in app details) |
o.a.p.cdestinationUrl
|
The destination URL. | Set to the service instance creation URL (the service's base URL + the service's create URL. These URLs are found in service details. |
Signature
Signed with an app's token secret.
When a service instance is copied, AMS sends the following payload to the app:
POST <service-base-url><service-copy-url>
Authorization: Bearer <JWT>
{
"originalApplicationServiceInstance": {
"status": "CREATED",
"assetId": "3iojr3d908",
"assetType": "campaign",
"uuid": "4420fa19-e8f6-4cdf-9754-d876dea3002f",
"secret": "c4321e9f-19a7-48b2-9796-c21142c709c9-fb24667dde63-4b6a-99af-10b23122a6d0",
"recordDefinition": {
//some valid record definition
...
},
"applicationServiceInstall": {
"uuid": "40fe3760-a487-4e89-8cf5-2d3e06977623",
"name": "Demo transform service for developer's test",
"description": "Demo transform service for developer's test",
"invokeUrl": "https://b3a3ba42.ngrok.io/CX-app-demo-1.0/rest/1.0/services/1/invoke",
"smallLogo": "https://www.iconexperience.com/_img/o_collection_png/green_dark_grey/48x48/plain/delivery_truck.png",
"mediumLogo": "https://www.iconexperience.com/_img/o_collection_png/green_dark_grey/128x128/plain/delivery_truck.png",
"largeLogo": "https://www.iconexperience.com/_img/o_collection_png/green_dark_grey/256x256/plain/delivery_truck.png",
"maxBatchSize": 200,
"application": {
"uuid": "b95d7bea-0154-47b8-81ca-ea4e35e784a9",
"name": "Demo App",
"description": "It is a demo app",
"baseUrl": "https://oap.p01.elqqa01.com/awesome-app",
"statusUrl": "/status",
"installUrl": "/install",
"configureUrl": "/configure",
"uninstallUrl": "/uninstall",
"saveConfigurationUrl": "/save",
"smallLogo":"https://images.martechadvisor.com/images/uploads/product_logos/Oracle%20Responsys.jpeg",
"mediumLogo":"https://images.martechadvisor.com/images/uploads/product_logos/Oracle%20Responsys.jpeg",
"largeLogo":"https://images.martechadvisor.com/images/uploads/product_logos/Oracle%20Responsys.jpeg",
"status": "UP",
"providerUuid": "9dbda2d4-e9ac-4aab-8886-be0402a662cb"
},
"serviceType": {
"name": "ACTIVITY",
"externalName": "Activity",
"description": "This service will ingest data and send it to an external service or process it to return back a status or modified data"
},
"installUuid": "05860261-2f24-4639-ae38-3616306e3f2d",
"productName": "Responsys",
"providerName": "ResponsysApps",
"status": "UP"
}
},
"newApplicationServiceInstance": {
"status": "CREATED",
"assetId": "k2lr4ijosd",
"assetType": "campaign",
"uuid": "8088b46e-93f3-4c71-b7c3-96a7d9dc9293",
"secret": "c8292396-2ab3-4bb8-b6de-f651d3704f6b-62d71c64-1de9-476a-ac34-4f7ac1cc300e",
"recordDefinition": null,
"applicationServiceInstall": {
"uuid": "40fe3760-a487-4e89-8cf5-2d3e06977623",
"name": "Demo transform service for developer's test",
"description": "Demo transform service for developer's test",
"invokeUrl": "https://b3a3ba42.ngrok.io/CX-app-demo-1.0/rest/1.0/services/1/invoke",
"smallLogo": "https://www.iconexperience.com/_img/o_collection_png/green_dark_grey/48x48/plain/delivery_truck.png",
"mediumLogo": "https://www.iconexperience.com/_img/o_collection_png/green_dark_grey/128x128/plain/delivery_truck.png",
"largeLogo": "https://www.iconexperience.com/_img/o_collection_png/green_dark_grey/256x256/plain/delivery_truck.png",
"maxBatchSize": 200,
"application": {
"uuid": "b95d7bea-0154-47b8-81ca-ea4e35e784a9",
"name": "Demo App",
"description": "It is a demo app",
"baseUrl": "https://oap.p01.elqqa01.com/awesome-app",
"statusUrl": "/status",
"installUrl": "/install",
"configureUrl": "/configure",
"uninstallUrl": "/uninstall",
"saveConfigurationUrl": "/save",
"smallLogo":"https://images.martechadvisor.com/images/uploads/product_logos/Oracle%20Responsys.jpeg",
"mediumLogo":"https://images.martechadvisor.com/images/uploads/product_logos/Oracle%20Responsys.jpeg",
"largeLogo":"https://images.martechadvisor.com/images/uploads/product_logos/Oracle%20Responsys.jpeg",
"status": "UP",
"providerUuid": "9dbda2d4-e9ac-4aab-8886-be0402a662cb"
},
"serviceType": {
"name": "ACTIVITY",
"externalName": "Activity",
"description": "This service will ingest data and send it to an external service or process it to return back a status or modified data"
},
"installUuid": "05860261-2f24-4639-ae38-3616306e3f2d",
"productName": "Responsys",
"providerName": "ResponsysApps",
"status": "UP"
}
}
}
Tip: The JWT Token in the Authorization Header is generated by following the AMS to App token generation. For more information about this call, including authentication details, see the endpoint API reference.
App's response to the Copy URL request
The service's Copy URL endpoint may either send back an empty response or a record definition. If the app responds with a 2xx response code, a service instance is created. It is up to the app developer to determine what they would like to store or copy from the original service instance.
Sample code for a record definition response
@RequestMapping(value = "/copy", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity copyServiceInstance(@RequestBody ServiceInstanceCopyRequestDTO requestBody) {
ModelMapper mapper = new ModelMapper();
if (requestBody == null) {
throw new IllegalArgumentException("Empty payload sent to create url");
}
// See ModelMappingConfiguration.java for how ServiceInstance is populated from ServiceInstanceCreateRequestDTO
ServiceInstance newServiceInstance = mapper.map(requestBody.getNewInstance(), ServiceInstance.class);
// New service instance will copy the record definition from the original service instance.
newServiceInstance.setRecordDefinition(requestBody.getOriginalInstance().getRecordDefinition());
// New service instance will copy the configuration mappings stored by the app
ServiceInstance originalServiceInstance = serviceInstanceService.getEntity(
requestBody.getOriginalApplicationServiceInstance().getUuid());
newServiceInstance.setConfig(originalServiceInstance.getConfig());
newServiceInstance.setStatus(originalServiceInstance.getStatus());
serviceInstanceService.addEntity(newServiceInstance);
return new ResponseEntity<RecordDefinitionDTO>(newServiceInstance.getRecordDefinition(), HttpStatus.OK);
}
Note: Both AMS and the app should save service instances and be in sync.
Sample JSON payload for a record definition
If responding with a record definition, the record definition must resemble the following. See Record definitions for more information.

{
"inputParameters": [
{
"name": "appcloud_row_correlation_id",
"dataType": "Text",
"width": 40,
"unique": true,
"required": true,
"readOnly": null,
"minimumValue": null,
"maximumValue": null,
"possibleValues": null,
"format": null,
"resources": null
}
],
"outputParameters": [
{
"name": "appcloud_row_correlation_id",
"dataType": "Text",
"width": 40,
"unique": true,
"required": true,
"readOnly": null,
"minimumValue": null,
"maximumValue": null,
"possibleValues": null,
"format": null,
"resources": null
},
{
"name": "appcloud_row_status",
"dataType": "Text",
"width": 10,
"unique": null,
"required": true,
"readOnly": null,
"minimumValue": null,
"maximumValue": null,
"possibleValues": [
"success",
"warning",
"failure"
],
"format": null,
"resources": null
},
{
"name": "appcloud_row_errormessage",
"dataType": "Text",
"width": 5120,
"unique": null,
"required": null,
"readOnly": null,
"minimumValue": null,
"maximumValue": null,
"possibleValues": null,
"format": null,
"resources": null
}
]
}