ICAT provides both a SOAP and a RESTful web service to communicate with the core ICAT code which makes calls to a relational DBMS. This document describes the RESTful interface but assumes some knowledge of ICAT as explained in the ICAT Java Client manual.
For each call the Java annotations in the server code are shown as these indicate precisely what is expected. @POST, @PUT, @DELETE and @GET denote the method and @Path shows the relative url path. They are all relative to "icat". The @Consumes and @Produces shows the expected format of the body of the message.
In the case of an error from the ICAT code the returned json will be of the form: {"code":"BAD_PARAMETER", "message":"password too short", "offset":"0"} where the offset (which shows the offset to the entity which caused the error) will be omitted when it is not relevant. The status code will correspond to the type of the ICAT exception as shown by the code value. In the case of any other error, the code field will always be "INTERNAL", the offset will always be omitted and the status code will be 500 ("Internal Server Error"). Clients should always check the status code and if status/100 is not 2 then an error has occured.
The @GET calls can be tried on a web browser and curl can be used to make any of the calls. For example a url of the form: https://example.com:443/icat/version will return some json such as {"version":"4.4.0"}
To obtain a new session.
@POSTThe form parameter is:
To obtain information about a session.
@GETThe path parameter is:
To create one or more entities in ICAT
@POSTThe form parameters are:
To search for information in ICAT. This includes the functionality of both search and get calls in the SOAP web service.
@GET @Produces(MediaType.APPLICATION_JSON)The query parameters are:
The import and export calls make use of a special format to represent ICAT data efficiently. The file may contain line starting with a # sign. The first non-comment line contains the version number of the file format with major and minor parts. Each entity type is preceded by a blank line line followed by a one line entity descriptor and then a line for each entity of that type. For example:
# Version of file format 1.0 Facility ( name:0, daysUntilRelease:1, createId:2, createTime:3) "Test port facility", 90, "Zorro", 1920-05-16T16:58:26.12Z InvestigationType (facility(name:0), name:1) "Test port facility", "atype" "Test port facility", "btype" Investigation(facility(name:0), name:1, visitId:2, type(facility(name:0), name:3), title:4) "Test port facility", "expt1", "one", "atype", "a title"
The entity descriptor starts with the name of the entity type followed by a comma separated list attribute of field names held inside parentheses. It is not necessary to include those which you don't wish to set as any that are not present and are allowed to be null will be set to null when importing. So we see that this file will create a Facility with fields: name, daysUntilRelease, createId and createTime. Following the field name is a colon and an integer showing the offset to the data field in each of the next set of rows. So a facility will be created with a name of "Test port facility" and with 90 daysUntilRelease. All strings must be enclosed in double quotes and to represent a double quote within the string then two double quotes must be used. True, false and null literals are not case sensitive. The last two fields of the facility are createId and createTime. If you specify that you want all attributes and you are a "root user" then the values of createId and createTime will be respected otherwise the current time is used and the id is that of the user doing the import. Timestamps literals follow ISO 8601 and support fractional seconds and time zones. If the time zone is omitted it is interpreted as local time.
Now consider the InvestigationType for which we need to specify the facility to which it belongs and its name. The facility cannot be descibed by its id because we don't know what it is. So instead we list in parentheses the field names that define it. So name:0 is the name of the facility and name:1 is the name of the InvestigationType.
The next line shows the convenience of this syntax. The investigation has a facility (identified by its name:0) and the name:1 of the investigation and the visitId but it also has a type which is identified a facility (identified by its name:0) and by the name:3 of the type. Finally it has a title:4 field. Note that name:0 is used twice as in this case the inverstigation belongs to the same facility as its type. This works fine as long as we deal with entity types which have key fields. This is shown in the next snippet from an import file:
DataCollection(?:0) "a" "b" "c" DataCollectionDatafile(datafile(dataset(investigation(facility(name:0), name:1, visitId:2), name:3), name:4), dataCollection(?:5)) "Test port facility", "expt1", "one", "ds1", "df1", "a" "Test port facility", "expt1", "one", "ds1", "df2", "b" Job(application(facility(name:0), name:1, version:2), inputDataCollection(?:3), outputDataCollection(?:4)) "Test port facility", "aprog", "1.2.3", "a", "b"
Import data into ICAT
@Path("port")The multipart form data starts with a form parameter with a ContentType of TEXT_PLAIN and a name of "json" and is followed by the data to be imported with a ContentType of APPLICATION_OCTET_STREAM.
The json takes the form: "{sessionId", "0d9a3706-80d4-4d29-9ff3-4d65d4308a24", "duplicate", "THROW", "attributes", "USER"} . The value "duplicate" if not specified defaults to "THROW". It is not case sensitive and it defines the action to be taken if a duplicate is found:
Export data from ICAT
@Path("port")The query parameter is:
The value "attributes" if not specified defaults to "USER". It is not case sensitive and it defines which attributes to consider:
The response is the requested export data.