[6] Cormac Flanagan, Rajeev Joshi, Xinming Ou, and James B. Saxe,. âTheorem ... [22] David Detlefs, Greg Nelson and James B. Saxe, Simplify: A theorem-.
Cauldron: A Policy-based Design Tool Lyle Ramshaw, Akhil Sahai, Jim Saxe, Sharad Singhal Hewlett Packard Laboratories Palo Alto, CA, USA {lyle.ramshaw, akhil.sahai, jim.saxe, sharad.singhal}@hp.com
Abstract—As applications and systems have grown complex, so has the complexity of maintaining valid configurations for them. Usually, policies are treated as {event, condition, action} rule sets and are used to maintain systems in valid configurations. In this paper, we use policies, defined as configuration constraints on object-oriented models of systems, to generate configurations that meet those policies. We describe Cauldron, a policy-based design tool for this purpose. The paper discusses the Cauldron language, and shows how various relationships present in object-oriented models are coded using the Common Information Model (CIM) as an example. We also discuss the implementation of Cauldron, specifically as it relates to the underlying theory that enables it to generate valid configurations. A case study of partitionable systems demonstrates that our implementation of Cauldron can generate configurations of practical systems in reasonable times. Keywords-component; object oriented modeling, policy-based configuration, system design, theorem provers
I. INTRODUCTION As computer systems and applications have grown more complex, ensuring correct configuration has become increasingly burdensome. Object oriented methods are often used in complex systems for the purpose of system design. However, available tools are usually tied to tasks such as code generation. Unlike program logic, which is usually determined at development time, system configuration is a recurring task. Any given system or application may have many different valid configurations that may be selected based on operator preference. Similarly, it is easy to generate configurations that are incorrect for almost any system because the underlying application cannot check for all invalid combinations of settable parameters. In this paper, we describe Cauldron, which is a policybased design tool for creating or validating system configurations. Cauldron is a part of a larger automation framework [1] that has been developed by us. Cauldron handles policy as constraints enforced on the configuration of a system. Thus Cauldron applies the concept of policy in a manner different from traditional policy-based systems. Cauldron considers the managed system as a set of related entities, each of which is characterized by a set of attributes and values taken by those attributes, along with relationships between those entities. Policies are then defined as constraints that limit the values that may be taken by the attributes or relationships between the entities. Cauldron allows systems to be modeled in an objectoriented manner, and permits design-constraints to be embedded within the model as policy statements. Note that
unlike software validation tools [2], [3], Cauldron is used primarily to generate valid configurations from model specifications, although it can also be used for validation purposes. We have used Cauldron to embed design and configuration policies in systems represented using the Common Information Model (CIM) [4] defined by Distributed Management Task Force (DMTF) [5]. CIM is an object-oriented model that defines how managed elements—ranging from physical devices and computer systems to applications— are modeled to facilitate integration between management systems. Note that Cauldron is independent of CIM and can represent most objectoriented models. In this paper, we will use CIM as a representative object-oriented model and show how concepts from CIM have been extended by the notion of policies to enable policy-based system design. The basic assumption is that a base type model is specified in a format akin to CIM. The rest of this paper is organized as follows. Section II describes the basic structure of Cauldron. Section III describes the Cauldron language, and how various object-oriented constructs are defined using Cauldron. The theory underlying Cauldron is described in Section IV. We describe the results of some evaluations using Cauldron in Section V. Section VI describes related work. We finish with a summary and a description of future work in Section VII. II. CREATING A DESIGN USING CAULDRON As shown in Fig. 1, we introduce configuration design constraints as policy statements within CIM by extending the CIM_Policy class. A Cauldron policy is a class-scoped obligation policy that has to be obeyed by all instances of the class defined in the policy instance. A configuration is considered valid if all policy assertions associated with that configuration are true.
Figure 1. Policy model used in Cauldron
The input to Cauldron is the set of class definitions with attributes and relationships (e.g., composition, association, references, and super-types), along with instances of policy constraints. A pre-processor combines the policy instances with the appropriate class definitions to embed the appropriate constraints within the class definitions as satisfy clauses (see
Section III.D). The constraints combine class attributes and relationships using a subset of first-order logic and linear arithmetic. The user request is rooted in the special class main. Cauldron tries to produce an instance of the class main along with instances of other classes, as necessary, so that all constraints specified in the resulting class instances are satisfied, along with constraints implicit within the Cauldron language itself. This enables the user to generate custom designs by requesting (in main) instances of one or more classes and some user specific policies to be obeyed by the resulting instances. III. CAULDRON AND OBJECT-ORIENTED MODELING In this section we will describe various features of Cauldron. Cauldron uses a much more compact representation of the object hierarchy than the Managed Object Format (MOF) used within CIM. A pre-processor is used to translate MOF into the Cauldron representation. A. Classes and Attributes A class is represented within Cauldron as a “structure type”, which is a class name followed by a list of typed attributes (fields) that belong to that class. Thus for example, Server { cost: float; }
could represent a server with a cost value attribute. Any instance S of this structure type would have a cost value associated with it, which would be written “S.cost”. That is, S.cost would be a numeric value. All primitive types within CIM are mapped to corresponding types within Cauldron. Additionally, Cauldron supports ranges of integers and userspecified enumerated types. Thus enum ServerType {itanium, x86}; TypedServer { id: 0 .. 50; serverType: ServerType; }
restricts id to be an integer in the range [0,50], and defines serverType as an enumerated field that can contain either the value “itanium” or “x86”. B. Composition and Inheritance Composition is represented within Cauldron using fields of structure types— fields whose values are other structures. For example, suppose that a Server is composed of a Computer and an Application. In Cauldron, we would then define the structure type Server to have two additional fields: Server { cost: float; comp: Computer; app: Application; }
Here, Computer and Application would be defined, in turn, as structure types with their own fields, representing their attributes and sub-sub-objects.
Subclassing is represented using Java-style inheritance of Cauldron structure types. For example, our CIM model might involve a DataServer, which is composed of a computer, an application, and a database. Rather than representing a DataServer in Cauldron as an independent structure type: DataServer { cost: float; comp: Computer; app: Application; data: Database; }
we can represent it by extending the structure type Server: DataServer extends Server { data: Database; }
With this latter definition, every instance DS of a DataServer will have four fields defined: DS.data will be a Dababase, DS.comp will be a Computer, DS.app will be an Application, and DS.cost will be a number— the latter three fields being inherited by DataServer from the superclass Server. When Cauldron is successful on a design problem, it produces, as its output, a collection of structures whose fields have defined values. The structures in this collection are required to form a tree, without sharing of substructures. For example, suppose that we asked Cauldron to design a datacenter composed of two DataServers, main { s1: DataServer; s2: DataServer; }
and that Cauldron succeeded in producing an instance of the structure type main, which we’ll refer to as main0. The structures of type DataServer representing main0.s1 and main0.s2 would have to be distinct and the structures of type Computer representing main.s1.comp and main.s2.comp would also have to be distinct. Cauldron's goal is to produce a structure main0 of the distinguished type main together with (recursively) all the other structures that main0 requires, and with all of the attributes of all of those structures appropriately chosen. C. Abstract Classes Cauldron supports the notion of abstract classes. Suppose we extend the structure type Server to define HardwareServer and VirtualServer: HardwareServer: extends Server { ... // hardware server specific attributes }; VirtualServer: extends Server { ... // virtual server specific attributes };
Now, we want each requested server to be either a hardware server or a virtual server. This can be accomplished by redefining Server to be an abstract class:
abstract Server { cost: float; comp: Computer; app: Application; }
The Cauldron engine will now ensure that whenever an instance of Server is required, a subclass that is not abstract (a HardwareServer or a VirtualServer in this case) is used instead. This enables the abstract class to be annotated with policies common to all servers, while placing type-specific policies in the refined classes. The user can simply request an instance of the abstract class, and Cauldron will select an appropriate (non-abstract) sub-class that meets the desired policies. D. Policy Constraints There are policies of many flavors that constrain a systemdesign problem. Cauldron encodes class-scoped policies as satisfy clauses embedded in the definition of a structure type. A satisfy clause constrains all instances of that structure type as well as all instances of any of its subtypes. For example, we might augment the definition of Server above with the policies Server { cost: float; comp: Computer; app: Application; satisfy cost == comp.purchaseCost + app.licenseFee; satisfy cost