Document Properties
Kbid
2329M3
Last Modified
22-Oct-2021
Added to KB
18-Jun-2012
Public Access
Everyone
Status
Online
Doc Type
Concepts
Product
  • ICM 7.10
  • ICM 11
Concept - Managed Service Framework

Introduction

If we talk about services, we must clearly understand what a service is (in our context). In an end-to-end communication arrangement one communication partner provides certain operations that are bundled in a service; a client calls those operations. The managed part of a service refers to the service framework's capabilities.
For example, a service connection could be established by taking certain objects and arranging (marshaling) them with a created set of call parameters, and sending them via technical connection. You also need to consider logging and monitoring, as well as the addition of structures to assist with call configuration and its assignment to the environment in which you want to run the service. Many of these activities are handled by the "Managed Service Framework".

Services are usually described by interfaces (generally speaking, these can be but not necessarily refer to Java interfaces). That said, we should not assume that every interface is a service.


For a service call situation we assume:

  • The call is addressed to another system outside the INTERSHOP platform.
  • If no specific call can be defined, it should potentially be useful to have an external call.
  • The service should offer useful operations.

Glossary

This glossary describes the terms used here ( typewriter style denotes terms that directly correspond with class/interface names):

Term

Description

Adapter

If you think of a stub/skeleton architecture where the skeleton is the service, then the adapter is the stub that communicates with the service.

Adapter Interface

A Java interface that is not a  marker interface and commonly not a  pojo interface.

Assignment

An assignment is the same as the ServiceAssignment described below.

Configuration

Mostly, configuration refers to the term "dynamic configuration".

Note

Make sure that you do not confuse configuration with ServiceConfiguration.

Dynamic Configuration

The term "dynamic configuration" refers to configurations that have specific parameters. For example, an HTTP request has URLs, timeouts and the like, while a mail sender may have SMTP server, security values, ports and so on. The managed service framework does not limit what parameters a service might support, but it offers easy-to-use parameter definitions to handle those configurations. Since the parameters vary from one to another ServiceDefinition, it is called "dynamic".

Event

A state change triggers an event. Events in this documentation are lifecycle updates on a ServiceConfigurationBO object or another lifecycle update on any other object of the Intershop platform.

Hook

A hook is the method that will be triggered by an event. Usually they implement ServiceConfigurationBO<ServiceConfigurationBO>.

Intershop platform

The Intershop server software as distributed.

New Services

New services are implementations that follow the design described in this document. The designation "new" merely serves to contrast to old services.

Old Services

Enfinity platform versions from 6.4 have service implementations that follow a distinct design. Those services are supported by the new service framework design, with one major limitation: it is not possible to create more than one ServiceConfigurationBO for a ServiceConfigurationBORepository.

Service

In an end-to-end communication, one communication partner provides some operations that are bundled in a service, while a client calls those operations.

ServiceAssignment

ServiceConfigurationBORepository objects can own and refer to ServiceConfigurationBO objects. Each ServiceConfigurationBORepository that refers to a ServiceConfigurationBO has a ServiceAssignment. From the service user's point of view, the ServiceAssignment is encapsulated in the ServiceConfigurationBO; however, it is used to store attributes that are distinctive for the actual ServiceConfigurationBORepository and not globally.

ServiceConfigurationBO

A ServiceConfigurationBO associates a ServiceConfigurationBORepository with a ServiceDefiniton. Think of it as an instance of a ServiceDefiniton that belongs to a ServiceConfigurationBORepository. It follows the "Entity" pattern designed in the Business Object Framework .

ServiceConfigurationBORepository

A ServiceConfigurationBORepository provides methods to access, manage assignments and manage the lifecycle of ServiceConfigurationBO objects. It follows the "Repository" pattern designed in the Business Object Framework.

ServiceDefinition

A ServiceDefinition is a stateless object that

  • bundles service adapter interfaces
  • handles the lookup of an appropriate adapter implementation for a certain adapter interface
  • reacts to ServiceConfigurationBO state changes by implementing BusinessObjectListener<ServiceConfigurationBO>.
    The term "service type" is synonymous to "ServiceDefinition", but focuses more on the business view.

ServiceDefinitionKey

The ServiceDefinitionKey is a kind of a bridge object that links the ServiceDefinition that is defined in Java with the database entities. A ServiceDefinition is uniquely defined by a cartridgeID and a serviceDefinitionID. To refer to a ServiceDefinition from a ServicePermission or ServiceConfiguration, the reference is the ServiceDefinitionKey, which holds the attributes cartridgeID and a serviceDefinitionID.

ServiceDefinitionRegistry

The ServiceDefinitionRegistry is a global point to register and retrieve ServiceDefinition objects. The default ServiceDefinitionRegistry is defined as a component in bc_service with the instance name serviceDefinitionRegistry.

ServiceDefinitionRegistry.Entry

When registering a ServiceDefinition at a ServiceDefinitionRegistry, it is registered with a number of parameters, among others cartridgeID and a serviceDefinitionID, also see ServiceDefinitionKey.

ServicePermission

A ServicePermission"allows"/"prohibits" a ServiceDefinition for a ServiceConfigurationBORepository. When "prohibited", neither the ServiceConfigurationBORepository nor its descendents are able to "see" or "access" the ServiceDefinition.

ServiceProvider

The ServiceProvider is a stateful object (as it may hold a ServiceConfigurationBO reference) that serves an adapter that corresponds to the requested adapter interface. It is served by a ServiceDefinition.

Service type

Synonym for ServiceDefinition, but focuses more on the business view.

XSD

XML schema description

Artifacts

This chapter describes some artifacts in the INTERSHOP platform that constitute the Managed Service Framework.

The following diagram shows - extremely simplified - the parts of the managed service framework.

  • There are the adapters that cover the aspects of the service call as shown above.
  • There is a ServiceDefinition that refers to one or more adapters and supports access to them.
  • There is the ServiceConfigurationBORepository that is the link to the context whereby services are accessed and these may own specific settings for a service.
  • There is the ServiceConfigurationBO that associates a ServiceConfigurationBORepository with the ServiceDefinition. Thus, ServiceConfigurationBORepository specific settings are stored and so the adapters operate  ServiceConfigurationBORepository-aware, hence App-aware (if ServiceConfigurationBORepository is an App-Repository).

The following chapters will take a closer look at the artifacts specified here and introduce additional artifacts that surround those previously mentioned.

Adapters

Definition

While an adapter is the object that makes the service call possible, still, it is not a part of the Managed Service Framework. The adapter is a component that "knows" how to access the service. In the INTERSHOP platform, an adapter is defined by any Java interface (see the following chapter). There is no restriction on the adapter implementation. Essentially, any object can become a service adapter as long as it implements at least one interface.

The adapter has to take care of:

  • Configuration
  • Mapping of request objects
  • Marshaling/Unmarshaling
  • Connection to the other endpoint

Adapter Interface

As mentioned before, any object that implements a Java interface can serve as an adapter.

However, there are some constraints that must be considered: Avoid adapters for marker interfaces and pojos.

  • Marker interfaces do not define any method, so they do not define any operation and thus no useful service, hence no call can be created against such an interface. It simply does not make any sense.
  • Pojo objects just offer getters (and maybe setters), i.e., methods that just access the attributes of a certain object. A pojo can be a good candidate for service call parameters or response values, but it would not make up an adapter interface.

Example:

Note

You could think of the Address interface as being an adapter interface. However, this would mean that getting a name or getting a street are service calls. That would not be very useful.

In the INTERSHOP platform, the adapter interface is represented in two shapes:

  • The generic <T> in the getServiceAdapter(Class<T>) method of the ServiceProvider in bc_service and
  • The Class values in the already mentioned getServiceAdapter(Class<T>) method and in the return value of the getServiceInterfaces() method of the ServiceDefinition

As a programmer you might be required to use an existing service, to implement a new stub or to do both.
After reading this concept and with the Cookbook - Managed Service Framework at hand, you should be able to fulfill your task.

Note

If you are asked to enhance/change the framework itself, do not forget to update this documentation.

Note

Adapter interfaces should be marked as managed service using com.intershop.component.service.capi.service.ManagedService. This marker annotation is used by external tools.

This is how a service is looked up and how it is called ("use an existing service") - using the "Address" example mentioned above:

ServiceConfigurationBORepository serviceConfigurationBORepository = applicationBO.getRepository( "ServiceConfigurationBORepository" );
for (AddressValidator addressValidator : serviceConfigurationBORepository.getServiceAdapters( AddressValidator.class ))
{
    addressValidator.validate( address );
}

The ServiceConfigurationBORepository will be discussed later in this document. The AddressValidator is a Java interface that defines a stub for an address validator service. The variable addressValidator contains an adapter implementation. The method validate encapsulates the address validation operation of a validation service. The address parameter is considered an Address object as defined in the example above.

To implement a new stub for a service, follow these proceedings:

  • Define one or more Java interfaces that represent the operations of a service.
  • Create an adapter that implements these interfaces.
    • Create the parameters (consider to choose XSD definitions to establish service objects).
    • Create the mapping between the INTERSHOP platform's standard objects and these parameters, if necessary.
    • Establish a connection to the remote service that is to be called.
    • Marshal the parameter to the remote service via the connection.
    • Receive the answer (if provided), unmarshal it, and process it.
    • Take care for error scenarios (like, for example, Timeouts o.t.l., consider fallbacks).

To make the new service adapter available in the INTERSHOP platform, some more artifacts have to be established, which will be discussed in the following chapters:

  • ServiceDefintion
  • ServiceProvider

Optionally, these parts may also be needed:

  • A configuration definition (see "Dynamic Configuration" chapter)
  • Establishing a ServiceConfigurationBORepository for a certain context.

There are abstract adapter classes that provide a lot of functionality that may be needed: SingleOperationAdapter and MultiOperationAdapter. For more details refer to the Cookbook - Managed Service Framework.

Service Definition / Service Type

A ServiceDefinition is a stateless object that

  • Bundles service adapter interfaces
  • Handles the lookup of an appropriate adapter implementation for a certain adapter interface
  • May react on ServiceConfigurationBO state changes by defining lifecycle hooks

Sometimes several adapter interfaces can be bundled for functional reasons. Think, for example, of an inventory service. There might be an interface that just retrieves the quantity on stock and another one that manages a reservation lifecycle. Thus, there might be a QuantityRequest interface and a Reservation interface. The two of them could be bundled to one InventoryServiceDefinition that supports both interfaces. The supported interfaces are retrievable by accessing the Collection<Class<?>> getServiceInterfaces() method.

When a service is looked up using the ServiceConfigurationBORepository, the lookup strategy of the framework will ask the ServiceDefinition to serve an appropriate ServiceProvider for a given ServiceConfigurationBO. That means, the ServiceDefinition must analyze the ServiceConfigurationBO and select a suitable ServiceProvider based on it.

The ServiceDefinition might cache instances, connections o.t.l. To remain up-to-date consistently, the ServiceDefinition can implement BusinessObjectListener<ServiceConfigurationBO>.

  • objectCreated( ServiceConfigurationBO serviceConfiguration )
  • objectChanged( ServiceConfigurationBO serviceConfiguration )
  • objectDeleting( ServiceConfigurationBO serviceConfiguration )

Service Provider

The ServiceProvider is a stateful object (as it may hold a ServiceConfigurationBO reference) that serves an adapter that corresponds to the requested adapter interface.
Thus, it does not define more than this method:

<T> T getServiceAdapter( Class<T> serviceInterface );

As both ServiceDefinition and ServiceProvider implementations are located in the internal section of a cartridge and the ServiceDefinition provides a ServiceProvider according to a ServiceConfigurationBO, there must be a technique to generically switch the ServiceProvider, if it is intended to be able to add new adapters in new cartridges that support a certain ServiceDefinition. The AbstractServiceDefinition offers capabilities to add adapters from outside the original cartridge.

Service Definition Registry

The ServiceDefinitionRegistry is the central point where ServiceDefinition instances are registered and retrieved. Usually, ServiceDefinition instances are wired to the ServiceDefinitionRegistry using the Component Framework.

The entry of the ServiceDefinitionRegistry contains some more (descriptive) attributes in addition to the ServiceDefinition itself.

There are so-called "old" services (services that have been implemented prior to INTERSHOP 7) and "new" services.

  • The old services are defined by ServiceInformation implementations,
  • The new services are defined by ServiceDefinition implementations. The old services will be supported.

The ServiceInformation interfaces provide some methods that correspond with some component configuration in the new framework. The ServiceInformationServiceDefinitionBridge is a wrapper around a ServiceInformation and turns it to a ServiceDefinition.

Component configuration key (new)

ServiceInformation (old)

prefix


cartridgeID

does not exist for old services.

constant "nocartridge"

A ServiceDefinition is uniquely defined by cartridgeID and serviceDefinitionID.

groupID

getGroupID()

service.group.name

All whitespace will be replaced by underscores ( replaceAll("\s+","_")).

parameterGroupID

getParameterGroupID()

not prefixed

serviceDefinitionID

getServiceID()

not prefixed

A ServiceDefinition is uniquely defined by cartridgeID and serviceDefinitionID.

localizationKeyForName

does not exist for old services

service.serviceinformation.name

All whitespaces will be replaced by underscores ( replaceAll("\s+","_")).

The ServiceDefinitionRegistry also holds references to so-called "chain elements". These are handlers that are part of the service call chain and may listen to the data exchange stream for, e.g., logging or monitoring reasons.

The following diagram shows the references between the adapter, adapter interface, ServiceProvider, ServiceDefinition, ServiceDefinitionRegistry.Entry and ServiceDefinitionRegistry.


There is an AbstractServiceDefinition that offers lots of implementations and makes it straightforward to have a new ServiceDefinition implementation (incl. a sufficient ServiceProvider). For more details refer to the Cookbook - Managed Service Framework.

ServiceDefinitionKeyPO

The ServiceDefinitionKeyPO represents the link between the "Java world" and the persistent layer. A ServiceDefinition is uniquely referenced by the cartridge id and the service definition id. This is because a programmer just needs to ensure that the ServiceDefinition has a unique service definition id within "his/her" cartridge. Some database objects, like ServicePermissionPO and ServiceConfigurationPO are holding references to that ServiceDefinitionKeyPO. These references are used by the ServiceConfigurationBORepository and ServiceConfigurationBO to be able to lookup "their" ServiceDefinition objects.

Service Configuration Repository

Definition

A ServiceConfigurationBORepository is a central point to manage the lifecycle of service configurations and it supports access to the adapters. Different ServiceConfigurationBORepository objects are available for different contexts, such as applications (see Concepts - App and Application Framework (until 6.6.x)). So a ServiceConfigurationBO associates a ServiceDefinition with a ServiceConfigurationBORepository. Any artifact that wants to handle services in any way must have a ServiceConfigurationBORepository to do so. When it is intended to use a service, it should be checked first whether there is a ServiceConfigurationBORepository for the context in mind.

The diagram above shows how ServiceConfigurationBORepository, ServiceConfigurationBO and ServiceDefinition correspond with each other.
It illustrates

  • That a ServiceConfigurationBORepository can have a ServiceMasterRepository- a kind of parent - that may share its ServiceConfigurationBO objects to the actual ServiceConfigurationBORepository
  • That a ServiceConfigurationBORepository can have one or more dependents - a kind of child element - that may get ServiceConfigurationBO objects shared from the actual ServiceConfigurationBORepository
  • That a ServiceConfigurationBORepository can own and refer to a ServiceConfigurationBO or just refer to a ServiceConfigurationBO
    • To own a ServiceConfigurationBO means that the actual ServiceConfigurationBORepository controls the lifecycle of it, i.e., it creates it. You can say "the ServiceConfigurationBO is located in the ServiceConfigurationBORepository". If a ServiceConfigurationBORepository owns a ServiceConfigurationBO, none of its parents can refer to it (because that would mean there is a circle dependency in the ServiceConfigurationBORepository structure).
    • To refer to a ServiceConfigurationBO means that it is a shared one from a ServiceMasterRepository. All "children" and "grandchildren" a.s.o. may refer to ServiceConfigurationBO objects. They may also control the activation behavior for themselves.
  • That a ServiceDefinition can have 0..n ServiceConfigurationBO that refers to it. Thus, several configurations for different use cases can be managed.

The ServiceConfigurationBORepository is just a composition of three interfaces that define three aspects of it:

  • ServiceExecutable that covers methods needed to access a service
  • ServiceInstantiable that covers methods to configure and to control the lifecycle of a ServiceConfigurationBO
  • ServiceMasterRepository that offers methods to access the ServiceConfigurationBORepository hierarchy. This is needed to be able to provide sharing capabilities.

Service Permissions

Service types can be allowed or prohibited for ServiceConfigurationBORepository instances.
Prohibiting a service type means that

  • it will not be seen in the back office, so it is not configurable in any way and
  • it will not be available for any of the descending ServiceConfigurationBORepository

As discussed above, a ServiceDefinitionKeyPO is the object that connects the ServiceDefinition, which is a pure Java object, with the persistence layer.
From the framework's point of view, all service-related tables can be empty at the beginning. Under normal circumstances they are not, since quite a few services are configured during DBInit.
But since ServicePermissionPO has a mandatory reference to a ServiceDefinitionKeyPO and nothing can be done with services before a ServicePermissionPO is in place, at first a ServiceDefinitionKeyPO must be in place and is created when allowing (or even prohibiting!) a ServiceDefinition.

Service Configuration

A ServiceConfigurationBO associates a ServiceConfigurationBORepository with a ServiceDefiniton. It has a name (and localizable display name and descriptions), can be made "accessible" (that will be discussed later on), and it may refer to some specific settings (called "Dynamic Configuration" within this document).

From the persistence layer point of view, the ServiceConfigurationBO is an aggregated object that consists of ServiceConfigurationPO and ServiceAssignmentPO. The ServiceConfigurationPO has attributes and methods that are valid for all artifacts that use the ServiceConfigurationBO object, while a ServiceAssignmentPO contains attributes and values that re-define the activation status of a service configuration. Those values are:

  • The activation flag, which defines if a service configuration can be accessed from the actual ServiceConfigurationBORepository
  • The Service Sharing Rule, which defines whether a service configuration is shared (i.e., available for sub- ServiceConfigurationBORepository) and if so, whether it should be activated by default or not or whether the usage is even mandatory

Activation / Enabled State / HardOff / Sharing Rules

There are different requirements with regard to when a service can be executed from a certain context:

  • The owner of a service might want to globally disable a service.
  • A user of a service might want to locally deactivate a service.
  • An administrator might want to globally disable a service (without overwriting the owner's settings!).
  • An owner or user might want to share a service to some other Repositories (e.g., storefront applications).

Note

A service can be executed if it is globally enabled, locally activated, not switched hard off and there is none of the master repositories whose sharing rule is UNSHARED.

Keep in mind that locally activated can be set explicitly, but also implicitly via the sharing rule of a master repository. That is, if there is no explicit local activation, the master repositories are then looked up. Their sharing rules will control its activation state in that case:

ServiceSharingRule

default activation state for descending repositories

UNSHARED

not activated

SHARED_ACTIVATED

activated

SHARED_DEACTIVATED

not activated

MANDATORY

activated - overrides locally activated flags

Dynamic Configuration

"Dynamic configurations" are configurations that are not "hard" bound to the ServiceConfigurationBO object, but the ServiceConfigurationBO is rather a key to the appropriate configuration definition and values.

Some services might not need any specific configurations, others do. Configuration parameters will differ widely. Thus, configuration parameter definitions must be configurable.
The usage of ParameterGroup definitions is supported by the managed service framework, but it is not required to do so. There are no methods defined in the ServiceConfigurationBO to access any dynamic configurations.

To access the dynamic configurations, commonly extensions of the ServiceConfigurationBO should be used. There is an ORMServiceConfigurationBOConfigurationExtensionImpl, for example. It implements a ConfigurationProvider interface whose only method is getConfiguration(): Configuration. See Concept - Component Framework (valid to 7.4 CI) to learn more about the Configuration artifacts.

To make a dynamic configuration editable, the ParameterGroup approach should be considered.
The following steps are needed to establish a ParameterGroup together with the ability to edit it in the back office:

  1. Define the parameters in staticfiles/configdef.
  2. Create localization values in sld_enterprise_app.
  3. Set the "root" ParameterGroup ID when registering a ServiceDefinition.

Following this approach there are parameters in the Intershop Commerce Management that must be defined. For detailed instructions, see the Cookbook - Managed Service Framework.

Artifacts Summary

The following diagram is a "big picture" of the discussed artifacts, but shows more detail than in the introduction of this chapter.

From the ServiceExecutable to the adapter interface, there is an imaginary "horizontal line" of artifacts that are obviously used during a service call, and the blue artifact section shows the persistent artifacts. All others are surrounding classes that help to manage the core artifacts.


Service Call Process

In the chapter "Adapter Interfaces", it has already been discussed how a service can be called. The following diagram repeats the steps once more:


The red section in the diagram above is worth a closer look:


Initializing Services

As mentioned above, there are 4 persistent objects handled by the managed service framework:

Persistent Object

Table name

Extensible/AV

ServiceDefinitionKeyPO

ServiceDefinitionKey

(minus)

ServicePermissionPO

ServicePermission

(minus)

ServiceConfigurationPO

ServiceConfiguration

(plus)

ServiceAssignmentPO

ServiceAssignment

(minus)

Without any database initialization none of the services will be available.

Sometimes specific services might be crucial to make the shop work properly, for example services that are used during the checkout. Therefore, these services should be available "out-of-the-box", i.e., after a server installation.
Therefore, 3 preparers are available to initialize a configuration:

  • ServiceAssignmentPreparer
  • ServiceConfigurationPreparer
  • ServicePermissionPreparer

There is no specific preparer to add rows to the ServiceDefinitionKey table since an entry is implicitly added "on the fly". That is, a ServicePermission or a ServiceConfiguration has a mandatory foreign key that refers to a ServiceDefinitionKey. When one of them is to be created, the ServiceDefinitionKey is looked up and if it is not already in place, it is created and used.

There is no way to add configuration parameters in DBInit. If that is required, a preparer must be implemented that adds values to the ServiceConfiguration-AV table as long as the type is a "new" type ("old" services use domain preferences for their configuration parameters).

The Cookbook - Managed Service Framework includes a chapter that describes in detail how to use the named preparers.

Monitoring Services

The monitoring of services is realized with MXBeans and handlers. The ServiceChain handles all registered handlers for a service, including MonitorHandler, LogHandler, and CachingHandler.
If the MonitorHandler is registered, it tracks various data, like successful requests, average answer time, failures etc.
A call works like this:


The RequestStatistics requires 3 parameters, which can be adjusted in the configuration tab of a service:

Long Call Threshold

If an answer of a request takes longer than the number defined in "Long Call", the request is considered a longCall

Number of Entries

The maximum number of entries, that will be saved in the statistics

Notification Threshold

Percentage of requests that have to be failures or timeouts for the notfication to be sent

Depending on those parameters, the statistics can return a status which is either ok (green), with errors (yellow), with exceptions (red), or not used (gray).

Disclaimer
The information provided in the Knowledge Base may not be applicable to all systems and situations. Intershop Communications will not be liable to any party for any direct or indirect damages resulting from the use of the Customer Support section of the Intershop Corporate Web site, including, without limitation, any lost profits, business interruption, loss of programs or other data on your information handling system.
The Intershop Knowledge Portal uses only technically necessary cookies. We do not track visitors or have visitors tracked by 3rd parties. Please find further information on privacy in the Intershop Privacy Policy and Legal Notice.
Home
Knowledge Base
Product Releases
Log on to continue
This Knowledge Base document is reserved for registered customers.
Log on with your Intershop Entra ID to continue.
Write an email to supportadmin@intershop.de if you experience login issues,
or if you want to register as customer.