Synchronous comparison is used when the response is obtained quickly and where the DocBook file is returned as part of the response.
However in other cases asynchronous comparison is useful:
-
If there is a risk of HTTP timeout
-
When using HTTP or Cloud IO - as the REST service will need to make HTTP requests to retrieve these resources
-
Using large inputs
-
When the comparison result is needed somewhere other than where the response is returned
-
Where progress, logging or resource consumption information is needed
-
When multiple comparisons can be started at once
XML / JSON Request
Whether using XML or JSON, an asynchronous comparison will use the async element to specify the optional values callback and output.
-
callbackprovides a callback URL that the REST service will make aGETrequest to after the comparison is complete. This is detailed in Callbacks below. -
outputallows you to specify a location for the result to be written to. For more information see I/O Types
The response will consist of the created Job, and a Location header pointing to where you can poll the Job status.
Request (XML)
<comparison>
<inputA type="http">
<uri>http://www.example.com/file1.xml</uri>
</inputA>
<inputB type="http">
<uri>http://www.example.com/file2.xml</uri>
</inputB>
<configuration>
<uri>http://www.example.com/configuration</uri>
</configuration>
<async>
<callback>http://www.example.com/comparison-callback</callback>
<output type="file">
<path>/Users/exampleUser/Documents/result.xml</path>
</output>
</async>
</comparison>
Request (JSON)
{
"inputA": {
"type": "http",
"uri": "http://www.example.com/file1.xml"
},
"inputB": {
"type": "http",
"uri": "http://www.example.com/file2.xml"
},
"configuration": {
"type": "file",
"path" : "/usr/local/deltaxml/DeltaXML-DocBook-Compare-11_0_0/resources/config.xml"
},
"async": {
"callback": "http://www.example.com/comparison-callback",
"output": {
"type": "file",
"path": "/Users/exampleUser/Documents/result.xml"
}
}
}
Response (XML)
<job>
<jobId>12346124</jobId>
<startTime>2022-11-15T13:55:32.484+0000</startTime>
<jobStatus>PROCESSING</jobStatus>
<phaseDescription>Comparison in progress</phaseDescription>
<totalNumberOfStages>23</totalNumberOfStages>
<currentStage>15</currentStage>
</job>
Response (JSON)
{
"jobId": 123456124,
"startTime": "2022-11-15T13:55:32.484+0000",
"jobStatus": "PROCESSING",
"phaseDescription": "Comparison in progress",
"totalNumberOfStages": 23,
"currentStage": 15
}
Form Request
When using multipart/form-data, set the parameter async to true.
You can also use the parameters callback and keepResult in a similar fashion to XML / JSON async requests.
.....
Content-Disposition: form-data; name= "async"
true
--boundary
Content-Disposition: form-data; name= "callback"
http: //www.example.com/comparison-callback
--boundary
Content-Disposition: form-data; name= "output"
/Users/exampleUser/Documents/out.xml
--boundary
.....
Jobs
For each async comparison a Job is created. The jobs can be read from the /jobs/{jobId} endpoint. For example, you can poll for the Job's status:
Request
GET /api/docbook-compare/v1/jobs/12346124
Response (XML)
<job>
<jobId>3180d315-fc13-42a4-a872-fca1126274b6</jobId>
<startTime>2021-11-15T13:50:58.528+0000</startTime>
<jobStatus>PROCESSING</jobStatus>
<totalNumberOfStages>23</totalNumberOfStages>
<currentStage>15</currentStage>
</job>
Response (JSON)
{
"jobId": 123456124,
"startTime": "2022-11-15T13:55:32.484+0000",
"jobStatus": "PROCESSING",
"totalNumberOfStages": 23,
"currentStage": 15
}
You can see that the comparison is currently in progress on stage 15 of 23, but some time later...
Response (XML)
<job>
<jobId>5e3e85ec-b1eb-45d8-9295-238767881e97</jobId>
<startTime>2022-11-15T13:55:32.484+0000</startTime>
<finishedTime>2022-11-15T13:55:44.249+0000</finishedTime>
<jobStatus>SUCCESS</jobStatus>
<output type="http">
<size>20409</size>
<uri>http://0.0.0.0:8080/api/docbook-compare/v1/downloads/5e3e85ec-b1eb-45d8-9295-238767881e97</uri>
</output>
<totalNumberOfStages>23</totalNumberOfStages>
<currentStage>23</currentStage>
</job>
Response (JSON)
{
"jobId": 123456124,
"startTime": "2022-11-15T13:55:32.484+0000",
"finishedTime": "2022-11-15T13:55:44.249+0000",
"jobStatus": "SUCCESS",
"output: [
{
"size": 20409,
"uri":
}
]
"totalNumberOfStages": 23,
"currentStage": 23
}
...the comparison is now finished.
Job Model
The Job contains the following objects:
|
Object |
Description |
|---|---|
|
|
The ID of the Job |
|
|
ISO 8601 timestamp when the comparison started. Depending on the number of queued jobs, there may be significant time between |
|
|
ISO 8601 timestamp when the comparison started. |
|
|
ISO 8601 timestamp of when the comparison finished. |
|
|
An enumeration of the state of the comparison. States include:
|
|
|
Number of stages in the pipeline, as an integer. |
|
|
The current stage of the comparison. |
|
|
Specifies where the result has been output to. |
|
|
Contains error information if an error happened. See Errors Page for more information. |
When using Cloud I/O output will contain the Cloud I/O information provided minus the client ID / secret information for security reasons, for example:
<output type="s3">
<region>EU-WEST-1</region>
<bucket>DeltaXML-Bucket</bucket>
<fileName>output.xml</fileName>
</output>
If not using Cloud I/O for the output, then it will contain a uri and size (which provides the result size in bytes - as an integer). For example:
<output type="http">
<uri>http://localhost:8080/api/docbook-compare/v1/downloads/12346124</uri>
<size>390</size>
</output>
If the comparison failed, an error element will contain details of the failure, including a stack trace which can help diagnose the issue. The size of the result is reported in terms of bytes.
A GET request to the output uri will then complete the asynchronous lifecycle:
Request
GET /api/docbook-compare/v1/downloads/123456
Response
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://missing.deltaxml.com/non-existent.dtd">
<article>
<title>Article Title</title>
<sect1>
<title>
<phrase revisionflag="deleted">Section1</phrase>
<phrase revisionflag="added">Section2</phrase> Title
</title>
<para>This file points to a non-existent dtd in its DOCTYPE. This forces it to use the catalog and therefore check that it works</para>
</sect1>
</article>
Note
If the POST request specified an output file location, the output file will be available at that location after a successful asynchronous comparison. A GET request from the downloads resource will merely provide the same file from that location.
Cancelling a Job
Jobs can be cancelled while they are queued or running, it is invoked by using a DELETE request to the specified Job:
Request
DELETE /api/docbook-compare/v1/jobs/12346124
The response will be the Job, note the jobStatus is now CANCELLED:
Response (XML)
<job>
<creationTime>2022-11-15T11:31:20.863+01:00</creationTime>
<jobStatus>CANCELLED</jobStatus>
<totalNumberOfStages>0</totalNumberOfStages>
</job>
Response (JSON)
{
"creationTime": "2022-11-15T11:31:20.863+01:00",
"jobStatus": "CANCELLED",
"totalNumberOfStages": 0
}
Callbacks
If the user registered a callback URL with the comparison request, the REST service will attempt an HTTP GET to that URL on completion of the comparison.
In this example the callback URL "http://www.example.com/comparison-callback" was registered in the comparison request - we will add a request parameter of jobId which allows the Job resource to be located:
Request
GET http://www.example.com/comparison-callback?jobId=12346124