The process for designing task-centric services usually require less effort than the previous two design processes, simply because reuse is generally not a primary consideration. Therefore, only the service operation candidates identified as part of the service modeling process are addressed here.
Figure 15.15. Task-centric business services can comprise the business service layer, along with entity-centric neighbors.
15.4.1. Process description
As shown in Figure 15.16, this process starts off with a new kind of step in which workflow logic is mapped out. This is because task-centric business services are expected to contain and govern portions of business processes.
Figure 15.16. The task-centric business service design process.
Note that there is no step encouraging you to extend the service design beyond the feature set you already defined in the service modeling stage. As previously mentioned, providing a generic and reusable interface is not a priority for task-centric services.
Time now to begin our service design.
The RailCo service modeling process identified the need for a task-centric business service to govern the processing of invoices produced by the legacy accounting system. This resulted in the Invoice Processing Service candidate shown in Figure 15.17.
Figure 15.17. The Invoice Processing Service candidate.
At first it appears as though this service does not contain much of anything. This is actually not unusual for smaller scale task-centric services. A service candidate with no operation candidates simply means that this service is a pure controller, solely dedicated to coordinating the underlying service composition. It also means that RailCo will need to define its service interface from scratch during this design process.
Fortunately, there is a starting point, provided by the composition model (Figure 15.18) produced during Step 6 of the service modeling process from Chapter 12.
Figure 15.18. The Invoice Processing Service composition.
It looks like the Invoice Processing Service actually will be quite busy, as it needs to compose up to four separate services to process a single invoice submission.
Step 1: Define the workflow logic
Task-centric services typically will contain embedded workflow logic used to coordinate an underlying service composition. Our first step, therefore, is to define this logic for every possible interaction scenario we can imagine. If you performed the mapping exercise in the Identify candidate service compositions step of the service modeling process in Chapter 12, then you will have preliminary composition details already documented.
Because we are designing our task-centric business service after our entity-centric and application service designs have been completed, we will need to revisit these scenario documents and turn them into concrete service interaction models.
Different traditional modeling approaches can be used to accomplish this step (we use simple activity diagrams in our case study examples). The purpose of this exercise is to document each possible execution path, including all exception conditions. The resulting diagrams also will be useful input for subsequent test cases.
The workflow logic does not reside in the service interface we are designing in this process. We are defining workflow logic for the purpose of extracting the message exchanges with which this service will be involved. This provides us with information that helps us define types, operations, and message formats.
RailCo generates activity diagrams for all foreseeable interaction scenarios involving the Invoice Processing Service. Let's have a look at two of these diagrams.
Figure 15.19 illustrates the conditions and message exchanges required to successfully complete the invoice submission.
Figure 15.19. A successful completion of the Invoice Submission Process.
Figure 15.20 shows how a failure condition stops the process dead in its tracks. In this case, the Transformation Service returns an error, perhaps due to receiving an invalid document.
Figure 15.20. A failure condition caused by an error during the transformation step.
Step 2: Derive the service interface
Follow these suggested steps to assemble an initial service interface:
Use the application service operation candidates to derive a set of corresponding operations.
Unlike previous design processes, the source from which we derive our service interface this time also includes the activity diagrams and the workflow logic we documented in Step 1. This information gives us a good idea as to what additional operations our task-centric service may require.
Document the input and output values required for the processing of each operation and populate the types section with XSD schema types required to process the operations.
Build the WSDL definition by creating the portType (or interface) area, inserting the identified operation constructs. Then add the necessary message constructs containing the part elements that reference the appropriate schema types.
Because our service candidate provided us with no operation candidates, RailCo turns to the activity diagrams it created to derive the set of actions the service is required to perform (Figure 15.21):
Figure 15.21. Identified requests and responses for the Invoice Processing Service.
Of these actions, the latter three require that the service act as a requestor to initiate a message exchange with other services. These actions therefore will be implemented as part of the service's underlying business logic.
The "Start RailCo Invoice Submission Process" action, though, is initiated by the Polling Notification Service, meaning that the Invoice Processing Service receives the request while acting as the service provider. This action therefore needs to be expressed in the service interface.
First, the naming is reconsidered to something more appropriate, as shown in Figure 15.22.
Figure 15.22. The Invoice Processing Service with a new operation.
Carrying forward with this naming change, RailCo begins by defining the data exchange requirements for this one operation. The service interface design needed to interact with the Polling Notification Service requires an ID value, along with the location path of the invoice document file to be supplied. (This is because the Polling Notification Service does not actually physically retrieve and forward documents; it simply notifies other services of the arrival of specific types of files in a particular folder.)
RailCo starts by creating a preliminary types construct with the following complexType to match these parameter requirements:
Example 15.15. A complexType construct designed to receive two parameters from the Polling Notification Service.
Next, it defines the operation and its associated message within the portType and message constructs:
Example 15.16. The remaining parts of the abstract Invoice Processing Service definition establishing an operation with just one input message.
Note that because the message sent by the Polling Notification Service is based on the one-way MEP, the SubmitInvoice operation construct contains one input message element and no output elements.
Step 3: Apply principles of service-orientation
Before we get too far ahead in our service design, it is beneficial to take another look at the four service-orientation principles we covered in Chapter 8, which are not automatically provided to us through the use of Web services (service reusability, service autonomy, service statelessness, and service discoverability).
Reuse opportunities for task-centric services are much more rare than for entity-centric and application services. This is because task-centric services represent a portion of workflow logic specific to a business process. However, reuse still can be achieved. The Take into account the potential cross-process reusability of the logic being encapsulated and Consider the potential intra-process reusability of the logic being encapsulated modeling guidelines in Chapter 12 address this and still are applicable to this process.
Because they almost always act as parent controller services in compositions, the autonomy of task-centric services is generally dependent on the autonomy of the underlying child services. A consistent state of autonomy can therefore be challenging to maintain.
Task-centric services contain workflow logic that may impose processing dependencies in service compositions. This can lead to the need for state management. However, the use of document-style SOAP messages allows the service to delegate the persistence of some or all of this state information to the message itself.
It is always useful for services to be discoverable, but the need for task-centric services to be discovered is not as pressing as with other, more generically reusable services. Regardless, task-centric services can achieve reuse, and their existence should be known to others. Therefore, the Document services with metadata guideline provided at the end of this chapter also is recommended.
There is no requirement for the Invoice Processing Service to be reusable, and autonomy and statelessness are also not considered immediate concerns. As with the RailCo Transform Service that was designed previously, this service design is supplemented with additional metadata documentation to support discoverability.
Example 15.17. The portType construct with an additional documentation element.
<documentation> Initiates the Invoice Submission Process. documentation>
Step 4: Standardize and refine the service interface
Although task-centric business services will tend to have more creative operation names, existing conventions still need to be applied. Here is the standard list of recommended actions you can take to achieve a standardized and streamlined service design:
With regard to design standards relating to operation granularity, some leniency may be required to accommodate the processing of the service's embedded workflow sequence logic. Also, task-centric business services can benefit from reusing existing WSDL modules, in particular, XSD schema definitions.
Supporting the characteristic of extensibility is key to RailCo, as they are uncertain as to how their SOA will grow and evolve over time. In reviewing the service interface definition for the Invoice Processing Service, they realize that they are tailoring this interface to a single service requestor: the Polling Notification Service. It is foreseeable that the process logic encapsulated by this service could need to be invoked differently in the future.
To address these extensibility requirements, RailCo makes an adjustment to the schema markup within the types construct. Because an XSD schema representing the invoice document already exists (as a result of building the underlying processing logic for the Transform Service), it is decided to incorporate this schema as part of this WSDL.
To avoid creating redundant markup, the schema is imported into the types construct. The original complexType then is extended to include a new element representing the root element of the invoice document defined in the Invoice.xsd file. Service requestors now are required to submit either a document location or the document itself.
Example 15.18. The revised types construct of the Invoice Processing Service definition.
"http://www.xmltc.com/railco/invoice/schema/" schemaLocation="Invoice.xsd"/> type="inv:InvoiceType"/>
The fact that acceptable input values for this operation have been altered should be reflected in the documentation element contents, as follows:
Example 15.19. The documentation element contents also have been changed.
Initiates the Invoice Submission Process. Requires either the invoice document location or the document.
One more change is made during this step of the service design process. The original operation name "SubmitInvoice" is reconsidered. Following an internal naming convention, the name is trimmed to just "Submit" (Figure 15.23). Because the service name already communicates the fact that its context revolves around the processing of an invoice document, there is no need to repeat the word "invoice" within operation names.
Figure 15.23. The Invoice Processing Service with a revised operation name.
This affects both the original portType and message constructs, as follows:
Example 15.20. The revised message and portType constructs.
Initiates the Invoice Submission Process. Requires either the invoice document location or the document.
Step 5: Identify required processing
To carry out their share of a solution's process logic, task-centric services can compose application and both entity-centric and additional task-centric business services. Therefore, the implementation of a task-centric service interface requires that any needed underlying service layers are in place to support the processing requirements of its operations.
Because this is the last of our three service design processes, all required supporting aplication services need to be identified. They may consist of services that already existed and/or services we just designed during the previous application service design process. The design of process logic within the task-centric business service may also reveal the need for additional application services that haven't yet been considered.
Because RailCo had already designed the previously modeled application services and because subsequent activity diagrams did not identify the need for any additional services, there are no further processing requirements involving other services. However, because the Invoice Processing Service interface was extended to support future extensibility, it now is capable of accepting a pre-transformed invoice document as an input parameter.
In our original workflow logic we established a step in the process that positioned the Transform Service as taking care of both validation and transforming tasks. The workflow logic therefore needs to be altered to make the interaction with the Transform Service optional if the Submit operation of the Invoice Processing Service receives an invoice document as part of its input (because it is already transformed and because validation of the document will occur at the time it is received). This change does not affect other services; it only requires that a new conditional processing step be added to the application logic encapsulated by the Invoice Processing Service.
Case Study (Process Results)
Following is the final version of the InvoiceProcessing Service definition, incorporating the changes to element names and all of the previous revisions.
Example 15.21. The final abstract service definition.
Initiates the Invoice Submission Process. Requires either the invoice document location or the document. ...
Those of you familiar with the XML Schema Definition Language may recognize an opportunity to introduce a choice construct around the InvoiceLocation and InvoiceDocument elements. Advanced XSD features, such as the choice and union elements, have limited vendor support when used with WSDL definitions. Check your products before using these features.
This process has produced an abstract definition only. The full WSDL document, including sample concrete definition details and the imported schema, can be downloaded at www.serviceoriented.ws.
SUMMARY OF KEY POINTS
Part I: SOA and Web Services Fundamentals
The Evolution of SOA
Web Services and Primitive SOA
Part II: SOA and WS-* Extensions
Web Services and Contemporary SOA (Part I: Activity Management and Composition)
Web Services and Contemporary SOA (Part II: Advanced Messaging, Metadata, and Security)
Part III: SOA and Service-Orientation
Principles of Service-Orientation
Part IV: Building SOA (Planning and Analysis)
SOA Delivery Strategies
Service-Oriented Analysis (Part I: Introduction)
Service-Oriented Analysis (Part II: Service Modeling)
Part V: Building SOA (Technology and Design)
Service-Oriented Design (Part I: Introduction)
Service-Oriented Design (Part II: SOA Composition Guidelines)
Service-Oriented Design (Part III: Service Design)
Service-Oriented Design (Part IV: Business Process Design)
Fundamental WS-* Extensions
Appendix A. Case Studies: Conclusion