java.lang.Object
org.gcube.informationsystem.resourceregistry.persistence.orientdb.base.ElementManagement<com.orientechnologies.orient.core.record.OVertex,ET>
org.gcube.informationsystem.resourceregistry.persistence.orientdb.base.EntityElementManagement<org.gcube.informationsystem.contexts.reference.entities.Context,org.gcube.informationsystem.types.reference.entities.EntitySchema>
org.gcube.informationsystem.resourceregistry.persistence.orientdb.contexts.ContextManagement

public class ContextManagement extends EntityElementManagement<org.gcube.informationsystem.contexts.reference.entities.Context,org.gcube.informationsystem.types.reference.entities.EntitySchema>
OrientDB-only persistence layer for Context entities.

Owns the low-level graph representation of the context hierarchy (the ChildOf child-to-parent edge), the persisted derived fields (Context.PATH and Context.EFFECTIVE_STATE, recomputed on creation, rename, and reparent), the cemetery move-on-delete mechanics (swapping record-level-security roles between LiveContextEnvironment and CemeteryContextEnvironment instead of a hard delete), and the append-only audit history recorded on every state-changing operation. This class has zero auth logic: role/visibility policy is owned by ContextPolicyEnforcementPoint, and Redis caching/fallback orchestration is owned by ContextRepository.

Author:
Luca Frosini (ISTI - CNR)
  • Field Details

    • name

      protected String name
      The name of the Context being managed.
    • lifecycle

      protected org.gcube.informationsystem.resourceregistry.api.rest.ContextLifecycle lifecycle
      The lifecycle filter configuration used to resolve the database environment.
    • purge

      protected boolean purge
      Whether the delete operation should permanently purge the context instead of moving it to the cemetery.
    • projection

      protected boolean projection
      Whether the last JSON query returned an _emit projection.
  • Constructor Details

    • ContextManagement

      public ContextManagement()
      Creates a new, uninitialized ContextManagement instance. Binds the management class to the AccessType.CONTEXT access type.
    • ContextManagement

      public ContextManagement(org.gcube.informationsystem.resourceregistry.api.rest.ContextLifecycle lifecycle, com.orientechnologies.orient.core.db.document.ODatabaseDocument oDatabaseDocument) throws org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Creates a new ContextManagement instance bound to the specified OrientDB database.
      Parameters:
      lifecycle - the current lifecycle state manager for contexts
      oDatabaseDocument - the OrientDB database connection to use
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - if the working environment cannot be initialized
  • Method Details

    • getLifecycle

      public org.gcube.informationsystem.resourceregistry.api.rest.ContextLifecycle getLifecycle()
      Retrieves the current context lifecycle configuration.
      Returns:
      the active context lifecycle configuration
    • create

      public String create() throws org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException, org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Initializes the Context version counter before the creation transaction starts.
      Overrides:
      create in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Returns:
      the serialized JSON representation of the created Context
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException - if the Context already exists
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - if creation fails
    • setLifecycle

      public void setLifecycle(org.gcube.informationsystem.resourceregistry.api.rest.ContextLifecycle lifecycle)
      Configures the context lifecycle filter and resets the resolved environment.
      Parameters:
      lifecycle - the context lifecycle configuration to set
    • isProjection

      public boolean isProjection()
      Reports whether the last query(String) call returned an _emit projection rather than complete Context objects.
      Returns:
      true for a projection query, false otherwise
    • getAffectedInstances

      public Map<UUID,org.gcube.com.fasterxml.jackson.databind.JsonNode> getAffectedInstances()
      Returns the map of instances affected by operations on this context. This operation is not supported on Contexts.
      Overrides:
      getAffectedInstances in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Returns:
      the map of affected instances
    • getName

      public String getName()
      Returns the name of the Context.
      Returns:
      the name of the Context
    • getWorkingEnvironment

      protected Environment getWorkingEnvironment() throws org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Returns the active LiveContextEnvironment working environment.
      Specified by:
      getWorkingEnvironment in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Returns:
      the working environment
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - if the environment cannot be resolved
    • getElement

      public com.orientechnologies.orient.core.record.OVertex getElement() throws org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException, org.gcube.informationsystem.resourceregistry.api.exceptions.instances.AvailableInAnotherContextException, org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Returns the OrientDB vertex for the configured UUID, restricted to the current lifecycle scope.

      When the base lookup fails and lifecycle is not ContextLifecycle.ALL, probes whether the vertex actually exists in the opposite environment (LiveContextEnvironment vs CemeteryContextEnvironment) to distinguish a genuine not-found from a lifecycle-scope mismatch, throwing ContextVisibilityException for the latter.

      Overrides:
      getElement in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Returns:
      the resolved OVertex
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException - if no context with this UUID exists in any lifecycle scope
      org.gcube.informationsystem.resourceregistry.api.exceptions.instances.AvailableInAnotherContextException - if the context exists but is not visible from the caller's current security context
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - if the lookup or lifecycle probe fails
    • getSpecificNotFoundException

      protected org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextNotFoundException getSpecificNotFoundException(org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException e)
      Converts a generic NotFoundException into a ContextNotFoundException.
      Specified by:
      getSpecificNotFoundException in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Parameters:
      e - the generic exception
      Returns:
      the converted ContextNotFoundException
    • getSpecificAlreadyPresentException

      protected org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextAlreadyPresentException getSpecificAlreadyPresentException(String message)
      Converts a generic AlreadyPresentException into a ContextAlreadyPresentException.
      Specified by:
      getSpecificAlreadyPresentException in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Parameters:
      message - the exception message
      Returns:
      the converted ContextAlreadyPresentException
    • checkContext

      protected void checkContext(ContextManagement parentContext) throws org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextNotFoundException, org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextAlreadyPresentException, org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Validates that the context is topologically valid and does not violate uniqueness constraints.
      Parameters:
      parentContext - the parent context
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextNotFoundException - if the parent context does not exist
      org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextAlreadyPresentException - if a context with the same name already exists under the parent
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - if database lookup fails
    • createCompleteJsonNode

      protected org.gcube.com.fasterxml.jackson.databind.JsonNode createCompleteJsonNode() throws org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Description copied from class: ElementManagement
      Abstract method to create the complete JSON node representation of the element.
      Specified by:
      createCompleteJsonNode in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Returns:
      the complete JSON node representing the element and its relationships
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - on serialization or mapping error
    • getPathFromVertex

      public static String getPathFromVertex(com.orientechnologies.orient.core.record.OVertex vertex)
      Reads a Context's persisted path directly off its OrientDB vertex, falling back to the legacy fullPath property name for a not-yet-migrated record.
      Parameters:
      vertex - the Context vertex to read, or null
      Returns:
      the persisted path, or null if vertex is null or carries neither property
    • getPreviousPathsFromVertex

      public static Set<String> getPreviousPathsFromVertex(com.orientechnologies.orient.core.record.OVertex vertex)
      Reads a Context's persisted set of previous paths directly off its OrientDB vertex.
      Parameters:
      vertex - the Context vertex to read, or null
      Returns:
      the persisted previous paths, in insertion order; empty if vertex is null or carries none
    • reallyCreate

      protected com.orientechnologies.orient.core.record.OVertex reallyCreate() throws org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException, org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Description copied from class: ElementManagement
      Persists a new element in the database (subclass hook).
      Specified by:
      reallyCreate in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Returns:
      the persisted OrientDB vertex
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException - if the element already exists in the database
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - on any database error
    • manageDerivedFields

      protected void manageDerivedFields() throws org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Computes and persists the Context.PATH and Context.EFFECTIVE_STATE of this context into the vertex.

      Called at:

      • Creation time
      • Rename time (see #25139)
      • Parent change (reparent) time (see #26544)
      When a context is deleted it is moved to the cemetery (CemeteryContextEnvironment) without any further path recomputation: the vertex already carries its last known path (see #19428).
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - if database lookup or property mapping fails
    • checkStateChange

      protected void checkStateChange(org.gcube.informationsystem.contexts.reference.ContextState newContextstate)
      Validates whether a context's state transition is legally permissible.
      Parameters:
      newContextstate - the target state to transition to
      Throws:
      jakarta.ws.rs.BadRequestException - if the target state is invalid or forbidden
    • reallyUpdate

      protected com.orientechnologies.orient.core.record.OVertex reallyUpdate() throws org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException, org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Tracked Update for a Context (rename/reparent/state-change) is performed exclusively via changeState(), which additionally enforces the ACTIVE-state and cyclic-reparent guards. This generic upsert path is not supported on Contexts.
      Specified by:
      reallyUpdate in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Returns:
      never returns
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException - if the element does not exist in the database
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - on any database error
    • reallyDelete

      protected void reallyDelete() throws org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException, org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Permanently deletes the context from the active topology and moves its vertex to the historical cemetery (CemeteryContextEnvironment).

      Strict validations:

      • The context must not have any child contexts (throws AlreadyPresentException).
      • The context must not contain any graph instances (throws AlreadyPresentException).

      Moves the context vertex by denying it in the LiveContextEnvironment and allowing it in CemeteryContextEnvironment (swapping RLS security roles).

      Specified by:
      reallyDelete in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException - if the context does not exist in the database
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - if database or topological validation fails
    • delete

      protected void delete(boolean purge) throws org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException, org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Deletes or purges the Context from the database using a privileged administrative session.

      This operation runs in a privileged admin transaction to allow schema/role modifications and bypass any uncommitted transactional lock conflicts on RLS records.

      Parameters:
      purge - true to permanently purge, false to move to the cemetery
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException - if the context does not exist
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - on database error
    • delete

      public void delete() throws org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException, org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Deletes the Context from the database (logical delete, moves to cemetery).
      Overrides:
      delete in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException - if the context does not exist
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - on database error
    • purge

      public void purge() throws org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException, org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Permanently purges the Context from the database entirely (bypassing the cemetery).
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException - if the context does not exist
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - on database error
    • reallyGetAll

      public String reallyGetAll() throws org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Retrieves all contexts from the database and returns them as a JSON array string.

      Applies pagination limits and offsets retrieved from the server request info, or overridden via force limits/offsets.

      Specified by:
      reallyGetAll in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Returns:
      JSON array string representing all matching contexts
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - if database traversal or serialization fails
    • query

      public String query(String jsonQuery) throws org.gcube.informationsystem.resourceregistry.api.exceptions.queries.InvalidQueryException, org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Executes a JSON query against the Context collection, returning either matching Context definitions or flat _emit projection rows. Full Context visibility filtering remains the caller's responsibility (see ContextRepository#query(...)), while projection aliases for sensitive metadata are masked when configured.

      Honours the limit/offset fields already configured on this instance, and the lifecycle already configured via setLifecycle(ContextLifecycle) (which determines which of LiveContextEnvironment/CemeteryContextEnvironment/ ContextEnvironment is opened via getWorkingEnvironment()).

      Parameters:
      jsonQuery - the JSON query payload describing the Context search criteria
      Returns:
      JSON array string of matching, unfiltered Context definitions
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.queries.InvalidQueryException - if the query is invalid or syntactically incorrect
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - on database or processing failure
    • sanityCheck

      public void sanityCheck() throws org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaViolationException, org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Description copied from class: ElementManagement
      Performs runtime validation of mandatory and not-null schema constraints that cannot be enforced directly by OrientDB in distributed mode.
      Overrides:
      sanityCheck in class ElementManagement<com.orientechnologies.orient.core.record.OVertex,org.gcube.informationsystem.types.reference.entities.EntitySchema>
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaViolationException - if a schema constraint is violated
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - on database lookup failure
    • changeState

      public String changeState() throws org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Applies only tracked local-state, name, or parent changes and recursively recomputes the effective states and paths of all descendants.

      Enforces state machine constraints (blocking rename/reparent if state is ACTIVE) and registers transition history events.

      Returns:
      the serialized JSON string of the updated context
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - if the database transaction or state change validation fails
    • getContextByPath

      public org.gcube.informationsystem.contexts.reference.entities.Context getContextByPath(String path) throws org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Returns the Context identified by path. Opens and closes its own database connection.
      Parameters:
      path - the fully-qualified context path, e.g. /gcube/devsec/devVRE
      Returns:
      the matching Context
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextNotFoundException - if no context matches the given path
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - on any other error
    • getCurrentContext

      public org.gcube.informationsystem.contexts.reference.entities.Context getCurrentContext() throws org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Returns the Context corresponding to the caller's current security context (path read from the thread-local SecretManagerProvider).
      Returns:
      the current Context
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - if the current context cannot be resolved
    • readHistory

      public String readHistory() throws org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException
      Reads the audit trail of this Context, returning the most recently appended event first.
      Returns:
      reverse-chronological JSON array string of history events
      Throws:
      org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException - if database lookup or JSON serialization fails