Package com.exonum.binding.core.runtime
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.
-
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 artifactsservicesFactory
- the factory of servicesruntimeTransport
- a web server providing transport to Java servicesartifactsDir
- the directory in which administrators place and from which the service runtime loads service artifacts; may not exist at instantiation time
-
-
Method Details
-
initialize
Initializes the runtime with the given node. Starts the transport for Java services. -
deployArtifact
public void deployArtifact(ServiceArtifactId id, java.lang.String filename) throws ServiceLoadingExceptionLoads 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 rejectedfilename
- 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
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 untilupdateInstanceStatus(ServiceInstanceSpec, InstanceStatus)
is invoked with theStatus=Active
.- Parameters:
blockchainData
- a database access to apply configurationinstanceSpec
- a service instance specification; must reference a deployed artifactconfiguration
- service instance configuration parameters as a serialized protobuf message- Throws:
java.lang.IllegalArgumentException
- if the service is already started; or its artifact is not deployedExecutionException
- if such exception occurred in the service constructor; must be translated into an error of kindErrors.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 kindErrors.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 toinstanceSpec
- a service instance specification; must reference a deployed artifactarguments
- a service arguments as a serialized protobuf message- Throws:
java.lang.IllegalArgumentException
- if the given service instance is active; or its artifact is not deployedExecutionException
- if such exception occurred in the service method; must be translated into an error of kindErrors.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 kindErrors.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 byinitiateAddingService(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 artifactinstanceStatus
- 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 belongsinterfaceName
- 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 identifierarguments
- the serialized transaction argumentsblockchainData
- a database accessor to apply changes tocallerServiceId
- the id of the caller service if transaction is invoked by other service. Currently only applicable to invocations of Configure interface methodstxMessageHash
- the hash of the transaction messageauthorPublicKey
- the public key of the transaction author- Throws:
ExecutionException
- if such exception occurred in the transaction; must be translated into an error of kindErrors.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 kindErrors.ErrorKind.UNEXPECTED
java.lang.IllegalArgumentException
- if any argument is not valid (e.g., unknown service)- See Also:
Transaction
-
beforeTransactions
Performs the before transactions operation on the specified service in this runtime.- See Also:
afterTransactions(int, BlockchainData)
-
afterTransactions
Performs the after transactions operation on the specified service in this runtime.- Parameters:
serviceId
- the id of the service on which to perform the operationblockchainData
- 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 kindErrors.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 kindErrors.ErrorKind.UNEXPECTED
java.lang.IllegalArgumentException
- if any argument is not valid (e.g., unknown service)
-
afterCommit
Notifies the services in the runtime of the block commit event.- Parameters:
snapshot
- a snapshot of the current database statevalidatorId
- an optional id of the validator node, or none for an auditorheight
- the current blockchain height
-
shutdown
public void shutdown() throws java.lang.InterruptedExceptionStops 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 interfacejava.lang.AutoCloseable
- Throws:
java.lang.InterruptedException
-