Resource Registry Service - Instances Management

From Gcube Wiki
Revision as of 13:38, 5 July 2021 by Luca.frosini (Talk | contribs) (List via REST API)

Jump to: navigation, search

These sections provide information regarding how to interact with Resource Registry Service for Entities and Relations instances Management. REST and JAVA API are presented for each functionality.

Please note that the provided examples can intentionally hide some details in the response to avoid unneeded complexity.

Instances Management

The Instances Management port type is responsible for the management of entities and relation instances. It offers the following APIs:

  • List: it allows to list instances of a certain type;
  • Create: it allows to create a new entity or relation instance in a certain context;
  • Exists: it allows to check if an instance exists in a certain context;
  • Read: it allows to get the representation of the requested instance in a certain context;
  • Update: it allows to update an instance in a certain context;
  • Delete: it allows to delete an instance.

The Instances Management implements the following policies:

  • it manages the Header automatically;
  • it allows identifying an instance via the Universally Unique Identifier (UUID) specified in the Header;
  • it allows the creation of an instance only if the declared type is already present in the system (previously registered via the Types Collection;
  • it validates the instance against the schema of the defined type;
  • it imposes the default values of propagation constraints (IsRelatedTo (remove=keep, add=unpropagate); ConsistsOf (remove=cascadeWhenOrphan, add=propagate).) when the client does not specify their values;
  • it guarantees propagation constraints.

Instances Collection

The following table shows the exposed APIs as REST Collection

Operation HTTP Method URL
List GET /instances/{TYPE_NAME}[?polymorphic=true]
Create PUT /instances/{TYPE_NAME}/{UUID}
Exists GET /instances/{TYPE_NAME}/{UUID}
Read GET /instances/{TYPE_NAME}/{UUID}
Update PUT /instances/{TYPE_NAME}/{UUID}
Delete DELETE /instances/{TYPE_NAME}/{UUID}

Security configuration based on Authorization Framework make this port type accessible only from Resource Manager. In other words, no others client is allowed to manage types rather than Resource Manager.

Instances Collection Administrative capabilities

Administrators are entitled to specify the following two query parameter in case of read operation:

Hierarchical Mode

An administrator has the possibilities not only the instances belonging to the current context (i.e. the context identified by the gCube Token) but also all the instances in all contexts which are children of the current context.

This functionality is only available for the list and the read operations.

This enables an administrator to have a complete overview of the instances at any level of the contexts tree.

Thanks to this functionality:

  • it is possible to create an instance at the VRE level but it is not needed to add the instance at VO level just for administrator overview;
  • the administrator is capable of observing the instance at any higher level in the context hierarchy;
  • any "normal" client read only the context instance. It is not needed to implement a strategy to chose to correct instance because we don't need to add the instances at VO level just for administrator overview.
Contexts in Header

This functionality allows listing all the contexts an instance belongs to. Used in conjunction with hierarchical mode provides the whole picture of the description of the resource and all different contexts it belongs. Please note that a resource can be described by different facets in different contexts.

Resource Registry Publisher

Resource Registry Publisher is a java library providing RPC facilities to interact with Instances Management and Instances Sharing Management. The library hides all the complexity of marshalling and unmarshalling of requests and results. By using this library any client is able to manage java classes instead of JSON objects.

To use the Java library to interact with Instances Collection declare the following dependency in your pom.xml file.

<dependency>
	<groupId>org.gcube.information-system</groupId>
	<artifactId>resource-registry-publisher</artifactId>
	<version>[4.0.0,5.0.0-SNAPSHOT)</version>
<dependency>

To use the client you just need to instantiate the client via the provided factory.

import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisher;
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisherFactory;
 
...
 
ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory.create();

APIs

List Instances

List via Java Client

Signature

public <IE extends IdentifiableElement, R extends Resource> List<R> list(Class<IE> clazz, Boolean polymorphic) throws ResourceRegistryException;
 
public String list(String type, Boolean polymorphic) throws ResourceRegistryException;

The following snippet of code shows how to retrieve all the resource instances.

ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory.create();
List<Resource> allResources = resourceRegistryPublisher.list(Resource.class, true);


The following snippet of code shows how to retrieve all the EService instances (only the EService).

ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory.create();
List<EService> allResources = resourceRegistryPublisher.list(EService.class, false);

List via REST API

Request URL

 /instances/Resource?polymorphic=true


Request URL

 /instances/EService

Create Instance

Create via Java Client

Signature

public <IE extends IdentifiableElement> IE create(IE er) throws SchemaViolationException, AlreadyPresentException, ResourceRegistryException;
 
public String create(String json) throws SchemaViolationException, AlreadyPresentException, ResourceRegistryException;

The first method gets any instance of IdentifiableElement (i.e. Resources, Facets, ConsistsOf, IsRelatedTo) The second method gets the instance to be created as a JSON string instead of a Java class.


Create via Java Client Example
EService eService = new EServiceImpl();
UUID uuid = UUID.fromString("7f37a79d-0c00-4166-8a68-165de0a438bf");
Header header = new HeaderImpl(uuid);
eService.setHeader(header);
 
SoftwareFacet softwareFacet = new SoftwareFacetImpl();
softwareFacet.setGroup("WhnManager");
softwareFacet.setName("VREManagement");
softwareFacet.setVersion("2.0.0-4.15.0-132431");
softwareFacet.setDescription("Web Hosting Node Service");
 
IsIdentifiedBy<Resource, Facet> isIdentifiedBy = new IsIdentifiedByImpl<Resource, Facet>(eService,
		softwareFacet, null);
eService.addFacet(isIdentifiedBy);
 
AccessPointFacet accessPointFacet = new AccessPointFacetImpl();
accessPointFacet.setEndpoint(new URI("http://pc-frosini.isti.cnr.it:8080/whn-manager/gcube/vremanagement/ws/whnmanager"));
accessPointFacet.setEntryName("whnmanager");
ValueSchema authz = new ValueSchemaImpl();
authz.setValue("gcube-token");
accessPointFacet.setAuthorization(authz);
eService.addFacet(accessPointFacet);
 
AccessPointFacet accessPointFacet2 = new AccessPointFacetImpl();
accessPointFacet2.setEndpoint(new URI("http://pc-frosini.isti.cnr.it:8080/whn-manager/gcube/resource"));
accessPointFacet2.setEntryName("WhnManager-remote-management");
ValueSchema authz2 = new ValueSchemaImpl();
authz2.setValue("gcube-token");
accessPointFacet2.setAuthorization(authz2);
eService.addFacet(accessPointFacet2);
 
 
EventFacet eventFacet = new EventFacetImpl();
eventFacet.setDate(Calendar.getInstance().getTime());
ValueSchema event = new ValueSchemaImpl();
event.setSchema(new URI("String"));
event.setValue("started");
eventFacet.setEvent(event);
eService.addFacet(eventFacet);
 
StateFacet stateFacet = new StateFacetImpl();
stateFacet.setValue("started");
eService.addFacet(stateFacet);
 
 
eService = resourceRegistryPublisher.create(eService);

Create via REST API

PUT  /instances/{TYPE_NAME}/{UUID}
Create via REST API Resource Example

The following listing shows an example of EService representation to be created.

Request URL

PUT PUT /instances/EService/7f37a79d-0c00-4166-8a68-165de0a438bf

Please note that EService and the UUID 7f37a79d-0c00-4166-8a68-165de0a438bf are parts of the request URI

Request Body

{
    "@class": "EService",
    "header": {
        "@class": "Header",
        "uuid": "7f37a79d-0c00-4166-8a68-165de0a438bf"
    },
    "consistsOf": [
        {
            "@class": "IsIdentifiedBy",
            "header": null,
            "propagationConstraint": null,
            "target": {
                "@class": "SoftwareFacet",
                "header": null,
                "name": "WhnManager",
                "group": "VREManagement",
                "version": "2.0.0-4.15.0-132431",
                "description": "Web Hosting Node Service",
                "qualifier": null,
                "optional": false
            }
        },
        {
            "@class": "ConsistsOf",
            "header": null,
            "propagationConstraint": null,
            "target": {
                "@class": "AccessPointFacet",
                "header": null,
                "entryName": "whnmanager",
                "endpoint": "http://pc-frosini.isti.cnr.it:8080/whn-manager/gcube/vremanagement/ws/whnmanager",
                "protocol": null,
                "description": null,
                "authorization": {
                    "@class": "ValueSchema",
                    "value": "gcube-token"
                }
            }
        },
        {
            "@class": "ConsistsOf",
            "header": null,
            "propagationConstraint": null,
            "target": {
                "@class": "AccessPointFacet",
                "header": null,
                "entryName": "WhnManager-remote-management",
                "endpoint": "http://pc-frosini.isti.cnr.it:8080/whn-manager/gcube/resource",
                "protocol": null,
                "description": null,
                "authorization": {
                    "@class": "ValueSchema",
                    "value": "gcube-token"
                }
            }
        },
        {
            "@class": "ConsistsOf",
            "header": null,
            "propagationConstraint": null,
            "target": {
                "@class": "StateFacet",
                "header": null,
                "value": "started"
            }
        },
        {
            "@class": "ConsistsOf",
            "header": null,
            "propagationConstraint": null,
            "target": {
                "@class": "EventFacet",
                "header": null,
                "event": {
                    "value": "started",
                    "schema": "String"
                },
                "date": "2021-06-30 14:38:26.464 +0000"
            }
        }
    ],
    "isRelatedTo": []
}

The following listing contains the response of the service containing the representation of the created EService:

Response Body

{
    "header": {
        "@class": "Header",
        "creationTime": "2021-07-01 08:51:02.353 +0200",
        "createdBy": "luca.frosini",
        "uuid": "7f37a79d-0c00-4166-8a68-165de0a438bf",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2021-07-01 08:51:02.353 +0200"
    },
    "@class": "EService",
    "@superClasses": [
        "Service",
        "GCubeResource",
        "Resource"
    ],
    "consistsOf": [
        {
            "header": {
                "@class": "Header",
                "creationTime": "2021-07-01 08:51:02.312 +0200",
                "createdBy": "luca.frosini",
                "uuid": "3b653a72-b182-41d6-bcc5-97e0141f0ceb",
                "lastUpdateBy": "luca.frosini",
                "lastUpdateTime": "2021-07-01 08:51:02.312 +0200"
            },
            "propagationConstraint": {
                "@class": "PropagationConstraint",
                "add": "propagate",
                "remove": "cascade"
            },
            "@class": "IsIdentifiedBy",
            "@superClasses": [
                "ConsistsOf"
            ],
            "source": {
                "header": {
                    "@class": "Header",
                    "creationTime": "2021-07-01 08:51:02.353 +0200",
                    "createdBy": "luca.frosini",
                    "uuid": "7f37a79d-0c00-4166-8a68-165de0a438bf",
                    "lastUpdateBy": "luca.frosini",
                    "lastUpdateTime": "2021-07-01 08:51:02.353 +0200"
                },
                "@class": "EService",
                "@superClasses": [
                    "Service",
                    "GCubeResource",
                    "Resource"
                ]
            },
            "target": {
                "name": "WhnManager",
                "description": "Web Hosting Node Service",
                "header": {
                    "@class": "Header",
                    "creationTime": "2021-07-01 08:51:02.298 +0200",
                    "createdBy": "luca.frosini",
                    "uuid": "97984812-90e6-4eb7-b804-50a9ad3fe4fb",
                    "lastUpdateBy": "luca.frosini",
                    "lastUpdateTime": "2021-07-01 08:51:02.298 +0200"
                },
                "optional": "false",
                "version": "2.0.0-4.15.0-132431",
                "group": "VREManagement",
                "@class": "SoftwareFacet",
                "@superClasses": [
                    "Facet"
                ]
            }
        },
        {
            "header": {
                "@class": "Header",
                "creationTime": "2021-07-01 08:51:02.322 +0200",
                "createdBy": "luca.frosini",
                "uuid": "5c78bec3-2fa6-46b3-892d-d41bed93e136",
                "lastUpdateBy": "luca.frosini",
                "lastUpdateTime": "2021-07-01 08:51:02.322 +0200"
            },
            "propagationConstraint": {
                "@class": "PropagationConstraint",
                "add": "propagate",
                "remove": "cascade"
            },
            "@class": "ConsistsOf",
            "@superClasses": [],
            "source": {
                "header": {
                    "@class": "Header",
                    "creationTime": "2021-07-01 08:51:02.353 +0200",
                    "createdBy": "luca.frosini",
                    "uuid": "7f37a79d-0c00-4166-8a68-165de0a438bf",
                    "lastUpdateBy": "luca.frosini",
                    "lastUpdateTime": "2021-07-01 08:51:02.353 +0200"
                },
                "@class": "EService",
                "@superClasses": [
                    "Service",
                    "GCubeResource",
                    "Resource"
                ]
            },
            "target": {
                "authorization": {
                    "@class": "ValueSchema"
                    "value": "gcube-token"
                },
                "endpoint": "http://pc-frosini.isti.cnr.it:8080/whn-manager/gcube/vremanagement/ws/whnmanager",
                "entryName": "whnmanager",
                "header": {
                    "@class": "Header",
                    "creationTime": "2021-07-01 08:51:02.318 +0200",
                    "createdBy": "luca.frosini",
                    "uuid": "f66a9fdf-3d5c-45fd-8437-6fecec463c4c",
                    "lastUpdateBy": "luca.frosini",
                    "lastUpdateTime": "2021-07-01 08:51:02.318 +0200"
                },
                "@class": "AccessPointFacet",
                "@superClasses": [
                    "Facet"
                ]
            }
        },
        {
            "header": {
                "@class": "Header",
                "creationTime": "2021-07-01 08:51:02.332 +0200",
                "createdBy": "luca.frosini",
                "uuid": "d4aec29c-3f18-4464-94ae-5fb77306eb82",
                "lastUpdateBy": "luca.frosini",
                "lastUpdateTime": "2021-07-01 08:51:02.332 +0200"
            },
            "propagationConstraint": {
                "@class": "PropagationConstraint",
                "add": "propagate",
                "remove": "cascade"
            },
            "@class": "ConsistsOf",
            "@superClasses": [],
            "source": {
                "header": {
                    "@class": "Header",
                    "creationTime": "2021-07-01 08:51:02.353 +0200",
                    "createdBy": "luca.frosini",
                    "uuid": "7f37a79d-0c00-4166-8a68-165de0a438bf",
                    "lastUpdateBy": "luca.frosini",
                    "lastUpdateTime": "2021-07-01 08:51:02.353 +0200"
                },
                "@class": "EService",
                "@superClasses": [
                    "Service",
                    "GCubeResource",
                    "Resource"
                ]
            },
            "target": {
                "authorization": {
                    "@class": "ValueSchema"
                    "value": "gcube-token"
                },
                "endpoint": "http://pc-frosini.isti.cnr.it:8080/whn-manager/gcube/resource",
                "entryName": "WhnManager-remote-management",
                "header": {
                    "@class": "Header",
                    "creationTime": "2021-07-01 08:51:02.327 +0200",
                    "createdBy": "luca.frosini",
                    "uuid": "a18eb180-398e-4302-942e-c3d7e55ad496",
                    "lastUpdateBy": "luca.frosini",
                    "lastUpdateTime": "2021-07-01 08:51:02.327 +0200"
                },
                "@class": "AccessPointFacet",
                "@superClasses": [
                    "Facet"
                ]
            }
        },
        {
            "header": {
                "@class": "Header",
                "creationTime": "2021-07-01 08:51:02.341 +0200",
                "createdBy": "luca.frosini",
                "uuid": "d5e73a7f-d85b-437b-ab2e-64c94061c5ff",
                "lastUpdateBy": "luca.frosini",
                "lastUpdateTime": "2021-07-01 08:51:02.341 +0200"
            },
            "propagationConstraint": {
                "@class": "PropagationConstraint",
                "add": "propagate",
                "remove": "cascade"
            },
            "@class": "ConsistsOf",
            "@superClasses": [],
            "source": {
                "header": {
                    "@class": "Header",
                    "creationTime": "2021-07-01 08:51:02.353 +0200",
                    "createdBy": "luca.frosini",
                    "uuid": "7f37a79d-0c00-4166-8a68-165de0a438bf",
                    "lastUpdateBy": "luca.frosini",
                    "lastUpdateTime": "2021-07-01 08:51:02.353 +0200"
                },
                "@class": "EService",
                "@superClasses": [
                    "Service",
                    "GCubeResource",
                    "Resource"
                ]
            },
            "target": {
                "header": {
                    "@class": "Header",
                    "creationTime": "2021-07-01 08:51:02.336 +0200",
                    "createdBy": "luca.frosini",
                    "uuid": "44abfa06-a78b-4e5a-a0c5-aa8fe7bcbcf9",
                    "lastUpdateBy": "luca.frosini",
                    "lastUpdateTime": "2021-07-01 08:51:02.336 +0200"
                },
                "value": "started",
                "@class": "StateFacet",
                "@superClasses": [
                    "Facet"
                ]
            }
        },
        {
            "header": {
                "@class": "Header",
                "creationTime": "2021-07-01 08:51:02.350 +0200",
                "createdBy": "luca.frosini",
                "uuid": "f1a41f5c-42a3-47ec-b289-6811e62a1c94",
                "lastUpdateBy": "luca.frosini",
                "lastUpdateTime": "2021-07-01 08:51:02.350 +0200"
            },
            "propagationConstraint": {
                "@class": "PropagationConstraint",
                "add": "propagate",
                "remove": "cascade"
            },
            "@class": "ConsistsOf",
            "@superClasses": [],
            "source": {
                "header": {
                    "@class": "Header",
                    "creationTime": "2021-07-01 08:51:02.353 +0200",
                    "createdBy": "luca.frosini",
                    "uuid": "7f37a79d-0c00-4166-8a68-165de0a438bf",
                    "lastUpdateBy": "luca.frosini",
                    "lastUpdateTime": "2021-07-01 08:51:02.353 +0200"
                },
                "@class": "EService",
                "@superClasses": [
                    "Service",
                    "GCubeResource",
                    "Resource"
                ]
            },
            "target": {
                "date": "2021-06-30 16:38:26.464 +0200",
                "header": {
                    "@class": "Header",
                    "creationTime": "2021-07-01 08:51:02.346 +0200",
                    "createdBy": "luca.frosini",
                    "uuid": "6142d408-f43c-4db7-851f-1dfeb4d98b99",
                    "lastUpdateBy": "luca.frosini",
                    "lastUpdateTime": "2021-07-01 08:51:02.346 +0200"
                },
                "event": {
                    "@class": "ValueSchema",
                    "schema": "String",
                    "value": "started"
                },
                "@class": "EventFacet",
                "@superClasses": [
                    "Facet"
                ]
            }
        }
    ]
}


Reading the response we can observe the following properties:

  • header: The service generated/managed the header for each entity and relation instances;
  • propagationConstraint: The service generated the propagationConstraint with default values when not provided by the client;
  • @superClasses: The service included the @superClasses property. This is required because the client can be model agnostic or could not know the type of an instance. In any case, the client should be able to manage the unknown instances. The list of supertypes enables the client to instantiate the closer type. The list is ordered starting by the first supertype and arriving to the base type. As last resort, the client should be capable of instantiating the base type. When the type of an instance is a base type (e.g. ConsistsOf), the @superClasses property is empty.

Schema Violation

As example, if you omit to include the EventFacet in the EService the service reply with a Schema Violation Exception.

{
    "@type": "SchemaViolationException",
    "cause": null,
    "stackTrace": [....],
    "message": "A EService must be described by ConsistsOf -> EventFacet with the following constraint: max:null, min:1. Found 0 instances. The constraint has been defined by EService type.",
    "localizedMessage": "A EService must be described by ConsistsOf -> EventFacet with the following constraint: max:null, min:1. Found 0 instances. The constraint has been defined by EService type.",
    "suppressed": []
}


The error message contains information regarding:

  • the violated constraint (i.e. A EService must be described by ConsistsOf -> EventFacet with the following constraint: max:null, min:1. Found 0 instances.);
  • the type which defined such a constraint (i.e. The constraint has been defined by EService type.). Please note that is important that the service provides such information because a constraint could be defied by a parent type. In such a way the developer is capable of retrieving the schema of the indicated type.

Update Facet Instance

REST API

POST /resource-registry/er/facet/{Facet Instance UUID}
Example
POST /resource-registry/er/facet/69f0b376-38d2-4a85-bc63-37f9fa323f82

Request Body

{
	"@class":"CPUFacet",
	"header":{"uuid":"69f0b376-38d2-4a85-bc63-37f9fa323f82"}, /* if you pass the header only the UUID is checked and must be the same of the one provided in the URL*/
	"model":"Opteron",
	"vendor":"AMD",
	"clockSpeed":"2 GHz"
}

Response Body

{ 
	"@class":"CPUFacet",
	"header": {
		"uuid":"69f0b376-38d2-4a85-bc63-37f9fa323f82",
		"creator":"luca.frosini", 
		"lastUpdater":"luca.frosini", 
		"creationTime":"2016-10-05 11:16:24",
		"lastUpdateTime":"2016-10-05 11:17:32"
	},
	"model":"Opteron",
	"vendor":"AMD",
	"clockSpeed":"2 GHz"
}

Java API

public <F extends Facet> F updateFacet(F facet) throws FacetNotFoundException, ResourceRegistryException;
Example
createdCpuFacet.setClockSpeed("2 GHz");
CPUFacet updatedCpuFacet = resourceRegistryPublisher.updateFacet(createdCpuFacet);

Alternative JAVA API

There are also two other equivalent methods with the following signature:

public String updateFacet(String facet) throws FacetNotFoundException, ResourceRegistryException;
public String updateFacet(UUID uuid, String facet) throws FacetNotFoundException, ResourceRegistryException;

The first methods get the Facet to be created as JSON string instead of as Java class. The second get also the uuid as parameter (which as to be specified as PATH PARAMETER in the request) avoiding to force client to retrieve it from the string. The second method is more efficient but you have to be sure that the provided uuid is the same specified in the header of the serialized facet.

Delete Facet Instance

REST API

DELETE /resource-registry/er/facet/{Facet Instance UUID}
Example
DELETE /resource-registry/er/facet/69f0b376-38d2-4a85-bc63-37f9fa323f82

Java API

public <F extends Facet> boolean deleteFacet(F facet) throws FacetNotFoundException, ResourceRegistryException;
Example
boolean deleted = resourceRegistryPublisher.deleteFacet(createdCpuFacet);

Alternative JAVA API

There is also another equivalent methods with the following signature:

public boolean deleteFacet(UUID uuid) throws FacetNotFoundException, ResourceRegistryException;

The method just need the UUID of the Facet to be deleted.