Class ServiceRuntime

java.lang.Object
com.exonum.binding.core.runtime.ServiceRuntime
All Implemented Interfaces:
java.lang.AutoCloseable

public final class ServiceRuntime
extends java.lang.Object
implements java.lang.AutoCloseable
A service runtime. It manages the services required for operation of Exonum services (e.g., a Server; allows the native code to load and unload artifacts (JAR archives with Exonum services), create and stop services defined in the loaded artifacts.

This class is thread-safe and does not support client-side locking. The thread-safety is provided because the class is a singleton and may be provided to other objects. Currently, however, there is a single injection point where ServiceRuntime is instantiated (during bootstrap) and it is used by the native runtime only in a single-threaded context, hence thread-safety isn't strictly required, but rather provided to avoid possible errors if it is ever accessed by other objects.

  • Constructor Summary

    Constructors 
    Constructor Description
    ServiceRuntime​(com.exonum.binding.core.runtime.ServiceLoader serviceLoader, com.exonum.binding.core.runtime.ServicesFactory servicesFactory, RuntimeTransport runtimeTransport, com.exonum.binding.core.runtime.BlockchainDataFactory blockchainDataFactory, java.nio.file.Path artifactsDir)
    Creates a new Java service runtime.
  • Method Summary

    Modifier and Type Method Description
    void afterCommit​(Snapshot snapshot, java.util.OptionalInt validatorId, long height)
    Notifies the services in the runtime of the block commit event.
    void afterTransactions​(int serviceId, BlockchainData blockchainData)
    Performs the after transactions operation on the specified service in this runtime.
    void beforeTransactions​(int serviceId, BlockchainData blockchainData)
    Performs the before transactions operation on the specified service in this runtime.
    void close()  
    void deployArtifact​(ServiceArtifactId id, java.lang.String filename)
    Loads a Java service artifact from the specified file.
    void executeTransaction​(int serviceId, java.lang.String interfaceName, int txId, byte[] arguments, BlockchainData blockchainData, int callerServiceId, HashCode txMessageHash, PublicKey authorPublicKey)
    Executes a transaction belonging to the given service.
    void initialize​(NodeProxy node)
    Initializes the runtime with the given node.
    void initiateAddingService​(BlockchainData blockchainData, ServiceInstanceSpec instanceSpec, byte[] configuration)
    Starts registration of a new service instance with the given specification.
    void initiateResumingService​(BlockchainData blockchainData, ServiceInstanceSpec instanceSpec, byte[] arguments)
    Initiates resuming of previously stopped service instance.
    boolean isArtifactDeployed​(ServiceArtifactId id)
    Returns true if an artifact with the given id is currently deployed in this runtime.
    void shutdown()
    Stops this runtime.
    void updateInstanceStatus​(ServiceInstanceSpec instanceSpec, Lifecycle.InstanceStatus instanceStatus)
    Modifies the state of the given service instance at the runtime either by activation it or stopping.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • ServiceRuntime

      @Inject public ServiceRuntime​(com.exonum.binding.core.runtime.ServiceLoader serviceLoader, com.exonum.binding.core.runtime.ServicesFactory servicesFactory, RuntimeTransport runtimeTransport, com.exonum.binding.core.runtime.BlockchainDataFactory blockchainDataFactory, java.nio.file.Path artifactsDir)
      Creates a new Java service runtime.
      Parameters:
      serviceLoader - a loader of service artifacts
      servicesFactory - the factory of services
      runtimeTransport - a web server providing transport to Java services
      artifactsDir - the directory in which administrators place and from which the service runtime loads service artifacts; may not exist at instantiation time
  • Method Details

    • initialize

      public void initialize​(NodeProxy node)
      Initializes the runtime with the given node. Starts the transport for Java services.
    • deployArtifact

      public void deployArtifact​(ServiceArtifactId id, java.lang.String filename) throws ServiceLoadingException
      Loads a Java service artifact from the specified file. The loading involves verification of the artifact (i.e., that it is a valid Exonum service; includes a valid service factory).
      Parameters:
      id - a service artifact identifier; artifacts with non-equal ids will be rejected
      filename - a filename of the service artifact in the directory for artifacts
      Throws:
      ServiceLoadingException - if it failed to load an artifact; or if the given artifact is already loaded
    • isArtifactDeployed

      public boolean isArtifactDeployed​(ServiceArtifactId id)
      Returns true if an artifact with the given id is currently deployed in this runtime.
      Parameters:
      id - a service artifact identifier
    • initiateAddingService

      public void initiateAddingService​(BlockchainData blockchainData, ServiceInstanceSpec instanceSpec, byte[] configuration)
      Starts registration of a new service instance with the given specification. It involves the initial configuration of the service instance with the given parameters. The instance is not registered until updateInstanceStatus(ServiceInstanceSpec, InstanceStatus) is invoked with the Status=Active.
      Parameters:
      blockchainData - a database access to apply configuration
      instanceSpec - a service instance specification; must reference a deployed artifact
      configuration - service instance configuration parameters as a serialized protobuf message
      Throws:
      java.lang.IllegalArgumentException - if the service is already started; or its artifact is not deployed
      ExecutionException - if such exception occurred in the service constructor; must be translated into an error of kind Errors.ErrorKind.SERVICE
      UnexpectedExecutionException - if any other exception occurred in the service constructor; it is included as cause. The cause must be translated into an error of kind Errors.ErrorKind.UNEXPECTED
      java.lang.RuntimeException - if the runtime failed to instantiate the service for other reason
    • initiateResumingService

      public void initiateResumingService​(BlockchainData blockchainData, ServiceInstanceSpec instanceSpec, byte[] arguments)
      Initiates resuming of previously stopped service instance. Service instance artifact could be upgraded in advance to bring some new functionality.
      Parameters:
      blockchainData - a database access object to apply changes to
      instanceSpec - a service instance specification; must reference a deployed artifact
      arguments - a service arguments as a serialized protobuf message
      Throws:
      java.lang.IllegalArgumentException - if the given service instance is active; or its artifact is not deployed
      ExecutionException - if such exception occurred in the service method; must be translated into an error of kind Errors.ErrorKind.SERVICE
      UnexpectedExecutionException - if any other exception occurred in the service method; it is included as cause. The cause must be translated into an error of kind Errors.ErrorKind.UNEXPECTED
      java.lang.RuntimeException - if the runtime failed to resume the service for other reason
    • updateInstanceStatus

      public void updateInstanceStatus​(ServiceInstanceSpec instanceSpec, Lifecycle.InstanceStatus instanceStatus)
      Modifies the state of the given service instance at the runtime either by activation it or stopping. The service instance should be successfully initialized by initiateAddingService(BlockchainData, ServiceInstanceSpec, byte[]) in advance. Activation leads to the service instance registration, allowing subsequent operations on it: transactions, API requests. Stopping leads to the service disabling i.e. stopped service does not execute transactions, process events, provide APIs, etc. But the service data still exists.
      Parameters:
      instanceSpec - a service instance specification; must reference a deployed artifact
      instanceStatus - a new status of the service instance
      Throws:
      java.lang.IllegalArgumentException - if activating already active service; or its artifact is not deployed; or unrecognized service status received
    • executeTransaction

      public void executeTransaction​(int serviceId, java.lang.String interfaceName, int txId, byte[] arguments, BlockchainData blockchainData, int callerServiceId, HashCode txMessageHash, PublicKey authorPublicKey)
      Executes a transaction belonging to the given service.
      Parameters:
      serviceId - the numeric identifier of the service instance to which the transaction belongs
      interfaceName - a fully-qualified name of the interface in which the transaction is defined, or empty string if it is defined in the service directly (implicit interface)
      txId - the transaction type identifier
      arguments - the serialized transaction arguments
      blockchainData - a database accessor to apply changes to
      callerServiceId - the id of the caller service if transaction is invoked by other service. Currently only applicable to invocations of Configure interface methods
      txMessageHash - the hash of the transaction message
      authorPublicKey - the public key of the transaction author
      Throws:
      ExecutionException - if such exception occurred in the transaction; must be translated into an error of kind Errors.ErrorKind.SERVICE
      UnexpectedExecutionException - if any other exception occurred in the transaction; it is included as cause. The cause must be translated into an error of kind Errors.ErrorKind.UNEXPECTED
      java.lang.IllegalArgumentException - if any argument is not valid (e.g., unknown service)
      See Also:
      Transaction
    • beforeTransactions

      public void beforeTransactions​(int serviceId, BlockchainData blockchainData)
      Performs the before transactions operation on the specified service in this runtime.
      See Also:
      afterTransactions(int, BlockchainData)
    • afterTransactions

      public void afterTransactions​(int serviceId, BlockchainData blockchainData)
      Performs the after transactions operation on the specified service in this runtime.
      Parameters:
      serviceId - the id of the service on which to perform the operation
      blockchainData - a database access object allowing the runtime and the service to modify the database state
      Throws:
      ExecutionException - if such exception occurred in the transaction; must be translated into an error of kind Errors.ErrorKind.SERVICE
      UnexpectedExecutionException - if any other exception occurred in the transaction; it is included as cause. The cause must be translated into an error of kind Errors.ErrorKind.UNEXPECTED
      java.lang.IllegalArgumentException - if any argument is not valid (e.g., unknown service)
    • afterCommit

      public void afterCommit​(Snapshot snapshot, java.util.OptionalInt validatorId, long height)
      Notifies the services in the runtime of the block commit event.
      Parameters:
      snapshot - a snapshot of the current database state
      validatorId - an optional id of the validator node, or none for an auditor
      height - the current blockchain height
    • shutdown

      public void shutdown() throws java.lang.InterruptedException
      Stops this runtime. It will stop the server providing transport to services, remove all services and unload their artifacts. The operation is irreversible; the runtime may not be used after this operation completes.
      Throws:
      java.lang.InterruptedException - if an interrupt was requested
    • close

      public void close() throws java.lang.InterruptedException
      Specified by:
      close in interface java.lang.AutoCloseable
      Throws:
      java.lang.InterruptedException