page loader

DOCUMENTATION Learn PoCAT Cloud Native Application Platform

Document Welcome to the PoCAT Cloud Native Application Platform documentation area.

Overview

What is Serbit?

A Serbit is a component designed to process certain type of message, managed by ServiceContainer, that process messages by purpose which delivered from other services. A Service can be organized by combine multiple related serbits.

A Serbit uses a publish/subscribe model to process messages, which is optimized for asynchronously propagating messages between services.

A ServiceContainer received A ServiceContainer subscribes messages from various type of service and passes them to serbit, and publish messages which sent from serbit to the actual destination. A ServiceContainer also manages life cycle of serbit and resources using by serbit.

Serbit

Serbit Lifecycle

A Serbit is managed through life cycle that defines how it is instantiated, is initialized, process messages, taken out of service.
Each life cycle is expressed by the init, serve, and destroy APIs, and all serbit Implementations must implement these APIs for each language.

For example, in Java, Serbit is implemented as follows:

package io.pocat.platform;
                                
                                public interface Serbit {
                                    void init(SerbitConfig config) throws UnavailableException;
                                    void serve(Delivery delivery) throws SerbitException;
                                    void destroy() throws UnavailableException;
                                }
                                

Instantiation

The Serbit must be instantiated at time chosen by the ServiceContainer. Instantiation order of Serbit is not guaranteed. ServiceContainer must contain exactly one instance for each serbit, that means, the implementation of serbit must guarantee concurrency.

Error Handling on Instantiation

If an error occured during instantiation, ServiceContainer must stop deploying service. A service should not be deployed if even only one serbit is failed to instantiate. The ServiceContainer must stop after proper error handling, such as logging.

Initialization

After instantiate, ServiceContainer must initialize Serbits. ServiceContainer must create SerbitConfig instance per serbit and call init api with ServiceConfig as argument. The serbit can access initial parameter which is set by container by using SerbitConfig object. If serbit needs to use shared resources or context parameters of service, it can be done by using ServiceContext which is included SerbitConfig instance.

If all serbit is not initialized, ServiceContainer should not pass the message to the serbit.

By default, all serbits have the same priority 1, priority can be set in the service descriptor. Serbit initialization is processed in the order of priority and for the same priority, the order is not determined.

SerbitConfig

During initialization, Serbit init API is called with argument SerbitConfig object. SerbitConfig object contains information which is needed for initialization of serbit as following:

  • SerbitId : Identifier of Serbit which is created during deploying. Each Serbit Instance has unique identifier.
  • SerbitName : Name of Serbit in service descriptor.
  • ServiceContext : Service context of service which contains this serbit. See the "ServiceContext" chaptor for more details.
  • Init parameters : Initial Parameters to initialize serbit.

ServiceContext

ServiceContext is an object to obtain information of service which the serbit belongs to. A ServiceContext instance is unique in service container, this means all serbit can access to the same instance of ServiceContext. A Serbit can access information of service like shared resources, context parameters, and so on through ServiceContext instance. You can set attributes in the ServiceContext in key-value format, and attributes set in one Serbit can be shared between Serbits included in the same ServiceContainer. ServiceContext has information as following:

  • ServiceId : Identifier of service which is created when the ServiceContainer is started. Each deployed service has a unique identifier.
  • ServiceName : Name of service in service descriptor.
  • Context parameters : Parameters which is shared in ServiceContainer
  • Resource : Shared Resource objects used by serbits belongs to a service. Resources external to the sevice, such as Database Connection. .
  • Attributes : Attribut value that shared. This can be readable and writable.

Error Handling

If an error occured during instantiation, ServiceContainer must stop initializing process and ServiceContainer must handle error properly.
The ServiceContainer can stop or retry initialization after proper error handling.

A service should not be deployed if even only one serbit is failed to initialize.

Serve

After initialization, Serbit can process message. It is the responsibility of ServiceContainer that send proper message to serbit by calling serve API.

See the "Message Delivery" chaptor for more details about the message.

Error Handling

Any errors that cannot be handled internally by the Serbit must be propagated to the ServiceContainer in a proper format like exception. ServiceContainer must handle error properly based on error code. If no error code provided, ServiceContainer must handle error with default error handling.

End of Service

Serbit must be destroyed only when Service is terminated and cannot be destroyed individually. When a termination of service occurs, the ServiceContainer must stop all message subscription immediately and wait until remained messages are processed or stop message processing with error. When there are no more messages, ServiceContainer call destroy API of service in the reverse order of initialization

Message Delivery

Message Delivery is the message structure delivered to the Serbit.

Message Delivery includes messages and management information.

The structure of Message Delivery are as follows:

Envelope

Envelope contains the message management information as following:

  • topic : Topic of message.
  • replyTo : The channel to response if needed. Serbit can pass the replyTo to other message.
  • Transaction ID : Identifier of transaction which this message is included.
  • Process ID : Identifier of process which this message is processed.
  • Previous Process ID : Identifier of process which this message is sent from.
  • Message ID : Identifier of message. Unique per message.
  • timestamp : Message creation time.
  • Hop Count : The maximum number of messages that can be transmitted within the current transaction.

Headers

A set of message headers

Payload

Message payload as byte array.

Service

A Service is a set of one or more serbits.
A ServiceContainer must deploy only one Service.

The Service directory is structured as following:

  • /SVC-INF/service.xml : Service descriptor which describe service architecture.
  • /SVC-INF/libs/ : Directory include library files for service
  • /SVC-INF/classes Directory include class files for service
  • /SVC-INF/scripts Directory include script files for service

Service Descriptor

Service Descriptor is a XML file to describe service architecture. Service Descriptor contains as following:

  • Service Name : name of service
  • Serbit list : The list of Serbit element included to service. The serbit element include name, class, initialize priority and initial parameters of serbit.
  • context params : The list of context parameters
  • resource list : The list of resources that used by service

Service Descriptor Schema

<?xml version="1.0" encoding="UTF-8"?>
                                <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
                                    <xs:element name="service-descriptor" type="serviceDescriptorType"/>
                                
                                    <xs:complexType name="serviceDescriptorType">
                                        <xs:sequence>
                                            <xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/>
                                            <xs:element name="serbits" type="serbitsType" minOccurs="1" maxOccurs="1"/>
                                            <xs:element name="context-params" type="contextParamsType" minOccurs="0" maxOccurs="1"/>
                                            <xs:element name="resource-refs" type="resourceRefsType" minOccurs="0" maxOccurs="1"/>
                                        </xs:sequence>
                                    </xs:complexType>
                                
                                    <xs:complexType name="serbitsType">
                                        <xs:sequence>
                                            <xs:element name="serbit" type="serbitType" minOccurs="1" maxOccurs="unbounded"/>
                                        </xs:sequence>
                                    </xs:complexType>
                                
                                    <xs:complexType name="serbitType">
                                        <xs:sequence>
                                            <xs:element name="serbit-name" type="xs:string" minOccurs="1" maxOccurs="1"/>
                                            <xs:choice minOccurs="1" maxOccurs="1">
                                                <xs:element name="serbit-class" type="xs:string"/>
                                                <xs:element name="serbit-script" type="xs:string"/>
                                            </xs:choice>
                                            <xs:element name="init-params" type="initParamsType" minOccurs="0" maxOccurs="1"/>
                                            <xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"/>
                                        </xs:sequence>
                                        <xs:attribute name="order" type="xs:positiveInteger" default="1" use="optional" />
                                    </xs:complexType>
                                
                                    <xs:complexType name="resourceRefsType">
                                        <xs:sequence>
                                            <xs:element name="ref" type="resourceRefType" minOccurs="1" maxOccurs="unbounded" />
                                        </xs:sequence>
                                    </xs:complexType>
                                
                                    <xs:complexType name="resourceRefType">
                                        <xs:attribute name="name" type="xs:string" use="required"/>
                                        <xs:attribute name="type" type="xs:string" use="required"/>
                                        <xs:attribute name="description" type="xs:string" use="optional"/>
                                    </xs:complexType>
                                
                                    <xs:complexType name="initParamsType">
                                        <xs:sequence>
                                            <xs:element name="init-param" type="paramType" minOccurs="1" maxOccurs="unbounded"/>
                                        </xs:sequence>
                                    </xs:complexType>
                                
                                    <xs:complexType name="contextParamsType">
                                        <xs:sequence>
                                            <xs:element name="context-param" type="paramType" minOccurs="1" maxOccurs="unbounded"/>
                                        </xs:sequence>
                                    </xs:complexType>
                                
                                    <xs:complexType name="paramType">
                                        <xs:attribute name="name" type="xs:string" use="required"/>
                                        <xs:attribute name="default-value" type="xs:string" use="required"/>
                                        <xs:attribute name="description" type="xs:string" use="optional"/>
                                    </xs:complexType>
                                
                                </xs:schema>
                                

Example of Service Descriptor

<service-descriptor>
                                  <name>HelloService</name>
                                  <serbits>
                                    <serbit order="1">
                                      <serbit-name>HelloSerbit</serbit-name>
                                      <serbit-class>io.pocat.service.HelloSerbit</serbit-class>
                                      <init-params>
                                        <init-param name="locale" default-value="en" description="Greetings locale"/>
                                      </init-params>
                                      <description>HelloSerbit in English</description>
                                    </serbit>
                                    <serbit order="2">
                                      <serbit-name>SalutSerbit</serbit-name>
                                      <serbit-class>io.pocat.service.HelloSerbit</serbit-class>
                                      <init-params>
                                        <init-param name="locale" default-value="fr" description="Greetings locale"/>
                                      </init-params>
                                      <description>HelloSerbit in French</description>
                                    </serbit>
                                  </serbits>
                                  <context-params>
                                    <context-param name="default-locale" default-value="en" description="Default locale if locale does not set."/>
                                  </context-params>
                                  <resource-refs>
                                    <ref name="greetingDatabase" type="javax,sql.DataSource" description="Greetings database"/>
                                  </resource-refs>
                                </service-descriptor>