At the heart of the Dynamic System Initiative is the System Definition Model, an XML-based modeling language used to capture formal representation of systems. More precisely, the SDM is a meta-model used to create models of a distributed system, including all information pertinent to its design, deployment, and ongoing operations.
The SDM provides enterprise customers, vendors, system integrators, and administrators the capability to create a dynamic "living blueprint" of their system. This blueprint can be used not only to describe the system, but also to actively facilitate its development, deployment, and ongoing operations.
The SDM defines the structure of the distributed system and maintains data about its various elements and how they relate to one another. In addition, the behavioral tasks of the system are captured. This includes the operational tasks that can be applied to the system as well as the constraints of the system: the rules or policies that must remain true in order for the system to be considered operational.
SDM models of distributed system elements can be defined in advance and made available through Microsoft or (eventually) non-Microsoft tools. For example, Visual Studio Team Edition for Software Architects ships with SDM models for web services, ASP.NET applications, IIS6, SQL Server, and Windows Application, among others. These predefined SDM prototype models may be further modified to support a particular element of a connected system. Along with these models are the necessary supporting tools such as the SDM Compiler (more on this later).
The benefits of SDM are as follows:
Communication: Using a single systems definition language enables developers and operations teams to communicate on common ground. Developers are able to communicate application requirements of the run-time environment, and operation teams can communicate application runtime, connectivity, and security requirements expressed in the target deployment environment's policies. With the SDM, architects can fully specify systems and polices in their designs. Reducing the level of misinterpretation when systems are implemented mitigates one of the biggest challenges in traditional software modeling: their limited utility to developers in real-world situations.
Extensibility: SDM is designed to be extensible and makes it possible for users to add or modify any system definitions. Users can add other types of applications, logical servers, or resource types created by Microsoft, third parties, or other users.
Efficiency: By capturing knowledge of the system at design time and "flowing" that knowledge through the entire life cycle of the system, developers can more readily create and deploy solutions that result in reduced costs, improved reliability, and increased responsiveness across the entire IT life cycle.
Design-time validation: The most evident benefit of SDM in Team Architect is to facilitate, at design-time, validation of a connected application against its target deployment environment. This design for deployment scenario is further described in this chapter and in Chapter 3 in this book.
This section provides a high-level overview of the SDM architecture, terminology, and basic elements of SDM and how they relate.
The configuration of connected systems and the interactions between their elements can be modeled using the System Definition Model (SDM) language.
At a high level, SDM is governed by an object-relational model. Objects are used to represent both the physical and logical elements in the modeled system and to specify the links between them. Objects and relationships are further classified to capture semantics important to the SDM. The definitions of these objects and relationships provide a way to create reusable configurations of resources and systems, much like classes in an object-oriented programming language. Abstractions of these objects help describe characteristics common (and largely immutable) to these object and relationships categorizations. For example, a characteristic that all SDM objects must have is support for a containment relationship; that is, an object should be able to contain other objects. This relationship is captured in an abstract definition from which all SDM objects can derive. In this way, abstractions provide meta-modeling support — they help model possible models. More pragmatically, abstract definitions enable tool support for a large number of applications, and are the basis for type checking at design time. There are two abstract definition types: abstract objects and abstract relationships. Abstract object definitions are the building blocks of a modeled system. Every entity in a modeled system is represented by an abstract object. Abstract relationship definitions model the interactions that can occur between abstract object definitions, and therefore identify the types of the instances that participate in the relationship. Abstract relationships provide a way to bind objects together in order to model, for example, their containment and communication relationships.
All abstract definitions have the ability to expose settings. These settings are basic name-value pairs that use XML schema to define the type or definition of the setting (such as Name=MyWebApp). Settings can be static or dynamic. Static settings can only be set during the deployment process. Dynamic settings can be changed after deployment
In Chapters 2 through 4, you saw such settings exposed to the user via the Settings and Constraints editor.
In addition to the meta-modeling support provided by abstract objects and relationship definitions, SDM also supports a set of core models used as the basis for defining real-world application or datacenter objects. Like building blocks, these core models simplify the design process of resources and help ensure consistency in the basic properties and behaviors associated with such basic types as user, file, and computer — a core model that may describe settings, relationships, and operations common to all computers.
Core models are derived from abstract definitions. As such, they cannot be directly instantiated or contain object or relationship members. Nonetheless, they represent real-world (albeit incomplete) types of objects. To emphasize this distinction, we will sometimes use the term concrete definitions to describe core models. You can view a concrete definition as a real-world reusable template of the abstract definition. Put another way, you can consider the concrete definition space a subset of the abstract object space. You can use the concrete space to create a reusable configuration based on one or more abstract definitions. Concrete definitions supply implementations for a specific abstract definition that includes extensions to the settings schema, values for settings, declarations for type and relationship members, and constraints on the relationships in which the type can participate.
A real-world instantiation of the concrete definition is called an instance. A distributed system is then built from collections of these instances. Instances come from a mix of sources and are typically associated with applications or datacenter infrastructure. Instances may result from models that ship with Team Architect — called built-in or prototype definitions (see C:/Program Files/Microsoft Visual Studio 8/Common7/IDE/ PrivateAssemblies), they may come from third-party libraries or online depositories, or they may be user defined. Microsoft's goal is to build into the SDM and tools a set of these core models that will entice users to create libraries of refined definitions. For example, under an SDM computer library (in which all models derive from a "computer" core model), you may find SDM descriptions for various models of Dell laptops, HP servers, and Apple devices. Manufacturers, companies, or individuals may refine these computer library models by describing standardized configurations for their datacenter around CPU, memory, and OS. Others may take a set of generic SDM computer component models (perhaps from other libraries) and build a computer for individual use. Each instance of these configured models would be unique. This concept is illustrated in Figure 7-1.
Constraints specify restrictions on the permissible set of relationships in which an instance can participate. They capture fine-grained requirements that depend on the configuration of objects involved in a relationship. For example, a constraint can be used to validate that participants on each end of a communication protocol are using compatible security settings.
Managers are used to both provide customized behavior to the runtime and to support interaction between the modeled system and the runtime. Managers are required for custom constraints.
An SDM document is the source XML file (.sdm) containing one or more definitions, resources, endpoints, and relationships.
The SDM Compiler validates the format, references, and constraints of an SDM document (.sdm). The compiler takes as input one or more SDM documents, executes a set of validation steps, and returns a set of errors. If successful, the compiler outputs a compiled and signed SDM file (.sdmDocument).
After the SDM file passes the compiler's initial load and validation processes, the compiler checks for constraints and flow. It does this by simulating an instance space for the SDM types given. The instance space captures both the current and desired state of the SDM defined application. Changes in the instance space are initiated by change requests.
A change request is initiated either through a declarative XML description or through APIs that enable the request to be constructed. A change request represents a set of create, update, or delete requests for objects and relationships associated with specific members of an existing instance.
Finally, the SDM run-time represents an extended version of the SDM Compiler. It provides a set of processes and components responsible for consuming and validating SDM files, loading associated binary information (files) and any third-party Microsoft Windows Installers (MSIs), generating and executing SDM change requests, and deployment of SDM-based applications into target, distributed server environments. The SDM run-time contains the deployment engines, the SDM Object Model APIs, and the Instance Space — the store of types, instances, and relationships relevant to the applications scoped by the current modeled system. By using the version history maintained by each instance, which is linked to each change request, the SDM run-time is able to maintain a complete account of each instance created as well as the relationships between these instances.
Currently, the runtime allows applications and hosting environments described using the SDM to be defined and validated in Team Architect. This is called design-time validation. In future Microsoft product releases, the runtime is expected to manage the loading of SDUs, SDM change requests, and deployment to a set of servers.
Because an SDM model captures the structure of the system, the relationships between a system's components, the settings and constraints of the system, and any operational task that can be performed on the system, SDM-based deployment and operational tools can be created to manipulate the model and not the real world.
Starting with Team Architect, users can model their distributed application and datacenter for design-time validation to ease deployment and operations. Users then request SDM validation within Team Architect during development to further ensure that the application being developed can be deployed.
Future versions of Visual Studio are expected to take SDM beyond design-time validation to help facilitate deployment and provide post-deployment handling of operational requests. Rather than directly manipulate real-world systems, users will have the capability to validate a change request within the simulated SDK environment and rely on adapters to effect the changes to these systems. Figure 7-2 shows the relationship between the system administrator, SDM models, and the real-world systems that future evolutions of DSI will support.
In the near future, you can also expect SDM to assist in the health monitoring of deployed applications. For example, if a problem occurs in the datacenter, adapters can send SDM documents reflecting the current state and configuration of the servers back to the Team System tools for immediate consideration.
As you work with SDM, you may wish to extend existing models and develop new models not supported natively in the first release of Team Architect. These new models may describe custom definitions for your connected system or datacenter, or capture third-party products or technologies. If that's the case, you'll want the capability to author Visual Studio Team Edition for Software Architect providers that plug in to the design surfaces and relevant user interfaces for the new models. This will enable you to use the design surfaces to load, compose, extend, and validate — and possibly provide code-generation capabilities with — these new models. This extensibility will enable you to better capture the breadth of your own distributed systems, thereby further reducing the development and operations communication gap. This capability will be provided through the SDM SDK discussed later in this chapter.
Figure 7-3 illustrates the principal flow of SDM in Team Architect.
Although the current SDM tools will not automate the actual deployment and versioning of distributed applications, Team Architect provides the capability to generate a deployment report of all required application and datacenter configuration settings. You can use these reports to create a script for custom deployment. In Figure 7-4, each step of the SDM deployment is presented.
SDM uses a four-layered approach to further represent the structure of distributed systems. These layers include the application, the application hosting environment, the network and operating systems environment, and lastly the hardware. These layers reflect the traditional role boundaries of IT professionals.
Each of these layers represents a set of definitions (resources, endpoints, subsystem) particular to the objects modeled in that layer. For example, the application layer may include web application and database system definitions, while the application hosts layer includes definitions related to IIS or SQL. The operating system layer may further include definitions for file systems and network devices. Some definitions may not be assigned to layers and will instead be usable across a range of layers.
Objects in one layer can describe constraints on the layers above or below. A system at one level is then bound to and validated against a system at the other level. Therefore, an application system defined at the application layer can be bound to or hosted on a logical server defined at the level below, the application host layer. Both the application system and the logical server on which it is hosted can describe constraints on the other. Thus, a mapping of one layer to another — in this instance, referred to as a system deployment definition — can be validated. Team Architect includes the SDM Compiler that checks the definitions of each entity defined in each layer and then checks the validity of the bindings between elements in adjacent layers. For example, the SDM Compiler will validate whether an ASP.NET 2.0 web application with a dependency on Windows Server 2003 SP1 is compatible with an IIS6 host deployed on Windows Server 2003 without SP1. This example would result in the compiler issuing an alert to the Visual Studio user that an OS incompatibility exists between the web application and its target host.
Team Architect supports only the top two layers of the DSI model, the application layer and the application host layer. Later releases of DSI supported tools and servers will include support for the remaining two levels, including support for deployment and management of distributed systems. Figure 7-5 illustrates the relationship between the SDM layers.
In Figure 7-5, the application layer describes the structure and behavior of application systems. The application host layer underneath describes a logical model of the application hosts, such as IIS and SQL Server. The term "logical" is used to indicate that elements described in the application host layer are scale-invariant — a single SDM modeled element, such as an IIS6 host, may represent one physical IIS6 box or a farm of IIS6 boxes, each sharing the same (pre-deployment) settings and constraints. The arrows between layers illustrate that the setting and constraints of an element in the application layer can be compared or validated against those of its intended logical host.
It is not yet clear whether future versions will allow comparisons directly between non-adjacent layers. However, it may be the case that such a detail, regardless of implementation, would make little difference in overall validation behavior.
As you would expect with any object-oriented technology, SDM relies on a type system for defining the behavior and structure of instances. At the highest level, the SDM type system categorizes types into simple types and complex types. Complex types represent those instances that have a unique identity, and thus are comparable to complex types in object-oriented terminology.
Simple type instances have no unique identity and can only exist within the context of a complex type instance. A simple type holds values, so you can generally think of a simple type as being a "value type." An example of a simple type could be a binary representation of data. Simple types are further refined into user-definable predefined simple types, enumeration types, and struct types. Predefined simple types may include integers (such as 4, 5, 9) and strings (such as "Hello, SDM World"). Like the Common Language Runtime (CLR), SDM defines a number of unalterable primitive types that form the basis of all other SDM types. However, through SDM's XML Schema Definition (more on this below) you can define a new SDM simple type to restrict the value space of a predefined type — for example, an integer type whose values lie between 50 and 99.
You can see the simple types the SDM relies on from the CLR by viewing the System.sdm document in NotePad (C:/Program Files/Microsoft Visual Studio 8/Common7/IDE/PrivateAssemblies/ System.sdmDocument).
Complex types are further categorized into class types and interface types. As with object-oriented methodology, SDM treats the class type as the most fundamental building block of an SDM system. A class type is a description of a set of objects that have the same structure, behavior, and semantics. An instance of a class type is an object. For example, instances of a Dir (i.e., directory) class type are objects (each representing a file or other directories), each with a unique identifier (the directory name and path).
In Visual Studio 2005, most SDM classes are hidden. The developer uses the SDM schema to create instances of these class types. Classes that are accessible (that is, public APIs) are those called by the SDM tools SdmC.exe, SdmG.exe, the Visual Studio 2005 design surface, and those related to the Manager class (more on this later).
Each class can have zero or more properties. A property is a named structural feature member of a class. Every property must contain a simple type. The property can manage single or multiple values. For multi-valued properties, lower and upper bounds can be specified via lower and upper attributes (e.g., MinOccurs, MaxOccurs attributes of the ObjectMember complex type).
Each class can also contain zero or more methods. A method represents code that solves a particular problem for a class or supports a particular behavior of a class. A method is defined by a set of formal parameters and a return value. Because SDM is not a programming language, the implementation of class methods must be done in an external programming language such as C# or Visual Basic .NET. (As of this writing, it is not clear yet whether other .NET languages will be supported by Visual Studio 2005.) An example of a method is the C# or Visual Basic .NET Compile method defined in the Compiler class. This class is part of the SdmCompile.dll assembly and is defined by the namespace Microsoft.SystemDefinition Model.Tools. The Compile method takes no parameters, is used by SdmC.exe to compile a SDM document (.sdm), and returns True if an error occurred during compilation; otherwise it returns false. In C#, the API signature is the public Boolean Compile().
In the SDM world, types are defined through type definitions. Like class inheritance, new types are defined based on existing type definitions. Type definitions may be nested, and they rely on enumeration types. Types may also use modifiers to define the characteristics of the type. As an example, the modifier abstract signifies that instances cannot be directly created from this type. Only non-abstract types that derive from this type can have direct instances.
In sum, an SDM type definition is similar to a class in that it defines the structure and behavior of an instance of that class.
The following sections describe the definition of these types in terms of their SDM schema. Following that, the instance space of these definitions is explored.
XML-based languages follow a set of grammar rules that define, for example, what types are allowed and what child elements a particular element may have. These definitions are captured in a file called (unsurprisingly) an XML Schema Definition, and have the file extension .xsd. The SDM is also an XML-based schema built upon the SDM type system. The SDM schema captures reusable configurations of a modeled system element that can be instantiated to create instances of that configuration. These configurations include definitions for member types and relationships, and define the settings required to act on the modeled instance.
By looking into the SDM schema (C:/Program Files/Microsoft Visual Studio 8/Common7/ Packages/SDM/Schema/SystemDefinitionModel.xsm), you can see the schema for each SDM type discussed in the architecture section.
All abstract and concrete objects (complex types) derive from a common root-level type definition called Definition. Objects, relationships, setting, and constraint definitions all extend from Definition. For example, the abstract definitions ObjectDefinition and RelationshipDefinition derive from Definition. SystemDefinition, EndpointDefinition, and ResourceDefinition derive from ObjectDefinition. The definitions HostingDefinition and ContainmentDefinition derive from RelationshipDefinition.
The definitions associated with settings and constraints do not use the base Definition but instead have their own base definitions, which are discussed in the Settings and Constraint sections that follow. Figure 7-6 relates the Object complex type definitions to the Distributed System Designers.
In the top-right box of Figure 7-6, two .NET projects are visualized as boxes in the Application Designer tool of Team Architect. Each is defined by an SDM (.sdm file). Both My_Web_Application and My_DB_Resource represent Object Instance definitions. They've been created by dragging and dropping the ASP.NETWebApplication concrete object (MicrosoftWebApplication:WebApplication) and ExternalDatabase concrete object (MicrosoftDatabase:Database) from the Application Designer toolbox to the design surface, configuring any and then implementing the design into code. Concrete objects are assembled from Abstract Object definitions of System, Endpoints, and Resources.
In the second row, a relationship is shown between an ASP.NETWebApplication and an ASP.NET WebService. The latter is also extended from MicrosoftWebApplication:WebApplication but with different settings and constraints. Although both are derived from the same concrete object, they are represented as two distinct components in the Application Designer toolbox that can be further customized. Each of these components in the toolbox is therefore called a prototype.
Relationships between these object instances can then be described via their endpoint instances. In the center-right box, these endpoints indicate the relationship MyWebService has between My_Web_Application and My_WebService_App.
The last row illustrates meta-data that further defines (configures) the policies or restrictions an object may have. In this example, an IIS Read constraint is placed on My_Web_Application.
Each definition is identified by a simple name. These (SDM) names are scoped by the namespace in which they are defined. A namespace is identified by a name, version, language, and public key token, and is contained within a single file. To uniquely identify a persisted definition (a definition "instance"), each identity includes a name, version, culture, platform, and public key token.
The SDM run-time allows namespaces to reference other namespaces by importing them into the current namespace and then associating an alias with the imported namespace. The imported namespace is referenced by name and version (and possibly by public key token).
The following list describes some of the elements in the definition schema that can be set with some simple values. All definitions can include a description, setting members, setting values, and design surface data:
Description: A text description of the definition.
SettingDeclaration: Contains the base definition for a setting member.
SettingValue: A value for a setting on the definition or its base definition. A value can only be provided once for a setting declaration within a definition.
SettingValueList: A list of values of the same type as the setting declaration.
DesignData: Design-surface-specific information about an object, relationship, constraint, or flow definition.
Name: A name for this definition that is unique within the scope of the containing SDM file.
Manager: A reference to the manager declaration for this definition.
ClrClassName: The name of the CLR class that supports this definition in the runtime. The class must exist in the assembly identified by the manager. The manager attribute must be present if this attribute is present.
The structure of the SDM Definition schema looks like this:
<xs:complexType name="Definition"> <xs:sequence> <xs:element name="Description" type="Description" minOccurs="0" /> <xs:element name="DesignData" type="DesignData" minOccurs="0" /> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="SettingDeclaration" type="SettingMember" /> <xs:element name="SettingValue" type="SettingValue" /> <xs:element name="SettingValueList" type="SettingValueList" /> </xs:choice> </xs:sequence> <xs:attribute name="Name" type="SimpleName" use="required" /> <xs:attribute name="Manager" type="QualifiedName" use="optional" /> <xs:attribute name="ClrClassName" type="xs:string" use="optional" /> </xs:complexType> <!--
The following is an excerpt of the DesignData complex type and ManagerDeclaration complex type elements from the Microsoft.Web.sdmDocument model shipping with Visual Studio 2005:
<DesignData> <VisualStudio xmlns= "http://schemas.microsoft.com/SystemDefintionModel/ 2005/1/DesignData/VisualStudio"> <ModelElement Type="Microsoft.VisualStudio.EnterpriseTools. LogicalInfrastructureDesign.Modeling.HostLayerDocument"> <PropertyName="DocumentType" Value="AbstractTypes" /> </ModelElement> </VisualStudio> </DesignData> <ManagerName="WebManager" AssemblyName="Microsoft.Sdm.Web" Version="1.0.41013.0" PublicKeyToken="31B3856AD364E35" Culture="neutral" SourcePath="Microsoft.Sdm.Web.dll" />
The complex type ObjectDefinition provides the abstract and concrete definitions for the objects that form the software and hardware building blocks for systems, and captures structure and behavior at a global level. ObjectDefinition is derived from the base definition. It includes elements for object members (derived from Member complex type) and object relationships (derived from RelationshipDefinition complex type). In addition to these, ObjectDefinition types share the ability to constrain the relationships in which the objects participate.
Attributes of this definition are as follows:
Layer: Supplies the modeling layer for which this abstract object definition can be used. If there is none, then the abstract object layer can be used in any layer. This attribute helps determine which designer can reference the object. In Visual Studio 2005, valid values are Application for the Application Designer and ApplicationHost for the Logical Datacenter Designer.
Extends: Provides the base object definition from which this object definition derives. If provided, the abstract object definition then inherits the settings and relationship constraints from that base object definition.
Abstract: Specifies whether this object can be instantiated. If the object is marked as abstract with Boolean value true, then the definition must be extended in order to fill in missing elements. The default value is false. Users of Team Architect need never to worry about this distinction. Users can only place abstract objects on the design surface and Visual Studio will automatically promote these objects to concrete upon output (i.e., all SDM objects represented in the Solution Explorer are concrete).
In addition to these attributes are numerous child elements. These elements and respective types define various parent-child, client-server, guest-host, and other relationships this object may have with other complex types. The following code illustrates the structure of the ObjectDefinition schema:
<xs:complexType name="ObjectDefinition"> <xs:complexContent> <xs:extensionbase="Definition"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Flow" type="FlowMember" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="RelationshipConstraintGroup" type="RelationshipConstraintGroup"/> <xs:element name"RelationshipConstraint" type="RelationshipConstraint"/> <xs:element name"Constraint" type="ConstraintMember"/> <xs:element name"ConstraintGroup" type="ConstraintGroup"/> <xs:element name"EndpointDefinition" type="EndpointDefinition"/> <xs:element name"SystemDefinition" type="SystemDefinition"/> <xs:element name"ResourceDefinition" type="ResourceDefinition"/> <xs:element name"CommunicationDefinition" type="CommunicationDefinition"/> <xs:element name"ContainmentDefinition" type="ContainmentDefinition"/> <xs:element name"DelegationDefinition" type="DelegationDefinition"/> <xs:element name"ReferenceDefinition" type="ReferenceDefinition"/> <xs:element name"HostingDefinition" type="HostingDefinition"/> <xs:element name"Endpoint" type="EndpointMember"/> <xs:element name"Subsystem" type="SystemMember"/> <xs:element name"Resource" type="ResourceMember"/> <xs:element name"Hosting" type="HostingMember"/> <xs:element name"Containment" type="ContainmentMember"/> <xs:element name"Connection" type="CommunicationMember"/> <xs:element name"Delegation" type="DelegationMember"/> <xs:element name"Reference" type="ReferenceMember"/> <!--flow --> <!--constraints --> <!--nested definitions --> <!--object /relationship members --> <!--flow--> </xs:choice> <xs:attribute name="Layer" type="xs:string" use="optional"/> <xs:attribute name="Extends" type="QualifiedName" use="optional"/> <xs:attribute name="Abstract" type="xs:boolean" use="optional"/> </xs:extension> </xs:complexContent> </xs:ComplexType>
Further classifications of ObjectDefinition are provided for systems, resources, and endpoints:
<xs:complexType name="SystemDefinition"> <xs:ComplextContent> <xs:extension base="ObjectDefinition"> <xs:attribute name="SimulationRoot" type="xs:boolean" use="optional" /> </xs:extension> </xs:complexContent> </xs:complexType <xs:complexType name="EndpointDefinition"> <xs:ComplextContent> <xs:extension base="ObjectDefinition" /> </xs:complexContent> </xs:complexType <xs:complexType name="ResourceDefinition"> <xs:ComplextContent> <xs:extension base="ObjectDefinition" /> </xs:complexContent> </xs:complexType
The SystemDefinition complex type is derived from ObjectDefinition and adds support for the following: endpoint, system, and resource types; endpoint, system, and resource members; and host, containment, connection, delegation, and reference relationships. Examples of a SystemDefinition attribute and schema element are provided as follows.
SimulationRoot: Determines how the definition should handle design-time checking (simulation) during compilation of the SDM document. This Boolean attribute is optional and is false by default. As such, it may not appear in the output. It is doubtful a beginning Visual Studio 2005 SDM developer will ever need to set it.
DesignData: In the following example, the Report element enables this system to be outputted in the Application section of the DeploymentReport.
These additional elements can be seen in the following schema snippet. Note the Name, Description, DesignData, SettingDeclaration, and SettingValue elements inherited from the Definition complex type:
<SystemDefinition Name="MySdkSystem" Layer="Application" Abstract="true"> <Description>My Sdm SDK System</Description> <DesignData> <Report Type="Application" xmlns="http://schemas.microsoft.com/ SystemDefinitionModel/2005/1/DesignData/DeploymentReport"/> </DesignData> <!-- Add Settings (Members) to this System --> <SettingDeclaration Name="SystemName" Definition="String" CanBeNull="true"/> <SettingValue Path="SystemName">SDK Authored System</SettingValue> <SettingDeclaration Name="Version" Definition="String" CanBeNull="true"/> </SystemDefinition>
The EndpointDefinition complex type is also derived from ObjectDefinition and provides support for abstract endpoint definitions, and facilitates communications within the system. An example of an "abstract" WebService definition (from Microsoft.Web.sdmDocument) is provided here:
<EndpointDefinition Name="WebService" Layer="Application" Extends="System:EndpointDefinition" Abstract="true"> <Description> <Entry Name="DisplayName">WebServiceEndpoint</Entry> </Description> <DesignData> <VisualStudio xmlns="http://schemas.microsoft.com/SystemDefinitionModel/ 2005/1/DesignData/VisualStudio"> <ModelElement> <Property Name="PrimaryRelationshipName" Value="HostingDefinition" /> <Property Name="PrimaryRelationshipRole" Value="Guest"/> <Property Name="DefaultRootName" Value="WebService1" /> <Property Name="ThemeColor" Value="145, 137, 213" /> <Property Name="ImageFileName" Value="WebServiceEndpoint.emf" /> <Property Name="Geometry" Value="WebService" /> </ModelElement> </VisualStudio> </DesignData> </EndpointDefinition>
The preceding properties show that the main relationship between the endpoint described above and its WebService Application is a hosting relationship. Because the object is defined at the application layer, the application is considered the host and the endpoint plays the role of the guest. If the layer were ApplicationHost, the roles would be viewed in reverse by the Logical Datacenter Designer. When the endpoint is created (dragged onto the design surface), the default name displayed is "WebService1." The endpoint is displayed as a circle.
The ResourceDefinition complex type is also derived from ObjectDefinition and adds support for resource type definitions, resource members, and host, containment, and reference relationship members. You should consider ResourceDefinition objects if they may be reused in many different configurations, if the resource object is not a stand-alone solution but used with other objects, and/or the object does not have communication relationships with other objects.
An example of a "concrete" Resource declaration found as part of a WindowsApplication.sdm file in the Solution Explorer is shown here. The NetSectionGroup definition is also used in other SDM definitions:
<Resource Name="NetSectionGroup" Definition="WindowsApplication1.Directory.Configuration .NETSectionGroup" MinOccurs="1" MaxOccurs="1" Reference="false"> <DesignData> <VisualStudio xmlns="http://schemas.microsoft.com/SystemDefinitionModel/ 2005/1/DesignData/VisualStudio"> <ModelElement> <Property Name="DisplayName" Value="NetSectionGroup" /> <Property Name="CreatedByUser" Value="true" /> </ModelElement> </VisualStudio> </DesignData> </Resource> <Containment Name="NetSectionGroupContainment" Definition="MicrosoftConfiguration:ConfigurationContainsNetSectionGroup" ChildMember="NetSectionGroup" /> </ResourceDefinition>
A ResourceDefinition, like any other ObjectDefinition derived complex type, may extend from existing definitions, as illustrated by the following example:
<ResourceDefinition Name="Directory" Extends="MicrosoftFileSystem:Directory">...
The RelationshipDefinition complex type defines the associations between systems, resources, subsystems, and endpoints by adding object constraints and flow to the base definition. Relationship members are used to define the relationships that object members will participate in when they are created. Like the ObjectDefinition complex type, the RelationshipDefinition defines the attributes Abstract and Extends. It also has similar elements for defining child relationships such as hosting, containment, and delegation, but it includes additional elements and respective types such as Flow, which may contain a FlowMember complex type instance that provides the instances participating in the transformation of values between themselves. The following example shows the RelationshipDefinition complex type schema:
<xs:complexType name="RelationshipDefinition" > <xs:complexContent> <xs:extension base="Definition"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="ObjectConstraintGroup" type="ObjectConstraintGroup" /> <xs:element name="ObjectConstraint" type="ObjectConstraint" /> <xs:element name="Constraint" type="ConstraintMember" /> <xs:element name="ConstraintGroup" type="ConstraintGroup" /> <xs:element name="Flow" type="FlowMember" /> <xs:element name="Connection" type="CommunicationMember" minOccurs="0" maxOccurs="unbounded" /> <xs:element name="Hosting" type="HostingMember" /> <xs:element name="Delegation" type="DelegationMember" /> <xs:element name="Reference" type="ReferenceMember" /> <xs:element name="Containment" type="ContainmentMember" /> </xs:choice> <xs:attribute name="Extends" type="QualifiedName" use="optional" /> <xs:attribute name="Abstract" type="xs:boolean" use="optional" /> </xs:extension> </xs:complexContent> </xs:complexType>
Five relationships are derived from RelationshipDefinition:
HostingDefinition: Captures the requirement that a guest object requires a host object in order to be constructed.
CommunicationDefinition: This is used to capture possible communication links between endpoint definitions. They are used to describe interactions between independently deployed software elements. Interactions between systems are explicitly modeled using communication relationships. In Visual Studio 2005, the most obvious example of communication is through ASP.NET Web services. (Other communication protocols can be modeled via your own custom SDM application and endpoints or via the GenericApplication and GenericEndPoints in the Application Designer.)
DelegationDefinition: This captures the fact that the source (outer) member will forward behavior to the (contained) object member. It states how pairs of abstract endpoint definitions can participate in the delegation.
ReferenceDefinition: A source member object has a dependency on an object member. The dependency captured between systems or resources may not be part of the execution environment of the dependent object, but may be required in order to achieve correct operation.
ContainmentDefinition: This states that an object member is contained by its parent. It implies that a parent instance can control the lifetime of the member instance.
A few of these relationships between objects located in the Application and Application Host layer are illustrated in Figure 7-7.
In this figure, a customer transaction database is hosted by an SQL 2005 server. The customer database is a guest on the server. It is therefore the server's responsibility to manage the life cycle of the database. A guest can be hosted by a number of (database) servers, as long as the guest has compatible configurations (i.e., behaves itself at the party). This database is also in communication with the ASP.NET application through Web services managed by SQL 2005.
A definition can contain member definitions. These member definitions are used to reference other definitions — and, in particular, members reference instances of a certain type. Members associate a definition name with a specific instance definition or array of instance definitions. This name is unique among all the members in the scope of the definition that includes the member.
Member definitions can also be used for setting configuration values, descriptions (Description), and data useful for a tools design surface (DesignData). Members can reference an array of instances and then specify the array's upper and lower bounds.
The root-level definition for members is the Member complex type. It is not derived from the Definition complex type. It has elements similar to Definition, but without the Manager and ClrClassname elements. Members can be customized depending on the kind of definition they reference. The Member complex type contains two attributes:
QualifiedName: This is typically a period-separated string name used to refer to definitions or members defined in an aliased (imported) namespace or an. sdm file's namespace. If the name does not include a period or is not an alias, then it is unqualified and will rely on the scoping rules to resolve. An example of an alias is as follows:
<Import Alias="WindowsApp" Name="Microsoft.WindowsApplication"/>
SimpleName: This may be used to supply names for members in an SDM definition.
Five complex types are derived from Member:
Object members: Used to create instances of a particular object definition. Object members reference abstract or concrete object definitions. The member can reference an array of instances that can be described in terms of lower and upper bounds. Values to objects can be obtained by flowing the setting values from one object to another.
Relationship members: Define the relationships (such as containment or hosting) that object members will participate in when they are created.
Setting members: Used to capture a definitions configuration.
Constraint members: Used to further define the set of relationships in which a particular object is willing to participate or the set of objects that can participate in a particular relationship.
Flow members: Used to define the flow of configuration between members. Flow members gather input values from settings on members, do some processing on that information, and then distribute the results to settings on members — on the same object or other objects.
Here are descriptions for some ObjectMember attributes:
MinOccurs: Defines the lower bound on the number of instances associated with this member. If it is zero, then the member is optional. The default is 1.
MaxOccurs: Defines the upper bound on the number of instances associated with this member. Must be one or greater. The default is 1.
Reference: If this attribute is set to false, the instance is created when the type is created. If it is set to true, the instance that is associated with the member must be explicitly created by the operator or referenced in another type.
Proxy: If this attribute is set to true, the object member represents a proxy, rather than a real instance in the target system. The Proxy attribute must be set to true in order to allow the member to participate in delegation relationships.
Following is the schema for the Member, ObjectMember, and RelationshipMember types:
<xs:complexType name="Member"> <xs:sequence> <xs:element name="Description" type="Description" minOccurs="0" /> <xs:element name="DesignData" type="DesignData" minOccurs="0" /> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="SettingValue" type="SettingValue" /> <xs:element name="SettingValueList" type="SettingValueList" /> </xs:choice> </xs:sequence> <xs:attribute name="Name" type="SimpleName" use="required" /> <xs:attribute name="Definition" type="QualifedName" use="required" /> </xs:complexType> <xs:ComplexType name="ObjectMember"> <xs:complexContent> <xs:extension base="Member"> <xs:attribute name="MinOccurs" type="MinOccurs" use="optional" /> <xs:attribute name="MaxOccurs" type="MaxOccurs" use="optional" /> <xs:attribute name="Reference" type="xs:boolean" use="required" /> <xs:attribute name="Proxy" type="xs:boolean" use="optional" /> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name="RelationshipMember"> <xs:complexContent> <xs:extension base="Member" /> </xs:complexContent> </xs:complexType> <!--
Settings maintain configuration information for system definitions. Unlike properties, which can be thought of as attributes that affect the design experience, settings are specific values used to control the behavior of the system. For Visual Studio 2005 Application and Logical Datacenter Designers, settings provide behavioral configuration for an application or the application's hosting environment.
You can declare settings when you create a definition by using the Setting members. Once declared, a constant value is assigned to define the default behavior of the definition in the system. You can modify these settings later using the Distributed System Designers Settings and Constraints Editor.
Settings are captured in the SDM file or, in the case of a WebApplication, within web.config files. When a WebApplication setting (for example, Application Pool) is edited, the changes are persisted back to both the SDM and web.config file.
All definitions can expose members for describing configuration values associated with that definition. Methods describe values using setting declarations to define the type of value and any behavioral attributes of the value. The following is the SettingMember schema:
<xs:complexType name="SettingMember"> <xs:complexContent> <xs:extension base="Member"> <xs:choice minOccurs="O" maxOccurs="unbounded"> <xs:element name="Facet" type="Facet" /> </xs:choice> <xs:attributeGroup ref="SettingsAttributes" /> </xs:extension> </xs:complexContent> </xs:complexType>
The runtime uses a number of attributes to describe the behavior of a particular setting. These attributes are maintained by the SettingAttributes Attribute Group. Here are a few attributes described in this group:
Access: Defines whether the setting's value can be read or written to by the SDM run-time or the designer editors.
Secure: Defines whether the value of a setting should be encrypted when stored to an SDM document.
DeploymentTime: Value used only as part of the deployment process for an instance. Not used for design-time constraints value evaluation.
Required: If this attribute is set to true, a value must be provided for this setting before deploying an instance.
The following is the SettingsAttributes schema:
<xs:attributeGroup name="SettingsAttributes"> <xs:attribute name="List" type="xs:boolean" /> <xs:attribute name="Access" type="SettingMemberAccess" /> <xs:attribute name="Secure" type="SettingMemberSecure" /> <xs:attribute name="DeploymentType" type="xs:boolean" /> <xs:attribute name="Required" type="xs:boolean" /> <xs:attribute name="CanBeNull" type="xs:boolean" /> <xs:attribute name="ElementsCanBeNull" type="xs:boolean" /> <xs:attribute name="DefaultRead" type="xs:boolean" /> <xs:attribute name="DefaultWrite" type="xs:boolean" /> </xs:attributeGroup> <xs:simpleType name="SettingMemberAccess"> <xs:restriction base="xs:string"> <xs:enumeration value="ReadWrite" /> <xs:enumeration value="ReadOnly" /> <xs:enumeration value="WriteOnly" /> </xs:restriction> </xs:simpleType> <xs:simpleType name="SettingMemberSecure"> <xs:restriction base="xs:string"> <xs:enumeration value="Always" /> <xs:enumeration value="PerInstance" /> <xs:enumeration value="Never" /> </xs:restriction> </xs:simpleType>
Values are provided for a particular setting declaration using setting value statements. A definition of the setting using xsd must be defined before a value is set, and the setting value must match or be able to be converted to the associated setting definition. Here is an example of a setting declaration for a new element Car, which must accept a string:
<SettingDeclaration Name="Car" Definition="String" List="false" CanBeNull="false"/>
Single-setting declaration values are provided using the SettingValue statement and can be used for both list and non-list values. When a new instance of a definition is created, the setting value statements are evaluated by the runtime to determine the initial values for the instance. For example, if the value is declared fixed, then the value provided will be used in all derived definitions. In the following example, the name of the SetttingDeclaration is specified by the Path attribute, and the lack of a set Fixed attribute specifies that the value Acura may be overwritten:
A SettingValueList statement is used to provide multiple setting values and may only be used against a setting attribute List = true declaration. The following example also signifies that values in this list cannot be changed and will replace, rather than merge with, the existing contents of the target's setting values:
<SettingDeclaration Name="Cars" Definition="String" List="true" CanBeNull="false"/> <SettingValueList Path="Cars" Fixed="true" Replace="true"> <Value>Acura</Value> <Value>Volkswagon</Value> </SettingValueList>
The following is the SettingValue, SettingValueList, and SettingValueAttribute schema:
<xs:complexType name="SettingValue" mixed="true"> <xs:sequence> <xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded" /> </xs:sequence> <xs:attributeGroup ref="SettingValueAttributes" /> </xs:complexType> <xs:complextType name="SettingValueList"> <xs:sequence> <xs:element name="Value" minOccurs="0" maxOccurs="unbounded"> <xs:complexType mixed="true"> <xs:sequence> <xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded" /> </xs:sequence> <xs:attribute name="Null" type="xs:boolean" use="optional" /> </xs:complexType> </xs:element> </xs:sequence> <xs:attributeGroup ref="SettingValueAttributes" /> </xs:complexType> <xs:attributeGroup name="SettingValueAttributes" /> <xs:attributename="Path" type="SettingPath" use="required" /> <xs:attributename="Null" type="xs:boolean" use="optional" /> <xs:attributename="Fixed" type="xs:boolean" use="optional" /> <xs:attributename="Unset" type="xs:boolean" use="optional" /> <xs:attributename="Definition" type="QualifiedName" use="optional" /> <xs:attributename="Convert" type="xs:boolean" use="optional" /> <xs:attributename="Secure" type="xs:boolean" use="optional" /> <xs:attributename="Replace" type="xs:boolean" use="optional" /> </xs:attributeGroup> <!--
You can use custom settings to define additional meta-data required to accurately model the system's development or deployment environment. Custom settings, however, can be used to restrict certain inputs. Rather than allow the SettingDeclaration Cars to take unrestricted strings, it is possible to restrict the strings to certain inputs by defining a new custom simple type that will provide validation for the settings. In the following example, allowable values are specified using the enumeration type:
<xs:simpleType name="AllowableCarNames"> <xs:restriction base="xs:string"> <xs:enumeration value="Acura" /> <xs:enumeration value="Ford" /> <xs:enumeration value="Volkswagon" /> <xs:enumeration value="Other" /> </xs:restriction> </xs:simpleType>
This example, like all custom setting declarations, requires a manager. Unlike regular settings, custom settings can be displayed in the Properties window.
A constraint is a requirement for a configuration value to be set in a particular way. These restrictions are evaluated in the instance space by the SDM run-time at both design time and, in future versions, at deployment time. Unlike the custom setting example earlier, all setting constraints use a constraint definition to evaluate the setting values.
Constraints in one SDM model layer may be applied against configuration settings and relationships in another layer. In this way, constraints connect or bind one layer to another. With the Distributed System Designers, constraints are used by developers to state their "requirements" of the datacenter and by operators to convey their "requirements" of the applications.
There are two kinds of constraints: constraints that set restrictions on settings (setting constraints ) and those that are constrained by the nature of their SDM structure (structural constraints ).
Structural constraints define the topology of the concrete object space and constrain the settings of objects participating in particular relationships. The StructuralConstraint complex type is the base type from which the complex types RelationshipsConstraint and ObjectConstraint are derived. The StructuralConstraint contains a description element and a design data element. The description element is returned with error messages should the constraint fail. A ConstraintEvaluation attribute determines when the constraint should be evaluated. The default is at design time. The RelationshipConstraint specifies the elements that constrain the relationships in which an object can participate.
The following RelationshipConstraint example shows a structural constraint whereby the abstract object definition ObjA needs to contain an instance of abstract object ObjB; and ObjA must play the role of parent and the type at the other end of the containment relationship must be of type ObjB:
<RelationshipConstraint name = "ObjAContainsObjB" relationship="ContainmentDefinition" myRole="parent" targetType="ObjB" minOccurs="1" maxOccurs="1" />
Setting constraints are made up of two parts: the constraint definition and the constraint member. The constraints specify values for a single setting or a group of them. Each setting constraint requires a constraint definition to evaluate the setting values. This evaluation is always done by a manager or code. The constraint definition uses settings declarations to identify the values it constrains.
A constraint definition specifies a reusable restriction that acts on a defined set of input values. The constraint can specify a set of nested relationships or object constraints that are evaluated in the context in which the constraint definition is being used, or the constraint can identify a manager that provides code to evaluate the input values. If a nested constraint is specified, the parent constraint evaluates to true only if all nested constraints evaluate to true. This is in contrast to constraint groups, where the entire constraint group can be true if only one of the nested constraints evaluates to true. This type has two attributes:
TargetDefinition: Identifies the definition to which this constraint will be applied. If a target definition is not supplied, the constraint is applicable to any object or relationship definition. A target definition must be supplied if this constraint definition contains object or relationship constraints or groups.
ReturnEarly: Determines whether a failed constraint should return early if part of a larger group of constraints.
Following are some of the elements associated with ConstraintDefinition:
Constraint: Identifies a list of input values for a particular constraint definition. Static values may be used for the settings along with input statements to bind a constraint setting to a path.
Input: Represents a list of inputs to the constraint. An input provides a path to the source setting value that will be sent to the constraint and constraint setting that will be set as a result. The source setting type and the constraint setting type must be compatible.
A constraint member associates a set of input values with a particular constraint definition. The setting value is transferred to the constraint before the constraint is executed by the SDM Compiler. Two attributes belong to this type:
Evaluate: A value that determines when the constraint will be evaluated. Possible values are Design and Never. The former will perform evaluation at design, deployment, or validation time.
RaiseError: A Boolean value of true is returned when the constraint catches an input value; otherwise, false is returned.
The following shows the schema for ConstraintDefinition and ConstraintMember:
<xs:complexType name="ConstraintDefinition"> <xs:complexContent> <xs:extension base="Definition"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="RelationshipConstraint" type="RelationshipConstraint" /> <xs:element name="RelationshipConstraintGroup" type="RelationshipConstraint" /> <xs:element name="ConstraintGroup" type="ConstraintGroup" /> <xs:element name="ObjectConstraint" type="ObjectConstraint" /> <xs:element name="ObjectConstraintGroup" type="ObjectConstraintGroup" /> <xs:element name="Constraint" type="ConstraintMember" /> </xs:choice> <xs:attribute name="TargetDefinition" type="QualifiedName" use="optional" /> <xs:attribute name="ReturnEarly" type="xs:boolean" use="optional" /> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name="ConstraintMember"> <xs:complexContent> <xs:extension base="Member"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Input" type="Input" /> </xs:choice> <xs:attribute name="RaiseError" type="xs:boolean" use="optional" /> <xs:attribute name="Evaluate" type="ConstraintEvaluation" use="optional" /> </xs:extension> </xs:complexContent> </xs:complexType> <!--
Following is a constraint definition for a simple comparison function that takes an operator and two arguments, evaluates the constraint, and finally returns success or an error:
<ConstraintDefinition Name=MyConstraint" Manager="MyManager" ClrClassName="MyCompany.MyManager.MyConstraint"> <SettingDeclaration Name="Limit" Definition="Int"/> <SettingDeclaration Name="ActualValue Definition="Int" Nullable="true"/> </ConstrainDefinition>
A constraint member is used to provide the values to the constraint type for evaluation. In this example, a specific constraint called FileSizeLimit is used to ensure that each file (guest) does not go beyond a certain limit:
<RelationshipConstraint Name="HostedFiles" RelationshipDefinition=" DirHostsForD" TargetRole="Guest" > <Constraint Name="FileSizeLimit" Definition="MyConstraint"> <Input Name="Limit" Path="FileSizeRestriction"/> <Input Name="realValue" Path="HostedFiles.Guests"/> </Constraint> </RelationshipConstraint>
Another type of member called FlowMember is used to flow or pass parameters between members of an object definition and between objects participating in a relationship. This enables the user to transform another member or object's setting values. FlowMember defines two elements: Input and Output. Input contains a list of setting value paths used as input to the flow. Output contains a list of settings that contain the results of this process flow.
Each setting flow member must use a flow definition type to implement the transformation. This FlowDefinition uses the Definition complex type to define the input settings, the output settings, and a description for those browsing the .sdm file. As with all Definition objects, a flow definition is identified by name within the namespace in which it is defined, and identifies a manager that will support the runtime when it evaluates the flow.
Following are the FlowDefinition and FlowMember schema:
<xs:complexType name="FlowDefinition"> <xs:complexContent> <xs:extension base="Definition" /> </xs:complexContent> </xs:complexType> <xs:complexType name="FlowMember". <xs:complexContent> <xs:extension base="Member"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Input" type="Input" /> <xs:element name="Output" type="Output" /> </xs:choice> </xs:extension> </xs:complexContent> </xs:complexType> <!--
The following is an example of a flow definition using three settings. The first two are Input settings and define input into the flow; the third is an Output setting that provides the path of the setting value that will receive the transformed flow output. This flow definition is used to calculate the full path name using the directory path and directory or filename. In addition, the Flow definition identifies the manager code and CLR class within the manager used to calculate the transformation:
<HostingDefinition Name="DirHostsForD" GuestDefinition="MyFile" Hostdefinition="MyDir" SimulationRoot="false"> <Flow Name="CreatePath" Definition="MyPathFlow"> //Find Path by going to the host <Input Name="DirPath" Path="Host.FullPath"/> //Find File or Dir by going to the Guest <Input Name="FileOrDirName" Path="Guest.Name"\> //Assign fullpath to guest in the hosting relationship <Output Name="FullPath" Path="Guest.FullPath" /> </Flow> </HostingDefinition>
Managers provide the mechanism by which objects and relationships can introduce custom behavior into the runtime environment. An object or relationship can use a manager in any number of ways. For example, a manager may provide the implementation for more involved constraints and flows. They may help in the object's installation, or they may be called upon to handle policy decisions regarding how bindings between types are resolved. The following is the ManagerDeclaration schema:
<xs:complexType name="ManagerDeclaration:> <xs:sequence> <xs:element name="Description" type="Description" minOccurs="0" /> </xs:sequence> <xs:attribute name="Name" type="SimpleName" use="required" /> <xs:attribute name="AssemblyName" type="xs:string" use="required" /> <xs:attribute name="Version" type="FourPartVersionType" use="optional" /> <xs:attribute name="PublicKeyToken" type="PublicKeyTokenType" use="optional" /> <xs:attribute name="Culture" type="CultureNeutral" use="optional" /> <xs:attribute name="Platform" type="xs:string" use="optional" /> <xs:attribute name="SourcePath" type="xs:string" use="optional" /> </xs:complexType> <!--
All object managers are exposed through the CLR as entry points into strongly named classes. Object managers are packaged and versioned in the same manner as other types in the SDM; they are distributed in system distribution units and their version and strong name are derived from the .sdm file in which they are declared.
SDM elements are declared within a source SDM XML document (.sdm). The .sdm document contains one or more definitions, resources, endpoints, and relationships. This document is then compiled to an immutable document (.sdmDocument). Both document types represent a unit of versioning and distribution of SDM definitions and are the cornerstone of every building block created in the SDM SDK. Each SDM document produced uses the SystemDefinitionModel XML schema (see C:/Program Files/ Microsoft Visual Studio 8/Common7/Packages/SDM/Schema/SystemDefinitionModel.xsd). A few of the many elements of this schema are provided here:
Information: General information about this document.
Import: References to other SDM documents (.sdmDocument).
DesignData: Design-surface-specific data.
SettingDefinitions: An XML schema document that contains setting definitions.
Definitions: The object, relationship flow, and constraint definitions that are contained in this document.
NamespaceIdentity: The attributes that form the identity of the document.
DocumentLanguage: The language of the description elements within the document.
CompilationHash: A unique value for the document. The hash value will change if any character in the document is changed. The SDM run-time will fail to load a referenced document if an incorrect hash value is detected.
The basic SDM document schema is presented here. Figure 7-8 gives a visualization of the expanded schema groups.
The following are top-level schema elements:
<?xml version="1.0" encoding="utf-8" ?> <xs:schema targetNamespace="http://schemas.microsoft.com/ SystemDefinitionModel/2005/1" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/SystemDefinitionModel/2005/1" elementFormDefault="qualified" blockDefault="#all" version="1.1" > <!-- ================================================================================= <!-- SDM root element --> <!-- ================================================================================= <xs:element name="SystemDefinitionModel"> <xs:complexType> <xs:sequence> <xs:element name="Information" type="Information" minOccurs="0" /> <xs:element name="Import" type="Import" minOccurs="0" maxOccurs="unbounded" /> <xs:element name="DesignData" type="DesignData" minOccurs="0" /> <xs:element name="SettingDefinitions" type="SettingDefinitions" minOccurs="0" /> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="CommunicationDefinition" type="CommunicationDefinition" /> <xs:element name="ContainmentDefinition" type="ContainmentDefinition" /> <xs:element name="DelegationDefinition" type="DelegationDefinition" /> <xs:element name="ReferenceDefinition" type="ReferenceDefinition" /> <xs:element name="HostingDefinition" type="HostingDefinition" /> <xs:element name="EndpointDefinition" type="EndpointDefinition" /> <xs:element name="ResourceDefinition" type="ResourceDefinition" /> <xs:element name="SystemDefinition" type="SystemDefinition" /> <xs:element name="FlowDefinition" type="ConstraintDefinition" /> <xs:element name="ContainmentDefinition" type="FlowDefinition" /> <xs:element name="Manager" type="ManagerDeclaration" /> </xs:choice> <xs:any namespace="http://www.w3.org/2000/09/xmldsig#" processContents="skip" minOccurs="0" /> </xs:sequence> <xs:attributeGroup ref="NamespaceIdentity" /> <xs:attribute name="DocumentLanguage" type="Culture" /> <xs:attribute name="CompilationHash" type="CompiliationHashType" /> </xs:complexType> </xs:element> <!--
Every compiled SDM document (.sdmDocument) contains SystemDefinitionModel elements. For example, the following code shows the first part of the compiled SDM Microsoft.FileSystem.sdmDocument (see, for example, C:/Program Files/Microsoft Visual Studio 8/Common7/IDE/PrivateAssemblies):
<?xml version="1.0" encoding="utf-8"?> <SystemDefinitionModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Name="Microsoft.FileSystem" Version="1.0.41013.0" xmlns="http://schemas.microsoft.com/SystemDefinitionModel/2005/1" CompilationHash="3D96173B92DB35CF305A2F449378FDA878E84065"> <Information> <CompanyName>Microsoft Corporation</CompanyName> <Description> <Entry Name="Description"> This is an SDM model for simple files and directories. The model contains abstract resources for files and directories, abstract hosting relationships for files- >files, files->directories and directories->directories.</Entry> </Description> <CompilerVersion>1.0.41013.0</CompilerVersion> </Information> <Import Alias="Flow" Name="System.Flow" Version="1.0.41013.0" Culture="neutral" /> <Import Alias="System" Name="System" Version="1.0.41013.0" Culture="neutral"/>
This example includes a reference to the SystemDefinitionModel schema version used, a unique hash code used to verify that an SDM file is a valid compiled document, a description of the definition, the version of the SdmC.exe compiler used to produce this .sdmDocument, and Import elements to necessary namespaces.
The distributed system designer tools of Team Architect use a core set of abstract definitions to define common characteristics of a class of applications, servers, and endpoints. Abstract applications, abstract servers, and abstract endpoints are all examples of abstract system definitions in SDM.
These abstract definitions can be predefined and persisted as SDM documents, and added to the toolboxes of the Distributed System Designers or distributed for use by other users.
The toolboxes of the Distributed System Designers use abstract SDM definitions with Visual Studio-dependent information to create and deploy distributed systems. This combination of abstract definitions and Visual Studio-specific information is called a prototype. Prototypes may also be referred to as subsystems because they can be nested within other prototypes
A prototype of these systems is required before they can appear in the toolbox in Team Architect designers. To create these toolbox-compatible abstract definitions, the ProtoGen.exe tool is used.
An abstract application definition is created by the Application Designer, and serves as a design-time description of an independently deployable application layer system that offers or consumes services. Web applications and Window applications are examples of abstract application definitions.
Each application that you define (that is, each prototype that you drag and drop on the Application Design surface) must conform to its abstract application definition. For example, the application definition MyWebService must conform to the prototype ASP.NET WebService, which in turn must conform to the web application abstraction. While you can think of an application definition as a self-contained SDM system, it may include a number of resources that must be deployed with it in order to be functional.
You create an abstract server definition with Logical Datacenter Diagram by dragging and dropping a prototype from the LDD toolbox, and it conforms to an application hosting system within a logical datacenter. LDD only uses the definition of a hosting server in the logical datacenter, as opposed to the definition of a particular server. However, because the abstract server is the only access point, logical servers will be considered both abstract and concrete. Hence, an IISWebServer is an example of both an abstract system definition and a subsystem definition.
The Distributed System Designers also rely on prototypes for endpoints. An endpoint prototype is created from an abstract definition, such as a Web service, and can have "consumer" or "provider" type. Examples include WebServerEndpoint and HttpClientEndpoint.
Figure 7-9 shows application, server, and endpoint prototypes exposed in each Designer's toolbox.
Users or third parties can define additional abstract and prototype definitions for different kinds of applications and logical application servers, and load them into these Designer toolboxes using the SDM SDK.
This first offering of the SDM SDK enables users to define their own application or hosting models, with relationships between existing host and application models supported in Team Architect. Future releases will introduce SDM infrastructure for the IT shop and use of the SDM to manage Windows and applications running on Windows.
The System Definition Model SDK is part of the Visual Studio 2005 SDK. Please see http://www.lab.msdn.microsoft.com/teamsystem/workshop/default.aspx for details.
The SDM SDK contains the tools, schema, classes, and documentation required to extend the base System Definition Models of the Distributed System Designers. The tools consist of the Prototype Generator, SDM Compiler, and SDM Generator. The SDM schema supports the creation of SDM objects such as systems, endpoints, and resources. In addition, the SDK provides tool classes that are part of the public API of the SDM tools and manager classes that enable users to write the custom constraints and flows for an SDK object. The documentation enables users to quickly ramp up using Get Started User documentation, reference materials, walkthroughs, and samples and code snippets.
The SDM SDK is part of Visual Studio 2005 SDK (VSIP SDK), which ships with Visual Studio 2005. More information about the SDK can be found at http://www.lab.msdn.microsoft.com/teamsystem/workshop/sdm/default.aspx.
You can create and manipulate an SDM model using the SDM authoring tools found in the SDK. After the model is created and deployed, the SDM Service maintains the model, ensuring consistency between the model and the real-world system.
The authoring tasks can be described in the following five high-level steps:
Author the model of your system in SDM using your favorite editor and any available SDM SDK documentation, walkthroughs, and samples.
Take the .sdm document that describes your model and compile it using the SDM command-line compiler tool. (It's interesting to note that the SDM Compiler uses the same DLLs as Team Architect when compiling SDM documents.) The output is a .sdmDocument document that describes an immutable form of your new model. This document may reference models (.sdmDocuments) that ship in Visual Studio or elsewhere. If your model is evaluating custom constraints or flows, you will also need to use a manager C# code-generation tool to produce your new manager DLL. You may author models that don't require managers.
Compile a Prototype.xml file using a prototype-generation tool. This will produce a Prototype.xml file that is required in order for you to install your model in the Team Architect design surface toolbox.
Build an install package. This includes your compiled model (.sdmDocument), any manager DLLs, the Prototype.xml, and registry key settings for the model.
The user of Team Architect can load the package into the toolbox.
These steps are illustrated in Figure 7-10.
The SDM Compiler will only be accessible to SDK users through the command line with the SdmC.exe tool. Although the SDM Compiler is the same compiler used by Team Architect, users will not be able to author, compile, and package models using the Team Architect user interface.
The SDM filename to compile is the only required argument. The remaining parameters are all optional. If there are no errors or warnings within the error level, SdmC.exe will return a value of 0; otherwise, the return value will be 1. The compiler command-line options are listed here:
SdmC.exe file.sdm [/Reference:ref1, ref2, ...] [/Output:file] [/KeyFile:file] [/KeyContainer:name] [/WarningAsError:level] [/WarningReported:level] [/SearchPath:dir1, dir2, ...] [/Help] [/InstanceOutput:file] [/ConfigReport:file] [/ErrorLimit:max] [/MaxComplexity:max] [/NoLogo] [/StopOnError] [@file1[@file2...]]