Content Record APIs

Read

Resolution

Resolution provides various views from the Registry of the metadata associated with a particular EIDR ID.

Usage

EIDR provides methods for performing the following types of resolution:

  • Full (All content metadata associated with a particular record, whether self-defined or inherited.)
  • Self-defined (All content metadata directly recorded in a particular record, excluding any inherited values.)
  • Simple (A high-level summary view of the Full metadata record.)
  • Provenance (A summary of a record’s editorial history, including its creation, last modification, and version number.)
  • DOI Kernel (A generic view of a record’s metadata specified by the International DOI Foundation.[1])

The org.eidr.sdk.api.Resolution class contains the following methods:

public KernelMetadataResponse resolveDOIKernel(EIDRConnection eidrConn, String assetID, boolean followAlias)

public FullObjectInfoResponse resolveFull(EIDRConnection eidrConn, String assetID, boolean followAlias)

public ProvenanceInfoResponse resolveProvenance(EIDRConnection eidrConn, String assetID, boolean followAlias)

public AllSelfDefinedInfoResponse resolveSelfDefined(EIDRConnection eidrConn, String assetID, boolean followAlias)

public SimpleInfoResponse resolveSimple(EIDRConnection eidrConn, String assetID, boolean followAlias)

The different Response types provide convenience methods for retrieving the actual metadata.

For example:

SimpleInfoResponse simple = res.resolveSimple(cfg.getConnection(), id, true);
String returnedID = simple.getSimpleInfoType().getID().getValue());

ALIASED RECORDS

When a duplicate record is found within the Registry, it is deprecated (aliased) so that its ID points to the correct record. This ensures that there is only ever one active EIDR record for any given object. The aliased ID itself is never deleted, but the Registry’s response to a read operation on that ID depends on how the followAlias flag has been set:

  • If followAlias is true (the default), information returned is from the Registry record to which the Alias refers, not from the aliased record itself.
  • If followAlias is false and the Registry record is not aliased, the information likewise comes from the record itself.
  • If followAlias is false and the Registry record is aliased, an AliasContinuation is returned.

Most applications will set followAlias to true. See “Aliases and Deletion Model” in the EIDR Registry Technical Overview for more information.

NOTE: In rare circumstances, an EIDR record may be deleted rather than aliased. For example, if a test data record is accidentally created in the production Registry. In these cases, the EIDR ID still exists, but is aliased to the EIDR Tombstone record – a special record that exists solely for this purpose. The EIDR Tombstone record has EIDR ID 10.5240/ 0000-0000-0000-0000-0000-X.

For each resolutionType, the defined values and behavior are as follows:

ResolutionTypeFollow Alias?Return Value
DOIKerneltrueReturns metadata formatted as a doi:kernelMetadata record. If the alias chain is too deep, returns an AliasContinuation object. For an InDev object, returns a structural type of restricted. The object’s name is “No information available”. For a deleted object, returns a structural type of “Restricted”, and field values from the standard tombstone object.
DOIKernelfalseIf the object is aliased this returns an doi:kernelMetadata record where:
• structural type is “Restricted”
• title is “aliased”
• referentCreation.identifier.type is DOI
• referentCreation.identifier.value is the DOI to which the object is aliased.
For a deleted object, returns a structural type of “Restricted”, and field values from the standard tombstone object.
SimpletrueReturns metadata formatted as eidr:simpleInfoType. This is the format returned by queries and traversals. If the alias chain is too deep, returns an AliasContinuation object.
SimplefalseIf the object is not aliased, returns an eidr:simpleInfoType record. If the object is aliased, returns an AliasContinuation object. (See above.)
FulltrueReturns metadata formatted as eidr:fullObjectInfoType. If the alias chain is too deep, returns an AliasContinuation object.
FullfalseIf the object is not deleted or aliased, returns an eidr:fullObjectInfoType record. If the object is aliased, returns an AliasContinuation object. (See above.)
SelfDefinedtrueReturns metadata formatted as an eidr:allSelfDefinedInfoType record. If the alias chain is too deep (beyond five levels), returns an AliasContinuation object. (See above.)
SelfDefinedfalseIf the object is not deleted or aliased, returns an eidr:allSelfDefinedInfoType record. If the object is aliased, returns an AliasContinuation object. (See above.)
InheritedtrueReturns metadata formatted as eidr:allInheritedInfoType. If the alias chain is too deep (beyond five levels), returns an AliasContinuation object. (See above.)
InheritedfalseIf the object is not deleted or aliased, returns an eidr:allInheritedInfoType record. If the object is aliased, returns an AliasContinuation object. (See above.)
ProvenancetrueThe provenance record for object (with the alias chain followed) as an eidr:provenanceInfoType record. If the alias chain is more than too deep, returns an AliasContinuation object.
ProvenancefalseThe provenance record for the object itself as an eidr:provenanceInfoType record. For details on this resolution see the EIDR Data Fields Reference.

Tips and Tricks

Inheritance

Most inheritable fields use simple inheritance – the value is taken directly from the parent, which in turn may have taken it from its parent, and so on up the inheritance chain until an object is found that defines the field. In these cases, a field’s value is one of either the self-defined metadata or the inherited metadata. Full metadata requests return all data associated with a record (both inherited and self-defined), while self-defined metadata requests exclude in inherited and return only the self-defined metadata (as one would expect).

Provenance

Provenance contains information about the user account that created and most recently modified a record. This information is not included in the Provenance resolution if the requester is not associated with the Party that registered the record. In that case, only the dates and version number are returned.

Detecting an Alias

An alias can be detected as follows:

  • When followAlias is true, by comparing the ID field of the returned object with the input ID; if they differ, the input ID is aliased.
  • When followAlias is false, by detecting that an AliasContinuation has been returned rather than formatted metadata.
  • Aliases are followed for five levels. If the final item is still aliased, an AliasContinuation object is returned that contains the last aliased ID found and the item to which it is aliased.

Virtual Fields Retrieval

Virtual fields are text fields constructed by combining some of the text-based metadata fields. Virtual fields are used for debugging and for certain kinds of shortcuts in searches, for example by looking for content records where a person’s name appears in any of the Resource Name, Alternate Resource Name, Director, or Actor fields. Because they are virtual, and are not actually present in the EIDR records, they may be queried and retrieved, but not updated directly.

An object has two virtual string fields that combine multiple other fields. One uses full metadata from the object, including inherited fields, and one uses only the fields defined on the object itself (self-defined). Both of these are normalized (punctuation stripped, spaces collapsed) and tokenized using the default (English) rules, as are the queries run against them. Stop-word filtering and stemming are not applied.[2] This also applies to strings as queries on the virtual fields. Note that many of the components of the virtual field are names and titles, which are not filtered or stemmed on their own, and this rule applies to the whole virtual field.

  • Full – composed of these fields from FullObjectMetadataType:
    • BaseObjectData/ResourceName
    • BaseObjectData/AlternateResourceName (using all that are present)
    • BaseObjectData/Description
    • BaseObjectData/Credits/Director/DisplayName (using all that are present)
    • BaseObjectData/Credits/Actor/DisplayName (using all that are present)
  • Self-defined – same as Full, but using only those fields that have not been inherited.

In queries, the virtual fields are:

/VirtualField/Full
/VirtualField/SelfDefined

The order of the tokens within each of the constituent fields is preserved, but the order in which the constituent fields are added to the virtual field is not defined. This means that an exact match query (using <field> “<string”>) returns unpredictable results when the query contains tokens that appear in more than one field. Virtual fields match token sequences within individual fields predictably as it would on a single field.

The SDK provides the org.eidr.sdk.api.VirtualFieldsRetrieval class with the following methods:

public Response getVirtualFields( EIDRConnection eidrConn, String assetID)

Once you have a successful Response, in Java the two virtual fields are retrieved with:

Response resp;
...
String full = resp.getResponseObj().getVirtualFields().getFull();
String self = resp.getResponseObj().getVirtualFields().getSelfDefind();

In .NET, they are retrieved with:

Response resp
...
String full = ObjResponseUtils.GetVirtualFields(resp).Full;
String self = ObjResponseUtils.GetVirtualFields(resp).SelfDefined;

Query

The Query API is the primary mechanism for searching the EIDR content record database.[3] Queries are built using text-based search expressions that describe matching criteria for metadata fields. These are documented in the EIDR Registry Technical Overview. The simplest query tests a single metadata field. More complex queries can be built up by grouping simple queries together with standard logical expressions.

There are two kinds of queries:

  • General queries return all content records that meet the query criteria.
  • Rooted queries return only content records that meet the query criteria and are descended from a specified EIDR ID.

org.eidr.sdk.api.Query provides a single method:

public Response generalQuery(EIDRConnection eidrConn, QueryType request)

Since there can be many results, the Response mechanism is paged. All the information needed for a query is provided to the API in the QueryType structure:

  • ID (The ID for a rooted query, null otherwise.)
  • Expression (The query string. For details, see the EIDR Registry Technical Overview.)
  • Page Size (The number of records to return per Response.)
  • Page Number (The Page for which to return results. Numbering starts with 1. 0 indicates that all results should be returned.)
  • Continuation Token (This should be set to null on the first request. For subsequent requests, it should be set to the value returned by the Registry in the previous Response.)

If the response status is Success, the Response object contains a QueryType, which is the original query, and a QueryResultsType, which contains any results.

QueryResultsType contains:

  • CurrentSize (The number of records in this chunk. Equal to pageSize, except perhaps for the last page.)
  • TotalMatches (The total number of records, across all pages, that can be returned.)
  • ContinuationToken (See above. Returned as null on the last page.)
  • A list of SimpleInfoType records for all objects that match the query. This list will have CurrentSize elements.

In addition to the standard errors, this API can return BadQuery and ResultTooLong.

Java Example

Query qryi = new Query( debugTraceState() );
Response queryResponse = null;
queryResponse = qryi.generalQuery(cfg.getConnection(), req);

if (queryResponse.getStatus() != StatusTypes.Success) {
// handle errors
}
else {
	QueryType retQuery = queryResponse.getResponseObj().getQuery();
	QueryResultsType queryResults = queryResponse.getResponseObj().getQueryResults();
	...
}

.NET Example

Query qryi = new Query(debugTraceState());
Response queryResponse = null;
queryResponse = qryi.generalQuery(cfg.getConnection(), req);

if (queryResponse.getStatus() != StatusTypes.Success) 
{
  // handle errors
  }
  else
  {
  queryResponse = qryi.generalQuery(cfg.getConnection(), req);
  queryType retQuery = ObjResponseUtils.GetFirstQuery(queryResponse);
  queryResultsType queryResults = ObjResponseUtils.GetFirstQueryResults(queryResponse);
  ...
    
  }
}
Tips and Tricks

See the QueryTool source code provided with the SDK for examples of iterating through multiple pages of results and how to build the QueryType object.  This operation is made simpler by using the QueryIterator that is defined in org.eidr.tools.QueryBaseTool. (The source code for all command-line tools is included with the SDK.) The iterator will return to the caller the query results IDs one at a time, taking care of multiple page results. So, instead of writing code to submit a request for each page of results, you can write code in the following form to go through all the results:

QueryType qtype = new QueryType();
.
.
Query qryi = new Query( false );
QueryIterator qi = new QueryIterator( cfg qryi, qtype );
while( qi.hasNext() ) {
    String id = qi.next();
.
.
}

A status of Success does not mean that there were any content records that matched the query, only that the query was properly processed. If there were matches, then Total Results will be greater than 0.

For the most efficient use of connection and transport resources, use a large Page Size, especially if you do not need to display the results interactively.

By default, the results are sorted by the Registry in strict Unicode order (essentially, alphabetically) based on the Resource Name (primary title).

Graph Traversal

EIDR content records may be connected to other content records by inheritance relationships, dependence relationships, and lightweight relationships.[4] While it is possible to traverse these networks using queries or a series of resolutions, the Graph Traversal API provides a specialized mechanism for exploring the content through its relationship structure.

The org.eidr.sdk.api.GraphTraversal class provides methods for all of the supported graph traversals. In general:

  • Each traversal takes an ID to use as its starting point.
  • For traversals that accept filter criteria, each type of filter (ReferentType, StructralType, etc) can contain 0 or more items. The number of items for each type is limited by the number of values for that type. For example, a StructuralType filter can only have at most four values in the list, since there are only four structural types.
  • Many of the traversals provide an indication of how many generations above or below each result is from the starting ID.
  • All the functions except GetSeriesAncestry return items with the metadata formatted as SimpleInfoType in the SDKs and as a <SimpleMetadata> XML element in the HTTP API.
  • Generations above and generations below are represented in the Response.
CommandReturn Values ForFilters
A Root NodeAn Internal NodeA Leaf Node
FindAncestors0 items1 or more items, with generations above1 or more items, with generations aboveReferentType
RelationshipType
StructuralType
GetRemotestAncestorself, GenerationsAbove=01 item, with generations above1 item, with generations above 
FindDescendants1 or more items, with generations below1 or more items, with generations below0 itemsReferentType
RelationshipType
StructuralType
GetLeafDescendants1 or more items, with generations below1 or more items, with generations belowself, generationsBelow=0 
GetLightweight
Relationships
0 or more items0 or more items0 or more items 
GetDependents0 or more items0 or more items0 or more items 
GetChildren1 or more items1 or more items“no children” error 
GetParent“no parent” error1 item1 item   
GetSeriesAncestrySeries: <Origin> is the Series itself; no other nodes  Season: <Origin> is the Season; <SeriesBasicData> is the Series Other internal node (e.g., Edit with children): <Origin> is the object itselfEpisode: <Origin> is the episodes; <SeriesBasicData> and (if these is a Season) <SeasonBasicData> are its ancestors Child of an Episode (e.g. an Edit or Manifestation): <Origin> is the item itself; <SeriesBasicData>, <SeasonBasicData>, and <EpisodeBasicData> are filled in Other leaf node: <Origin> is the item itself 

The three fundamental methods in org.eidr.sdk.api.GraphTraversal are:

public Response findAncestors(EIDRConnection eidrConn, FindAncestorsType request)

This method returns SimpleInfoType records and GenerationsAbove for all ancestors which match the filters in the request. Empty lists match anything. Only inheritance relationships are considered (for example, none of the ‘lightweight relationships’ count). The traversal stops when it encounters an object with no ancestors.

generationsAbove is 1 for a parent, 2 for the parent’s parent, etc.

The object itself is not returned.

public Response findDescendants(EIDRConnection eidrConn, FindDescendantsType request)

This method returns SimpleInfoType records and GenerationsBelow for all descendants that match the filters in the request. Empty lists match anything. Only inheritance relationships are considered (for example, none of the ‘lightweight relationships’ count). The traversal stops when it encounters an object with no descendants.

generationsBelow is 1 for a child, 2 for a child’s child, etc.

The object itself is not returned.

public Response getDependants(EIDRConnection eidrConn, GetDependantsType request)

This method returns a list of SimpleInfoType records that depend on the input ID but that are not part of an inheritance relationship or a lightweight relationship with it.

This can be used to find composites, compilations, and manifestations that reference a particular ID.

NOTE: The remaining traversal functions are provided as a convenience; they could all be implemented by parsing the results of queries, resolutions, and the primary traversals listed above.

public Response getSeriesAncestry(EIDRConnection eidrConn, GetSeriesAncestryType request)

This method returns a Response with a SeriesAncestryType result that contains:

  • SimpleInfoType result for the input ID.
  • SimpleInfoType and EpisodeInfoType result for the nearest ancestor (which can be the input ID) that has episode data. Not present if there is no such ancestor.
  • SimpleInfoType and SeasonInfoType result for the nearest ancestor (which can be the input ID) that has season data. Not present if there is no such ancestor.
  • SimpleInfoType and SeriesInfoType result for the nearest ancestor (which can be the input ID) that has series data. Not present if there is no such ancestor.

The Registry validation rules guarantee that there can be no more than one ancestor of each of the types.

public Response getLightweightRelationships(EIDRConnection eidrConn, GetLightweightRelationshipsType request)

This method returns SimpleInfoType result for each content record to which the input ID has a non-inheriting (i.e., Lightweight) relationship.

public Response getRemotestAncestor(EIDRConnection eidrConn, GetRemotestAncestorType request

This method returns a SimpleInfoType result and GenerationsAbove for the most distant ancestor (the root node of the identified registration tree).

If the input object has no ancestors (it is a root record), the input object is returned.

If the object has ancestors, this is the equivalent of looking for the highest-numbered GenerationsAbove in the return values from FindAncestors with no filters.

public Response getLeafDescendants(EIDRConnection eidrConn, GetLeafDescendantsType request)

This method returns a SimpleInfoType result and GenerationsBelow for all descendants that have no descendants of their own (the leaf nodes of the identified registration tree). Note that GenerationsBelow may not be the same for all leaf nodes.

If the input object has no descendants, the input object itself is returned.

If the object has descendants this can also be done by interpreting the results from GetDescendants with no filters, but that is a little tricky since not all leaf descendants will be at the same level; you really do have to build a tree from the returned values to achieve the same result.

public Response getParent(EIDRConnection eidrConn, GetParentType request)

This method returns a SimpleInfoType result for the input ID’s parent, and returns an error of NoParent if the input object is already at the top of a tree. This is useful if all you have is an ID, but not any of its metadata, and want to know its parent. It can also be done by looking for GenerationsAbove=1 in the results of GetAncestors.

public Response getChildren(EIDRConnection eidrConn, GetChildrenType request)

This method returns SimpleInfoType result for all of the input ID’s immediate descendants, and returns an error of NoChildren if the input ID is a leaf of a registration tree. Alternatively, this can be implemented by looking for GenerationsBelow=1 in the results of GetAncestors.

Tips and Tricks

Remember that a content record can only inherit directly from one parent.

The variety of return types for these calls can be daunting. See the source code for FlattenTool and GraphTool provided with the SDK for examples.

Match

It is possible to obtain de-duplication results without submitting a Create or Modify request to the Registry by using the Match API.

This API call is similar to the Register API, but the response is more like a query. If there are no errors, then the response (Operation Status) will show success. If there are no entries in the duplicate results list, then no existing records were found that scored above the low threshold and the submitted record would be accepted as a new registration. If there are one or more entries in the duplicate results list, then a number of potential duplicates were found. Each item in the duplicate list includes matching scores to indicate what would happen at registration time (records with duplicate candidates that score above the low threshold go into manual de‐duplication while a records with a single duplicate candidate that is above the high threshold would be returned as a duplicate registration).

The org.eidr.sdk.api.Match class has two methods:

public Response matchSingleFromObject(EIDRConnection eidrConn, Object req )

public Response matchSingleFromXML(EIDRConnection eidrConn, String bareXML )

The arguments for these calls are analogous to the equivalent methods in the Registration class, and return information about EIDR content records that match the arguments.

Write

This section covers the batchable write operations.

See the following sections in the EIDR Registry Technical Overview for some essential underlying concepts:

  • Content Records
  • Categorization of Objects
  • Content Record Creation and Modification

On success, all the calls in this section return a response with a Request token, which can be used to discover individual operation tokens if the request contained more than one item. The order in which errors are generated is:

  • Authentication Errors (No further processing is done if the submitted credentials are invalid.)
  • XML Validation Errors (No further processing is done if the submitted XML does not pass schema validation – e.g. is missing a required field or has an illegal field value.)
  • Authorization Errors (This is performed separately for each item in the batch.)
  • Rule-based Validation Errors (These are enforced by the Registry’s data validation rules, and are evaluated separately for each item in a batch. The rules are covered in an Appendix to the EIDR Data Fields Reference.)
  • Operation-specific Errors (The specific errors and responses are detailed below.)

Registration

The org.eidr.sdk.api.Registration class has the following methods:

registerSingleFromXML(EIDRConnection conn, String bareXML, boolean bImmediate)

registerBatchFromXML(EIDRConnection conn, String[] xml)

The XML passed to these functions must of the form:

<Create type="CreateBasic">
	<Basic>...</Basic>
</Create>

or

<Create type="CreateSeries">
	<Series>...</Series>
</Create>

The XML generated by objects such as CreateBasicDataType and CreateSeriesDataType is of the form:

<Basic>...</Basic> or <Series>...</Series>.

See below for helper functions in the Registration class to add the <Create type=”…”> boilerplate around the XML.

Registration.registerSingleFromObject(EIDRConnection conn, Object obj, boolean bImmediate)

Registration.registerBatchFromObj(EIDRConnection conn, Object obj[])

The object must be of a type such as CreateBasicDataType or CreateSeriesDataType. Otherwise these calls will return an SDKError.

It is common to get a ValidationError for registration requests. If the error details indicate invalid XML, this either means that a required field is missing in the created type or that an illegal value has been used for a field. Other validation errors relate to the constraints enforced by the Registry’s validation rules.

Modify

Modifying objects is done by retrieving the current version of an object from the Registry, modifying it, and re-submitting it to the Registry. Use a GetModificationBase request to retrieve the information, and a Modify request to submit it once it has been changed. See “Appendix: Notes on Modifying Records” for information on how to use GetModificationBase.

A modify operation cannot change the presence or type of a relationship, so it is not possible to change a root record into a child record or a child record into a root record using a Modify request. Nor is it possible to change the Registrant or the Status fields.

The org.eidr.sdk.api.Modify class has the following methods:

modifySingleFromXML(EIDRConnection conn, String bareXML, boolean bImmediate)

modifyBatchFromXML(EIDRConnection conn, string[] xml)

The XML passed to these functions must of the form

<Modify type="CreateBasic">
	<ID>10.4240/....</ID>
	<Basic>...</Basic>
</Modify>

or

<Modify type="CreateSeries">
	<ID>10.4240/....</ID>
	<Series>...</Series>
</Modify>

The value contained in the Response for GetModificationBase(…,CreationType.CREATE_BASIC) is a CreateBasicDataType, and the XML for that object is <Basic>…</Basic>. See “Helper Functions for Register and Modify” for utilities to add the necessary headers.

Modify.modifySingleFromObject(EIDRConnection conn, Object obj, String id, boolean bImmediate)

modify.modifyBatchFromObj(EIDRConnection conn, Object obj[], String id[])

The object must be of a type such as CreateBasicDataType or CreateSeriesDataType. Otherwise these calls return an SDKError. The id is the ID of the object being modified; for the batch version, the two arrays are processed in parallel.

NOTE: Modifications that do not pass the de-duplication system will generate the same kind of Duplicate messages as the Registration functions.

Besides the standard errors, Modify can also return IncompatibleCreationTypes.

Helper Functions for Register and Modify

These functions are useful for converting the XML from the CreateXXXDataType classes into XML suitable for passing to the Registration and Modify interfaces.

public static Registration.CreationType discoverCreationType(Object req)

public static Registration.CreationType discoverCreationType(Object xml)

Both of these return null if a CreationType cannot be determined.

public static String Registration.addCreateHeader(String xml)

Adds <Create type=”….”> </Create> tags around the XML if it can find a creation type, null otherwise. See the source code for MatchTool and Error! Reference source not found. provided with the SDK for examples.

public static String Modify.addModifyHeader(String xml, String id)

Uses the input XML and id to generate XML of the following form:

<Modify type="...."><ID>id</ID>xml</Modify>

if it can find a creation type, returning null otherwise. See the source code for ApplyModBaseTool provided with the SDK for an example.

public static String objToModificationXML(Object obj, String id)

Turn the input object into <Modify>…</Modify> XML if a creation type can be discovered for the referenced obj; null otherwise.

Modification Base

Record modification requests require a ModificationBase record. These can be retrieved from the Registry using one of two methods:

public Response getModificationBase(EIDRConnection eidrConn, String assetID, CreationType ct)

public Response getModificationBase(EIDRConnection eidrConn, String assetID, String type)

These return object metadata for creationType. The object returned is CreateBasicDataType; CreateSeriesDataType; etc., and the XML is <Basic>…</Basic>; <Series>…</Series>; etc.

The underlying object must be able to support all the fields needed by the identified creationType. It is incorrect to call GetModificationBase(ID, “CreateSeason”) on an object that was created with CreateSeries, for example. In this case, only CreateBasic and CreateSeries would be permitted.

Errors: standard errors plus IncompatibleCreationTypes.

Add Relationship

Any relationship added to a content record must pass both schema validation and the Registry’s validation rules. See “Content Record Creation and Modification” in the EIDR Registry Technical Overview for tables of permitted combinations.

The org.eidr.sdk.api.AddRelationship class has the following methods:

public Response addSingleRelationshipFromObj(EIDRConnection eidrConn, String sourceID, Object infoObj, boolean bImmediate)

infObj is of a type such as CompositeInfoType or PackagingInfoType. The sourceID is the ID of the content record to which the relationship is to be added.

public Response addSingleRelationshipFromXML(EIDRConnection eidrConn, String sourceID, String infoXML, boolean bImmediate)

infoXML is the XML for <CompositeInfo>…</CompositeInfo>, <PackagingInfo>…</PackagingInfo>, etc. The sourceID is the ID of the content record to which the relationship is to be added.

Both of these calls return a status token, as with all batchable operations. If the relationship cannot be added to the object, a ValidationError is returned.

The creation type and relationship in the XML version of the call must match when using:

  • CompositeRelationship, compositeInfoType
  • PackagingRelationship, packaginInfoType
  • SupplementalRelationship, supplementalInfoType
  • AlternateContentRelationship, alternateContentInfoType

Remove Relationship

Removing a relationship is subject to the Registry’s validation rules. org.eidr.sdk.api.RemoveRelationship provides the following methods:

public Response removeSingleRelationship(EIDRConnection eidrConn, String idSource, TargetRelationshipType type, boolean bImmediate )

This request, if successful, removes all relationships of the given type from idSource:

public Response removeSingleRelationship(EIDRConnection eidrConn, String idSource, TargetRelationshipType type, String targetID, boolean bImmediate )

This request, if successful, removes the single relationship described by the pair {type, targetID} from idSource.

public Response removeRelationshipBatch(EIDRConnection eidrConn, string[] idSource, TargetRelationshipType type)

This request, if successful, removes all relationships of a type from the content IDs in the array idSource.

public Response removeRelationshipBatch(EIDRConnection eidrConn, RemoveRelationshipType removals[])

This request, if successful, performs a fully general relationship removal, allowing a mix of removal with and without targetID, and a mix of relationship types. RemoveRelationshipType, which identifies the type that will be removed by removeRelationshipBatch, has three fields:

  • ID (The ID from which to remove the relationship.)
  • TargetID (The optional target of the relationship to be removed. If present, it removes only a relationship of type with a target of targetID. If not present, the operation removes all relationships of the given type from the record identified by ID.)
  • Type (The type of relationship to remove.)

removeSingleRelationship and removeRelationshipBatch return a status token, as with all other batchable operations. If the relationship cannot be removed from the object, the Registry returns a NotRemovable error.

Tips and Tricks

The IsCompositeOf relationship is only removable if the object’s referent type is not Composite.

TargetID is allowed only for lightweight relationships.

Alias

One of the fundamental goals of the EIDR Registry is to have only a single ID for a particular piece of content. (See “Aliases and Deletion Model” in the EIDR Registry Technical Overview.) This is enforced by the de-duplication system, which uses both automated systems and human review for identification of potential duplicates. Sometimes, however, a content record is registered that later turns out to be a duplicate of an already-existing record. It would be inappropriate to just delete the duplicate record, since it may have already been promulgated to third parties. Instead, EIDR supports aliasing an ID to a different content record.

Only an object with no relationships and no dependents can be aliased. Use FindDescendents() and GetLightweightRelationships() (or resolve to simpleDataInfoType) to find the relationships and Get Dependents() for dependent items. When an ID is aliased:

  • All resolutions related to the old ID will return data from the new content record, unless the resolution has set the followAlias flag to false. (See the “Resolution” section for details.)
  • All other calls related to this ID return an error. Applications should follow the alias chain to get the definitive EIDR ID, and then use it in place of the aliased ID in the future. For example, an aliased ID cannot be used as the ID in a rooted query, nor can it be passed in to a GraphTraversal. Most EIDR calls will return an AliasNotAllowed error, although some may return BadID.
  • The LastModificationDate field in the Provenance record for an aliased ID is the time at which the ID was aliased. Users may not further modify an aliased record.

The org.eidr.sdk.api.Alias class aliases an ID to a different record. This class two methods:

public Response aliasSingle(EIDRConnection eidrConn, String id, String target, boolean bImmediate)

public Response aliasBatch(EIDRConnection eidrConn, string[] ids, string[] targets)

In both of these calls, the both the ID and target must be valid EIDR content IDs. Both of these calls return a status token, as with all batchable operations.

Errors: standard errors plus HasDependents and IncompatibleAliasTarget.

Tips and Tricks

See the “Resolution” section for ways of determining whether an ID has been aliased.

The ForceDedupe flags do not apply to this call.

Delete

EIDR IDs are permanently resolvable, as are all DOIs (of which EIDR IDs are an implementation). In other words, once an ID has been issued, it persists in the Registry and can always be resolved. To ensure this, EIDR IDs are never physically deleted. Instead, deleted IDs are just aliased to the EIDR “tombstone” record. See the EIDR Registry Technical Overview for more information.

The org.eidr.sdk.api.Delete class has two methods:

public Response deleteSingle(EIDRConnection eidrConn, String id, boolean bImmediate)

public Response deleteBatch(EIDRConnection eidrConn, string[] ids)

The response to these requests contains a status token, as with all batchable operations.

If a Delete request is successful, the LastModificationDate field in the Provenance for the ID will be set to the time at which the ID was aliased to the tombstone record.

Only an object with no relationships and no dependents can be deleted. Use FindDescendents and GetLightweightRelationships (or do a Simple resolution) to find any relationships and GetDependents to find dependent records. Each defined relationship must be removed before an object may be deleted.

Errors: standard errors plus dependency errors.

Tips and Tricks

The ForceDedupe flags do not apply to this call. See the EIDR HTTP API Reference for more information about error handling.

Promote

An “in development” content record can be promoted to be a “valid” object. “In development” objects are not subject to de-duplication review because they are private to the registrant. This means they are not compared to other records in the registry at the time of their creation or in the future when other, potentially similar, records are created or modified. They are only checked for duplicates when they are promoted to “valid” objects.

The org.eidr.sdk.api.Promote class has two methods:

public Response promoteSingle(EIDRConnection eidrConn, String id, boolean bImmediate)

public Response promoteBatch(EIDRConnection eidrConn, string[] ids)

The response to these requests contains a status token, as with all other batchable operations. The status may indicate success or the reason that the candidate was not promoted (typically, because it failed to pass de-duplication review).

If Promote is successful:

  • The content record’s Status is set to “valid”.
  • The LastModificationDate field in the provenance record for the promoted ID is set to the time at which the object was promoted.
  • The Promote and View ACLs are removed from the object, and it becomes viewable by any user

Errors: Standard errors plus NotInDev.

Tips and Tricks

Because of their special de-duplication handling, it is possible for other records to be registered that duplicate records in “in development” status. To avoid this, in development records should be used only when absolutely necessary and then promoted to valid status as soon as possible.

Token Status Lookup

StatusLookup requests return information about previous registry operations using their associated batch, operation, or user tokens. The information returned may change in the future if the token is not presently in a terminal state.

Terminal States

Operation tokens

The OperationStatus/Status element returned by StatusLookup operation will not change once the processing of the associated registry operation has reached a terminal state. Anything other than Pending is a terminal state. OperationStatus/Status/Code is numeric from 0-6, and corresponds to the OperationStatus/Status/Type states listed below. (These are defined in detail in api-common.xsd).

OperationStatus CodeOperationStatus Type
0success
1duplicate
2pending
3authorization error
4validation error
5other error
6rejected

Usually, if a non-Success result is returned by a request, the request needs to be corrected before it is resubmitted. If a transient error is returned, the problem is not with the request, but with communications with the Registry or operations within the Registry.

  • Duplicate Error (The metadata in the request was found to be duplicative of the metadata in other object(s) in the registry. The request should not be resubmitted until the metadata in the submitted record or the identified duplicates have been changed – unless there is certainty that the submitted record is unique despite the reported duplicate(s), in which case it can be submitted for forced manual review.)
  • Authorization Error (The credentials in the request were not appropriate given the requested operation, the requester’s allowed roles, and/or the ACL of the objects involved. The request should not be resubmitted until one of the above security conditions has changed.)[5]
  • Validation Error (The metadata in the request or the related objects did not conform to the XML schema specification or the Registry’s additional data validation rules. The request should not be resubmitted until the affected metadata has changed)
  • Rejected Error (A request has been rejected during manual de-duplication review without being processed. This is very rare. The request should not be resubmitted without first consulting with EIDR support.)
  • Other Error (Returned for various transient problems, like bad communication with the de-duplication system, and may be resubmitted. Since it may reflect some other error, and “transient” does not necessarily mean short-lived, caution should be used before submitting a third time.)

Batch Tokens

The following applies only to batches containing more than one item.

Once a batch has passed top-level authentication, syntax checking, and so on, these are the possible states:

  • 1 (batch received) The batch itself has passed validation and is being turned into individual requests subject to further validation. No further information is available at this point.
  • 2 (batch queued) The individual requests have passed validation and have all been submitted. StatusLookup requests may now be used with the batch token return the individual tokens and the current state of each individual request.
  • 3 (invalid batch) This can result from a bad user token. This can also result from abnormal operation of the Registry, which should be reported to EIDR support.

Batch queued and invalid batch are terminal states for a batch token.

Match Scores

Scores can be returned in response to immediate-mode Match requests, to give an idea of how close any current Registry records are to the contemplated registration. Scores are meaningful only for immediate-mode Match requests. If they are present in the response to a non-immediate (asynchronous) request, they should be ignored.

Polling

Poll (request the current status of) a token at intervals using StatusLookup until it reaches one of the possible end states. For a batch token, extract all the operation tokens once the batch has reached the “batch queued” state[6] and manage them all individually, or you can poll on the Batch Token, dealing with each operation token as it reaches an end state or after all of them have reached an end state. The former is usually somewhat better, since you do not need to continually poll on the Batch Token; the latter is less efficient but may be preferable when you do not want the complexity of managing multiple tokens.

For operation tokens, poll them individually, one at a time, unless they are part of a batch, when they can be polled indirectly via the batch token..

StatusLookup

The org.eidr.sdk.api.StatusLookup class has the following methods:

  • Response statusLookupViaRegistrant(EIDRConnection eidrConn, java.lang.String registrant, int pageNumber, int pageSize)
  • Response statusLookupViaRegistrant(EIDRConnection eidrConn, String registrant, int pageNumber, int pageSize, java.util.Date from, Date to, java.lang.String status)
  • Response statusLookupViaRegistrant(EIDRConnection eidrConn, String registrant, String pageNumber, String pageSize)
  • Response statusLookupViaToken(EIDRConnection eidrConn, String token, int pageNumber, int pageSize)
  • Response statusLookupViaToken(EIDRConnection eidrConn, String token, String pageNumber, String pageSize)
  • Response statusLookupViaUser(EIDRConnection eidrConn, String user, int pageNumber, int pageSize)
  • Response statusLookupViaUser(EIDRConnection eidrConn, String user, int pageNumber, int pageSize, Date from, Date to, String status)
  • Response statusLookupViaUser(EIDRConnection eidrConn, String user, String pageNumber, String pageSize)

To retrieve the status of a recent request, invoke the getStatus()method of the Response object. An org.eidr.sdk.model.StatusTypes enumeration value is returned, indicating success or an error.

One of the GetStatus methods can be used to query the status of the request.

GetStatus(token, pageNumber, pageSize, continuationToken)

Errors: standard errors plus BadQuery and ResultTooLong.

The paging parameters are used as follows:

  • Results are returned with pageSize objects per batch.
  • The pageNumber-th page of pageSize records is returned. Page 1 is the first page. Page 0 is a request for all results.
  • ContinuationToken should be a value returned by the previous paged GetStatus request using this query string, or null if this is the first call in the set.

Returns (token, status) elements if token is not a batch token.

If token is a batch token, returns:

  • PageSize (Max number of records included in a single response page – equal to input parameter pageSize.)
  • MySize (The size of this chunk – equal to pageSize, except perhaps for the last page.)
  • TotalPages (The total number of response pages that can be returned given the pageSize. Returned – equal to .)
  • PageNum (The number of the current returned page.)
  • TotalResults (The total number of result records across all pages.)
  • ContinuationToken (A simple string marking the current position within the results. Must be passed as the ContinuationToken to a new GetStatus request to obtain the next results page in sequence.)
  • A list of the (token, status) elements for each item in the request response that falls in the current returned page of results.

Response statuses for a batch GetStatus request:

  • BatchReceived (The batch has been fully read by the Registry, but no status for its individual sub-elements is yet available.)
  • BatchQueued (The batch is being processed by the Registry. Each sub-element in the batch now has an available status that may be queried.)
  • BatchInvalid (There was a Registry error processing the batch; one of the standard errors is also returned as a detail.)

Response statuses for the individual sub-elements in the batch:

  • Success (The request has succeeded. For example, by creating a new object or deleting an old one. The detail field contains the EIDR ID associated with the successful operation: a new EIDR ID for creation, and the passed-in EIDR ID in other cases.)
  • Duplicate (When a duplicate or potential duplicates are found during create, modify, or promote. The detail field contains one or more EIDR IDs of items detected as possible duplicates; the IDs for all duplicates are returned.)
  • Pending (When the Registry is waiting to finish an operation, but has not yet had any errors; in the case of create, modify, and promote it may have as a detail a list of EIDR IDs for one or more potential duplicates.)
  • Failure (When the request fails. For example, after an attempt to create a duplicate item.)
  • Error (Adds one or more of the error values as a detail.)

Errors: any of the standard errors or a BadToken error.

GetStatus(Registrant, filter, token, page, pageSize, continuationToken)

GetStatus(User, filter, token, page, pageSize, continuationToken)

The last four arguments are treated as they are for other GetStatus requests.

Filter can be:

  • Status (legal-status-value : Only tokens that match the supplied value are returned.)
  • After (date-time : Only tokens issued after the supplied time are returned.)
  • Range (date-time-start date-time-end: Only tokens generated between the two dates are returned.)

Legal combinations are:

  • No filter
  • Status only
  • After only
  • Range only
  • Status and After
  • Status and Range

A Registrant request returns a paginated list of (token, status) records for every token belonging to Registrant that matches Filter. A token belongs to a Registrant if a user in the Registrant Party made the request with which it is associated.

User returns a paginated list of (token, status) for every token generated by a request from User and matching Filter.


[1] See Appendix 6 DOI® Kernel Metadata Declaration: XML Schema at www.doi.org/handbook_2000/appendix_6.pdf.

[2] See “Appendix B: Text Processing and Queries” in the EIDR Registry Technical Overview for more information.

[3] Excluding EIDR ID or token resolution, of course.

[4] See “Relationships” in the EIDR Registry Technical Overview for more information.

[5] A very small number of Authorization Errors may actually be transient, but this is extremely rare and cannot be distinguished from a true authentication error.

[6] It is not sufficient to check for Success in /Response/Status field – that just means the request was accepted by the Registry.

Updated on April 11, 2021

Was this article helpful?

Related Articles