Chapter 19 Composition Implementation Patterns

Depending on the processing requirements of a service composition, certain design options can be considered as a means of improving the composition architecture. The patterns in this chapter provide a mixed set of design solutions that address implementation-level issues pertaining primarily to runtime service activity management and composition structure.

When working with task services, Agnostic Sub-Controller (607) provides a method by which sub-process logic can be reused as a nested composition structure. Composition Autonomy (616) is focused on increasing the collective performance and behavioral predictability of a service composition and is closely related to the Service Autonomy design principle. Both Atomic Service Transaction (623) and Compensating Service Transaction (631) enhance the integrity of runtime service activities by wrapping them in coordinated boundaries.

Table 19.1 Profile summary for the Agnostic Sub-Controller pattern.

image

Note

The term “sub-controller” is not new to this pattern. It is used to represent any service or service capability that composes services and is itself also composed. See SOAGlossary.com for a full definition.

Problem

When following Non-Agnostic Context (319), non-agnostic logic, at the time it is originally defined, is considered single purpose and non-reusable. By applying Process Abstraction (182), this type of logic is isolated within a task service that is typically positioned as the parent controller of a composition. When also having services based upon Entity Abstraction (175), the task service will generally be comprised of composition logic that needs to span multiple business entity boundaries in order to compose the respective entity services.

Subsequent to its definition and usage, it may be discovered that the task service contains segments of cross-entity logic that are, in fact, agnostic. This type of logic is most comparable to sub-processes that represent composition sequences so common that they are considered reusable. However, because this logic resides embedded within a larger body of non-agnostic logic, its reuse potential cannot be realized (Figure 19.1).

Figure 19.1 A subset of the parent process logic is deemed reusable but it is trapped among the other non-agnostic process logic encapsulated by the task service.

image

Solution

The newly discovered, cross-entity agnostic logic is separated into an agnostic service or an agnostic capability is added to the original task service. Either way, the result is a body of composition logic that itself can now be independently recomposed, thereby establishing an agnostic sub-controller (Figure 19.2).

Figure 19.2 A traditional, single-purpose composition is often configured in a two-tier hierarchy, with all of the composition logic residing in the parent task service. Alternatively, the composition can be structured into additional tiers so that the composition is comprised of a parent controller service and one or more nested compositions represented by sub-controller services. These nested compositions may be necessary to carry out the parent task, but individually they can also provide logic that can be used independently to automate a smaller task, or they may have logic that can be used to automate other larger tasks. Either way, they can be structured to represent and abstract agnostic logic for reuse purposes.

image

Application

There are two common methods for abstracting agnostic, cross-entity logic, each with its own set of trade-offs:

New Agnostic Service – The logic forms the basis of a new agnostic service. The challenge may lie in positioning this service within any of the layers previously established by Service Layers (143). Because it will usually represent cross-entity logic, it may be possible to assign it a coarse-grained business entity-based scope, thereby qualifying it as a standalone entity service.

New Agnostic Capability – The logic remains within the task service but it is made accessible via a new capability exposed by the task service contract. Although a practical approach, this can disturb the clean separation previously achieved by Process Abstraction (182).

With either technique, supporting infrastructure will need to be upgraded to prepare for the reuse of the newly found agnostic logic.

Impacts

The main challenge with the application of this pattern is its effect on the overall logical structure of the service inventory. Depending on the scope and nature of the agnostic sub-controller logic, its isolation into a separate service or capability can easily violate one or more of the patterns associated with Service Layers (143). The resulting confusion and misalignment of functional service contexts may not be warranted.

It is recommended that the actual reuse potential of the identified logic be first established and confirmed before proceeding with this pattern.

Relationships

Agnostic Sub-Controller is applied to service logic that is likely to have previously been non-agnostic, which is why this pattern has relationships with Process Abstraction (182), Process Centralization (193), and Agnostic Context (312).

Service Façade (333) is often employed to help structure the internal logic of an agnostic sub-controller service, and Contract Centralization (409) is important and relevant to the successful long-term usage of this type of service (as with any service).

Figure 19.3 Agnostic Sub-Controller is in the unique position of having relationships with patterns focused on non-agnostic and agnostic logic.

image

Table 19.2 Profile summary for the Composition Autonomy pattern.

image

Problem

Services are ideally individually autonomous so that they can provide a high degree of behavioral predictability when repeatedly reused and shared across multiple compositions. However, a natural result of typical distributed service composition is a loss of autonomy by any service composing another simply due to the fact that the service is required to invoke solution logic that resides outside of its controlled execution environment.

When individual services provide high levels of individual autonomy, the collective autonomy of the composition is correspondingly elevated, and this is generally adequate for most service compositions. But when one or more composition participants have a poor level of autonomy or when the requirements of the composition as a whole demand a higher degree of robustness and reliability, then a distributed composition may be insufficient (Figure 19.8).

Figure 19.8 In a highly distributed environment, a service composition’s overall autonomy will be collectively determined by the autonomy of its individual composition members. When services are designed in accordance with the Service Autonomy design principle, this collective autonomy will generally be sufficient. However, there are times when a higher degree of composition autonomy is required. As shown in this figure, Service D offers the lowest level of autonomy because its logic is accessed by external programs.

image

Solution

The services participating in the composition are deployed within an isolated environment so as to give the composition as a whole a high level of autonomy (Figure 19.9).

Figure 19.9 By grouping the services of a composition into a separate deployment environment, the collective autonomy is maximized because the implementation is dedicated to the composition, and none of the services are otherwise shared. Services C and D in particular benefit from this new implementation as they are no longer subject to shared access.

image

Application

To increase the autonomy of a composition the following steps can be taken:

• Two or more composed services are deployed on the same physical server to avoid remote communication.

• The composed services are isolated to avoid shared access.

• The agnostic composed services are redundantly implemented, as per Redundant Implementation (345).

• Services requiring data access are supplied with dedicated or replicated data stores, as per Service Data Replication (350).

It’s important to keep in mind that a service composition is a design-time representation of the aggregated service capabilities required to automate a specific business task. This has the following implications when applying this pattern:

• Even though entire services are redundantly deployed, only a subset of the capabilities will likely be utilized by the composition.

• Depending on the complexity of the business task, a variety of runtime scenarios can result in different capability compositions, some of which may need to involve services outside of the dedicated composition environment.

Note

There are variations in the extent to which this design pattern can be applied, several of which correspond to autonomy levels described in Chapter 10 of SOA Principles of Service Design.

Impacts

Because the requirements for increasing the overall autonomy of a service composition usually involve upgrading or extending the existing enterprise infrastructure, there are obvious costs and impacts that need to be taken into consideration.

Redundant implementations of agnostic services further add governance effort and expense so that these independent implementations are kept in synch with their shared counterparts.

Relationships

Because of its narrow emphasis on supporting the goals of the Service Autonomy design principle, this pattern has just a handful of relationships. Fundamentally, Composition Autonomy is concerned with maximizing the reliability and availability of services based on Agnostic Context (312).

Service Data Replication (350) and Redundant Implementation (345) help establish an appropriate level of isolation for service compositions. Often, security needs will dictate the decision to isolate externally facing services and any services they may compose, which may lead to the need to apply Composition Autonomy in support of Inventory Endpoint (260).

Figure 19.10 Composition Autonomy is implementation-centric and will generally require the application of more specialized patterns to realize required levels of composition isolation.

image

Table 19.3 Profile summary for the Atomic Service Transaction pattern.

image

Problem

During the course of a runtime service activity, a variety of issues can arise, relating either to the delivery of data between participating services or to problems occurring within service boundaries.

If a serious failure condition is encountered and insufficient exception handling logic is available within all affected services, then the overarching business process will not be allowed to complete successfully, nor will it be allowed to complete a pre-defined failure condition.

Instead, services may simply be left hanging in suspension indefinitely or until they time out. Outstanding changes that some services may have made to databases or other resources can end up causing problems or even corrupting parts of the enterprise because other required changes were never completed (Figure 19.13).

Figure 19.13 This figure shows three services being sequentially invoked in support of automating a parent business task. The first two services successfully complete their required database updates (1, 2), but the third service fails at its attempt to update its database (3). According to the rules of the business process, either all three updates must succeed or none at all. However, because the first two updates have already been completed, the failed update of the third database compromises the quality of the data in the first two (4).

image

Solution

A transaction system can require that services within a particular composition register themselves as part of a transaction prior to completing their changes. Then, as the service activity is underway, participating services communicate with the transaction system as to their status (Figure 19.14).

Figure 19.14 As per the previous figure, Services A and B complete their respective tasks successfully. However each time they do, they initiate a local transaction, temporarily saving the current state of the database prior to making their changes (1, 2). After Service C fails its database update attempt (3), Services A and B restore their databases back to their original states (4, 5). The business task is effectively reset or rolled back across services within the pre-defined transaction boundary.

image

At some point, the system queries all services to ask whether their functions were carried out successfully. If any one service responds negatively (or if any one service does not respond at all), a rollback command is issued, requesting that all services now restore any changes made up until that point. However, if all services respond favorably, then a commit command is issued asking all services to commit their changes.

Application

Depending on the transaction management system being used, the application of this design pattern can vary. Fundamentally, though, some mechanism needs to be in place so that all services within a given composition can be tracked at runtime and then contacted to receive status updates and for notification of commit or rollback commands.

For services delivered as components, runtime transaction management systems are capable of natively establishing transaction boundaries across services, especially when they rely on traditional binary protocols that create persistent connections.

When services are built as Web services, the WS-Coordination and WS-AtomicTransaction standards provide an industry standard mechanism to support transaction propagation across Web service implementations. Figure 19.15 illustrates how, when using WS-Coordination, a coordinator service is positioned to define the transaction boundary and manage transaction activity.

Figure 19.15 The transaction coordinator establishes the transaction boundary as per participating services that register for this transacted activity. These services are then queried as to whether the transaction should be committed or rolled back. Because Service C’s database update attempt failed, it votes to abort the transaction, which is what subsequently happens.

image

Note

For more information about WS-Coordination and related standards, visit SOASpecs.com and WS-Standards.com and see Chapter 6 in Service-Oriented Architecture: Concepts, Technology, and Design.

Impacts

For services to effectively participate in an atomic transaction, they need to capture a snapshot of a resource prior to making changes to it. This previous condition is often loaded into memory as state data and will continue to consume memory until the service receives the commit or rollback command. In larger transactions involving multiple services, this amount of memory consumption can add up and reduce overall service scalability (an issue especially important to shared agnostic services).

Relationships

This pattern can touch on many runtime activity-related parts of an inventory architecture, which is why it has so many relationships with patterns concerned with messaging, agent, and composition processing.

Atomic transactions are often initiated and coordinated via the parent business process layer as per Process Abstraction (182) and are extra effective when all participants can be physically isolated as per Composition Autonomy (616).

Figure 19.16 Atomic Service Transaction establishes a framework for coordinating transactions that involve numerous services and therefore relates to a variety of other patterns that provide runtime processing features.

image

However, asynchronous-based messaging patterns, such as Event-Driven Messaging (599) and Asynchronous Queuing (582), are often incompatible with this pattern due to its need to lock resources and its common reliance on synchronous data exchanges.

When centralizing process logic as part of an orchestration environment, the scope and complexity of service compositions can increase, primarily due to the rich feature set usually provided by orchestration products. Orchestrated logic therefore benefits from the runtime control provided by Atomic Service Transaction, which is why this pattern represents a common extension to Orchestration (701).

Figure 19.17 Atomic Service Transaction represents an optional part of Orchestration (701).

image

Table 19.4 Profile summary for the Compensating Service Transaction pattern.

image

Problem

When services being composed at runtime encounter failure conditions, runtime exceptions are raised either by individual services or by the platform hosting the service composition instance.

Services may or may not have adequate internal logic to gracefully handle some exceptions, thereby preserving the integrity of the remaining composition. However, with serious or unanticipated exceptions, services often have no choice but to propagate the exception to other services in the composition. Similarly, when the runtime platform itself generates an exception, it may be required to halt the execution of the composition or terminate the composition instance altogether. One approach to solving this problem while preserving the integrity of the composition is the usage of transactions.

When applying Atomic Service Transaction (623), these situations are resolved by enabling all services to rollback to their original state before the composition instance is destroyed. In order to obtain this type of functionality, back-end resources (such as database tables and records, as well as other systems) will typically need to be locked for the duration of the transaction (Figure 19.18).

Figure 19.18 Services involved in an atomic transaction are required to lock up resources for the duration of the transaction.

image

Depending on the length and scope of the transaction, this can severely degrade performance and can also reduce the scalability of the overall service inventory.

Solution

Instead of being wrapped in an atomic transaction, the service composition is supplemented with compensating logic. This logic differs from atomic transactions in that it does not require services to maintain the original state or lock resources for the duration of the transaction.

As long as there is no firm requirement for compensations to restore a runtime activity back to its original state, exception conditions can be handled gracefully without jeopardizing the integrity of the composition (Figure 19.19).

Figure 19.19 Compensating transactions do not require that resources be locked or that the original state be preserved.

image

Application

Compensating logic is typically defined at these levels:

• composition member

• composition controller

A service is considered a composition member when it is being composed by parent composition logic. At this level, compensating routines can extend a service via the addition of undo capabilities. For every capability that alters the state of the underlying service implementation (including any repositories or other resources accessed by the service logic), a corresponding undo capability is added. This allows the parent composition logic to respond to an exception condition by calling the undo capability of each service that was invoked up until that point.

The composition controller may be a task service that is composing other services or it may represent parent composition logic that is part of a platform based on Orchestration (701). When applied within middleware environments, the role of a composition controller is comparable to that of a transaction manager.

Either way, this logic can be extended with compensating routines that also respond to exception conditions with pre-determined exception handling logic. The only difference is that, in this case, the logic resides with the task logic, as per Process Abstraction (182).

At the controller level, the compensating logic may optionally invoke the individual undo capabilities of composition member services. It can also be designed to carry out additional functions, such as sending out a notification message or starting up a new instance of the composition after the previous instance was terminated. In most cases, compensation logic will invalidate the last “commited” state, as opposed to canceling back to the original pre-state.

The undo logic can vary from carrying out a simple notification to restoring some or all of the resources modified by the service. Another approach is to have the undo capability simply tag affected resources (such as an updated database record) with a marker that indicates its invalidation.

When redundant service capabilities are appended to a contract via Contract Denormalization (414), correspondingly redundant undo capabilities (that provide undo functionality at different levels of granularity) can also be added.

Note

When designing services as Web services and applying Orchestration (701), the WS-BPEL language provides a common means of defining compensating processes as part of the overall parent composition logic. For more information about WS-BPEL, visit SOASpecs.com and see Chapters 6 and 16 in Service-Oriented Architecture: Concepts, Technology, and Design.

Impacts

Because the nature and extent of compensating logic is left up to the designer, it can vary in quality and effectiveness. Creating a series of undo capabilities that perform little or no logic that actually undoes anything can lead to a false assumption that an exception was effectively handled, when in fact it wasn’t. This is especially the case when composition designers are not allowed access to the underlying logic of composition member services and must therefore simply assume that undo capabilities provided by service contracts are handling failure conditions properly.

Additionally, for services that do perform a range of data or resource access functions, having to append the service contract with an undo capability for each existing capability that alters the service implementation state can bloat the service contract.

Relationships

Compensating Service Transaction shares several of the same relationships as Atomic Service Transaction (623) and also has its own relationship with that pattern as any one compensating transaction can encompass one or more individual atomic transactions.

Figure 19.20 Compensating Service Transaction relates to several messaging and composition design patterns.

image

The ability to define and carry out compensation logic positions Compensating Service Transaction as a core part of Orchestration (701).

Figure 19.21 Compensating Service Transaction represents a key part of Orchestration (701).

image
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.242.141