为虚拟应用程序模式创建插件,第 1 部分:简介

本系列的第 1 部分将向您介绍如何在 IBM® Workload Deployer 和 IBM PureApplication™ Systems 中为虚拟应用程序模式开发插件。这里提供的示例也适用于 IBM SmartCloud Application Workload Services。本文将演示一个简单示例,展示开始开发插件和模式类型所必需的关键概念。本系列可作为 “导航 IBM 云” 文章系列 的补充。

José De Jesús, 高级认证架构师, IBM

Jose De Jesus 的照片José De Jesús 是 ISSW for IBM (I4I) 团队的一名高级认证架构师。他拥有福特汉姆大学的计算机科学专业理学士学位和迈阿密大学的管理技术专业理学硕士学位。José 是 Blue Harmony 内部项目的 Non-SAP Infrastructure Team Lead,以及 ISSW Certification Lead。他还领导着 I4I Cloud Initiative 和 I4I Technical Vitality Initiative,是 Distributed Management Task Force (DMTF) 的成员。



Vanessa Oktem, 软件开发人员, IBM

Vanessa Oktem 的照片Vanessa OktemIBM Software Services for WebSphere for IBM (I4I) 团队的一名软件开发人员。她目前是 IBM 的 SmartCloud Commerce Engine 项目 IC2E 的开发团队成员。在加入此团队之前,她是 Tivoli Provisioning Manager (TPM) 团队的成员,在那里研究各种与 Virtualization、Server Management 和 Image Library 相关的技术。她加入了 I4I Technical Vitality Initiative 下的 I4I Cloud Task Force,在 I4I 团队中进一步参与云技术的研究。她拥有加拿大多伦多大学计算机工程专业的应用科学荣誉学士。



2013 年 3 月 11 日

简介

Workload Deployer 和 PureApplication Systems 附带了预定义的模式类型和插件,它们整合了多年专家经验和最佳实践来实现具体的工作负载解决方案。它们是以应用程序为中心的(而不是以中间件为中心),因为它们允许您专注于应用程序本身,而不是所需的硬件或架构。

这些模式和插件的理念是,您指定一个现有应用程序(例如一个 .ear 文件)和一组对应于您希望实现的服务水平协议 (SLA) 的策略,让 Workload Deployer 或 PureApplication Systems 将输入转换为一个已安装、配置和集成的中间件解决方案。您无需直接创建所需的拓扑结构。在应用程序运行时,其他节点(比如缓存节点、应用服务器节点和 Web 代理节点)会依照您建立的策略自动添加或删除,以保持性能可被人接受。部署的虚拟应用程序模式称为虚拟应用程序实例,或者简称为虚拟应用程序。

虚拟应用程序模式有望通过提供云解决方案交付方式的模式转变来节省时间和资金。但是,虚拟应用程序模式的动态行为不是免费的。除非使用某种预定义的模式类型和插件来获取这种功能,否则您需要开发一个或多个插件。尽管插件一般容易使用,但开发它们可能是一项艰巨的任务。我们打算借助这个系列改变上述观念,鼓励进行更多的插件开发。

本系列文章由三部分组成:

  • 为虚拟应用程序模式创建插件,第 1 部分:简介(本文)
  • 为虚拟应用程序模式创建插件,第 2 部分:详细分析(未来的文章)
  • 为虚拟应用程序模式创建插件,第 3 部分:设计考虑因素(未来的文章)

先决条件

要顺利完成本文的学习,则需要下载和安装以下软件:

  1. IBM Workload Plug-in Development Kit (PDK):可以从 Workload Deployer 或 PureApplication Systems 的 GUI 中使用欢迎页面上显示的 Download Tooling 菜单下载此工具包。也可以直接从 IBM Workload Plugin Development Kit 页面下载它。这些文章中使用的版本是 PDK v1.0.0.6。

如果您尚未注册一个 IBM Common Profile 帐户,系统会要求您注册该帐号。

  1. Eclipse Helios 3.6 SR2 或更高版本(32 位):从 eclipse.org 站点下载它。推荐使用 Java EE Developers 包。
  2. Java 6 JDK 32 位:从 Java 站点 下载它。
  3. Apache Ant 7.1 或更高版本:从 Apache Ant 站点 下载它。

确保您使用了上述的准确软件版本。Eclipse 是可选的,不使用它也可以为虚拟应用程序模式构建插件,但我们强烈建议使用它,因为它简化了插件创建过程中涉及的一些工作。我们选择它作为本文章系列的开发工具。如果使用 Eclipse,可以(可选地)使用 Eclipse 安装目录中提供的 Ant 工具:

<eclipse-installation-directory>/ plugins/org.apache.ant_1.*

准备好您的环境

下一节将大致介绍如何安装必要的组件,准备好您的 Eclipse 环境来开发插件。这些信息足够您入门使用,如果需要更多的信息,请查阅 IBM Workload DeployerIBM PureApplication Systems 的信息中心,以及 PDK 附带的插件开发指南

安装和构建插件开发组件

下载所有必要的软件后,执行以下步骤:

  1. 为 PDK 创建一个目录,并将 pdk-1.0.0.6 压缩文件解压到这里。
  2. 安装 Ant
  3. ANT_HOME 环境变量设置为您安装 Ant 的目录。
  4. Ant bin 目录添加到您的路径中。
  5. 安装 Java 6 JDK 32 位
  6. JAVA_HOME 环境变量设置为指向您的 Java 安装目录。
  7. 将 Java bin 目录添加到您的路径中。
  8. 转到 PDK 压缩包解压后所在的目录,从命令行运行 Ant 来构建插件开发组件(键入 ant 并按下 Enter 键)。

Eclipse PDK 环境设置

为了进行插件开发而安装和配置 Eclipse 涉及到以下步骤:

  1. 安装 Eclipse Helios 3.6 SR2 32 位 或更高版本(32 位)。
  2. 启动 Eclipse。
  3. 在 Eclipse 工作区内,单击 Help > Install New Software 调出 “Available Software” 窗口。
  4. 单击 Add 添加一个新软件存储库,然后单击 Archive 指向压缩文件:com.ibm.maestro.plugin.pdk.site.zip
  5. 为存储库提供一个名称,比如 Workload Deployer Eclipse Plug-in,并单击 OK
  6. 等待 Name 区域显示 “IBM Workload Plugin Development Kit”,然后单击 Select All
  7. 在安装期间取消选择标为 Contact all update sites 的方框,以查找所需的软件。
  8. 单击 Next 并等待安装完成。

在正确配置好环境之后,就可以开始创建模式类型和插件了。在本文中,我们展示了一个简单的示例,帮助您初步了解插件开发,但首先让我们要回顾一下一些基本术语和概念。


创建虚拟应用程序模式

无论使用现有的模式类型和插件,还是自行创建它们,一旦将它们加载到 Workload Deployer 或 PureApplication System 目录中,就可以使用它们构建虚拟应用程序模式。为此,可以使用 GUI 中包含的 Virtual Application Builder。图 1 演示了如何打开 Virtual Application Builder:

  1. 根据您正在使用的是哪种系统(Workload Deployer 或 PureApplication System),选择 Patterns > Virtual ApplicationsWorkload Console > Patterns > Virtual Applications。单击绿色加号来启动一个新模式。
  2. 在 Create Application 对话框中,选择 Pattern Type 和您希望使用的对应模板。然后单击 Start Building

依据一种特定的模式类型和一个可选的模板来构建虚拟应用程序模式。例如,要构建标准 JEE Web 应用程序,可选择 Web Application Pattern Type 2.0 和 Blank Java EE Web 应用程序模板。这些模板是以前创建的模式,将其保存为应用程序模板是为了方便重用。

图 1. 启动 Virtual Application Builder
启动 Virtual Application Builder

单击 Start Building 打开 Virtual Application Builder。

图 2. Virtual Application Builder
Virtual Application Builder

图 2 演示了 Virtual Application Builder 的工作原理。使用可选模板选择一种模式类型并打开构建器之后,资源面板将显示您可用于构建模式的资产列表。这些资产由关联的插件所公开的组件、链接和策略组成。将组件从资源面板拖到画布上,然后在它们之间创建链接。可以将策略应用于各个组件或整个模式(它们将应用到在其模型中定义了这样一条恶略的每个组件)。

单击画布上的一个元素将在属性编辑器中显示它的可配置属性。这些属性是您可以自定义的属性。图 2 将它们显示为带圆圈的 “A”。组件、策略和链接都可拥有可配置的属性。

构建应用程序时,Virtual Application Builder 的后端会扫描与该插件有关联的工件,以便依据插件的用途来帮助指导建模。组件、策略和链接的实现和维护细节都封装在插件自身中。

您的模式的不同视图

默认情况下,在 Virtual Application Builder 中看到的是模式的 Diagram View。也可以使用 List ViewSource View 格式查看模式,如图 3 所示。以下是这些视图的用途的简短说明:

  • Diagram View 允许您以图形形式构建拓扑结构,并不断提供许多可视线索。它在初步设计虚拟应用程序模式时非常有用。
  • List View 使您能够轻松地查看需要由给定的虚拟应用程序模式设计配置的所有属性。
  • Source View 显示只读内容。它是 Diagram View 中所显示模式的一种序列化形式。如果在尝试部署模式时出现错误,这是开始分析错误的一个好位置。
图 3. 虚拟应用程序模式的不同视图
虚拟应用程序模式的不同视图

模式类型和插件

图 4 显示了模式类型与插件之间的总体关系。模式类型 表示一个插件集合,它们一起决定了哪些资源将显示在资源面板中,哪些属性可在 Virtual Application Builder 中配置。插件公开了组件、链接和策略,您可以使用它们构建模式。它们还决定了如何构建、配置和部署应用程序,以及如何管理其整个生命周期。

模式类型在逻辑上将一组相关插件分组在一起,以支持特定类型的工作负载解决方案。出于这个原因,模式类型也称为工作负载模型

您可以创建自己的模式类型来解决自定义工作负载,或者使用附加插件扩展现有的模式类型。

图 4. 模式类型和插件
模式类型和插件

一个简单示例

第一篇文章将提供一个简单示例,它由一个模式类型和一个插件组成,该插件包含两个组件和一个链接,如图 5 所示。

图 5. 我们的简单示例
我们的简单示例

模式类型和插件允许您构建一种基本的虚拟应用程序模式,在组件之间建立连接。每个组件有一个可自定义的属性。链接支持您将 Simple Component 1 连接到 Simple Component 2,但不会创建任何真实的依赖关系或简化两个组件之间额任何交互。

在第一篇文章中,我们仅在这一范围内进行讨论,因为这已为我们提供了很多值得讨论的话题。我们的想法是先帮助您深入了解基本概念,然后在后续文章中介绍其他主题。


从应用程序模型到虚拟机

在 Virtual Application Builder 中创作一个虚拟应用程序模式,这会创建虚拟应用程序的一种逻辑描述或应用程序模型。您保存的工作将成为一个名为 app model 的 JSON 文档。在部署期间,此应用程序模型或元数据会转换为一个拓扑结构文档,这是组成虚拟应用程序的拓扑结构的物理描述。Workload Deployer 和 PureApplication System 知道如何将拓扑结构文档部署为一组虚拟机,以及如何在它们之上安装和配置软件。

一个虚拟应用程序模式中的组件通常代表一个或多个已部署的虚拟机,而链接代表它们之间的依赖关系。但是,实际情况可能并不总是这样,因为应用程序模型是独立于拓扑结构文档的。您拖到画布上的工件只是插件公开的逻辑模型部分,提供它是为了方便您根据插件提供的设计来构建虚拟应用程序模式。

从逻辑模型到物理文档的转换步骤实际上是在插件自身中定义的。


开发插件的一般步骤

执行以下步骤,使用 Elipse PDK 开发一个模式类型和关联的插件。本文将介绍每个步骤:

  1. 创建一个模式类型项目。
  2. 更新生成的 patterntype.json 文件,以满足您项目的需求。
  3. 创建一个新的插件项目。
  4. 更新 plugin/appmodel/metadata.json 文件,以定义应在 Virtual Application Builder 中公开的可配置的应用程序模型组件。
  5. 更新生成的 plugin/config.json 文件,以满足您项目的需求。
  6. 创建需要安装在虚拟机上的部件和节点部件。
  7. 根据需要创建其他角色。
  8. 更新生成的生命周期脚本。
  9. 创建 OSGi 服务组件。如果使用 Eclipse PDK,那么该步骤将自动完成以下操作:
    1. 生成 .vm 模板或 .java 源文件,以便将应用程序模型转换为拓扑结构文档。
    2. 创建相应的服务声明 .xml 文件。
    3. 更新插件的 META-INF/MANIFEST.MF 文件,以便引用新的 OSGi 服务组件。
  10. 更新默认的速度模板。
  11. 构建模式类型(或插件),并将结果 .tgz 文件导出到文件系统中。
  12. 将模式类型或插件导入 Workload Deployer 或 PureApplication System 中,并使用插件构建一个虚拟应用程序模式。

为新插件创建模式类型不是强制性的。也可以将新插件添加到现有的模式类型中。


第 1 步:创建一个模式类型项目

在 Eclipse 内,要创建一个模式类型,可以执行以下步骤:

  1. 选择 File > New > Other... 并选择 IBM Workload Plug-in Development > IBM Workload Pattern Type Project
  2. 单击 Next
  3. 为您的项目提供一个名称,并对 Pattern type name 字段使用相同的名称。此示例中使用的名称为 patterntypeSimple
  4. 对于 Pattern type version 字段,使用的是 1.0.0.0
  5. 单击 Finish。如果 Eclipse 询问您是否希望切换到 Workload Plug-in Development 透视图,回复 Yes
  6. 这些步骤为模式类型创建一个目录结构,其根文件夹中包含文件 patterntype.json,如图 6 所示。
    图 6. 为一个新模式类型项目生成的骨架代码
    为一个新模式类型项目生成的骨架代码

Eclipse 为项目中添加了更多的项,比如 Tivoli® maestro 库和 Ant 就绪的构建文件,它们可以帮助简化创建模式类型的流程。构建目录包含用于构建模式类型的 build.patterntypes.xml 文件和 Ant .jar 文件。lib 文件夹包含编译项目所需的 .jar 文件,build.xml 是构建模式类型项目所需的 Ant 构建文件。文件 patterntype.json 包含模式类型的详细信息。从某种意义上讲,模式类型项目是自成一体的,这表明构建它所必要的所有库和脚本都包含在项目自身中。插件项目也是如此。

JSON 编辑器

Eclipse PDK 环境包含一个 JSON 编辑器,它使您能够轻松编辑和验证 JSON 文件的内容。在 Package Explorer 视图中,如果双击刚刚创建的模式类型的 patterntype.json 文件,系统会在 JSON 编辑器中显示它的内容。如图 7 所示,您可以使用编辑器的 Configuration 视图或它的 Source 视图。如果对一个视图进行更改,则会自动更新另一个视图。JSON 编辑器对输入执行就地验证,必要时会在 Configuration 视图中显示相关的错误、警告和提示。

图 7. 为一个新模式类型项目生成的骨架代码
为一个新模式类型项目生成的骨架代码

第 2 步:更新 patterntype.json 文件

生成的 JSON 源代码已拥有您需要的所有功能,所以您无需针对此示例修改 patterntype.json 文件。请注意,模式类型不包含对插件的任何引用。这是因为插件将自身与模式类型有关联,但没有反向关联。

切换到 Source 视图,并确保 patterntype.json 看起来类似图 7 中所示的源代码。如果执行了任何更改,请按 Ctrl+S 保存工作。


第 3 步:创建一个新插件项目

要创建一个新插件项目,请执行以下步骤:

  1. 通过 Window > Open Perspective > Other > Workload Plug-in Development perspective 切换到 Workload Plug-in Development 透视图(如果还未打开该透视图)。
  2. 选择 File > New > Project > IBM Workload Plug-in Development > IBM Workload Plug-in Project。IBM Workload Plug-in Project 也可能直接显示在 Project 下方。单击 Next
  3. 在 New Project 对话框中,为项目和新插件提供一个名称。对于本示例,对二者使用名称 pluginSimple
  4. 单击 Generate project skeleton,然后单击 Finish

Eclipse 将生成图 8 所示的目录结构。

图 8. 为一个新插件项目生成的项目骨架
为一个新插件项目生成的项目骨架

乍一看,生成的项目可能让您觉得掌握一个简单示例很难,但事实上,在插件目录之外,您看到的大多数都是支持文件和库。除了帮助您构建插件的 Tivoli maestro 库和 Ant 就绪的构建文件之外,在选择生成一个新插件项目的骨架代码时,还会生成其他文件夹。表 1 提供了这方面的简短描述。

表 1. 为一个插件项目自动生成的文件夹
文件夹描述
src 包含与 OSGi 服务组件有关联的任何 Java™ 源代码。
build 包含用于构建插件的 build.plugins.xml 文件和 Ant .jar 文件。
i18n 包含用于插件本地化的翻译文件。
lib 包含编译插件项目所需的 .jar 文件。
META-INF 包含插件的清单文件。
OSGI-INF 包含 OSGi 服务组件。
plugin 包含 config.json 文件以及插件配置目录。
build.xml 这是构建插件项目所需的 Ant 构建文件。可根据需要进一步自定义它。

plugin 目录

plugin 目录表示插件本身,插件是虚拟设备的基本内容单元。插件是实现特定功能的文件和目录的集合。插件封装为 .tgz 压缩文件,这些文件将导入 Workload Deployer 或 PureApplication Systems 中。图 9 显示了项目内的 plugin 目录的结构。从技术上讲,惟一的必要文件是 config.json,它必须放在插件压缩文件的根目录下,但我们在插件开发过程中首先会重点创建两个文件:metadata.json 和 config.json。

图 9. plugin 文件夹目录结构
plugin 文件夹目录结构

表 2 提供了与 plugin 文件夹中的文件和目录相关的详细信息。如果无法完全理解表 1 和 2 中的描述,不用担心。您很快就会理解它们。一些条目未在我们的简单示例中使用,所以目前没有什么好担心的。

表 2. 插件文件和目录
文件/目录描述
appmodel/metadata.json 定义了您希望在 Virtual Application Builder 中向用户提供的插件元素(组件、链接和策略)和属性。
appmodel/operation.json 定义了可在虚拟应用程序运行时调用的操作。此文件中定义的操作将在正在运行的模式的一个组件上启动操作。我们未在示例中使用 operation.json
appmodel/tweak.json 定义了可在运行的虚拟应用程序上更改(调整)的配置参数。这些参数是运行的部署中的可变配置。我们未在示例中使用 tweak.json
nodeparts 此目录包含节点部件,这些部件是激活脚本安装在所部属的虚拟机上的工件,一般用于扩展 OS 或供其他部件使用。工作负载代理(是负责安装插件部件的组件)是节点部件。除了工作负载代理(它们是自动生成的)之外,我们未在示例中使用节点部件
parts 部件最常用于将软件安装在虚拟机上。它们是可能特定于目标机器的文件分组。激活脚本下载和安装所有节点部件,包括工作负载代理。工作负载代理进而会下载和安装所有需要的部件。
templates 模板将应用程序模型的转换映射到它在云中的物理模型。

第 4 步:更新 metadata.json 文件

metadata.json 文件是定义了应在 Virtual Application Builder 中提供给用户的组件、链接和策略的地方。在第一次创建插件项目时,生成的 appmodel/metadata.json 文件是空的,其中仅包含一个开始和结束括号 ([ ])。您需要编辑 metadata.json 文件,使其类似于清单 1。

清单 1. 更新的 metadata.json 文件
[
   {
      "id": "componentSimple1",
      "type": "component",
      "image": "appmodel\/images\/monkey.png",
      "thumbnail": "appmodel\/images\/thumbnail\/monkey.png",
      "label": "componentSimple1",
      "description": "Simple Component 1",
      "attributes": [
         {
            "id": "Name",
            "type": "string",
            "required": false,
            "label": "SampleValue1",
            "description": "Sample Value 1"
         }
      ],
      "category": "application"
   },
   {
      "id": "linkSimple",
      "type": "link",
      "source": [
         "componentSimple1"
      ],
      "target": [
         "componentSimple2"
      ],
      "label": "Simple Link",
      "description": "Simple Link",
      "attributes": [
         {
            "id": "simpleConnector",
            "type": "string",
            "required": false,
            "label": "Simple Connector"
         }
      ]
   },
   {
      "id": "componentSimple2",
      "type": "component",
      "label": "componentSimple2",
      "description": "Simple Component 2",
      "category": "application",
      "image": "appmodel\/images\/banana.png",
      "thumbnail": "appmodel\/images\/thumbnail\/banana.png",
      "attributes": [
         {
            "id": "Name",
            "type": "string",
            "required": false,
            "label": "SampleValue2",
            "description": "Sample Value 2"
             
         }
      ]
   }
]

可采用多种方式更新 metadata.json:

  • 键入,键入,再键入。
  • 将清单 1 中的代码直接剪切并粘贴到您的工作区中。
  • patterntypeSimple-1.0.0.0.tgz 文件导入该文件,这个压缩文件已在本文的 下载 部分中提供。
  • 使用 JSON 编辑器的 Configuration 视图来创建条目。

清单 1 中外部的方括号表明 metadata.json 是一个逗号分隔的 JSON 对象数组,每个对象都位于描述元素的花括号字段中。在本例中,我们有 3 个元数据元素,分别称为 componentSimple1、componentSimple2 和 linkSimple。请记住它们的 ID,因为它们与 config.json 文件中相应的包名称相匹配。文件末尾的链接对象包含一个来源和目标组件数组。这个示例告诉 Virtual Application Builder 显示两个组件和一个链接,允许进行从 Simple Component 1 到 Simple Component 2 的单向链接,如 图 5 所示。

元素和它们在 metadata.json 文件中的元素都很容易理解。例如,image 和 thumbnail 属性指装饰 Virtual Application Builder 中的组件的图像和缩略图。请注意,清单 1 中的 metadata.json 包含对 appmodel/images 文件夹中不存在的图像的引用。您需要从本文末尾所提供的压缩文件导入这些图像,或者选择您自己的图像。只需确保用作缩略图的图像文件为 48 x 48 像素。

将这些图像导入到您工作区的最简单方式或许是对 metadata.json 使用 JSON 编辑器的 Configuration 视图。在标为 Image 和 Thumbnail 的字段中,按下 Browse… 并找到您希望导入的图像。系统会自动创建 appmodel/imagesappmodel/images/thumbnail 文件夹,并将它们放入不同的图像文件。对于本示例,我们对图像和缩略图使用了相同的图像文件(monkey.png 和 banana.png)。确认 appmodel/images 目录已创建,并且包含您导入的图像。

在完成 metadata.json 文件的修改后,按下 Ctrl+S,或从菜单选择 File > Save 来保存您的工作。

针对插件开发人员的直观教具

请注意 图 9pluginsimple.scripts 文件夹旁边的 P 图标和 PLUGINSIMPLE 文件夹旁边的 R 图标,以及一些标有星号或勾选符号的文件。这些类型的装饰符号是一些直观教具,可帮助插件开发人员更轻松地识别内容。表 3 列出了一些较常见的装饰符号。

表 3. 插件项目中使用的装饰符号
装饰符号描述
R 表示一个插件角色。
* 表示它是一个节点部件或一个部件的标准脚本。
勾选符号 表示它是一个角色生命周期脚本。
P 表示一个插件部件。
N 表示一个插件节点部件。

插件配置文件

config.json 文件(已在 图 9 中突出显示)称为插件配置文件,它是您定义模式类型与插件之间的关系的地方。图 10 显示了默认的 config.json 文件。至少需要使用 3 个元素:nameversionpatterntypes。name 和 version 是插件的名称和版本号,而 patterntypes 是与插件有关联的模式类型。

图 10. config.json 的 Configuration 和 Source 视图
config.json 的 Configuration 和 Source 视图

第 5 步:更新生成的 config.json 文件

本示例需要的 config.json 文件比默认生成的文件稍微复杂一些。本示例中的下一步是将它更改为类似清单 2。

清单 2. 已更新的 config.json 文件
{
   "name": "pluginSimple",
   "version": "1.0.0.0",
   "patterntypes": {
      "primary": {
         "patterntypeSimple": "1.0"
      }
   },
   "packages": {
      "componentSimple1Pkg": [
         {
            "persistent": true,
            "requires": {
               "arch": "x86_64",
               "memory": 128
            },
            "parts": [
               {
                  "part": "parts\/componentSimple1.scripts.tgz"
               }
            ]
         }
      ],
      "componentSimple2Pkg": [
         {
            "requires": {
               "arch": "x86_64",
               "memory": 128
            },
            "parts": [
               {
                  "part": "parts\/componentSimple2.scripts.tgz"
               }
            ]
         }
      ],
      "linkSimplePkg": [
         {
            "parts": [
               {
                  "part": "parts\/linkSimple.scripts.tgz"
               }
            ]
         }
      ]
   }
}

JSON 代码中转义的正斜杠

您可能想知道,在单个正斜杠就能解决时,清单 2 中的正斜杠为什么会在包含路径的字符串中转义。在字符串中使用 \/ 有助于将 JSON 代码嵌入到 <script> HTML 标记中,这不允许将 </ 包含在字符串内。因此,对 JSON 代码中的正斜杠进行转移被视为一种很好的做法。一些编码机制(比如 PHP 的 json_encode() 方法)会自动转义正斜杠。PDK 插件也会对它生成的任何代码这样做。


将一个插件与模式类型关联

清单 2 中的 patterntypes 元素是将一个插件与模式类型进行关联的地方。一个插件可与一个主要模式类型相关联,也可与一个或多个辅助模式类型相关联。对于适用的插件,它的主要模式类型必须在 Workload Deployer 或 PureApplication System GUI 中启用。

在 config.json 文件中以这种方式定义插件是将一个插件与模式类型相关联的最简单的方法。还有一个 linked 选项提供了更高的灵活性。如果已经声明了某个插件声明与一个模式类型的 linked 关系,则会将该 linked 模式类型与插件的主要模式类型相关联,这意味着在导入该插件时,任何与 linked 模式类型关联的插件都会自动与该插件的主要模式类型相关联。例如,假设您的 config.json 文件拥有一条条目:

"patterntypes": {
      "primary": {
         "patterntypeSimple": "1.0"
      },
      "linked": {
         "webapp": "2.0"
      }
   },

所有与 webapp(Web Application Pattern Type 2.0 的简称)关联的插件都会自动与 patterntypeSimple 相关联。因此,当使用 patterntypeSimple 时,还会在资源面板中看到 webapp 的资产。您还可以使用 linked 来利用更多插件扩展现有的模式类型,无需更改模式类型本身。


使用包

顾名思义,packages 元素允许您将包包含在插件自身内。包指配置特定的角色 所必需的图像、二进制文件和属性。一个角色一般指一个 VM 在所部属的虚拟应用程序模式中的不同 VM 中扮演的中间件角色。例如,DB2®、WebSphere® Application Server 和 WebSphere MQ 都是角色。

插件开发中的角色概念乍看起来可能难以理解。实际上,可以将角色想象为一个软件,它可以安装在一个或多个虚拟机上,以便在部署的模式中启用一项功能(也可以将它称为角色)。此软件在 config.json 文件的 packages 元素中指定为一系列节点部件和部件。而且,软件的安装和配置顺序是通过生命周期脚本来管理的,主要是为了在虚拟应用程序模式中按正确的顺序部署功能。下面将进一步讨论此主题。

packages 元素定义了应与某个特定角色的 VM 捆绑在一起的节点部件和部件。无需将图像和二进制文件直接包含在插件中,也可以从本地或远程位置引用它们。我们的示例使用了 3 个包,每个包对应于组成我们的简单插件的每项资产。

与组件相关的包中包含一个 requires 元素,它标识了应用于包的具体条件和约束。例如,如果某个包特定于 PureApplication System 而不是 Workload Deployer,那么 requires 元素将包含这样一个条目:

"products" : ["IPAS"]

可以使用 requires 元素定义可部署某个特定包的虚拟机的必要的架构、硬件配置和操作系统。例如,清单 2 中的代码指定一个包中包含的任何软件都只能安装在具有至少 128 GB 内存的 64 位操作系统上。

插件包有助于从您在 Virtual Application Builder 中使用的 GUI 元素中抽象出操作系统、硬件和架构需求细节。这么做的目的是向构建 Virtual Application Pattern 的人隐藏配置和部署细节,以便他或她可专注于应用程序本身,Workload Deployer 或 PureApplication System 在幕后通过插件处理操作系统、硬件和架构需求。


使用持久 VM

除了 清单 2 中的 requires 元素之外,组件的每个 packages 元素都有一个设置为 truepersistent 属性。这告诉系统如果虚拟机意外停止,则重新启动而不是替换它。对于拥有可恢复的状态信息的虚拟机,适合将此属性设置为 true,因此我们的示例实际上不需要它。我们将它放在这里是为了引出持久 VM 的概念。关于合适使用持久还是非持久虚拟机的规则不属于第一篇文章的讨论范围。请注意,linkSimple 包没有 persistent 属性或任何架构需求,因为链接主要用于其他用途。


使用部件和节点部件

将一个包与插件捆绑在一起的方式是使用部件节点部件。config.json 文件中的 packages 元素用于指定部件、节点部件或二者的一个集合。部件只是一组与一个特定角色或依赖关系有关联的文件,一般为脚本和二进制文件。部件由工作负载代理安装。节点部件是一组脚本,主要用于在部署部件之前安装和配置操作系统和基础软件。节点部件由激活脚本安装。部件和节点部件的脚本都封装在与插件捆绑在一起的 .tgz 文件中。清单 2 中的 config.json 文件引用了我们的示例所需的部件。下一步是创建它们。


第 6 步:创建部件和节点部件

要创建部件或节点部件,请执行以下步骤:

  1. 对于部件,右键单击 plugin/parts 文件夹并选择 New > Plug-in Part。类似地,对于节点部件,右键单击 plugin/nodeparts 文件夹并选择 New > Plug-in Node Part。根据您的选择显示 New Plug-in Part 或 New Plug-in Node Part 对话框。
  2. 为部件或节点部件提供一个名称,这个名称与它在 config.json 文件中的条目保持一致(没有 .tgz 扩展名)。
  3. 选择您希望在创建部件或节点部件时自动包含的脚本存根。对于本示例中的每个条目,选择创建字典结构以及 install.py 和 uninstall.py Python 脚本。图 11 演示了第一个简单组件的输入。
  4. 创建 清单 2 中所示的 config.json 文件的部件。在以后构建插件时,PDK 会为这些部件创建相应的 .tgz 文件,并将它们包含在插件 .tgz 包中。请注意,对于我们的示例,我们仅创建了相应部件。
    图 11. 创建一个新的插件部件
    创建一个新的插件部件

使用激活脚本

在部署一个虚拟应用程序模式时,每个 VM 中的激活脚本会下载并安装您在插件中为它定义的所有节点部件。无论是否创建了节点部件,在激活脚本时都会下载一个叫做工作负载代理 的内部节点部件,这是负责安装部件和管理插件中的角色和依赖关系生命周期的 Open Services Gateway initiative (OSGi) 应用程序。激活脚本会下载和安装所有节点部件,包括工作负载代理,工作负载代理进而会下载并安装所有必要的部件。

表 4 列出了节点部件与部件之间的一些重要区别。

表 4. 节点部件与部件的对比
节点部件部件
  1. 在项目目录中的 plugin/nodeparts/ 下定义。
  2. 由主要用于安装、配置和启动系统级软件的脚本和二进制文件组成。
  3. 需要在其根目录中包含一个 install.py 脚本。
  4. 由激活脚本下载和安装。
  1. 在项目目录中的 plugin/parts/ 下定义。
  2. 由主要用于安装、配置和启动应用程序(一般是中间件软件)的脚本和二进制文件组成。
  3. 需要在其根目录中包含一个 install.py 脚本。
  4. 由工作负载代理(一个节点部件)下载和安装。
示例:一个防火墙节点部件,用于在安装部件之前修改防火墙规则。示例:一个 WebSphere Application Server。

使用链接

链接有助于在组件之间建立通信。在 Virtual Application Builder 中,链接显示为带有表明通信方向的箭头的浅蓝色线条。在两个组件分别映射到一个虚拟机时,一个链接通常会打开从一个 VM 到另一个 VM 或到一个外部服务的传入和传出端口。默认情况下,VM 中的所有传入和传出流量都已禁用。

链接还提供了额外的配置点。例如,在 Virtual Application Builder 中,您可以使用一个链接(比如 User Registry 链接)将您应用程序中定义的一个角色映射到 LDAP 中定义的物理用户或组。这个链接在 VM 之间开启必要的防火墙端口,并要求您提供额外的配置信息,比如角色名和用户或组映射信息。


虚拟映像与虚拟设备

虚拟映像 是虚拟机的二进制映像,其中包含一个操作系统,还可以包含中间件和其他应用程序。虚拟映像通常不是可自配置的,这意味着它们不接受来自部署平台(在本例中为 Workload Deployer 或 PureApplication System)的配置点,部署平台使它们能够基于特定于部署的值来重新配置操作系统或软件。在部署一个虚拟映像后,可能还必须手动配置它运行的操作系统或中间件。

虚拟设备 是一个可自配置的 虚拟映像,这意味着它包含一个激活引擎(一组脚本和库),该引擎可接受一组来自部署平台的参数,并使用这些值进一步配置操作系统和捆绑的软件。使用 Workload Deployer 和 PureApplication System 部署的 VM 是拥有激活引擎的虚拟映像,该引擎可在部署时运行脚本(例如激活脚本)来配置操作系统和软件。

注意:出于遗留原因,Workload Deployer 和 PureApplication System 中交替使用了术语 “虚拟映像” 和 “虚拟设备”。只要您可区分它们,这就不是真正的问题。Workload Deployer 和 PureApplication System 使用遵守 OVF(Open Virtualization Format,开放虚拟化格式)的虚拟设备,这是打包和分发虚拟机的标准方式。


使用角色和生命周期脚本

回想一下,角色实质上代表需要安装在一个或多个虚拟机上的软件,可供 VM 在部署的虚拟应用程序模式中履行一种角色。一个 VM 可有多种角色,也可以让多个 VM 具有同一个角色。

因为在一种模式下,VM 的安装和配置可能依赖于另一个 VM,您不能允许系统盲目地一次安装所有部件。对于每个 VM,您需要管理软件的安装和配置,以确保它与所部属的模式中的其他 VM 正确同步。例如,一个 WebSphere Application Server 角色可能需要根据一个 DB2 角色的配置来完成自己的配置。这种类型的业务流程是通过生命周期脚本(也称为角色生命周期脚本)完成的。在本例中,管理者是安装在每个 VM 上的工作负载代理。在一个 VM 完全部署和实例化后,工作负载代理开始针对它将在应用程序中扮演的角色来配置它。

您为每个部件创建的 install.py 和 uninstall.py 脚本就是生命周期脚本的例子。生命周期脚本主要使用 Python 实现控制逻辑,利用 maestro 脚本和库执行大部分基础架构工作。表 5 提供了可用的生命周期脚本的简短描述。

表 5. 生命周期脚本
脚本描述
install.py 仅在 VM 的整个生命周期中运行一次,即使在机器重新启动时也不会再次运行。install.py 很有用,比如可用于下载和安装需要安装在 VM 上的软件。
configure.py 下载由插件上传的任何工件并配置软件。
starts.py 启动软件,通常是一个中间件服务器。
stops.py 停止软件。
uninstall.py 卸载软件。

角色依据运行的生命周期脚本来更改其状态。在我们的示例中,仅关注 3 种类型的脚本:install.py、configure.py 和 start.py。图 12 展示了这些脚本如何和触发下一个角色状态,假设存在一个没有错误的场景。如果流程因为错误而终止,那么角色将进入 TERMINATED 或 ERROR 状态。

一个角色可使用的各种生命周期状态可用来解决角色之间的依赖关系。换言之,支持执行某个角色的脚本可能依赖于另一个角色的生命周期状态更改。生命周期状态更改用于协调整个模式中的脚本执行顺序(比如跨 VM)。

图 12. 触发角色状态更改的生命周期脚本
触发角色状态更改的生命周期脚本

生命周期脚本可帮助工作负载代理协调部署在 VM 上的软件的安装和配置。该脚本通过设置 maestro.role_status 变量,向工作负载代理告知角色的状态。例如:

set maestro.role_status = 'RUNNING'

此主题还有更多可讨论的内容,但不会在第 1 部分中讨论。在第 2 部分中,我们将深入介绍角色和它们如何帮助实现 VM 之间的事件通知。对于现在,允许脚本向工作负载代理报告它处于 RUNNING 状态就足够了。


第 7 步:根据需要创建更多角色

当为本示例创建部件时,Eclipse PDK 仅生成 install.pyuninstall.py 生命周期脚本。因为我们未在本示例中使用 uninstall.py,所以您可以放心地删除它。但是,您需要创建 configure.pystart.py 脚本。为此,可创建与每个部件有关联的新角色。

对于每个组件部件(componentSimple1.script 和 componentSimple2.script),可通过以下操作创建一个新角色:

  1. 右键单击 Project Explorer 窗口内部并选择 New > Plug-in Role
  2. 为角色提供一个与(在 metadata.json 文件中输入的)组件 ID 一致的名称。对于我们的示例,componentSimple1.script 的角色名称为 componentSimple1,componentSimple2.script 的角色名称为 componentSimple2。
  3. 从标为 Create in part: 的下拉列表中选择您将用来创建角色的部件。
  4. 选择 configure.pystart.py 的目录结构和脚本存根。取消选择所有其他选项。

对于链接部件,可通过以下操作创建一个新角色:

  1. 右键单击 Project Explorer 窗口内部并选择 New > Plug-in Role
  2. 为角色提供一个与(在 metadata.json 文件中输入的)组件 ID 一致的名称。对于我们的示例,linkSimple.script 的角色名称为 linkSimple。
  3. 从标为 Create in part: 的下拉列表中选择 linkSimple.script
  4. 选择创建 changed.py 的目录结构和脚本存根。取消选择其他所有选项。

完成这些步骤后,您生命周期脚本的目录结构将类似于图 13。假设您已删除了 uninstall.py 的所有实例。

图 13. 本示例中使用的生命周期脚本
本示例中使用的生命周期脚本

生命周期脚本的规则和技巧

以下是每个生命周期脚本必须遵守的规则:

  1. 所有部件都必须在脚本的 .tgz 压缩文件的根目录中有一个 install.py 生命周期脚本。对于要加载的脚本,每个组件部件的 install.py 脚本必须包含以下行:
    maestro.install_scripts('scripts')

    这会将与插件捆绑的脚本复制到工作负载代理的脚本目录 (scriptdir),使它们成为可执行文件,以便代理可在部署中调用它们。

  2. 每个角色的 start.py 脚本必须向工作负载代理告知其状态。例如:
    	maestro.role_status = 'RUNNING'

    这会告诉系统,软件已安装且处于 RUNNING 状态。

  3. 角色不能在其名称中包含点 (.) 字符。
  4. 因为不同角色的生命周期脚本会同时被调用,所以请确保对它们进行了正确的管理,尤其在它们共享资源或服务时。为了避免资源冲突,您可以安排任务,在特定时刻运行某些脚本,而不与其他角色脚本并行运行。
  5. 要在一个生命周期脚本中调用 .sh shell 脚本,始终应使用方法 maestro.trace_call
  6. 在您调用的每个 shell 脚本中,使用 & 将它作为一个独立的后台进程运行,将 stdout (1) 和 stderr (2) 重定向到 /dev/null(空设备)。例如:
    yourscript.sh 1>2>/dev/null &

    这会阻止来自 stdout 或 stderr 的任何输出显示。

  7. 在生命周期脚本中实现尽可能多的代码,以避免对可能与特定 shell 或操作系统捆绑在一起的 shell 脚本产生依赖。

第 8 步:更新生成的生命周期脚本

解释了上述规则后,此步骤将更有意义。要使我们的示例正确运行,则需要向生成的生命周期脚本添加一些重要的遗失部分:

遵守上述规则 #1

编辑所有部件的 install.py 脚本,如果尚未提供它,则在每个文件的末尾(在记录器条目之后)添加以下行:

maestro.install_scripts('scripts')

遵守上述规则 #2

编辑所有组件部件的 start.py 脚本,在每个文件的末尾(在记录器条目之后)添加以下行:

maestro.role_status = 'RUNNING'

也可记录一条额外的消息,比如:

Logger.info("componentSimple1 status changed to RUNNING!");

这使您能够在部署和测试应用程序时,在日志文件中看到该消息。

最后,修改 linkSimple 组件中的 changed.py 脚本,以记录相应消息:

logger.info("Something has changed!");

转换和拓扑结构文档

目前为止,您通过 appmodel/metadata.json 文件描述了应出现在 Virtual Application Builder 中的组件和链接,还通过 plugin/config.json 文件描述了插件的插件配置信息。您为我们在本示例中提供的不同角色创建了必要的部件和生命周期脚本。下一步是告诉 Workload Deployer 或 PureApplication System,如何将元数据或应用程序模型转换为拓扑结构文档。

回想一下,config.json 中的每个包都定义了自己的一组硬件、操作系统和架构需求。对于 config.json 中定义的每个包,需要指定表明如何将该条目转换为拓扑结构文档片段的信息。可通过两种方式完成此操作:

  1. plugin/templates 目录中定义一个或多个 VM 模板(.vm 文件)。vm-template 是一种虚拟机模板。每个 .vm 文件都描述了如何基于 metadata.json 文件中定义的组件、链接和策略来创建特定的 VM。它还可以包含针对其他资源(比如存储)的请求。
  2. 创建扩展特定的内核服务类的 Java 代码,这些类包括 TopologyProvider、TopologyProcessor、ServiceProvisioner 和 PostProvisioner 等。

拓扑结构片段会在以后组合并解析为一个拓扑结构文档。通常建议尽可能地使用模板,仅将 Java 代码用于一个模板不够用的较复杂的情况。但是,一些人可能更喜欢(且建议)您直接使用 Java 代替模板。这是一个哲学问题。无论如何,您最终都会得到 Java 代码,因为在运行时,Apache Velocity 引擎会将 VM 模板(也称为速度模板)转换为 Java 代码。VM 模板为大多数简单任务提供了方便。您也可以混合使用两种方法。例如,一个组件可以使用一个基于模板的实现,而另一个组件使用一个基于 Java 的实现。

幸运的是,无论您使用何种实现,Eclipse PDK 都会为您完成创建转换的大部分工作。您需要做的就是使用 New OSGI Service Component 向导创建服务组件。该向导自动创建服务组件,以及您指定的每个组件或链接的拓扑结构提供程序。这是我们的下一个步骤。


第 9 步:创建 OSGi 服务组件

要创建一个新 OSGi 服务组件,请执行以下步骤:

  1. 转到 Project Explorer 视图,并右键单击 OSGI-INF 文件夹。
  2. 选择 New > OSGI Service Component 来调出 OSGI Service Component 向导。
  3. 在 Name 字段中,输入 config.json 文件中指定的组件或链接 ID。该向导自动填充剩余字段。请注意,定义文件的名称以及服务声明 .xml 文件的名称会自动设置为小写。针对组件 vm-template 名称的字段也会自动填写。
  4. Service type 下拉列表可用于选择要创建何种服务类型,在本例中,是选择使用基于模板还是基于 Java 的拓扑结构提供程序。图 14 演示了在选择基于模板的实现时出现的情形,图 15 演示了在选择基于 Java 的实现时出现的情形。
  5. 为我们的示例选择基于模板的实现。
  6. 当单击 Finish 时,新服务组件会添加到插件中的 OSGI-INF 文件夹中。创建任何关联的模板或 Java 源文件,自动更新 MANIFEST.MF 文件。
  7. 对于我们的示例,需要对 componentSimple1 和 componentSimple2 重复这些步骤。
  8. 对 linkSimple 执行相同的步骤,但删除自动填入 Component vm-template 字段中的名称 (linksimple.vm),将它复制到 Link vm-template 字段中,然后单击 Finish。这样,向导会自动生成一个链接 VM 模板,而不是组件 VM 模板。
    图 14. 创建基于模板的拓扑结构文档
    创建基于模板的拓扑结构文档
    图 15. 创建基于 Java 的拓扑结构
    创建基于 Java 的拓扑结构

OSGi 声明性服务

OSGi 是一个创建高度模块化的 Java 应用程序的规范。它允许您将一个复杂 Java 应用程序分解为多个模块,使您更容易管理它们之间的交叉关系。转换实现以 OSGi Declarative Services (DS) 类的形式提供。这时它们可以是声明性的,表明它们不需要显式的代码来发布或使用服务。无需为每个组件、链接和策略直接创建显式的 Java 接口和实现,OSGi 支持在一个 XML 文件中声明执行拓扑结构转换所需的相应实现类和接口。

OSGi 还向 Java 提供了其他许多优势。所有著名的 Java 应用服务器提供商如今都在使用 OSGi,而且许多复杂的应用程序(比如 Eclipse)都在其核心引擎中嵌入了 OSGi 技术。如果您感兴趣的话,可以访问 OSGi 网站

检查服务声明文件

清单 3 和清单 4 显示了为第一个组件 (componentSimple1) 的基于模板和基于 Java 的实现生成的服务声明文件。我们提供了第一个组件的基于 Java 的实现,以强调一些注意点,但请记住,每个组件或链接只需要一种类型的实现,本例中使用的是基于模板的实现。

如果对比清单 3 和清单 4,您会注意到基于模板的实现仍然使用了一个扩展 TopologyProvider 的实现类。两种实现的区别在于:对于基于 Java 的实现,您提供自己的扩展 TopologyProvider 的 Java 类(清单 5 中的类 ComponentSimple1 就是一个示例),而基于模板的实现会转换成为一个扩展 TopologyProvider 的 Java 类(基于所生成的 VM 模板文件)。该 Java 代码创建了一个 topology.json 输出,使用一个动态创建 JSON 元素的 JSON4J 类型库。本系列的第 2 部分会更详细地介绍这个主题。

清单 3. 基于模板的 componentsimple1.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" 
 name="componentSimple1">;
  <implementation class="com.ibm.maestro.model.transform.template.
   TemplateTransformer" />;
  <service>
   <provide interface="com.ibm.maestro.model.transform.TopologyProvider" />
  </service>
  <property name="component.template" type="String" value="templates/
   componentsimple1.vm" />
</scr:component>
清单 4. 基于 Java 的 componentsimple1.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" 
  name="componentSimple1">;
	<implementation class="SimpleComponent1" />;
	<service>
		<provide interface="com.ibm.maestro.model.transform.TopologyProvider" />
	</service>
</scr:component>
清单 5. 基于 Java 的实现骨架
package default;

import com.ibm.json.java.JSONObject;
import com.ibm.maestro.model.transform.TopologyProvider;

public class ComponentSimple1 extends TopologyProvider {

	/**
     * Transforms a component from the application model into objects for the topology 
     * document.
     *
     * @param vmTemplateNamePrefix
     *            Prefix for the vm-template name. Ensures uniqueness in the topology
     *            document; transforms may append arbitrary strings.
     * @param applicationUrl
     *            URL of the root of the application artifacts (within the storehouse).
     * @param applicationComponent
     *            Component object from the application model.
     * @param transformer
     *            TODO
     * @return Partial topology document containing objects created for the component.
     * @throws Exception
     *             Terminates the transformation process with an error.
     */
	@Override
	public JSONObject transformComponent(String prefix, String applicationUrl,
			JSONObject component, com.ibm.maestro.model.transform.Transformer 
            transformer) throws Exception {
		//TODO: implement your component transform logic
		return new JSONObject();
	}

	/**
     * Transforms a link from the application model by updating the partial 
     * topology documents associated with the source and target components. 
     * Note that all component transforms are run before the link transforms.
     *
     * @param sourceFragment
     *            Partial topology document associated with the source component.
     * @param targetFragment
     *            Partial topology document associated with the target component.
     * @param applicationUrl
     *            URL of the root of the application artifacts (within the storehouse).
     * @param applicationLink
     *            Link object from the application model.
     * @param transformer
     *            TODO
     * @throws Exception
     *             Terminates the transformation process with an error.
     */
	@Override
	public void transformLink(JSONObject sourceFragment, JSONObject targetFragment, 
     String applicationUrl,
		JSONObject link, com.ibm.maestro.model.transform.Transformer transformer) 
         throws Exception {
		//TODO: Implement your link transform logic
	}	
}

第 10 步:更新速度模板

当创建我们的示例的 OSGi 服务组件时,该工具会生成默认的速度模板(.vm 文件),并将它们放在 plug-in/templates 文件夹中。如果正确创建了 OSGi 服务组件,您的 MANIFEST.MF 文件就会已经更新为指向清单 3 和清单 4 中的 .xml 文件(如 图 14图 15 所示),您的 plug-in/templates 文件夹包含 3 个文件:componentsimple1.vmcomponentsimple2.vmlinksimple.vm。下一步是更新这些文件,使之与我们示例中的组件匹配。清单 6 到清单 8 给出了这 3 个文件。相应地更新它们。

清单 6. 已更新的 componentsimple1.vm 文件
{
    "vm-templates": [
        {
            "persistent":false,                 
            "name": "componentSimple1",
            "roles": [
                {
                    "parms": {
		
                    },
                    "type": "componentSimple1",
                    "name": "componentSimple1"
                }
            ],
            "packages": [
                "componentSimple1Pkg"
            ]
        }
    ]
}
清单 7. 已更新的 componentsimple2.vm 文件
{
    "vm-templates": [
        {
            "persistent":false,                 
            "name": "componentSimple2",
            "roles": [
                {
                    "parms": {
		
                    },
                    "type": "componentSimple2",
                    "name": "componentSimple2"
                }
            ],
            "packages": [
                "componentSimple2Pkg"
            ]
        }
    ]
}
清单 8. 已更新的 linksimple.vm 文件
#set( $sourceRole     = "componentSimple1" )  ## sourceRole     
 value used after template rendered
#set( $sourcePackages = ["linkSimplePkg"] )  ## sourcePackages 
 value used after template rendered
#set( $source = $provider.getMatchedRole( $sourceFragment, $sourceRole ) )
#set( $targetRole  = "componentSimple2" )
#set( $target = $provider.getMatchedRole( $targetFragment, $targetRole ) )
#if ( $target )
      #set( $roleType    = "banana" )
      #set( $dependsRole = "${target.template.name}.$target.role.name" )
#end


[
    {
        "role"        : "$dependsRole",
        "type"        : "$roleType",
        
    }
]

可通过链接组件在与每个组件有关联的角色之间引入依赖关系。这些依赖关系是在链接的转换文档中定义的,显示了哪个角色依赖于另一个角色,以及使用一个角色 depends 元素在它们之间传递哪些参数。在部署期间,这些依赖关系用于处理和同步应用程序。


第 11 步:构建模式类型和插件

要构建模式类型,只需右键单击它的项目并选择 IBM Workload Plug-in > Build。这还会构建所有关联插件。在构建期间,控制台窗口会显示不同的构建操作,最终会显示一条 “BUILD SUCCESSFUL” 或 “BUILD FAILED” 消息。如果构建成功,那么在刷新您的项目后,就可以看到一个已创建的导出目录,如图 16 所示。您需要将 .tgz 文件导入 Workload Deployer 或 PureApplication System 中。

图 16. 构建一个模式类型后生成的导出文件
构建一个模式类型后生成的导出文件

还可以采用相同方式独立构建插件项目。右键单击插件项目并选择 IBM Workload Plug-in > Build


将您的作品直接部署到 Workload Deployer 或 PureApplication System 中

如果拥有正确的访问权,那么可将您的作品直接从 Eclipse 部署到 Workload Deployer 或 PureApplication System 中。为此,首先必须配置与部署器通信所必要的信息。转到 Windows > Preferences 并选择 IBM Workload Plug-in,调出 IBM Workload Plug-in 窗口,如图 17 所示。

图 17. IBM Workload Plug-in 首选项窗口
IBM Workload Plug-in 首选项窗口

测试您的连接,确保测试成功后再应用更改。

完成此步骤后,可以右键单击某个模式类型或插件项目,然后选择 IBM Workload Plug-in > Install/update to deployer,以便使用您的模式类型和插件直接更新 Workload Deployer 或 PureApplication System。类似地,可以选择 IBM Workload Plug-in > Remove from deployer,从部署器删除模式类型和插件。请记住,要添加或删除一个插件,则必须启用与之关联的模式类型。如果获得 HTTP 响应代码 403 (Access Forbidden),则表示您无法使用此方法。必须手动导出该文件并导入 Workload Deployer 中。


第 12 步:手动导出和导入模式类型和插件

导出

从 Eclipse 成功构建一个模式类型或插件后,要手动导入它,请执行以下步骤:

  1. 右键单击相应的项目(模式类型或插件)并选择 Export
  2. 在 Export 对话框中,选择 General > File System 并单击 Next
  3. 指定导出目录下的 .tgz 包和系统应放置导出的文件的位置。单击 Finish

导入

在 Workload Deployer 或 PureApplication System 内,转到 Cloud > Pattern Types 菜单,导入您之前导出的对应于 Simple 模式类型的 .tgz 文件,如图 18 所示。导入模式类型会自动导入关联的插件。导入模式后,必须启用它。您还可以选择单独导入插件。为实现此操作,必须导航到 Cloud > System Plug-ins,单击工具栏上的 + 图标来添加新插件,并找到相应的 .tgz 文件。

图 18. 导入并启用一种模式类型
导入并启用一种模式类型

使用插件创建和部署一个虚拟应用程序

现在可以基于您所创建的模式类型和插件创建和部署一个虚拟应用程序实例:

  1. 回顾一下 图 1图 2图 5,导航到 Patterns > Virtual Applications,基于模式类型 “patterntype.Simple 1.0” 创建一个新虚拟应用程序实例。
  2. 在 Virtual Application Builder 内,将资源面板中现在显示的简单组件拖放到画布上,并使您的虚拟应用程序模式类似于 图 5
  3. 保存您的工作,为新模式提供一个名称。
  4. 退出 Virtual Application Builder。
  5. Patterns > Virtual Application 下找到新的 Virtual Application Pattern 并选择 Deploy
  6. 在 Deploy Virtual Application 窗口中,保留默认值并单击 Ok 开始部署。
  7. 在部署和激活期间,可导航到 Instances > Virtual Application Instances 检查所创建的 VM 实例和它们的状态。您还可以检查日志,确保系统调用了您插件中不同的生命周期脚本。图 19 显示了一个示例。
    图 19. 检查日志
    检查日志

结束语

我们对创建插件以将它用于虚拟应用程序模式的介绍到此就结束了。借助这些基本概念,您可以探索更复杂的示例。第 2 部分将通过一个更复杂的示例深入探讨一些插件主题。

致谢

感谢 Andre Tost 在评审本文期间提供的见解和建议。


下载

描述名字大小
代码样例patterntypeSimple-1.0.0.0.zip26KB

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere, Cloud computing
ArticleID=861008
ArticleTitle=为虚拟应用程序模式创建插件,第 1 部分:简介
publish-date=03112013