Professional Documents
Culture Documents
ABC
Colin Ashford
OSS Evolution
www.ossevolution.com
E-mail: ashford@ossevolution.com
Pierre Gauthier
OSS Wave
www.osswave.com
E-mail: pierre.gauthier@osswave.com
DOI 10.1007/978-3-642-01396-6
c 2009 Springer-Verlag Berlin Heidelberg
This work is subject to copyright. All rights are reserved, whether the whole or part of the mate-
rial is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilm or in any other way, and storage in data banks. Dupli-
cation of this publication or parts thereof is permitted only under the provisions of the German
Copyright Law of September 9, 1965, in its current version, and permission for use must always
be obtained from Springer. Violations are liable to prosecution under the German Copyright Law.
The use of general descriptive names, registered names, trademarks, etc. in this publication does
not imply, even in the absence of a specific statement, that such names are exempt from the relevant
protective laws and regulations and therefore free for general use.
987654321
springer.com
In loving memory of Carole and for Jean-Loup
—Pierre
For Jo and Leon-Philip
—Colin
Foreword
Audience
The primary audience for this book is software engineers and architects who are
responsible for the design of telecommunications management systems and for sys-
tem integrators who are responsible for the development of management solutions.
Software development managers and network managers will also find the book use-
ful.
ix
x Preface
Goals
The main goal of the book is to present a compelling case for the adoption of
a core set of design patterns across the OSS community that will help in the rapid
delivery of effective and reliable management solutions. We support our case by
focussing on a consistent presentation format, discussion of the relevance of each
pattern to telecommunications management, and extensive code examples. We hope
that the patterns will contribute to the growing ecosystem of best practices and stan-
dards, common code, and proven designs for OSS applications and their interfaces.
It is both customary, and it gives us great pleasure, to have this opportunity to thank
all those who made this book possible. First those who reviewed the various drafts
of the book and made so many useful recommendations: Adam Boyle, Eric Dil-
lon, Craig Gallen, Philippe Lalande, Tony Richardson, and Mike Kelly. Special
thanks are due to Eugene Deery for going well beyond the call to keep us hon-
est and to Anne Jones for proof reading our text at short notice. Thanks are also
due to Martin Creaner for writing the foreword and for permission to use the TM
Forum’s Business Process Framework Map. We would also like to thank the team
at Springer, Christoph Baumann and Carmen Wolf, for their editorial support and
Frank Holzwarth for his help in cheerfully answering all our question on LATEX.
Despite the combined efforts of all these people, any errors or omissions that
remain are the responsibility of the authors.
xi
Contents
Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Colophon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Acronyms
xv
Chapter 1
Managing Telecommunications Services
The growth of telecommunications services over the last twenty years has been
driven by two major innovations: mobility and broadband data. Mobile technologies
like GSM and CDMA have made mobile voice-services ubiquitous in most urban
centres around the world, and the emergence of higher-bandwidth mobile technolo-
gies, such as UMTS and LTE, are enabling new services like mobile email, video
to the handset, and web browsing. Similarly broadband data-services like DSL and
Fiber-to-the-Home have enabled new services such as high-speed internet access,
audio and video downloading, and IPTV. Using their existing approaches, telecom-
munications service-providers are having difficulty in managing these new tech-
nologies and services.
Customers are demanding ever-increasing levels of service: they expect that ser-
vices, whether fixed or mobile, be always available, that new service offerings be
rapidly deployed, and that service-level agreements be honoured. At the same time
fierce competition is putting pressure on prices and customer loyalty. Thus prudent
service providers are looking to cut costs by managing their networks more effi-
ciently and increasing their revenue by rolling out new services more quickly.
In this chapter we will look at the elements that go to make up a telecommunica-
tions management deployment and the challenge that service providers face in man-
aging telecommunications networks. We will go on to develop a reference model
for telecommunications management that will form a basis for the patterns that we
will discuss in the rest of the book.
1
2 1 Managing Telecommunications Services
Operations Support Systems (OSSs) are servers that host OSS applications.
Managed systems are computer systems that host or manage managed resources.
Managed resources are logical or physical assets that provide services within the
telecommunications network and are manageable; examples of managed resources
include connectivity resources, end-user applications, and support resources.
Management-integration applications are software components that coordinate
the functionality of OSS applications to deliver management solutions.
OSS applications are software components that manage a particular aspect of a
telecommunications system such as a connectivity resource, an end-user applica-
tion, or a support resource; OSS applications implement the management logic and
business rules derived from an analysis of the management requirements.
Operator systems are generally cost-effective workstations or PCs that engage,
via the network, with one or more Management Integration Systems or with one or
more OSSs in a client-server style. As we will see later, operator systems can also
engage with OSSs in a publish-and-subscribe style to receive event notifications.
OSS applications typically implement a single management function, and come
from three main sources:
• Independent software vendors offering applications such as trouble ticketing,
alarm management, and service activation.
• Service providers who develop in-house applications to support specific aspects
of their business.
• Telecommunications-equipment vendors providing vendor- and equipment-specific
applications such as configuration, performance monitoring, and fault reporting.
As we shall see in the next section, a major part of deploying any new telecommuni-
cations service is integrating the various OSS applications into an effective manage-
ment solution. A management solution is a coordination of manual procedures and
the functionality of OSS applications that addresses a particular management prob-
lem; examples include service fulfillment, problem resolution, and provisioning of
network facilities.
will likely also require the development of some custom software to implement the
solution workflow and logic and to manage any operator interactions required.
However, not all OSS applications are built on compatible software and hard-
ware platforms, expose consistent interface styles, expose consistent models of the
resources to be managed, or use the same communications or database technologies.
These differences make it more difficult for a systems integrator or service provider
to integrate OSS applications into a management solution.
Over the years, a number of industry initiatives to reduce integration costs by
means of specifying standardized interfaces to OSS applications have been at-
tempted. Each has been based on detailed models and the particular implementation
technologies that were available at the time. Many initiatives have been quite suc-
cessful but, given the demanding nature of telecommunications management, there
has been an inevitable trend to re-write the standards using newer (and hopefully
better) technologies. Initiatives to standardize OSS application interfaces continue
today with the latest software technology offerings—Web Services and Service Ori-
ented Architectures (SOA). Although the technology may change, the core software
issues of designing effective, consistent interfaces to OSS applications remain.
The relationships between the processes in each area are represented by a map;
the map for the Operations area, which will be our focus, is shown in Fig. 1.2. The
processes depicted vertically (Operations Support & Readiness, Fulfillment, Assur-
ance, and Billing) represent a high-level view of flow-through operational activities,
whereas the processes depicted horizontally (Customer Relationship Management,
Service Management & Operations, Resource Management & Operations, and Sup-
plier/Partner Relationship Management) represent high-level business-related activ-
ities. These processes are successively decomposed into more detailed processes
that will form the basis of the OSS Reference Model which we will describe in the
next section.
In order to better understand a class of system requirements and solutions (in our
case those of telecommunications management), it is often useful to develop a ref-
erence model. A reference model is an accepted functional decomposition based on
a class of requirements; the parts of the model cooperate to meet the requirements.
It is an important tool in helping to move from a particular system requirement to a
solution.
The OSS Reference Model shown in Fig. 1.3 is a five-layer model that decom-
poses functional aspects of management solutions. It is based on a layered model
shown in Marinescau[3]; the functional partitioning is as follows.
Presentation layer is responsible for all aspects of interfacing with operators such
as network managers, craft technicians, or customer-service representatives.
Operator-support layer is responsible for operator-task workflow and validation
of operator input; it delegates all requests for management functionality to either the
OSS integration layer or directly to the OSS application layer. Examples of operator
tasks are resolving trouble-tickets, simple configuring, and event report alerting.
1.6 OSS Systems Architecture 7
1.7 Summary
In this chapter we have reviewed some of the forces driving the development
of telecommunications management systems and indicated that successful service
providers are those that see telecommunications management as a strategic tool to
improve service delivery and not as a necessary evil. We have also introduced two
models that underpin telecommunications management. In the next chapter, we will
talk about how these models are used in designing the software for management
solutions.
References 9
References
1. TM Forum, www.tmforum.org.
2. Business Process Framework, TM Forum,
http://www.tmforum.org/BusinessProcessFramework/1647/home.html.
3. Marinescu, F., EJB Design Patterns. Wiley, New York, 2002. p. 128.
4. Enterprise Java Beans, Sun Developer Network, http://java.sun.com/products/ejb.
5. Common Object Request Broker, Object Management Group,
http://www.omg.org/gettingstarted/corbafaq.htm.
6. Web Services, World Wide Web Consortium, http://www.w3.org/2002/ws.
Chapter 2
Designing Management Solutions
The OSS Reference Model we discussed in the previous chapter is a useful func-
tional way of thinking about management solutions; however, we need to turn this
functional view into a software architecture that allows us to develop and deploy
an OSS systems architecture that delivers the management solution. A typical OSS
client (either an operator-support application or a management-integration appli-
cation), will implement a management solution by engaging with one or more OSS
applications running on one or more OSSs. For example, a service-fulfillment appli-
cation supporting a customer-service agent in fulfilling a customer request for DSL
service might access an inventory application to query availability, a DSL EMS
to provision and activate the DSL multiplexer, and a billing application to initiate
billing.
It is the style of the engagement between the OSS client and the OSS application,
that is, the style of the interface exposed by the OSS application, that will concern
us for most of this chapter. But first we will review the process of developing an
OSS systems architecture.
11
12 2 Designing Management Solutions
tectural style and sets a consistent architectural direction for system implementa-
tion. The software architecture is a combination of design patterns (the subject of
this book), a related information model, the OSS Reference Architecture, an imple-
mentation profile, and a binding to a particular software technology. The software
architecture is a specification of the systems architecture that will be deployed to
solve the management problem. We will now look at these various items in detail.
Management requirements a statement of general telecommunications-manage-
ment requirements systems must meet. The TMF Business Process Framework Op-
erations Map (see Sect. 1.4), is a key industry source for telecommunications man-
agement requirements.
OSS Reference Model a functional decomposition that meets telecommunication-
management requirements. It is a division of functionality and the data flows be-
tween the divisions. The OSS Reference Model, developed in Sect. 1.5, is the model
that we shall use as a basis for our discussions.
• A consistent style of information exchange between OSS clients and OSS appli-
cations (Remote Operations Model, see Sect. 2.4; Managed-Entity Value pattern,
see Sect. 3.1; and OSS Event Notification pattern, see Sect. 3.3).
• Consistent rules on the non-functional aspects of information exchange between
OSS clients and OSS applications (OSS Implementation Profiles, see Sect. 2.5).
• A consistent query mechanism (OSS Named-procedure pattern, see Sect. 3.7).
In our experience, meeting these requirements will reduce integration and develop-
ment time, reduce errors, and reduce training costs.
In the next section we will show how many of these criteria can be captured in
a reference architecture that we will use as the basis for discussing the OSS Design
Patterns in the next chapters of the book.
We will discuss each of the parts of the reference architecture in the following
sections:
OSS client an application that engages with a remote OSS application to access the
latter’s functionality employing a client-server style for operations and a publish-
and-subscribe style for notifications.
OSS Façade a view, in terms of remote operations, exposed by an OSS applica-
tion; applications that present similar styles of façade are more easily integrated,
see Sect. 3.2.
2.4 Remote Operations Model 15
The Remote Operations Model models the way a client can invoke operations on a
remote application. The remote operations model defines three interactions between
a client and a remote application:
• a named request, possibly including some calling arguments;
• a response, possibly with return arguments, indicating a normal completion; and
• one or more named exceptions, possibly including return arguments, indicating
an abnormal completion.
Operation and notification signatures and argument types are specified in terms of
XML document types and XML data types respectively using the XML Schema
Language[9]. In Appendix C we discuss a binding of the message profile to Web
Services.
The resources that we want to manage, that is the managed resources, may take
many forms, for example: a record in an inventory, a line card in a network ele-
ment, or a trouble ticket in a trouble ticketing system. In developing management
solutions, it is helpful to have a consistent model of the management aspects of man-
aged resources. The OSS Reference Architecture models the management aspects
of managed resources as managed entities. Managed entities are abstract software
entities that can be uniquely identified and expose a number of named attributes.
It is by reading and updating the attributes of the managed entities that the corre-
sponding managed resources are managed.
managed entity. A OSS Application Context could, for example, be a session bean,
a JMS queue, or a Web Services endpoint.
In the following chapters of the book, we will discuss a core set of over a dozen
patterns that we believe are fundamental to designing consistent OSS application in-
terfaces. These patterns are the distillation of many years of experience in the speci-
fication and standardization of OSS applications. They are not necessarily unique to
OSS applications; many are adaptations of patterns commonly found in distributed
systems—patterns such as the Façade Pattern, the Factory Pattern, and the Trans-
fer Object Pattern. In order to help readers quickly become comfortable with OSS
Design Patterns, we have adopted a format similar to that used by the Gamma et
al.[10]. We will describe each design pattern under the following headings:
Name a succinct encapsulation of the essence of the pattern—it should become
part of the OSS design vocabulary.
Intent a short statement of the rationale and intent of the pattern and the design
problem it solves.
Motivation a description or scenario that illustrates the problem the pattern ad-
dresses.
Solution a detailed description of the solution to the design problem, either in nar-
rative or graphical form.
Example fragments of code or schemata that illustrate how the design pattern
might be implemented and used in the context of the two implementation profiles.
We will use Java to illustrate the use of patterns in the session profile, and XML
Schema grammar and JMS in the message profile.
22 2 Designing Management Solutions
To illustrate the patterns, we will use a running example OSS application—the Sim-
ple Inventory OSS application. The Simple Inventory application implements (as its
name implies) a simple inventory of spare parts, and supports three record types:
• an equipment record type;
• an extended equipment record type; and
• a supplier record type.
The equipment record type contains the following fields:
Creation date the date the record was created;
Equipment type a short description of the type of equipment;
Number on hand the number of equipment items on hand;
Location the location of the equipment items; and
Record key a unique key to the record.
The extended equipment record type contains the following fields in addition to
those in the equipment record:
Re-order level the level of inventory triggering re-order; and
Supplier name the name of the preferred equipment supplier.
The supplier record type contains the following fields:
Creation date the date the record was created;
Name the name of the supplier;
Address the address of the supplier;
Contact number a contact telephone number; and
Record key a unique key to the record.
As we discuss the various patterns, we will introduce example code that an OSS
client might use to create records, delete records, read records, and update records
in the inventory.
2.9 Summary
In this chapter we have introduced a number of tools to help in the design of OSS
systems architectures: the design process, implementation profiles, the OSS Refer-
ence Architecture, and the Managed-entity model. This chapter builds on the pre-
vious one in setting the context for our pattern approach to the design of OSS in-
terfaces. In the next two chapters of the book, we describe in detail over a dozen
important OSS Design Patterns; the text will be accompanied code and schema ex-
amples to illustrate how a client might use the patterns.
References 23
References
1. Bass, L. and Kazman, R., Software Architecture in Practice. Addison Wesley Longman,
Reading, 1998.
2. Information Framework, TM Forum,
http://www.tmforum.org/InformationFramework/1684/home.html.
3. Common Information Model, Distributed Management Task Force,
http://www.dmtf.org/standards/cim.
4. Management Information Base, Internet Engineering Task Force, http://www.ietf.org.
5. Java Platform, Enterprise Edition, Sun Developer Network, http://java.sun.com/javaee.
6. .NET, Microsoft, http://www.microsoft.com/net.
7. Java Message Service, Sun Developer Network, http://java.sun.com/products/jms.
8. Web Services, World Wide Web Consortium, http://www.w3.org/2002/ws.
9. XML Schema, World Wide Web Consortium, http://www.w3.org/XML/Schema.
10. Gamma, E., Helm, R., Johnson, R., Vlissides, J., Design Patterns. Addison-Wesley, Reading,
1994.
Chapter 3
OSS Architectural Patterns
In this chapter we will introduce a number of architectural patterns that are useful
in designing the overall structure of OSS integration interfaces; they will set the
context for programming patterns that we will introduce in the next chapter. Of all
the architectural patterns, the Managed-Entity Value pattern and the OSS Façade
pattern are the two most important. The Managed-Entity Value pattern is the pattern
that is used by clients to read and update the attributes of managed entities (models
of the resources to be managed), be they trouble tickets or mobile base stations.
The OSS Façade pattern is the fundamental pattern used by clients to engage with
OSS applications—it packages the functionality offered by the OSS application and
makes it available in a consistent manner.
In the OSS Reference Architecture (see Sect. 2.3), the management aspects of man-
aged resources are modelled as managed entities and the information aspects of
managed resources are modelled as attributes of the managed entities. It is by read-
ing and updating the values of the attributes of the managed entities, that the cor-
responding managed resources can be managed. In order for OSS clients to easily
engage with multiple OSS applications, it is important that each application expose
a consistent read/update interface model.
Intent
Provide a mechanism to efficiently read and update the attribute values of managed
entities.
25
26 3 OSS Architectural Patterns
Motivation
The OSS Reference Architecture does not say how managed entities are to be im-
plemented nor how their attribute values can be read or updated. However, it is by
reading and updating the attributes of managed entities that managed resources are
managed. To help facilitate the development of management solutions, we need to
devise a consistent interface style across all OSS applications to read and update the
attribute values of managed entities.
Solution
Adapt the Data Transfer Object pattern[1] to support the reading and updating of
the attribute values of managed entities. For each managed-entity type, define a
managed-entity value type, that acts as a surrogate for the managed entity and in-
stances of which can be transferred between the OSS client and the OSS application
(see Fig. 3.1).
To read and update the attributes of a managed entity, an OSS client requests
that a managed-entity value, corresponding to the managed entity of interest, be
transferred from the OSS application to the client’s address space. The managed-
entity value contains a copy, at that point in time, of the attribute values of the
managed entity. The client can read and update these copies in its local environment,
and subsequently can request that the managed-entity attribute values be updated by
sending an updated copy of the managed-entity value to the OSS application (see
Fig. 3.2 and Sect. 4.3).
An OSS client creates a managed entity by sending a suitably-populated managed-
entity value to the OSS application with a request to create the managed entity. We
deal with the creation (and deletion) of managed entities in detail in Sect. 4.2.
It is useful to arrange managed-entity value types in an inheritance hierarchy to
factor out common fields and produce a type hierarchy to take advantage of poly-
morphic operations. We discuss this in more detail in Sect. 4.2.
3.1 Managed-Entity Value Pattern 27
The Managed-Entity Value pattern is based on the Transfer Object pattern, and
shares a number of its advantages, including:
• It shields the OSS client from the actual implementation of the managed entity.
• It offers a consistent mechanism for reading and updating the attributes of a man-
aged entity.
• Field-level validation and integrity checking of attribute values can be accom-
plished in the local environment.
• By reading or updating a number of attributes of a managed entity in one go, it
reduces the network traffic and delay that would be associated with reading or
updating each attribute individually.
Fig. 3.2 Reading the Attribute Values of a Managed Entity Using a Managed-Entity Value
One of the consequences of the Managed-Entity Value pattern is that all of the
attribute values are transferred whether they are all needed or not. In the case of
a managed entity that has a large number of attributes, and where only a few are
required, this can lead to unnecessary consumption of bandwidth and poor response.
The Managed-Entity Attribute Population pattern can help alleviate the problem
(see Sect. 4.4).
Example
In the next sub-sections, we will show how managed-entity values are read in the
two OSS profiles. We will use for this, and all the other examples, the Simple In-
ventory application introduced in Sect. 2.8. The interface diagram for the Simple
Inventory value-objects is shown in Fig. 3.3.
28 3 OSS Architectural Patterns
/**
*
* Record-key inteface declaration
*/
public interface RecordKey extends java.io.Serializable {
3.1 Managed-Entity Value Pattern 29
/**
* Constants to identify the fields of
* the managed-entity record key
*/
public static final String RECORDTYPE = "RecordType";
public static final String RECORDID = "RecordId";
/**
* Accessors and mutators for fieldsSet
*/
public void setRecordId(String id);
/**
* Managed-entity value-object interface declaration.
*
* This the base interface for all managed-entity value-objects.
*/
public interface ManagedEntityValue extends java.io.Serializable {
//public interface ManagedEntityValue {
/**
* Constants to identify the fields of
* the managed-entity value-object
*/
public static final String LASTUPDATEVERSIONNUMBER =
"LastUpdateVersionNumber";
public static final String RECORDKEY = "RecordKey";
/**
* Managed-entity value is a factory for record keys
*/
public RecordKey makeRecordKey();
/**
* Accessors and mutators for fields
*/
public RecordKey getRecordKey();
/**
* Get managed-entity attribute/value pairs
30 3 OSS Architectural Patterns
*/
public java.util.Hashtable getAttributeValues(String[] names)
throws ApplicationException;
/**
* Get managed-entity attribute names
*/
public String[] getAttributeNames();
/**
* Attribute population methods
*/
public void unPopulate(String attributeName);
/**
* Inventory record value-object interface declaration.
*
* This the base interface for all Simple Inventory Record value-objects.
* The fields of the value object carry copies of the values
* of the attributes of the Inventory Record managed entities.
*/
public interface InventoryRecordValue extends ManagedEntityValue{
/**
* Constant to identify the field of
* the inventory record value-object
*/
public static final String CREATIONDATE = "RecordCreationDate";
/**
* Accessors for field
*/
public Calendar getRecordCreationDate();
}
3.1 Managed-Entity Value Pattern 31
/**
* Constants to identify the fields of the equipment record value-object
*/
public final static String EQUIPMENTTYPE = "EquipmentType";
public final static String NUMBERONHAND = "NumberOnHand";
public final static String LOCATION = "Location";
/*
* Accessors and mutators for the fields of the value-object
*/
void setEquipmentType(String equipmentType);
String getEquipmentType();
int getNumberOnHand();
String getLocation();
}
/**
* Extended-equipment record value-object interface declaration
*/
public interface ExtendedEquipmentRecordValue
extends EquipmentRecordValue {
/**
* Constants to identify the extended-equipment record
* fields (attributes)
*/
public final static String REORDERLEVEL = "ReorderLevel";
public final static String SUPPLIERNAME = "SupplierName";
int getReorderLevel();
String getSupplierName();
}
32 3 OSS Architectural Patterns
/**
* Supplier record value object interface
*/
public interface SupplierRecordValue
extends InventoryRecordValue {
/**
* Constants to identify the fields of the supplier record value-object
*/
public final static String NAME = "SupplierName";
public final static String ADDRESS = "SupplierAddress";
public final static String CONTACTNUMBER = "ContactNumber";
/**
* Accessor and mutators for the fields of the value-object
*/
void setSupplierName(String supplierName);
String getSupplierName();
String getSupplierAddress();
String getContactNumber();
}
/*
* Print equipment record
*/
/*
* session = ... get a Simple Inventory session bean
* key = ... set the key to a previously-saved value and
* get the equipment record value-object identified by the key
*/
3.1 Managed-Entity Value Pattern 33
With a previously-saved key value, the client requests an equipment record value-
object from the session bean corresponding to the supplied key, and then prints out
the fields in the value object that correspond to attribute values of the equipment
record managed-entity. The output might look like this:
<!--
Define record-key type
-->
<complexType name="RecordKeyType">
<sequence>
<element name="recordId" type="string" nillable="false"/>
<element name="recordType" type="string" nillable="true"/>
</sequence>
</complexType>
<!--
Define managed-entity value-type
-->
<complexType name="ManagedEntityValueType">
<sequence>
<element name="recordKey" type="entities:RecordKeyType"></element>
<element name="lastUpdateNumber" type="xsd:long" minOccurs="0"></element>
</sequence>
</complexType>
34 3 OSS Architectural Patterns
<!--
Define inventory record value-type
-->
<complexType name="InventoryRecordValueType">
<complexContent>
<extension base="entities:ManagedEntityValueType">
<sequence>
<element name="creationDate" type="xsd:dateTime" minOccurs="0"></element>
</sequence>
</extension>
</complexContent>
</complexType>
Again, using the <extension> element in XML Schema, we now define com-
plex types for the equipment record, extended-equipment record, and supplier
record value-types. Each of the elements of the complex types (and those extended
from the inventory record value-type) correspond to an attribute of the respective
inventory record managed-entity.
<!--
Define equipment record value-type
-->
<complexType name="EquipmentRecordValueType">
<complexContent>
<extension base="entities:InventoryRecordValueType">
<sequence>
<element name="equipmentType" type="string" minOccurs="0"/>
<element name="numberOnHand" type="int" minOccurs="0"/>
<element name="location" type="string" minOccurs="0"/>
</sequence>
</extension>
</complexContent>
</complexType>
<!--
Define extended-equipment record value-type
-->
<complexType name="ExtendedEquipmentRecordValueType">
<complexContent>
<extension base="entities:EquipmentRecordValueType">
<sequence>
<element name="reorderLevel" type="int"/>
<element name="supplierName" type="string"/>
</sequence>
</extension>
</complexContent>
</complexType>
3.1 Managed-Entity Value Pattern 35
<!--
Define supplier-record value-type
-->
<complexType name="SupplierRecordValueType">
<complexContent>
<extension base="entities:InventoryRecordValueType">
<sequence>
<element name="supplierName" type="string" minOccurs="0"/>
<element name="supplierAddress" type="string" minOccurs="0"/>
<element name="contactNumber" type="string" minOccurs="0"/>
</sequence>
</extension>
</complexContent>
</complexType>
We finally define four element types as the respective Simple Inventory value
document types.
<!--
Define Simple Inventory value-elements
-->
<element name="inventoryRecordKey" type="entities:RecordKeyType"/>
<element name="managedEntityValue" type="entities:ManagedEntityValueType"/>
<element name="inventoryRecordValue" type="entities:InventoryRecordValueType"/>
<element name="equipmentRecordValue" type="entities:EquipmentRecordValueType"/>
<element name="extendedEquipmentRecordValue"
type="entities:ExtendedEquipmentRecordValueType"/>
<element name="supplierRecordValue" type="entities:SupplierRecordValueType"/>
<!--
Instance of an equipment record value document
-->
<entities:equipmentRecordValue
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/Entities file:...
<entities:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</entities:recordKey>
<entities:lastUpdateNumber>1234</entities:lastUpdateNumber>
<entities:creationDate>2009-04-01T12:15:00-05:00</entities:creationDate>
<entities:equipmentType>LineCard</entities:equipmentType>
<entities:numberOnHand>10</entities:numberOnHand>
<entities:location>Montreal</entities:location>
</entities:equipmentRecordValue>
Summary
The Managed-Entity Value pattern provides a consistent and effective way of read-
ing and updating the attribute values of managed entities. The pattern is also used
in the creation of managed-entities and associative addressing of managed entities.
The value pattern is also used to invoke named operations and queries. By arranging
value types in type hierarchy, it is possible to exploit the polymorphic features of
software technologies such as Java and XML Schema.
36 3 OSS Architectural Patterns
The Managed-Entity model gives an OSS client a consistent view of the attributes
of a managed entity and, by extension, the information aspects of the corresponding
managed resource. It is also important that OSS applications expose a consistent
view of their operational aspects.
Intent
Motivation
The primary operational aspects of an OSS application are the operations that sup-
port the read-update model of accessing managed entities (see Sect. 4.3). However,
there are other operational aspects that need to be supported such as the retrieval
of metadata and the creation of various objects and documents. In order to facili-
tate the efficient engagement of multiple OSS applications by an OSS client, OSS
applications should expose a consistent set of operations.
Solution
Define a canonical set of operations that supports the engagement between an OSS
client and an OSS application and package the operations in a façade. We will
adapt the Session Façade pattern[4] to provide such packaging. A façade to sup-
port telecommunications management should expose operations to at least:
• Create one or more managed entities given initial values for the attributes (see
Sect. 4.2).
• Read the attribute values of one or more managed entities selected by key or by
matching attribute values (see Sect. 4.3).
• Update the attribute values of one or more managed entities selected by key or
by matching attribute values (see Sect. 4.3).
• Create empty value objects such as keys, managed-entity values (see Sect. 3.5).
• Retrieve metadata about the OSS application (see Sect. 3.6).
• Carry out tasks not amenable to a simple read-update model (see Sect. 3.7).
3.2 OSS Façade Pattern 37
Example
As an example of the OSS Façade pattern, we will develop façades to support the
Simple Inventory OSS application (see Sect. 2.8) for each of the profiles using
JEE[2] and JMS[6].
In our session profile example, the façade is implemented by means of the EJB 3.0
session bean and the remote operations are implemented by RMI (see Fig. 3.4). The
interface declaration for the session bean would look like this:
/**
* Simple Inventory session bean declaration.
*
* This interface defines the operational aspects of the Simple
* Inventory session bean that implements the facade pattern.
*/
@Remote
public interface SimpleInventorySession
{
In EJB 3.0, the session bean is declared as plain Java interface but with the anno-
tation @Remote to denote a remote interface. We will describe the remote methods
in the following sections:
makeInventoryRecordValue() make an inventory record value-object given
the name of the inventory record value-type (see Sect. 4.2).
getInventoryRecordByKey() return, in a value object, the requested at-
tribute values of the inventory record managed-entity indicated by the supplied key
(see Sect. 4.3).
getInventoryRecordsByTemplate() return an iterator (see Sect. 3.4) that
will return, in value objects, the requested attribute values of the inventory record
managed-entities matching the supplied template (see Sect. 4.5).
setInventoryRecordByValue() update the attribute values of an inventory
record managed-entity using the fields in the supplied value object (see Sect. 4.3).
setInventoryRecordsByValues() update the attribute values of multiple
inventory record managed-entities atomically using the fields in the supplied value
objects (see Sect. 4.6).
createInventoryRecordByValue() create an inventory record managed-
entity using the fields in the supplied value object (see Sect. 4.2).
removeInventoryRecordByKey() remove (delete) the inventory record managed-
entity indicated by the supplied key (see Sect. 4.2).
getManagedEntityTypes() return an array of strings representing the fully-
qualified names of managed-entity types supported by the façade (see Sect. 3 .6 ).
makeNamedProcedureValue() return a empty named-procedure value-object
(see Sect. 3.7).
execute() return the results of a named-procedure call (see Sect. 3.7).
3.2 OSS Façade Pattern 39
To illustrate the use of the OSS Façade pattern in the message profile, we will
define schema fragments for the two operations getInventoryRecordByKey and
setInventoryRecordByValue. The following schema fragment defines the get-
InventoryRecordByKey request and response types and elements:
<!--
Define Get Inventory Record By Key request/response types
-->
<complexType name="GetInventoryRecordByKeyRequestType">
<sequence>
<element name="recordKey" type="entities:RecordKeyType"/>
<element name="attributeNames" type="appmsg:ArrayOfString" minOccurs="0"/>
</sequence>
</complexType>
<complexType name="GetInventoryRecordByKeyResponseType">
<sequence>
<element name="record" type="entities:InventoryRecordValueType"/>
</sequence>
</complexType>
<!--
Define Get Inventory Record By Key request/response elements
-->
<element name="getInventoryRecordByKeyRequest"
type="appmsg:GetInventoryRecordByKeyRequestType"/>
<element name="getInventoryRecordByKeyResponse"
type="appmsg:GetInventoryRecordByKeyResponseType"/>
40 3 OSS Architectural Patterns
<!--
Define Set Inventory Record By Value request/response types
-->
<complexType name="SetInventoryRecordByValueRequestType">
<sequence>
<element name="record" type="entities:InventoryRecordValueType"/>
</sequence>
</complexType>
<complexType name="SetInventoryRecordByValueResponseType">
<sequence/>
</complexType>
<!--
Define SetInventoryRecordbyValue request/response elements
-->
<element name="setInventoryRecordByValueRequest"
type="appmsg:SetInventoryRecordByValueRequestType"/>
<element name="setInventoryRecordByValueResponse"
type="appmsg:SetInventoryRecordByValueResponseType"/>
<element name="setInventoryRecordByValueRequestException"
type="appmsg:ApplicationFaultType"/>
The following schema fragment defines the ApplicationFaultType type and ele-
ment:
<!--
Define Application Fault type
-->
<complexType name="ApplicationFaultType">
<sequence>
<element name="errorMessage" type="string"/>
</sequence>
</complexType>
Summary
The OSS Façade pattern encourages the definition of a consistent set of operations
to be exposed by all OSS applications. By defining such a set, the learning curve as-
sociated with integrating a number of OSS applications into a management solution
will be reduced.
3.3 OSS Event Notification Pattern 41
Intent
Motivation
OSS applications need to notify multiple OSS clients about event occurrences at
unpredictable times, and OSS clients need to be able to select the types of events
about which they are prepared to receive information and the rate at which they are
prepared to receive it.
42 3 OSS Architectural Patterns
Solution
Example
/**
* Base interface to access the payload of all Simple
* Inventory event notification messages
*/
public interface BaseEvent extends java.io.Serializable {
/*
* Accessor for the time the event was published as a String
*/
public String getEventTimeAsString();
/*
* Accessor for the time the event was published
*/
public Calendar getEventTime()
throws ApplicationException;
}
/**
* Interface to access the payload
* of the record-create notification
*/
public interface RecordCreateEvent extends BaseEvent {
/*
* Accessor/mutator for the record created
*/
public InventoryRecordValue getInventoryRecordValue()
throws ApplicationException;
/**
* Implementation of the onMessage method to handle
* receiving a record-creation event notification
*
*/
public class OSSListenerImplementation implements
javax.jms.MessageListener {
Finally, we run the following code, to register the OSS client to receive messages:
/*
* Register the MessageListener and start message delivery
*/
String destName = null;
String topicFactory = null;
InputStreamReader inputStreamReader;
char answer = 0;
try {
Context jndiContext = null;
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Destination dest = null;
MessageConsumer consumer = null;
destName = "jms/simpleInventoryTopic";
topicFactory = "jms/simpleInventoryTopicFactory";
/*
3.3 OSS Event Notification Pattern 45
/*
* look-up connection factory and destination.
*/
try {
connectionFactory = (ConnectionFactory) jndiContext.lookup(
topicFactory);
dest = (Destination) jndiContext.lookup(destName);
} catch (Exception e) {
System.out.println("JNDI API lookup failed: " + e.toString());
System.exit(1);
}
/*
* Create the connection.
*/
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
consumer = session.createConsumer(dest);
MessageListener listener = new OSSListenerImplementation();
/*
* Register the listener and start delivery
*/
consumer.setMessageListener(listener);
connection.start();
The report of the creation of an equipment record managed-entity will look like
this:
Message Received--->
Message type: RecordCreateEvent notification
Event Time= 2009 3 3 1h37 50s
Notification content:
The following schema fragment defines the base notification type and the create-
record notification type and element.
<!--
Define Base Event Type for notifications
-->
<xsd:complexType name="BaseEventNotifcationType">
<xsd:sequence>
<xsd:element name="eventTime" type="xsd:date" nillable="false"/>
</xsd:sequence>
</xsd:complexType>
<!--
Define Record Create Notification Type
-->
<xsd:complexType name="RecordCreateEventType">
<xsd:complexContent>
<xsd:extension base="appmsg:BaseEventNotifcationType">
<xsd:sequence>
<xsd:element name="inventoryRecordValue"
type="entities:InventoryRecordValueType"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<!--
Define Record Create Notification element
-->
<xsd:element name="recordCreateEventNotification"
type="appmsg:RecordCreateEventType"/>
<!--
Equipment Record Notification Message
-->
<appmsg:recordCreateEventNotification
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xsi:schemaLocation=’http://xml.netbeans.org/schema/Entities file:...
http://xml.netbeans.org/schema/appmsg file:...
<appmsg:eventTime>2009-02-20T13:20:00-05:00</appmsg:eventTime>
<appmsg:inventoryRecordValue xsi:type = "entities:EquipmentRecordValueType">
<entities:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</entities:recordKey>
<entities:lastUpdateNumber>1234</entities:lastUpdateNumber>
<entities:creationDate>2009-04-01T12:15:00-05:00</entities:creationDate>
<entities:equipmentType>LineCard</entities:equipmentType>
<entities:numberOnHand>10</entities:numberOnHand>
<entities:location>Montreal</entities:location>
</appmsg:inventoryRecordValue>
</appmsg:recordCreateEventNotification>
3.3 OSS Event Notification Pattern 47
Although the schema for the inventory-record create notification specifies the re-
turn of details of an inventory record, the xsi:type attribute indicates that details of
an extension of an inventory record, in fact an equipment record, have been returned.
Summary
Intent
Motivation
Some OSS requests, such as query requests and template matching requests, can
potentially match a large number of managed entities. The OSS client cannot deter-
mine how many managed entities are going to be matched and how many managed-
entity values or keys might subsequently be returned. If all of the data were to be
returned in one response, it might overwhelm the OSS client.
Solution
Rather than returning all of the managed-entity values or managed-entity keys cor-
responding to a template or query request in a single response, return an iterator
from which the OSS client can iteratively request a small number of values or keys
for processing. Fig. 3.8 shows how the OSS Iterator pattern is used in the case of
a query potentially returning a large number of managed-entity values. The OSS
client prepares a query, sends it to the OSS application, and receives an iterator in
response. The client then requests the next “n” managed-entity values, receives at
most “n” managed-entity values from the iterator, and extracts the required attribute
values. This process is continued until the OSS client receives an empty return indi-
cating the end of the sequence. The OSS client then deletes the iterator.
Being able to abandon the iteration part way through when, for example, the
required values or keys have been returned, is an added benefit. The OSS Iterator
pattern is based on the Iterator pattern[5].
In the OSS Session Profile, the iterator is implemented as an object with method
getNext<items>(n); in the OSS Message Profile, the iterator is implemented by
including in the request and response documents additional complex types to allow
for multiple responses. We will look at these implementations in more detail in the
next section.
3.4 OSS Iterator Pattern 49
Example
To illustrate the use of the OSS Iterator pattern, we will use it, in the Simple Inven-
tory application, to print a list of all of the equipment items and numbers on hand in
Montreal.
/*
* Managed-entity value iterator/ template pattern example
*
* Return all equipment items and numbers-on-hand in Montreal
*/
SimpleInventorySession session;
EquipmentRecordValue template, equipvo;
InventoryRecordValue recordvos[];
InventoryRecordValueIterator iterator;
/*
* Get Simple Inventory session bean
*/
ServiceLocator serviceLocator = new ServiceLocator();
session = serviceLocator.getInventorySession();
50 3 OSS Architectural Patterns
/*
* Make an equipment record value object to use as a template
*/
template = (EquipmentRecordValue) session.makeManagedEntityValue(
"simpleinventory.EquipmentRecordValue");
/*
* Set the location field in the template
*/
template.setLocation("Montreal");
/*
* Request all equipment records where location = "Montreal"
*/
iterator =
session.getInventoryRecordsByTemplate(template, null);
/*
* Process 5 equipment record-value objects at a time
*/
recordvos = iterator.getNextInventoryRecords(5);
while (recordvos.length > 0) {
for (int i = 0; i < recordvos.length; i++) {
equipvo = (EquipmentRecordValue) recordvos[i];
System.out.println(equipvo.getEquipmentType() + " " +
String.valueOf(equipvo.getNumberOnHand()));
}
recordvos =
iterator.getNextInventoryRecords(5);
}
iterator.remove();
<!--
Define Iterator request/response types
-->
<complexType name="IteratorRequest" abstract="false">
<sequence>
<element name="n" type="unsignedInt" nillable="true" minOccurs="0"/>
</sequence>
</complexType>
The IteratorRequest complex type defined in the above schema fragment in-
cludes the element, <n>, to indicate the maximum number of value documents to be
returned in the response. The IteratorResponse complex type definition includes
two additional elements: <sequence>, an ordinal indicating the ordering of the re-
sponse, and <endOfReply>, a boolean indicating the last response of the sequence.
These complex types are introduced into simple request and response documents by
means of the XML Schema element <extension>.
The schema fragment for the getInventoryRecordsByTemplateRequest and
getInventoryRecordsByTemplateResponse types is as follows:
<!--
Define Get Inventory Records By Template request/response types
-->
<complexType name="GetInventoryRecordsByTemplateRequestType">
<complexContent>
<extension base="appmsg:IteratorRequest">
<sequence>
<element name="template" type="entities:InventoryRecordValueType"/>
<element name="attrNames" type="appmsg:ArrayOfString" minOccurs="0"/>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="GetInventoryRecordsByTemplateResponseType">
<complexContent>
<extension base="appmsg:IteratorResponse">
<sequence>
<element name="records" type="entities:InventoryRecordValueType"
maxOccurs="unbounded"/>
</sequence>
</extension>
</complexContent>
</complexType>
52 3 OSS Architectural Patterns
<!--
Define Get Inventory Records By Template elements
-->
<element name="getInventoryRecordsByTemplateRequest"
type="appmsg:GetInventoryRecordsByTemplateRequestType"/>
<element name="getInventoryRecordsByTemplateResponse"
type="appmsg:GetInventoryRecordsByTemplateResponseType"/>
<element name="getInventoryRecordsByTemplateResponseException"
type="appmsg:ApplicationFaultType"/>
To illustrate the use of the OSS Iterator pattern in the message profile, we will
use the same example as in session profile example—making a list of all the equip-
ment items on hand in Montreal. The following XML document requests equipment
record value-documents, two at a time, for all equipment records where location
is “Montreal”. The <appmsg:template> element type in the document is derived
from the type defined by the schema fragment (i.e. InventoryRecordValueType)
by use of the xsi:type attribute indicating that equipment records and extended
equipment records are to be matched.
<!--
Get Inventory Records By Template Request document
-->
<appmsg:getInventoryRecordsByTemplateRequest
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xsi:schemaLocation=’http://xml.netbeans.org/schema/Entities file:...
http://xml.netbeans.org/schema/appmsg file:...
<appmsg:n>2</appmsg:n>
<appmsg:template xsi:type = "entities:EquipmentRecordValueType">
<entities:location>Montreal</entities:location>
</appmsg:template>
</appmsg:getInventoryRecordsByTemplateRequest>
Summary
The OSS Iterator pattern is an important pattern for the practical implementation
of OSS integration interfaces: it allows OSS clients to control the rate at which
information is returned from OSS applications.
3.5 OSS Factory Pattern 53
A number of OSS patterns are realized by the passing of value types (managed-
entity values, managed-entity keys, or named-procedure values) between OSS clients
and OSS applications; examples include the Managed-Entity Life Cycle pattern (see
Sect. 4.2) and the OSS Named-procedure pattern (see Sect. 3.7). In a typical sce-
nario an OSS client will:
• make an instance of the particular value type;
• populate the fields of the instance as required; and
• transfer the instance to the OSS application for it to execute the pattern.
In order for an OSS client to be able to make an instance of a value type, it would
normally need to have access to a local copy of the related specification. During the
life cycle of an OSS application, the specifications and implementations of value
types may change to accommodate upgrades or patches, and having to distribute
revised specifications to OSS clients in a timely manner would be a maintenance
headache. The solution is to put the responsibility on the OSS client to make or
obtain up-to-date instances of value types.
Intent
Enable OSS clients to make or obtain up-to-date instances of value types without
local knowledge of the related specification.
54 3 OSS Architectural Patterns
Motivation
The primary motivation of the OSS Factory pattern is to reduce the level of coupling
between an OSS client and an OSS application. For example, if an OSS application
were to be upgraded or vendors were to make extensions that changed the imple-
mentation of value type, each OSS client would have to be updated and possibly
re-compiled to take advantage of the upgrades or extensions. In a large telecommu-
nications system, it would be a substantial logistical problem.
Solution
In the OSS Session Profile, OSS clients obtain object implementations from fac-
tories. The OSS Session Façade and managed-entity value-objects are factories
for managed-entity value instances and managed-entity key instances respectively.
Types and keys are arranged in type hierarchies to support polymorphic operations.
In the OSS Message Profile, OSS clients obtain document specifications, in the form
of XML schemata, from external repositories. The XML Schema types are arranged
in a derivation hierarchy (i.e. by using the extension element in XML Schema), to
support polymorphic operations.
3.5 OSS Factory Pattern 55
Example
OSS Session Profile Example
In the following example, we will show how a Java client might request the man-
ufacture of a record key and use it to get a particular Simple Inventory equipment
record value-object.
/*
* Factory pattern example--make and use a key
*/
EquipmentRecordValue recordvo;
RecordKey key;
SimpleInventorySession session;
/*
* Get Simple Inventory session bean
*/
session = serviceLocator.getInventorySession();
/*
* The Simple Inventory session bean is a factory
* for creating Inventory Record value-objects...
*/
recordvo = (EquipmentRecordValue) session.makeManagedEntityValue(
"simpleinventory.EquipmentRecordValue");
/*
* The key is empty, so populate it
*/
key.setRecordId("42");
key.setRecordType("EquipmentRecordType");
/*
* Try the key
*/
recordvo = (EquipmentRecordValue) session.getInventoryRecordByKey(key,
null);
System.out.println(recordvo.toString());
The OSS client first gets a reference to a Simple Inventory session bean. It next
requests the session bean to make an equipment record value-object, and then uses
it to make a record key. The OSS client then populates the key, and requests an
equipment record value-object corresponding to the key. Running the above code
might result in the following output:
<!--
Define Get Inventory Record By Key request/response types
-->
<complexType name="GetInventoryRecordByKeyRequestType">
<sequence>
<element name="recordKey" type="entities:RecordKeyType"/>
<element name="attributeNames" type="appmsg:ArrayOfString" minOccurs="0"/>
</sequence>
</complexType>
<complexType name="GetInventoryRecordByKeyResponseType">
<sequence>
<element name="record" type="entities:InventoryRecordValueType"/>
</sequence>
</complexType>
<!--
Define Get Inventory Record By Key request/response elements
-->
<element name="getInventoryRecordByKeyRequest"
type="appmsg:GetInventoryRecordByKeyRequestType"/>
<element name="getInventoryRecordByKeyResponse"
type="appmsg:GetInventoryRecordByKeyResponseType"/>
A client might populate the key in the request document as shown below:
<!--
Get Inventory Record By Key request
-->
<appmsg:getInventoryRecordByKeyRequest
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
http://xml.netbeans.org/schema/Entities file:...
<appmsg:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</appmsg:recordKey>
</appmsg:getInventoryRecordByKeyRequest>
3.5 OSS Factory Pattern 57
<!--
Get Inventory Record By Key response
-->
<appmsg:getInventoryRecordByKeyResponse
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
http://xml.netbeans.org/schema/Entities file:...
<appmsg:record xsi:type = "entities:EquipmentRecordValueType">
<entities:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</entities:recordKey>
<entities:lastUpdateNumber>1234</entities:lastUpdateNumber>
<entities:creationDate>2009-04-01T12:15:00-05:00</entities:creationDate>
<entities:equipmentType>LineCard</entities:equipmentType>
<entities:numberOnHand>10</entities:numberOnHand>
<entities:location>Montreal</entities:location>
</appmsg:record>
</appmsg:getInventoryRecordByKeyResponse>
Summary
The OSS Factory pattern centralizes either the definition of, or the implementation
of, value objects and documents thus reducing administrative issues associated with
application upgrades and vendor-specific extensions. By arranging the definitions in
a type hierarchy, polymorphic operations can be supported.
58 3 OSS Architectural Patterns
Intent
Motivation
As we have noted, type safety is an important part of software design. One of the
ways of achieving type safety is to make interfaces strongly typed, and to imple-
ment them using statically-typed programming languages such as Java or statically-
typed schemata, such as at XML Schema[3]. Static typing allows type errors to be
detected at compile time or at XML document generation time. However, statically-
typed interfaces and schemata imply a tight coupling between OSS client and OSS
application. To take advantage of upgraded or vendor-enhanced OSS applications,
statically-typed OSS clients have to be modified, and that can lead to a prolifera-
tion of versions of OSS clients. We need to provide a mechanism for OSS clients to
discover and use the functionality of an OSS application at runtime.
Solution
Require OSS applications and managed-entity values to expose metadata about the
functionality they offer. Using this metadata, an OSS client can dynamically build
a request (see Fig. 3.11) or process the results from a request (see example sec-
tion below). For example, a vendor-enhanced trouble-ticket managed-entity value
might expose metadata about additional fields in a trouble ticket; a generic operator-
support application can present those additional fields to the operator. Or an OSS
application might expose metadata to enable an operator to discover, and subscribe
to, event types supported by an OSS application. Metadata about the following is
typically useful:
• operations supported;
• attribute names supported;
• managed-entity types supported;
• named-procedure and query types supported;
• attributes of managed-entity types supported; and
• event types supported.
3.6 OSS Discovery Pattern 59
Example
In the following examples, we will illustrate the use of the OSS Discovery pattern
to develop generic browsers to allow clients to browse the names of the managed
entities exposed by the session and message façades and the names and types of
their attributes.
For each inventory record managed-entity type, the client requests the creation
of an inventory record managed-entity value-object and, from each, discovers the
names of the respective managed-entity attributes. By introspecting the accessors
of the field names of each managed-entity value, the client discovers the respec-
tive field types and hence can infer the types of the corresponding managed-entity
attributes.
/**
* Example of OSS Discovery pattern use: a generic managed entity browser
*/
SimpleInventorySession session;
ManagedEntityValue ir1;
ServiceLocator serviceLocator = new ServiceLocator();
String[] entityTypes;
/*
* Get the session bean
*/
session = serviceLocator.getInventorySession();
/*
* Discover the names of the Simple Inventory managed-entity types
*/
try {
entityTypes = session.getManagedEntityTypes();
/*
* For Simple Inventory managed-entity type, request the
* session bean to make a inventory record value-type
*/
for (int i = 0; i < entityTypes.length; i++) {
ir1 = session.makeManagedEntityValue(entityTypes[i]);
System.out.println("Managed-entity value-type: " + entityTypes[i]);
/*
* Discover the names of the attributes of the inventory managed-entity
*/
String[] attributeNames = ir1.getAttributeNames();
/*
* For each attribute get the type by introspection
*/
for (int k = 0; k < attributeNames.length; k++) {
try {
String name = attributeNames[k];
String upperCaseString = name.substring(0, 1).toUpperCase() + name.
substring(1);
The output of browsing the Simple Inventory façade will look like this:
/**
* Example of OSS Discovery pattern use: a generic schema browser
*/
SchemaGlobalElement element;
/*
* Parse the schema into a list of global element specifications
*/
schemaTypeSystem = XmlBeans.compileXsd(new XmlObject[]{
org.apache.xmlbeans.XmlObject.Factory.parse(schema)}, XmlBeans.
getBuiltinTypeSystem(), null);
SchemaGlobalElement[] elements = schemaTypeSystem.globalElements();
List list = Arrays.asList(elements);
62 3 OSS Architectural Patterns
/*
* Iterate over the list get the global element names and types
*/
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
element = (SchemaGlobalElement) iterator.next();
System.out.println("Element Name: " +
element.getName().getLocalPart());
System.out.println("Element Type: " + element.getType());
/*
* Print out the child elements--the attribute names and types
*/
printElementChildren(element);
}
}
/**
* Print out the names and types of child elements of input element
*
*/
public void printElementChildren(SchemaGlobalElement element) {
if (toto != null) {
if (toto.getParticleType() == SchemaParticle.SEQUENCE) {
atts = toto.getParticleChildren();
}
if (atts != null) {
for (int kk = 0; kk < atts.length; kk++) {
System.out.println("Attribute Name " + atts[kk].getName());
System.out.println("Attribute Type " + atts[kk].getType().getName());
if (atts[kk].getParticleType() == SchemaParticle.ELEMENT) {
SchemaLocalElement zzz = (SchemaLocalElement) atts[kk];
}
}
}
}
System.out.println("-----------------------------------------------------");
}
The output of browsing the Simple Inventory façade schema will look like this:
Summary
The OSS Discovery pattern allows developers to strike a balance between type
safety and future proofing in the design of interfaces to OSS applications.
64 3 OSS Architectural Patterns
During the life cycle of an OSS application, new operations and queries may need
to be added to extend functionality and accommodate vendor-specific extensions.
In addition, not all of the day-to-day tasks of network managers can be supported
by OSS clients that implement patterns such as the Managed-Entity Update pat-
tern (see Sect. 4.3) or the Managed-Entity Template Filter pattern (see Sect. 4.5).
A number of routine, but important, tasks may be quite complex and may be the
subject of complex business or consistency rules that evolve over time. Other tasks
might be complex, but routine, queries that are not amenable to associative look-up
techniques.
Intent
To provide a flexible and extensible method for defining arbitrary procedures and
queries.
Motivation
It is not usual to be able to predict all of the operations that are needed during the
design of an OSS application; it is often necessary to add operations as applications
mature and new requirements are identified. If new operations were to be added to
the façade, it would lead to a proliferation of operations and require the repeated
re-compilation and redeployment of clients to take advantage of the new features.
In addition, relying on OSS clients to correctly validate operator input to com-
plex procedures invoked on OSS applications adds complexity to the OSS clients
and is risky from an operational perspective. Allowing operators to invoke complex
queries based on just associative lookup techniques can have consequences in terms
of performance and availability of OSS applications.
Solution
Use strongly-typed value types to carry the name and the parameters of named pro-
cedures to OSS applications and to return results. The general approach is for OSS
applications to define value types for the named procedures that OSS clients can ei-
ther obtain, or locally instantiate, and populate with the required parameters. When
an OSS application receives such a value instance, it can validate the parameters
and apply any business or consistency rules before carrying out the procedure. The
application returns any results as a value type. Fig. 3.12 illustrates the approach.
In addition to centralizing validation, the pattern centralizes the maintenance of
the business and consistency rules. It can also reduce network traffic by replacing a
3.7 OSS Named-Procedure Pattern 65
number of simple operations with fewer, higher-value, operations. The pattern also
helps reduce complexity in OSS clients.
In collaboration with the OSS Discovery pattern (see Sect. 3.6) and the OSS Fac-
tory pattern (see Sect. 3.5), the pattern can help OSS clients accommodate updates
or vendor-specific extensions to OSS applications without modification. The pattern
is based on the Command pattern[9].
Example
Using the Simple Inventory application, suppose we want to routinely obtain a list
of all the equipment records, filtered by location, that have fallen below their re-
order level. Given only the Managed-Entity Template Filter pattern, we would have
to bring back to the client managed-entity values representing all of the equipment
records for the desired location and locally select those where the number-on-hand
had dropped below the re-order level—not a pretty solution. A better solution is to
do the filtering on the OSS and return only the relevant managed-entity values. We
will define a named procedure to do just that.
/**
* Base interface for the named-procedure-request value-objects
*/
public interface NamedProcedureRequest extends java.io.Serializable {
}
66 3 OSS Architectural Patterns
/**
* Base interface for named-procedure response value-objects
*/
public interface NamedProcedureResponse extends java.io.Serializable{
}
/**
* Query re-order-items request interface
*/
public interface QueryReorderItemsRequest extends NamedProcedureRequest {
/**
* mutator for the single parameter "location"
*/
void setLocation(String location);
}
/**
* Query re-order-items response interface
*/
public interface QueryReorderItemsResponse extends NamedProcedureResponse,
InventoryRecordValueIterator {
}
/*
* Named-procedure example
* Request list of equipment-levels by location that
* have fallen below the re-order level
*/
SimpleInventorySession session;
QueryReorderItemsRequest query;
InventoryRecordValueIterator iterator;
InventoryRecordValue recordvos[];
InventoryRecordValue irvo;
/*
* Get Simple Inventory session bean
*/
ServiceLocator serviceLocator = new ServiceLocator();
3.7 OSS Named-Procedure Pattern 67
session = serviceLocator.getInventorySession();
<!--
Define Named-procedure request and response types and elements
-->
<xsd:complexType name="NamedProcedureRequestType">
<xsd:sequence/>
</xsd:complexType>
68 3 OSS Architectural Patterns
<xsd:complexType name="NamedProcedureResponseType">
<xsd:sequence/>
</xsd:complexType>
<xsd:element name="namedProcedureRequest"
type="appmsg:NamedProcedureRequestType"/>
<xsd:element name="namedProcedureResponse"
type="appmsg:NamedProcedureResponseType"/>
<!--
Define Iterator Named-procedure request and response types and elements
-->
<xsd:complexType name="IteratorNamedProcedureRequestType">
<xsd:complexContent>
<xsd:extension base="appmsg:NamedProcedureRequestType">
<xsd:sequence>
<element name="iteratorRequest" type="appmsg:IteratorRequest"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="IteratorNamedProcedureResponseType">
<xsd:complexContent>
<xsd:extension base="appmsg:NamedProcedureResponseType">
<xsd:sequence>
<element name="iteratorResponse" type="appmsg:IteratorResponse"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="iteratornamedProcedureRequest"
type="appmsg:IteratorNamedProcedureRequestType"/>
<xsd:element name="IteratorNamedProcedureResponse"
type="appmsg:IteratorNamedProcedureResponseType"/>
<!--
Define Query Reorder Named-procedure request and response types and elements
-->
<xsd:complexType name="QueryReorderItemsRequestType">
<xsd:complexContent>
<xsd:extension base="appmsg:IteratorNamedProcedureRequestType">
<xsd:sequence>
<xsd:element name="location" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
3.7 OSS Named-Procedure Pattern 69
<xsd:complexType name="QueryReorderItemsResponseType">
<xsd:complexContent>
<xsd:extension base="appmsg:IteratorNamedProcedureResponseType">
<xsd:sequence>
<xsd:element name="records"
type="entities:ExtendedEquipmentRecordValueType"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="queryReorderItemsResponse"
type="appmsg:QueryReorderItemsResponseType"/>
<xsd:element name="queryReorderItemsRequest"
type="appmsg:QueryReorderItemsRequestType"/>
<xsd:element name="namedProcedureException"
type="appmsg:ApplicationFaultType"/>
<!--
Query-reorder-items Request document
-->
<appmsg:queryReorderItemsRequest
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
<appmsg:iteratorRequest>
<appmsg:n>2</appmsg:n>
</appmsg:iteratorRequest>
<appmsg:location>Toronto</appmsg:location>
</appmsg:queryReorderItemsRequest>
<!--
Query-reorder-items response document
-->
<appmsg:queryReorderItemsResponse
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
http://xml.netbeans.org/schema/Entities file:...
<appmsg:iteratorResponse>
<appmsg:sequence>1</appmsg:sequence>
<appmsg:endOfReply>false</appmsg:endOfReply>
</appmsg:iteratorResponse>
<appmsg:records>
70 3 OSS Architectural Patterns
<entities:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</entities:recordKey>
<entities:lastUpdateNumber>1234</entities:lastUpdateNumber>
<entities:creationDate>2009-04-01T12:15:00-05:00</entities:creationDate>
<entities:equipmentType>LineCard</entities:equipmentType>
<entities:numberOnHand>9</entities:numberOnHand>
<entities:location>Toronto</entities:location>
<entities:reorderLevel>10</entities:reorderLevel>
<entities:supplierName>Nortel</entities:supplierName>
</appmsg:records>
<appmsg:records>
<entities:recordKey>
<entities:recordId>4242</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</entities:recordKey>
<entities:lastUpdateNumber>5678</entities:lastUpdateNumber>
<entities:creationDate>2009-04-01T12:19:00-05:00</entities:creationDate>
<entities:equipmentType>LineCard</entities:equipmentType>
<entities:numberOnHand>25</entities:numberOnHand>
<entities:location>Toronto</entities:location>
<entities:reorderLevel>27</entities:reorderLevel>
<entities:supplierName>Acme</entities:supplierName>
</appmsg:records>
</appmsg:queryReorderItemsResponse>
Summary
Some OSS management tasks involve multiple operations, and those operations in-
volving manual intervention may last for long periods of time, often measured in
days. For example, a Customer Relationship Management (CRM) application might
initiate the processing of a customer order. Customer orders for service can be long-
lived involving a number of operations, some of which might be assigned to OSS
applications such as work-order and configuration applications that involve manual
intervention. Rather that maintain the session with the client for the duration of the
transaction, the CRM application acknowledges the request and informs the client
of the progress of the request through a series of asynchronous notifications.
Intent
Minimize the amount of session information that an OSS client needs to retain in
order to complete long-lived requests.
72 3 OSS Architectural Patterns
Motivation
Some requests may take a long time to complete and requiring OSS clients to main-
tain session information about such requests can be impractical. However, the client
needs to know when a request has been completed and ideally the progress of the
request in the interim.
Solution
The OSS application sends periodic event notifications to inform the OSS client of
the progress of the request and when it has been completed.
Example
In the example shown in Fig. 3.13, we show how the Command–Status pattern might
be used for a long procedure, that of restoring the Simple Inventory database from
backup. The OSS client requests a named-procedure value-type to initiate a restore
of the Simple Inventory from backup, and sets the backup information field to re-
quest a full restore. The client then invokes the restore procedure, receives an ac-
knowledgment, and waits for notifications. As the restore procedure executes, the
client receives progress information in the form of event notifications.
SimpleInventorySession session;
RestoreFromBackupRequest request;
RestoreFromBackupResponse response;
/*
* Get Simple Inventory session bean
*/
ServiceLocator serviceLocator = new ServiceLocator();
session = serviceLocator.getInventorySession();
try {
/*
* Get a restore-from-backup Named-procedure value-object
* and set the backup information to "Full Restore"
*/
request = (RestoreFromBackupRequest) session.makeNamedProcedureRequest(
"simpleinventory.RestoreFromBackupRequest");
3.9 Summary 73
request.setBackupInfo("Full Restore");
/*
* Execute the name request and listen for notifications
*/
response = (RestoreFromBackupResponse) session.execute(request);
Message Received--->
Message type: RestoreFromBackUpStateEvent notification
Event Time= 2009 3 3 1h23 14s
Notification content: Restore status=STARTED Completion=0%
Message Received--->
Message type: RestoreFromBackUpStateEvent notification
Event Time= 2009 3 3 2h26 19s
Notification content: Restore status=INPROGRES Completion=25%
Message Received--->
Message type: RestoreFromBackUpStateEvent notification
Event Time= 2009 3 3 4h45 24s
Notification content: Restore status=INPROGRES Completion=50%
Message Received--->
Message type: RestoreFromBackUpStateEvent notification
Event Time= 2009 3 3 6h21 29s
Notification content: Restore status=INPROGRES Completion=75%
Message Received--->
Message type: RestoreFromBackUpStateEvent notification
Event Time= 2009 3 3 7h23 34s
Notification content: Restore status=COMPLETED Completion=100%
Summary
The OSS Command–Status pattern allows an OSS client to maintain minimal ses-
sion information in order to keep abreast of long-lived requests that it has made.
The OSS Event Notification Pattern is used to send asynchronous event notifica-
tions about progress and completion to the OSS client.
3.9 Summary
References
Intent
Motivation
In the OSS Managed-Entity Model (see Sect. 2.6), managed resources are modelled
as managed entities so, to refer to a managed resource, an OSS client must actually
refer to the managed entity that models the resource. (As we saw in Sect. 2.6, it
is the responsibility of the OSS application to maintain the relationship between
the managed resource and the managed entity.) Therefore to get an unambiguous
reference to a managed resource, we actually need to get an unambiguous reference
to a managed entity.
75
76 4 OSS Programming Patterns
Solution
All managed entities expose a key whose value is unique with respect to the other
managed entities within the application context. The application context is that nam-
ing context defined by an application that is responsible for the managed entities.
The Managed-Entity model does not prescribe the structure of the key nor the algo-
rithm used to determine equality of keys; the only requirement is that the value of
the key uniquely identify the managed entity within the application context.
When creating a managed entity, an OSS client can choose to assign the value of
the key or request that the OSS application assign the value of the key. In either case
it is the responsibility of the application to ensure the value of the key is unique.
In order for a client to create a key, the OSS application must make the structure
of the key available either by means of a factory method or by means of a schema.
Example
To illustrate the creation of keys, we will show how a client might obtain, popu-
late, and use a managed-entity key. The key structure of the Simple Inventory is, as
you might expect, fairly simple. It is two level structure: a naming context (Record
Type) and an identifier (ID) within that context, see Fig. 4.1.
key. The OSS client then populates the key, and requests an equipment record value-
object corresponding to the key.
/*
* Managed-entity Key Pattern Example--make a record key
*/
EquipmentRecordValue recordvo;
RecordKey key;
SimpleInventorySession session;
/*
* Get Simple Inventory session bean
*/
session = serviceLocator.getInventorySession();
/*
* The Simple Inventory session bean is a factory
* for creating inventory record value-objects...
*/
recordvo = (EquipmentRecordValue) session.makeManagedEntityValue(
"simpleinventory.EquipmentRecordValue");
/*
* The key is empty, so populate it
*/
key.setRecordId("42");
key.setRecordType("EquipmentRecordType");
/*
* Try the key
*/
recordvo = (EquipmentRecordValue) session.getInventoryRecordByKey(key,
null);
System.out.println(recordvo.toString());
<!--
Define Get Inventory Record By Key request/response types
-->
<complexType name="GetInventoryRecordByKeyRequestType">
<sequence>
<element name="recordKey" type="entities:RecordKeyType"/>
<element name="attributeNames" type="appmsg:ArrayOfString" minOccurs="0"/>
</sequence>
</complexType>
<complexType name="GetInventoryRecordByKeyResponseType">
<sequence>
<element name="record" type="entities:InventoryRecordValueType"/>
</sequence>
</complexType>
<!--
Define Get Inventory Record By Key request/response elements
-->
<element name="getInventoryRecordByKeyRequest"
type="appmsg:GetInventoryRecordByKeyRequestType"/>
<element name="getInventoryRecordByKeyResponse"
type="appmsg:GetInventoryRecordByKeyResponseType"/>
A client might populate the key in the request document as shown below:
<!--
Get Inventory Record By Key request
-->
<appmsg:getInventoryRecordByKeyRequest
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
http://xml.netbeans.org/schema/Entities file:...
<appmsg:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</appmsg:recordKey>
</appmsg:getInventoryRecordByKeyRequest>
<!--
Get Inventory Record By Key response
-->
<appmsg:getInventoryRecordByKeyResponse
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
http://xml.netbeans.org/schema/Entities file:...
4.1 Managed-Entity Key Pattern 79
Summary
Intent
Motivation
Managed entities are a consistent way to model the management aspects of managed
resources whether those resources be logical resources or physical resources. We
need to be able to model the creation of logical resources, such as the creation of
a trouble ticket, and the activation of physical resources, such as the activation of
a line card. And, of course, we need to model the reverse: the deletion of a trouble
ticket and the deactivation of a line card. In the Managed-Entity model, we could
do this by respectively creating and deleting the managed entities that represent the
managed resources, but the OSS Reference Architecture (see Sect. 2.3) does not
prescribe the implementation of managed entities, and that leaves us in a bit of a
quandary.
Solution
Use the Managed-Entity Value pattern to create managed entities. A single managed
entity is created by populating a managed-entity value with the desired values for
the managed-entity attributes and sending the managed-entity value to the façade
as an argument to a create request (see Fig. 4.2). Attributes corresponding to fields
not populated in the managed-entity value are set to default values by the façade.
The successful creation of the managed entity indicates the successful creation or
activation of the managed resource.
A single managed entity is deleted by sending a suitably populated key as an
argument to a delete request. The successful deletion of the managed entity indicates
the successful deletion or de-activation of the managed resource.
So far, we have only talked about the creation and deletion of single managed en-
tities, but bulk creation and deletion operations are useful. For example, the creation
of multiple managed entities with the same attribute values, the creation of mul-
tiple managed entities with different attribute values, and the deletion of multiple
managed entities with the same attribute values (see Sect. 4.6).
4.2 Managed-Entity Life Cycle Pattern 81
Example
In the following examples, we will show how clients might create and delete an
equipment record managed-entity in the Simple Inventory.
/*
* Equipment Record Life Cycle Example
*/
EquipmentRecordValue recordvo, recordvo2;
RecordKey key;
String[] meTypes;
SimpleInventorySession session;
82 4 OSS Programming Patterns
/*
* Get Simple Inventory session bean
*/
ServiceLocator serviceLocator = new ServiceLocator();
session = serviceLocator.getInventorySession();
/*
* Get managed entity types supported by the session bean
*/
meTypes = session.getManagedEntityTypes();
for (int i = 0; i < meTypes.length; i++) {
System.out.println("ME TYPE= " + meTypes[i]);
}
/*
* get an empty equipment record value-object
*/
recordvo = (EquipmentRecordValue) session.makeManagedEntityValue(
meTypes[2]);
/*
* Set the attribute values in the value object
*/
recordvo.setEquipmentType("LineCard");
recordvo.setLocation("Montreal");
recordvo.setNumberOnHand(10);
/*
* Make an empty record key (the equipment record value-object
* is a factory record keys)
*/
key = recordvo.makeRecordKey();
/*
* Populate the key
*/
key.setRecordId("42");
key.setRecordType("EquipmentRecordType");
/*
* Insert the key in the recordvo
*/
recordvo.setRecordKey(key);
/*
* Create the equipment record managed-entity
*/
key = session.createInventoryRecordByValue(recordvo);
/*
* To validate the insertion of the record into the inventory,
* request a new equipment record value-object
* corresponding the returned key and print the values
*/
recordvo2 = (EquipmentRecordValue) session.getInventoryRecordByKey(key,
null);
System.out.println(recordvo2.toString());
/*
* Delete the record using the record key
*/
session.removeInventoryRecordByKey(key);
4.2 Managed-Entity Life Cycle Pattern 83
ME TYPE= ManagedEntityValue
ME TYPE= simpleinventory.InventoryRecordValue
ME TYPE= simpleinventory.EquipmentRecordValue
ME TYPE= simpleinventory.ExtendedEquipmentRecordValue
ME TYPE= simpleinventory.SupplierRecordValue
<complexType name="CreateInventoryRecordByValueResponseType">
<sequence>
<element name="record" type="entities:RecordKeyType"/>
</sequence>
</complexType>
<!--
Define Create Inventory Record By Value request/response elements
-->
<element name="createInventoryRecordByValueRequest"
type="appmsg:CreateInventoryRecordByValueRequestType"/>
<element name="createInventoryRecordByValueResponse"
type="appmsg:CreateInventoryRecordByValueResponseType"/>
<element name="createInventoryRecordByValueResponseException"
type="appmsg:ApplicationFaultType"/>
<!--
Create Inventory Record By Value Request instance document
-->
<appmsg:createInventoryRecordByValueRequest
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
http://xml.netbeans.org/schema/Entities file:...
<appmsg:record xsi:type = "entities:EquipmentRecordValueType">
<entities:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</entities:recordKey>
<entities:equipmentType>LineCard</entities:equipmentType>
<entities:numberOnHand>10</entities:numberOnHand>
<entities:location>Montreal</entities:location>
</appmsg:record>
</appmsg:createInventoryRecordByValueRequest>
The client enqueues the above request onto the message queue for Simple Inven-
tory application and subsequently receives the following instance record in reply
4.2 Managed-Entity Life Cycle Pattern 85
indicating the successful creation of the equipment record managed-entity and the
corresponding equipment record in the inventory:
<!--
Create Inventory Record By Value Response instance document
-->
<appmsg:createInventoryRecordByValueResponse
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
http://xml.netbeans.org/schema/Entities file:...
<appmsg:record>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</appmsg:record>
</appmsg:createInventoryRecordByValueResponse>
Summary
Intent
Motivation
Solution
an OSS client might update a managed entity. The client first gets a managed-entity
value corresponding to the managed entity in question. The client updates the fields
of the managed-entity value locally, and then returns the managed-entity value to
the façade with a request to write the new values back to the managed entity and, by
extension, to the managed resource. Only attributes that are to be updated need be
included in the managed-entity value.
Example
/*
* Update Equipment Record Managed Entity Example
*/
int number, newNumber;
SimpleInventorySession session;
/*
* Get the session bean
*/
session = serviceLocator.getInventorySession();
/*
* Get an empty Record Key and populate it
*/
//key = ...
key.setRecordId("42");
key.setRecordType("EquipmentRecordType");
/*
* Get an equipment record value object representing the
* equipment record managed-entity indicated
* by the supplied key and print it
*/
recordvo = (EquipmentRecordValue) session.getInventoryRecordByKey(key,
null);
System.out.println(recordvo.toString());
The OSS client creates an instance of a Simple Inventory session bean and re-
quests, from the session bean, an equipment record value-object representing the
equipment record managed-entity indicated by the supplied key. Having received
the equipment record value-object, the client then locally updates the values using
the equipment record value-object interface. The client finally requests that the up-
dated value-object be written back to update the equipment record managed-entity
and hence to update the equipment record that the managed entity represents.
The output might look like this:
<!--
Get Inventory Record By Key request
-->
<appmsg:getInventoryRecordByKeyRequest
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
http://xml.netbeans.org/schema/Entities file:...
<appmsg:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</appmsg:recordKey>
</appmsg:getInventoryRecordByKeyRequest>
4.3 Managed-Entity Update Pattern 89
<!--
Get Inventory Record By Key response
-->
<appmsg:getInventoryRecordByKeyResponse
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
http://xml.netbeans.org/schema/Entities file:...
<appmsg:record xsi:type = "entities:EquipmentRecordValueType">
<entities:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</entities:recordKey>
<entities:lastUpdateNumber>1234</entities:lastUpdateNumber>
<entities:creationDate>2009-04-01T12:15:00-05:00</entities:creationDate>
<entities:equipmentType>LineCard</entities:equipmentType>
<entities:numberOnHand>10</entities:numberOnHand>
<entities:location>Montreal</entities:location>
</appmsg:record>
</appmsg:getInventoryRecordByKeyResponse>
<!--
Set Inventory Record By Value request
-->
<appmsg:setInventoryRecordByValueRequest
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
http://xml.netbeans.org/schema/Entities file:...
<appmsg:record xsi:type = "entities:EquipmentRecordValueType">
<entities:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</entities:recordKey>
<entities:lastUpdateNumber>1234</entities:lastUpdateNumber>
<entities:equipmentType>LineCard</entities:equipmentType>
<entities:numberOnHand>9</entities:numberOnHand>
<entities:location>Montreal</entities:location>
</appmsg:record>
</appmsg:setInventoryRecordByValueRequest>
90 4 OSS Programming Patterns
Finally, the client receives the following response document indicating that the
equipment record managed-entity, and the equipment record it represents, have been
updated.
<!--
Set Inventory Record By Value response
-->
<appmsg:setInventoryRecordByValueResponse
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xsi:schemaLocation=’http://xml.netbeans.org/schema/appmsg file:...
http://xml.netbeans.org/schema/Entities file:...
Summary
In reading and updating the attributes of managed entities, we take advantage of the
Managed-Entity Value pattern (see Sect. 3.1) to reduce the amount of network traf-
fic, and to reduce the number of operations required to read and update the attributes
of multiple managed entities.
4.4 Managed-Entity Attribute Population Pattern 91
Using managed-entity values to read and update the attributes of managed entities,
and to create managed entities themselves, is a consistent way to manage managed
resources irrespective of their implementation. However, a managed entity may ex-
pose a large numbers of attributes, and transferring all of the attribute values in a
managed-entity value, when only a few are required, unnecessarily consumes band-
width. This is particularly a problem when OSS clients make queries or selections
that result in a large number of managed-entities being returned.
OSS clients need a way of specifying a subset of attribute values to be transferred
between an OSS client and OSS application.
Intent
To reduce the unnecessary transfer of attribute values between OSS clients and OSS
applications.
Motivation
Managed entities may contain a large number of attributes and client requests may
result in selecting a large number of managed entities. Transferring all the attribute
values of all of the managed entities either for reading or updating, when only a
subset is required, is an inefficient use of bandwidth.
Solution
Allow the transfer of partially populated managed-entity values. For reading: in-
clude a list of the attribute names that are of interest to the client in the syntax of
all attribute read methods and all query methods. For updating: allow clients to pop-
ulate only those fields corresponding to managed-entities attributes that need to be
updated and to un-populate fields of received managed-entity values. In the session
profile, the client will need to be able to determine which fields are populated.
Example
Revisiting our example of updating an inventory record in Sect. 4.3, we will just
retrieve the NumberOnHand and Location attributes of the equipment record man-
aged entity rather than all of the attributes. We will also un-populate the Location
field before we request the update. (To be sure, not much of a saving in this case!)
92 4 OSS Programming Patterns
/*
* Update equipment record managed entity
* with Attribute Selection Example
*/
EquipmentRecordValue recordvo;
RecordKey key;
int number, newNumber;
SimpleInventorySession session;
String[] attributeNames;
/*
* Get Simple Inventory session bean
*/
session = serviceLocator.getInventorySession();
/*
* Make an Inventory Record Value object, use it to make
* a Record Key, and populate the key
*/
recordvo = (EquipmentRecordValue) session.makeManagedEntityValue(
"simpleinventory.EquipmentRecordValue");
key = recordvo.makeRecordKey();
key.setRecordId("42");
key.setRecordType("EquipmentRecordType");
/*
* Get an equipment record value-object representing the
* equipment record managed entity indicated
* by the supplied key retrieving only NumberOnHand and Location
*/
attributeNames = new String[2];
attributeNames[0] =
(EquipmentRecordValue.NUMBERONHAND);
attributeNames[1] =
(EquipmentRecordValue.LOCATION);
recordvo = (EquipmentRecordValue) session.getInventoryRecordByKey(key,
attributeNames);
Message Profile
Below is the amended getInventoryRecordByKey request document that includes
an additional element, <attributeNames>, with two child elements with content of
“numberOnHand” and “location” respectively indicating that only the numberOn-
Hand and Location managed-entity attributes are to be returned:
<!--
Get Inventory Record By Key with Attribute Selection request
-->
<appmsg:getInventoryRecordByKeyRequest
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xsi:schemaLocation=’http://xml.netbeans.org/schema/Entities file:...
http://xml.netbeans.org/schema/appmsg file:...
<appmsg:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentTypeRecord</entities:recordType>
</appmsg:recordKey>
<appmsg:attributeNames>
<appmsg:item>numberOnHand</appmsg:item>
<appmsg:item>location</appmsg:item>
</appmsg:attributeNames>
</appmsg:getInventoryRecordByKeyRequest>
<!--
Get Inventory Record By Key with Attribute Selection response
-->
<appmsg:getInventoryRecordByKeyResponse
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xsi:schemaLocation=’http://xml.netbeans.org/schema/Entities file:...
http://xml.netbeans.org/schema/appmsg file:...
<appmsg:record xsi:type = "entities:EquipmentRecordValueType">
<entities:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentRecordType</entities:recordType>
</entities:recordKey>
<entities:lastUpdateNumber>1234</entities:lastUpdateNumber>
<entities:creationDate>2009-04-01T12:15:00-05:00</entities:creationDate>
<entities:numberOnHand>10</entities:numberOnHand>
<entities:location>Montreal</entities:location>
</appmsg:record>
</appmsg:getInventoryRecordByKeyResponse>
<!--
Set Inventory Record By Value request with un-populated attribute values
-->
<appmsg:setInventoryRecordByValueRequest
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xsi:schemaLocation=’http://xml.netbeans.org/schema/Entities file:...
http://xml.netbeans.org/schema/appmsg file:...
94 4 OSS Programming Patterns
Summary
A typical OSS application will contain a large number of managed resources, and it
is useful for a network operator to be able to target operations on resources based on
their state. For example, a network manager might want to query all line cards that
are currently off-line and start maintenance testing on them, or might want to obtain
a listing of all of the trouble tickets that are outstanding for a particular customer.
Languages to specify such selections, for example formal query languages, can be
difficult to implement and intimidating to use.
In the Managed-Entity model (see Sect. 2.6), managed resources are modelled as
managed entities so OSS clients need a mechanism for selecting managed entities
based on their state.
Intent
Motivation
OSS clients need to be able to make ad hoc selections of managed entities based
on the values of their attributes—that is, an associative look-up. Such selections
can be used to return selected managed-entity values in response to a query, or to
selectively update managed entities.
Solution
Discussion
The rules for matching are quite straightforward:
• Attribute values and template values that are equal, match (where the values are
complex types, a basis for equality must have been defined).
• Un-populated values in the template are ignored.
• An empty template matches all managed entities of the type of the template (for
example, an empty equipment record value-object or document would match all
equipment records in the Simple Inventory).
• If the managed entities are arranged in a type hierarchy, sub-types of those enti-
ties that are requested in the template will be considered for selection (for exam-
ple an empty inventory record value-object or document would match all records
in the Simple Inventory).
96 4 OSS Programming Patterns
Example
In the OSS Iterator pattern section, we give an example of using a template to list
all of the equipment items on hand in Montreal, so we will use the same example
here to illustrate the Managed-Entity Template pattern in more detail.
/*
* Managed-entity value iterator/ template pattern example
*
* Return all equipment items and numbers-on-hand in Montreal
*/
SimpleInventorySession session;
EquipmentRecordValue template, equipvo;
InventoryRecordValue recordvos[];
InventoryRecordValueIterator iterator;
/*
* Get Simple Inventory session bean
*/
ServiceLocator serviceLocator = new ServiceLocator();
session = serviceLocator.getInventorySession();
/*
* Make an equipment record value object to use as a template
*/
template = (EquipmentRecordValue) session.makeManagedEntityValue(
"simpleinventory.EquipmentRecordValue");
/*
* Set the location field in the template
*/
template.setLocation("Montreal");
/*
* Request all equipment records where location = "Montreal"
*/
iterator =
session.getInventoryRecordsByTemplate(template, null);
/*
* Process 5 equipment record-value objects at a time
*/
recordvos = iterator.getNextInventoryRecords(5);
while (recordvos.length > 0) {
for (int i = 0; i < recordvos.length; i++) {
equipvo = (EquipmentRecordValue) recordvos[i];
System.out.println(equipvo.getEquipmentType() + " " +
4.5 Managed-Entity Template Filter Pattern 97
String.valueOf(equipvo.getNumberOnHand()));
}
recordvos =
iterator.getNextInventoryRecords(5);
}
iterator.remove();
<!--
Define Get Inventory Records By Template request/response types
-->
<complexType name="GetInventoryRecordsByTemplateRequestType">
<complexContent>
<extension base="appmsg:IteratorRequest">
<sequence>
<element name="template" type="entities:InventoryRecordValueType"/>
<element name="attrNames" type="appmsg:ArrayOfString" minOccurs="0"/>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="GetInventoryRecordsByTemplateResponseType">
<complexContent>
<extension base="appmsg:IteratorResponse">
<sequence>
<element name="records" type="entities:InventoryRecordValueType"
maxOccurs="unbounded"/>
</sequence>
</extension>
</complexContent>
</complexType>
<!--
Define Get Inventory Records By Template elements
-->
<element name="getInventoryRecordsByTemplateRequest"
type="appmsg:GetInventoryRecordsByTemplateRequestType"/>
<element name="getInventoryRecordsByTemplateResponse"
type="appmsg:GetInventoryRecordsByTemplateResponseType"/>
<element name="getInventoryRecordsByTemplateResponseException"
type="appmsg:ApplicationFaultType"/>
To illustrate the use of the Managed-Entity Template pattern in the message pro-
file, we will use the same example as in the session profile example—making a list
of all the equipment items on hand in Montreal. The following XML document re-
98 4 OSS Programming Patterns
quests equipment record value-documents, two at a time, for all equipment records
where the location is “Montreal”. The <appmsg:template> element type in the
document is derived from the type defined by the schema fragment (i.e. Inventory-
RecordValueType) by use of the xsi:type attribute indicating that equipment
record managed-entities and extended-equipment record managed entities are to be
matched.
<!--
Get Inventory Records By Template Request document
-->
<appmsg:getInventoryRecordsByTemplateRequest
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xsi:schemaLocation=’http://xml.netbeans.org/schema/Entities file:...
http://xml.netbeans.org/schema/appmsg file:...
<appmsg:n>2</appmsg:n>
<appmsg:template xsi:type = "entities:EquipmentRecordValueType">
<entities:location>Montreal</entities:location>
</appmsg:template>
</appmsg:getInventoryRecordsByTemplateRequest>
The following XML document might be received in response: the value of the
<appmsg:sequence> element indicates that this response is the first of the sequence
and that the value of the <appmsg:endOfReply> element indicates that there are
more responses to come. The xsi:type attribute in the first <appmsg:records>
element indicates that an EquipmentRecordValueType has been returned; the
xsi:type attribute in the second <appmsg:records> element indicates that an
ExtendedEquipmentRecordValueType has been returned. Both are subtypes of
InventoryRecordValueType.
<!--
Get Inventory Records By Template Response document
-->
<appmsg:getInventoryRecordsByTemplateResponse
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xsi:schemaLocation=’http://xml.netbeans.org/schema/Entities file:...
http://xml.netbeans.org/schema/appmsg file:...
<appmsg:sequence>1</appmsg:sequence>
<appmsg:endOfReply>false</appmsg:endOfReply>
Summary
Intent
Motivation
Solution
Example
In the following example, using the Simple Inventory, we want to update two in-
ventory records to reflect that a number of line cards have been transferred from
4.6 Managed-Entity Bulk Update Pattern 101
Montreal to Toronto. Clearly we must make sure that both updates occur atomically
because if either fails, we will have inconsistencies in the inventory.
/*
* Atomic Update of equipment record managed-entity Example
*/
int number, newNumber;
EquipmentRecordValue r1vo, r2vo;
/*
* Get an equipment record value objects for Montreal and Toronto
*/
r1vo = (EquipmentRecordValue) session.getInventoryRecordByKey(key1,
null);
System.out.println(r1vo.toString());
r2vo = (EquipmentRecordValue) session.getInventoryRecordByKey(key2,
null);
System.out.println(r2vo.toString());
<!--
Define Set Inventory Records By Values request/response types
-->
<complexType name="SetInventoryRecordsByValuesRequestType">
<sequence>
<element name="record" type="entities:InventoryRecordValueType"
maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="SetInventoryRecordsByValuesResponseType">
<sequence/>
</complexType>
<!--
Define Set Inventory Record By Values request/response elements
-->
<element name="setInventoryRecordsByValuesRequest"
type="appmsg:SetInventoryRecordsByValuesRequestType"/>
<element name="setInventoryRecordsByValuesResponse"
type="appmsg:SetInventoryRecordsByValuesResponseType"/>
<element name="setInventoryRecordsByValuesRequestException"
type="appmsg:ApplicationFaultType"/>
<!--
Atomic bulk update example
-->
<appmsg:setInventoryRecordsByValuesRequest
xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xmlns:entities=’http://xml.netbeans.org/schema/Entities’
xmlns:appmsg=’http://xml.netbeans.org/schema/appmsg’
xsi:schemaLocation=’http://xml.netbeans.org/schema/Entities file:...
http://xml.netbeans.org/schema/appmsg file:...
<appmsg:record xsi:type = "entities:EquipmentRecordValueType">
<entities:recordKey>
<entities:recordId>42</entities:recordId>
<entities:recordType>EquipmentTypeRecord</entities:recordType>
</entities:recordKey>
<entities:lastUpdateNumber>1234</entities:lastUpdateNumber>
<entities:equipmentType>LineCard</entities:equipmentType>
<entities:numberOnHand>5</entities:numberOnHand>
<entities:location>Montreal</entities:location>
</appmsg:record>
<appmsg:record xsi:type = "entities:EquipmentRecordValueType">
<entities:recordKey>
<entities:recordId>4242</entities:recordId>
<entities:recordType>EquipmentType</entities:recordType>
4.6 Managed-Entity Bulk Update Pattern 103
</entities:recordKey>
<entities:lastUpdateNumber>5678</entities:lastUpdateNumber>
<entities:equipmentType>LineCard</entities:equipmentType>
<entities:numberOnHand>15</entities:numberOnHand>
<entities:location>Toronto</entities:location>
</appmsg:record>
</appmsg:setInventoryRecordsByValuesRequest>
Summary
Intent
Ensure that attribute values of the managed entities remain consistent in the face of
concurrent updates.
Motivation
OSS clients request to update the attribute values of managed entities by sending
populated managed-entity values to OSS applications. Concurrent updating by mul-
tiple clients can cause inconsistencies because of stale values in the managed-entity
values.
Solution
For each managed entity, OSS applications locally maintain a counter, the last-
update-version number, which is incremented each time the managed entity is up-
dated. Each managed-entity value carries a copy of the last-update-version number
set when it was populated by the OSS application. This allows the OSS application
to subsequently detect stale values in a requested update and, in such cases, apply a
policy such as signalling the client. The client could take appropriate action such as
restarting the transaction.
The pattern is based on the Version Number pattern described in Marinescu[1].
References 105
In this book we have examined the case for a pattern-based approach to the design of
interfaces to OSS applications, and have supported the case with over a dozen design
patterns. We have described the design patterns in a technology-neutral manner, but
we have shown the practicality of the approach by giving examples of how each
can be implemented by clients using two different software technologies—JEE and
JMS. But more than that, the technology-neutral descriptions future-proof designs:
the patterns can be bound to new software technologies as they become available.
In Appendix C we show how the Managed-Entity Life Cycle pattern can be bound
to Web Services.
Many of the OSS applications and standards on which we have worked over the
years have successfully used these patterns to make systems integration easier and
more reliable. We believe that were the OSS community to begin to adopt these
patterns, the integration tax—the cost of integrating OSS applications into OSS
solutions—would rapidly fall. Other communities have adopted a pattern-based ap-
proach with great profit—we believe that the OSS community can do the same.
References
1. Marinescu, F., EJB Design Patterns. Wiley, New York, 2002. pp. 70–75.
Appendix A
Type Definitions for the Simple Inventory
The type definitions for the Simple Inventory application that we have been using,
take different forms for each of the two profiles. In the session profile, we use Java
interface declarations to define the data and operation types, in the message profile
we use XML Schema[1] to define the data message types. The interface diagram for
the Simple Inventory value-objects is shown in Fig. A.1.
For the session profile, we have split the declarations into three parts: the dec-
laration of the Simple Inventory value-object interfaces, the declarations of the
façade operations, and the declarations of the interfaces to the event notifica-
tion object-messages. The Java declarations for the RecordKey, ManagedEntity-
Value, InventoryRecordValue, EquipmentRecordValue, ExtendedEquipmen-
tRecordValue, and SupplierRecordValue value-object interfaces are as follows:
/**
*
* Record-key inteface declaration
*/
public interface RecordKey extends java.io.Serializable {
/**
* Constants to identify the fields of
* the managed-entity record key
*/
public static final String RECORDTYPE = "RecordType";
public static final String RECORDID = "RecordId";
/**
* Accessors and mutators for fieldsSet
*/
public void setRecordId(String id);
107
108 A Type Definitions for the Simple Inventory
/**
* Managed-entity value-object interface declaration.
*
* This the base interface for all managed-entity value-objects.
*/
public interface ManagedEntityValue extends java.io.Serializable {
//public interface ManagedEntityValue {
/**
* Constants to identify the fields of
* the managed-entity value-object
*/
public static final String LASTUPDATEVERSIONNUMBER =
"LastUpdateVersionNumber";
A.1 OSS Session Profile Declarations 109
/**
* Managed-entity value is a factory for record keys
*/
public RecordKey makeRecordKey();
/**
* Accessors and mutators for fields
*/
public RecordKey getRecordKey();
/**
* Get managed-entity attribute/value pairs
*/
public java.util.Hashtable getAttributeValues(String[] names)
throws ApplicationException;
/**
* Get managed-entity attribute names
*/
public String[] getAttributeNames();
/**
* Attribute population methods
*/
public void unPopulate(String attributeName);
/**
* Inventory record value-object interface declaration.
*
* This the base interface for all Simple Inventory Record value-objects.
* The fields of the value object carry copies of the values
* of the attributes of the Inventory Record managed entities.
*/
public interface InventoryRecordValue extends ManagedEntityValue{
/**
* Constant to identify the field of
* the inventory record value-object
*/
public static final String CREATIONDATE = "RecordCreationDate";
/**
* Accessors for field
*/
public Calendar getRecordCreationDate();
}
110 A Type Definitions for the Simple Inventory
/**
* Equipment record value-object interface declaration
*/
public interface EquipmentRecordValue
extends InventoryRecordValue {
/**
* Constants to identify the fields of the equipment record value-object
*/
public final static String EQUIPMENTTYPE = "EquipmentType";
public final static String NUMBERONHAND = "NumberOnHand";
public final static String LOCATION = "Location";
/*
* Accessors and mutators for the fields of the value-object
*/
void setEquipmentType(String equipmentType);
String getEquipmentType();
int getNumberOnHand();
String getLocation();
}
/**
* Extended-equipment record value-object interface declaration
*/
public interface ExtendedEquipmentRecordValue
extends EquipmentRecordValue {
/**
* Constants to identify the extended-equipment record
* fields (attributes)
*/
public final static String REORDERLEVEL = "ReorderLevel";
public final static String SUPPLIERNAME = "SupplierName";
int getReorderLevel();
String getSupplierName();
}
/**
* Supplier record value object interface
*/
public interface SupplierRecordValue
extends InventoryRecordValue {
/**
* Constants to identify the fields of the supplier record value-object
*/
A.1 OSS Session Profile Declarations 111
/**
* Accessor and mutators for the fields of the value-object
*/
void setSupplierName(String supplierName);
String getSupplierName();
String getSupplierAddress();
String getContactNumber();
}
The Java declaration for the OSS Session Façade interface is as follows:
/**
* Simple Inventory session bean declaration.
*
* This interface defines the operational aspects of the Simple
* Inventory session bean that implements the facade pattern.
*/
@Remote
public interface SimpleInventorySession
{
/**
* Base interface to access the payload of all Simple
* Inventory event notification messages
*/
public interface BaseEvent extends java.io.Serializable {
/*
* Accessor for the time the event was published as a String
*/
public String getEventTimeAsString();
/*
* Accessor for the time the event was published
*/
public Calendar getEventTime()
throws ApplicationException;
}
/**
* Interface to access the payload
* of the record-create notification
*/
public interface RecordCreateEvent extends BaseEvent {
/*
* Accessor/mutator for the record created
*/
public InventoryRecordValue getInventoryRecordValue()
throws ApplicationException;
The XML definitions for the Simple Inventory application are split into two schemata:
the first, Entities.xsd, defines the inventory record complex-types and element
types, and the second, Appmsg.xsd, the message and notification complex-types
and element-types supported by the message profile.
The schema for inventory record complex-types and element types is as follows:
<schema targetNamespace="http://xml.netbeans.org/schema/Entities"
xmlns:entities="http://xml.netbeans.org/schema/Entities"
xmlns:tns="http://xml.netbeans.org/schema/Entities"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<!--
Define record-key type
A.2 OSS Message Profile Declarations 113
-->
<complexType name="RecordKeyType">
<sequence>
<element name="recordId" type="string" nillable="false"/>
<element name="recordType" type="string" nillable="true"/>
</sequence>
</complexType>
<!--
Define managed-entity value-type
-->
<complexType name="ManagedEntityValueType">
<sequence>
<element name="recordKey" type="entities:RecordKeyType"></element>
<element name="lastUpdateNumber" type="xsd:long" minOccurs="0"></element>
</sequence>
</complexType>
<!--
Define inventory record value-type
-->
<complexType name="InventoryRecordValueType">
<complexContent>
<extension base="entities:ManagedEntityValueType">
<sequence>
<element name="creationDate" type="xsd:dateTime" minOccurs="0"></element>
</sequence>
</extension>
</complexContent>
</complexType>
<!--
Define equipment record value-type
-->
<complexType name="EquipmentRecordValueType">
<complexContent>
<extension base="entities:InventoryRecordValueType">
<sequence>
<element name="equipmentType" type="string" minOccurs="0"/>
<element name="numberOnHand" type="int" minOccurs="0"/>
<element name="location" type="string" minOccurs="0"/>
</sequence>
</extension>
</complexContent>
</complexType>
<!--
Define supplier-record value-type
-->
<complexType name="SupplierRecordValueType">
<complexContent>
<extension base="entities:InventoryRecordValueType">
<sequence>
<element name="supplierName" type="string" minOccurs="0"/>
<element name="supplierAddress" type="string" minOccurs="0"/>
<element name="contactNumber" type="string" minOccurs="0"/>
</sequence>
</extension>
</complexContent>
</complexType>
<!--
Define extended-equipment record value-type
-->
<complexType name="ExtendedEquipmentRecordValueType">
114 A Type Definitions for the Simple Inventory
<complexContent>
<extension base="entities:EquipmentRecordValueType">
<sequence>
<element name="reorderLevel" type="int"/>
<element name="supplierName" type="string"/>
</sequence>
</extension>
</complexContent>
</complexType>
<!--
Define Simple Inventory value-elements
-->
<element name="inventoryRecordKey" type="entities:RecordKeyType"/>
<element name="managedEntityValue" type="entities:ManagedEntityValueType"/>
<element name="inventoryRecordValue" type="entities:InventoryRecordValueType"/>
<element name="equipmentRecordValue" type="entities:EquipmentRecordValueType"/>
<element name="extendedEquipmentRecordValue"
type="entities:ExtendedEquipmentRecordValueType"/>
<element name="supplierRecordValue" type="entities:SupplierRecordValueType"/>
</schema>
The schema for the message and notification complex-types and element-types
is as follows:
<schema targetNamespace="http://xml.netbeans.org/schema/appmsg"
xmlns:entities="http://xml.netbeans.org/schema/Entities"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:appmsg="http://xml.netbeans.org/schema/appmsg"
xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<import namespace="http://xml.netbeans.org/schema/Entities"
schemaLocation="EntitiesOld.xsd"/>
<!--
Define Create Inventory Record By Value request/response types
-->
<complexType name="CreateInventoryRecordByValueRequestType">
<sequence>
<element name="record" type="entities:InventoryRecordValueType"/>
</sequence>
</complexType>
<complexType name="CreateInventoryRecordByValueResponseType">
<sequence>
<element name="record" type="entities:RecordKeyType"/>
</sequence>
</complexType>
<!--
Define Create Inventory Record By Value request/response elements
-->
<element name="createInventoryRecordByValueRequest"
type="appmsg:CreateInventoryRecordByValueRequestType"/>
<element name="createInventoryRecordByValueResponse"
type="appmsg:CreateInventoryRecordByValueResponseType"/>
<element name="createInventoryRecordByValueResponseException"
type="appmsg:ApplicationFaultType"/>
<!--
Define Get Inventory Record By Key request/response types
-->
A.2 OSS Message Profile Declarations 115
<complexType name="GetInventoryRecordByKeyRequestType">
<sequence>
<element name="recordKey" type="entities:RecordKeyType"/>
<element name="attributeNames" type="appmsg:ArrayOfString" minOccurs="0"/>
</sequence>
</complexType>
<complexType name="GetInventoryRecordByKeyResponseType">
<sequence>
<element name="record" type="entities:InventoryRecordValueType"/>
</sequence>
</complexType>
<!--
Define Get Inventory Record By Key request/response elements
-->
<element name="getInventoryRecordByKeyRequest"
type="appmsg:GetInventoryRecordByKeyRequestType"/>
<element name="getInventoryRecordByKeyResponse"
type="appmsg:GetInventoryRecordByKeyResponseType"/>
<element name="getInventoryRecordByKeyResponseException"
type="appmsg:ApplicationFaultType"/>
<!--
Define Set Inventory Record By Value request/response types
-->
<complexType name="SetInventoryRecordByValueRequestType">
<sequence>
<element name="record" type="entities:InventoryRecordValueType"/>
</sequence>
</complexType>
<complexType name="SetInventoryRecordByValueResponseType">
<sequence/>
</complexType>
<!--
Define SetInventoryRecordbyValue request/response elements
-->
<element name="setInventoryRecordByValueRequest"
type="appmsg:SetInventoryRecordByValueRequestType"/>
<element name="setInventoryRecordByValueResponse"
type="appmsg:SetInventoryRecordByValueResponseType"/>
<element name="setInventoryRecordByValueRequestException"
type="appmsg:ApplicationFaultType"/>
<!--
Define Set Inventory Records By Values request/response types
-->
<complexType name="SetInventoryRecordsByValuesRequestType">
<sequence>
<element name="record" type="entities:InventoryRecordValueType"
maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="SetInventoryRecordsByValuesResponseType">
<sequence/>
</complexType>
<!--
Define Set Inventory Record By Values request/response elements
-->
<element name="setInventoryRecordsByValuesRequest"
116 A Type Definitions for the Simple Inventory
type="appmsg:SetInventoryRecordsByValuesRequestType"/>
<element name="setInventoryRecordsByValuesResponse"
type="appmsg:SetInventoryRecordsByValuesResponseType"/>
<element name="setInventoryRecordsByValuesRequestException"
type="appmsg:ApplicationFaultType"/>
<!--
Define Remove Inventory Record By Key request/response types
-->
<complexType name="RemoveInventoryRecordByKeyRequestType">
<sequence>
<element name="inventoryRecordKey" type="entities:RecordKeyType"
nillable="false"/>
</sequence>
</complexType>
<complexType name="RemoveInventoryRecordByKeyResponseType">
<sequence/>
</complexType>
<!--
Define Remove Inventory Record By Value request/response elements
-->
<element name="removeInventoryRecordByKeyRequest"
type="appmsg:RemoveInventoryRecordByKeyRequestType"/>
<element name="removeInventoryRecordByKeyResponse"
type="appmsg:RemoveInventoryRecordByKeyResponseType"/>
<element name="removeInventoryRecordByKeyResponseException"
type="appmsg:ApplicationFaultType"/>
<!--
Define Application Fault type
-->
<complexType name="ApplicationFaultType">
<sequence>
<element name="errorMessage" type="string"/>
</sequence>
</complexType>
<element name="applicationFault" type="appmsg:ApplicationFaultType"/>
<!--
Define Datatype types
-->
<complexType name="ArrayOfString">
<sequence>
<element name="item" type="string" nillable="true" maxOccurs="unbounded"/>
</sequence>
</complexType>
<!--
Define Iterator request/response types
-->
<complexType name="IteratorRequest" abstract="false">
<sequence>
<element name="n" type="unsignedInt" nillable="true" minOccurs="0"/>
</sequence>
</complexType>
<!--
Define Get Inventory Records By Template request/response types
-->
<complexType name="GetInventoryRecordsByTemplateRequestType">
<complexContent>
<extension base="appmsg:IteratorRequest">
<sequence>
<element name="template" type="entities:InventoryRecordValueType"/>
<element name="attrNames" type="appmsg:ArrayOfString" minOccurs="0"/>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="GetInventoryRecordsByTemplateResponseType">
<complexContent>
<extension base="appmsg:IteratorResponse">
<sequence>
<element name="records" type="entities:InventoryRecordValueType"
maxOccurs="unbounded"/>
</sequence>
</extension>
</complexContent>
</complexType>
<!--
Define Get Inventory Records By Template elements
-->
<element name="getInventoryRecordsByTemplateRequest"
type="appmsg:GetInventoryRecordsByTemplateRequestType"/>
<element name="getInventoryRecordsByTemplateResponse"
type="appmsg:GetInventoryRecordsByTemplateResponseType"/>
<element name="getInventoryRecordsByTemplateResponseException"
type="appmsg:ApplicationFaultType"/>
<!--
Define Named-procedure request and response types and elements
-->
<xsd:complexType name="NamedProcedureRequestType">
<xsd:sequence/>
</xsd:complexType>
<xsd:complexType name="NamedProcedureResponseType">
<xsd:sequence/>
</xsd:complexType>
<xsd:element name="namedProcedureRequest"
type="appmsg:NamedProcedureRequestType"/>
<xsd:element name="namedProcedureResponse"
type="appmsg:NamedProcedureResponseType"/>
<!--
Define Iterator Named-procedure request and response types and elements
-->
<xsd:complexType name="IteratorNamedProcedureRequestType">
<xsd:complexContent>
<xsd:extension base="appmsg:NamedProcedureRequestType">
<xsd:sequence>
<element name="iteratorRequest" type="appmsg:IteratorRequest"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="IteratorNamedProcedureResponseType">
118 A Type Definitions for the Simple Inventory
<xsd:complexContent>
<xsd:extension base="appmsg:NamedProcedureResponseType">
<xsd:sequence>
<element name="iteratorResponse" type="appmsg:IteratorResponse"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="iteratornamedProcedureRequest"
type="appmsg:IteratorNamedProcedureRequestType"/>
<xsd:element name="IteratorNamedProcedureResponse"
type="appmsg:IteratorNamedProcedureResponseType"/>
<!--
Define Query Reorder Named-procedure request and response types and elements
-->
<xsd:complexType name="QueryReorderItemsRequestType">
<xsd:complexContent>
<xsd:extension base="appmsg:IteratorNamedProcedureRequestType">
<xsd:sequence>
<xsd:element name="location" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="QueryReorderItemsResponseType">
<xsd:complexContent>
<xsd:extension base="appmsg:IteratorNamedProcedureResponseType">
<xsd:sequence>
<xsd:element name="records"
type="entities:ExtendedEquipmentRecordValueType"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="queryReorderItemsResponse"
type="appmsg:QueryReorderItemsResponseType"/>
<xsd:element name="queryReorderItemsRequest"
type="appmsg:QueryReorderItemsRequestType"/>
<xsd:element name="namedProcedureException"
type="appmsg:ApplicationFaultType"/>
<!--
Define Base Event Type for notifications
-->
<xsd:complexType name="BaseEventNotifcationType">
<xsd:sequence>
<xsd:element name="eventTime" type="xsd:date" nillable="false"/>
</xsd:sequence>
</xsd:complexType>
<!--
Define Record Create Notification Type
-->
<xsd:complexType name="RecordCreateEventType">
<xsd:complexContent>
<xsd:extension base="appmsg:BaseEventNotifcationType">
<xsd:sequence>
<xsd:element name="inventoryRecordValue"
type="entities:InventoryRecordValueType"/>
</xsd:sequence>
A.2 OSS Message Profile Declarations 119
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<!--
Define Record Create Notification element
-->
<xsd:element name="recordCreateEventNotification"
type="appmsg:RecordCreateEventType"/>
<!--
Define Record Delete Notification Type
-->
<xsd:complexType name="RecordDeleteEventType">
<xsd:complexContent>
<xsd:extension base="appmsg:BaseEventNotifcationType">
<xsd:sequence>
<xsd:element name="inventoryRecordValue"
type="entities:InventoryRecordValueType"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<!--
Define Record Delete Notification element
-->
<xsd:element name="recordDeleteEventNotification"
type="appmsg:RecordDeleteEventType"/>
</schema>
Appendix B
Implementing an OSS Client Using JAXB
To illustrate the use of patterns in the OSS Message Profile, we have shown exam-
ples of the XML messages that a client might use to access OSS applications via a
message-driven bean (see Fig. 3.5, p. 39).
For the sake of clarity, we have not shown any supporting code for generating
the messages, enqueueing the messages, or receiving responses. Within the JEE
platform, there are a number tools and APIs that help in the development of Java-
based clients using the message profile. In this chapter we will show how an OSS
client might create an equipment record managed-entity within the message profile
using Java and the JAXB API. We will also look at the overall implementation
architecture for implementing OSS Message Profile using JEE.
The Java Architecture for XML Binding (JAXB[2]) API is a framework for pro-
cessing XML documents within the Java programming language. The API provides
methods for un-marshalling an XML document into a tree of Java objects and, con-
versely, for marshalling Java objects to an XML message. The Java type information
is normally obtained by compiling the relevant XML schema into Java classes by
the use of the JAXB binding complier[3].
In the following example, we will show the use of the JAXB API to create
an equipment record managed-entity (q.v. Sect. 4.2) in the Simple Inventory. The
first step is to compile the relevant XML schemata into Java classes and make the
classes available to the OSS client as a package. The schema fragments for the Cre-
ateInventoryRecordByValue request and response complex types and Equip-
mentRecordValueType complex types are as follows.
121
122 B Implementing an OSS Client Using JAXB
<!--
Define Create Inventory Record By Value request/response types
-->
<complexType name="CreateInventoryRecordByValueRequestType">
<sequence>
<element name="record" type="entities:InventoryRecordValueType"/>
</sequence>
</complexType>
<complexType name="CreateInventoryRecordByValueResponseType">
<sequence>
<element name="record" type="entities:RecordKeyType"/>
</sequence>
</complexType>
<!--
Define Create Inventory Record By Value request/response elements
-->
<element name="createInventoryRecordByValueRequest"
type="appmsg:CreateInventoryRecordByValueRequestType"/>
<element name="createInventoryRecordByValueResponse"
type="appmsg:CreateInventoryRecordByValueResponseType"/>
<element name="createInventoryRecordByValueResponseException"
type="appmsg:ApplicationFaultType"/>
<!--
Define record-key type
-->
<complexType name="RecordKeyType">
<sequence>
<element name="recordId" type="string" nillable="false"/>
<element name="recordType" type="string" nillable="true"/>
</sequence>
</complexType>
<!--
Define managed-entity value-type
-->
<complexType name="ManagedEntityValueType">
<sequence>
<element name="recordKey" type="entities:RecordKeyType"></element>
<element name="lastUpdateNumber" type="xsd:long" minOccurs="0"></element>
</sequence>
</complexType>
<!--
Define inventory record value-type
-->
<complexType name="InventoryRecordValueType">
<complexContent>
<extension base="entities:ManagedEntityValueType">
<sequence>
<element name="creationDate" type="xsd:dateTime" minOccurs="0"></element>
</sequence>
</extension>
B.1 Create Equipment Record Managed-Entity Example 123
</complexContent>
</complexType>
<!--
Define equipment record value-type
-->
<complexType name="EquipmentRecordValueType">
<complexContent>
<extension base="entities:InventoryRecordValueType">
<sequence>
<element name="equipmentType" type="string" minOccurs="0"/>
<element name="numberOnHand" type="int" minOccurs="0"/>
<element name="location" type="string" minOccurs="0"/>
</sequence>
</extension>
</complexContent>
</complexType>
<element name="equipmentRecordValue" type="entities:EquipmentRecordValueType"/>
The following code fragment creates and populates the JAXB equivalents of the
CreateInventoryRecordByValueRequestType, the RecordKeyType, and the Equip-
mentRecordValueType:
The next step is to wrap the request object in its XML element and write it out:
// Create the marshaller that writes the XML file from the Java objects
try {
marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
} catch (JAXBException ex) {
Logger.getLogger(JMSClient.class.getName()).log(Level.SEVERE, null, ex);
}
And finally to start the connections, enqueue the message, and wait for the response:
/*
* Start connection to the message queues and consumer
*/
try {
connection = simpleInventoryQueueFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
MessageConsumer consumer = session.createConsumer(replyToDestinationQueue);
The request message generated and sent by the client to the message-driven bean
will look like this:
And the response received by the client will look like this:
In the message profile example described in Sect. 3.2, the OSS Façade is imple-
mented by means of a message-drive bean that intercepts XML messages and makes
the appropriate method calls on the OSS application. Fig. B.1 shows a more detailed
software architecture with the session bean and the marshalling and un-marshalling
components. The sequence of operations is as follows:
1. Using the JAXB packages and the JAXB API, the OSS client builds a create-
inventory-record-managed-entity XML request and enqueues it onto the Simple
Inventory queue as described in Sect B.1.
2. Using an implementation of the onMessage() method, the message-driven bean
retrieves the XML message from the queue.
3. Using the JAXB API, the message-driven bean un-marshals the XML message
into a tree of objects.
126 B Implementing an OSS Client Using JAXB
Here is the complete code for the create equipment record managed-entity example:
import java.io.StringWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.netbeans.xml.schema.appmsg.CreateInventoryRecordByValueRequestType;
import org.netbeans.xml.schema.appmsg.ObjectFactory;
import org.netbeans.xml.schema.entities.EquipmentRecordValueType;
import org.netbeans.xml.schema.entities.RecordKeyType;
/**
*
* Example OSS client--message profile
*/
public class JMSClient {
/**
* Example of creating an equipment record managed-entity-
* by-value XML document using JAXB and sending it to the
* Simple Inventory application using JMS
*
* The schemata for XML message types and entity types have
* been compile to generate the following Java classes:
*
* CreateInventoryRecordByValueRequestType;
* EquipmentRecordValueType;
* RecordKeyType; and
* ObjectFactory.
*
*/
public void createInventoryByValue() throws JMSException {
ObjectFactory objFactory = new ObjectFactory();
/*
* Wrap the request in its XML element and write it out
*
*/
JAXBContext jaxbContext = null;
JAXBElement<CreateInventoryRecordByValueRequestType> request = objFactory.
createCreateInventoryRecordByValueRequest(value);
try {
jaxbContext = JAXBContext.newInstance("org.netbeans.xml.schema.appmsg");
} catch (JAXBException ex) {
Logger.getLogger(JMSClient.class.getName()).log(Level.SEVERE, null, ex);
}
Marshaller marshaller = null;
// Create the marshaller that writes the XML file from the Java objects
try {
marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
} catch (JAXBException ex) {
Logger.getLogger(JMSClient.class.getName()).log(Level.SEVERE, null, ex);
}
marshaller.marshal(request, writer);
System.out.println("XML File to be enqueued = \n" + writer.toString());
} catch (JAXBException ex) {
Logger.getLogger(JMSClient.class.getName()).log(Level.SEVERE, null, ex);
}
/*
* Start connection to the message queues and consumer
*/
try {
connection = simpleInventoryQueueFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
MessageConsumer consumer = session.createConsumer(replyToDestinationQueue);
/**
* Create and populate a message to send to the Simple Inventory
*/
private Message createJMSMessageForJMSSimpleInventoryQueue(Session session,
String messageData) throws JMSException {
TextMessage tm = session.createTextMessage();
tm.setText(messageData);
return tm;
}
/**
* Send a message to the Simple Inventory Queue
*/
private void sendJMSMessageToSimpleInventoryQueue(String messageData) throws
JMSException {
MessageProducer messageProducer = session.createProducer(
simpleInventoryQueue);
messageProducer.send(createJMSMessageForJMSSimpleInventoryQueue(session,
messageData));
}
/**
* Initialize name resolution and connections
*/
public void init() {
Context jndiContext = null;
B.3 Create Equipment Record Managed-Entity Example—Complete Code 129
/*
* Create a JNDI API InitialContext object if none exists
*/
try {
jndiContext = new InitialContext();
} catch (NamingException ex) {
Logger.getLogger(JMSClient.class.getName()).log(Level.SEVERE, null, ex);
}
/*
* Look up connection factory and destination.
*/
try {
simpleInventoryQueueFactory = (ConnectionFactory) jndiContext.lookup(
"jms/simpleInventoryQueueFactory");
simpleInventoryQueue = (Queue) jndiContext.lookup(destName);
replyToDestinationQueue = (Queue) jndiContext.lookup(replyToDestName);
} catch (Exception e) {
System.out.println("JNDI API lookup failed: " + e.toString());
System.exit(1);
}
}
}
Appendix C
Binding the OSS Patterns to Web Services
In describing the two OSS Implementation Profiles (see Sect. 2.5), we chose to
describe the OSS Message Profile by binding the OSS Design Patterns to JMS—
that is describing OSS clients that use XML messages carried by JMS. In order to
demonstrate the flexibility of our pattern-based approach, we will show how the
OSS Design Patterns can be bound to Web Services, see Fig. C.1.
131
132 C Binding the OSS Patterns to Web Services
Example
To illustrate how we might use WSDL to define Web Service, we will use the same
example as we used in Sect. B.1, that is, from the Managed-Entity Life Cycle pat-
tern, the creation of an equipment record managed-entity (q.v. Sect. 4.2) in the Sim-
ple Inventory.
First we will define the request, response, and exception <message> elements by
re-using the element definitions in the OSS Message Profile (see Sect. A.2):
<!--
Define the message types for the createInventoryRecordByValue
request, response, and exception messages by re-using
the definitions in the message profile
-->
<message name="createInventoryRecordByValueOperationRequest">
<part name="createInventoryRecordByValueRequest"
element="appmsg:createInventoryRecordByValueRequest"/>
</message>
<message name="createInventoryRecordByValueOperationResponse">
<part name="createInventoryRecordByValueResponse"
element="appmsg:createInventoryRecordByValueResponse"/>
</message>
<message name="createInventoryRecordByValueOperationFault">
<part name="createInventoryRecordByValueRequestException"
element="appmsg:createInventoryRecordByValueResponseException"/>
</message>
C Binding the OSS Patterns to Web Services 133
<!--
Define the portType with the one operation: createInventoryRecordByValue
-->
<portType name="CreateInventoryRecordByValuePortType">
<operation name="createInventoryRecordByValueOperation">
<input name="input1"
message="tns:createInventoryRecordByValueOperationRequest"/>
<output name="output1"
message="tns:createInventoryRecordByValueOperationResponse"/>
<fault name="fault1"
message="tns:createInventoryRecordByValueOperationFault"/>
</operation>
</portType>
<!--
Define the binding of the portType in a document/literal style to SOAP
-->
<binding name="CreateInventoryRecordByValueBinding"
type="tns:CreateInventoryRecordByValuePortType">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="createInventoryRecordByValueOperation">
<soap:operation/>
<input name="input1">
<soap:body use="literal"/>
</input>
<output name="output1">
<soap:body use="literal"/>
</output>
<fault name="fault1">
<soap:fault use="literal" name="fault1"/>
</fault>
</operation>
</binding>
A SOAP message to create an equipment record managed entity might look like
this:
<!--
Example of createInventoryRecordByValue request SOAP document
-->
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Header/>
<soapenv:Body>
<ns2:createInventoryRecordByValueRequest
xmlns:ns2="http://xml.netbeans.org/schema/appmsg"
xmlns="http://xml.netbeans.org/schema/Entities">
<ns2:record xsi:type="EquipmentRecordValueType"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
134 C Binding the OSS Patterns to Web Services
<recordKey>
<recordId>42</recordId>
<recordType>EquipmentRecordType</recordType>
</recordKey>
<equipmentType>LineCard</equipmentType>
<numberOnHand>10</numberOnHand>
<location>Montreal</location>
</ns2:record>
</ns2:createInventoryRecordByValueRequest>
</soapenv:Body>
</soapenv:Envelope>
<!--
Example of createInventoryRecordByValue response SOAP document
-->
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Header/>
<soapenv:Body>
<ns2:createInventoryRecordByValueResponse
xmlns:ns2="http://xml.netbeans.org/schema/appmsg"
xmlns="http://xml.netbeans.org/schema/Entities">
<ns2:record>
<recordId>42</recordId>
<recordType>EquipmentRecordType</recordType>
</ns2:record>
</ns2:createInventoryRecordByValueResponse>
</soapenv:Body>
</soapenv:Envelope>
Appendix D
OSS Design Pattern Interaction and Usage
The various patterns that we have introduced in this book do not stand alone: many
are related and many rely on other patterns. To help the reader understand the rela-
tionships we show them in graphical format.
In the two pattern interaction diagrams, Figs. D.1a and D.1b, we show the relation-
ships between the patterns. The nodes of the graphs represent the patterns and the
edges the relationships.
135
136 D OSS Design Pattern Interaction and Usage
In Fig. D.2 we show the usage of the patterns by OSS clients and OSS applications.
The patterns supporting the OSS Application Services set the overall, coarse-grained
architectural structure for an OSS solution. The patterns supporting the Managed-
Entity Services allow the fine-grained access to the managed entities. OSS clients
will engage with the OSS Application Services to set up the context of the data
transfers using the patterns supporting the Data Transfer Services.
References
139
140 Glossary
OSS client A software component that engages with a remote OSS application to
access the latters functionality.
OSS Design Pattern A description of an abstract architectural or programming
solution to telecommunications management problem that has proven successful in
practice.
OSS Façade A view, in terms of remote operations, exposed by an OSS applica-
tion.
OSS integration interface The interface at which OSS application functionality is
made available.
OSS Message Profile A description of the non-functional aspects of a message-
oriented engagement between an OSS client and an OSS application.
OSS Reference Architecture A refinement of an architectural style in terms of
interaction patterns, granularity of operation, and client-server separation; it is a
mapping of the OSS Reference Model into the architectural style.
OSS Reference Model A functional decomposition that meets telecommunica-
tions management requirements.
OSS Session Profile A description of the non-functional aspects of a session-
oriented engagement between an OSS client-component and an OSS application.
programming pattern A design pattern that addresses a problem encountered
within the overall framework of the software architecture.
session-oriented data exchange A style of data exchange between a client and a
remote application that includes a preamble to agree the rules for the exchange.
sessionless data exchange A style of data exchange between a client and a remote
application that does not include any preamble to agree the rules for the exchange;
the client normally includes a call-back address for replies.
software architecture The specification of the systems architecture in terms of
programming and data elements bound to a particular software technology.
support resource An asset that supports the revenue-generating services; support
resources include trouble tickets, alarm reports, and customer and billing records.
systems architecture The architecture of the system that is actually deployed; it
may be a direct realization of the software architecture, but may also be comple-
mented by deployment considerations such as clustering and virtualization.
142 Glossary
Pierre Gauthier is the President and CTO of OSS Wave, a software consulting
and training company. For the last decade Pierre has been involved in the design
and development of software for telecommunications and Operation Support
Systems (OSSs), holding senior positions with Oracle and Nortel. Pierre was the
driving force behind the development of the OSS/J Design Guidelines and is Spec
Lead for JSR 91, the OSS Trouble Ticket API. Pierre is a JavaOne alumnus,TMF
invited speaker, and JCP Star Spec Lead.
He holds a master’s degree in Electrical Engineering from the École Polytech-
´ Canada.
nique, Montreal,
143
Index
145
146 Index
Network Element (NE), 140 OSS Reference Architecture, 12, 14, 141
network latency, 100 OSS Reference Model, 6, 12, 141
notification service, 15, 140 OSS Session Profile, 16, 17, 141
notification signatures, 17, 19 OSS Systems Architecture, 7
notification style, 18 developing, 11
null, 92
NUMBERONHAND, 31 pattern, see design pattern
NumberOnHand, 92 pattern approach, 4
numberOnHand, 93, 101 pattern interactions, see OSS Design Patterns
pattern relationships, see OSS Design Patterns
ObjectMessage, 43 pattern usage, see OSS Design Patterns
onMessage(), 43, 72, 125 performance of interfaces, 16
operation signatures, 16, 17, 19 polling, 41
Operations Support System, 3, 8 polymorphism, 83, 85
Operations Support System (OSS), 140 populated attributes, 80
operator applications, 7 population pattern, see Manage-Entity
operator system, 2, 7, 140 Attribute Population pattern
operator-support application, 7, 13, 140 presentation layer, 6, 7
operator-support layer, 6, 7 procedure call model, 17
OSS, see Operations Support System programming pattern, 141
OSS application, 3, 15, 140 publish-and-subscribe model, 42
operational aspects, 36 publish-and-subscribe style, 3, 14, 18
OSS Application Context, 20
OSS application layer, 7 query mechanism, 14
OSS Application Services, 137 QueryReorderItems, 68, 69
OSS client, 13, 14, 141
OSS Command–Status pattern, 71 rapid development, 13
OSS Design Pattern, 141 read-update model, 86
OSS design pattern, 12 Record Type, 76
OSS Design Patterns, 20 RecordCreateEvent, 43
interactions, 135 RECORDID, 29
relationships, 135 RecordKey, 28–30, 107
usage, 137 RecordKeyType, 33, 123
OSS Discovery pattern, 58 records, 68
OSS Event Notification pattern, 14, 41 RECORDTYPE, 29
use, 73 reference model, 6, see OSS Reference Model
OSS Façade pattern, 36 referencing managed entities, 19
OSS Façade, 14, 141 reliable implementation, 13
OSS Façade pattern, 13 remote operations, 14, 15
OSS Factory pattern, 53, 81 Remote Operations Model, 14, 15
OSS functionality asynchronous mode, 16
discovery, 58 synchronous mode, 16
OSS Implementation Profiles, 14, 16 Remote Procedure Call, 16
OSS Integration Interface, 6, 14 removeInventoryRecordByKey(), 38
OSS integration interface, 141 REORDERLEVEL, 32
OSS integration layer, 7 RPC, see Remote Procedure Call
OSS interfaces
brittle, 16 Service Oriented Architecture, 4
coupling, 16 service providers, 3
performance, 16 service quality, 41
OSS Iterator pattern, 48, 96 service-fulfillment application
OSS Message Profile, 16, 18, 18, 141 example, 11
OSS Named-procedure pattern, 14, 64, 99 service-level agreements, 1
use, 72 session-oriented, 17
Index 149
The text of this book was prepared in LATEX using TeXShop on a Macintosh Mac
Pro computer. The Java and XML examples were collaboratively prepared on the
same Mac Pro and a Windows computer both using NetBeans. The example code
was extracted from the NetBeans files with Applescripts that look for specially-
formatted comments and then copy the code into the LATEX source file.
The diagrams were prepared on the Mac Pro using Microsoft PowerPoint and
CS Odessa ConceptDraw. The .pdf outputs of the programs were cropped using
Mac Preview and placed in the appropriate locations for inclusion by TeXShop.
151