pennate 发表于 2017-1-5 10:00:13

在 Geronimo 中管理 Apache Pluto

  Apache Pluto 简介
  Apache Pluto 是 Apache Portals 项目的子项目,它是 Java Portlet Specification 的开源实现。Pluto 项目提供了符合规范要求的 portlet 容器运行时环境,可以在其中初始化和管理 portlet。在本文中,我将讨论 Pluto 的高级功能以及如何将 Pluto 与 Apache Geronimo 集成。还有包含 Geronimo GBean 的样例应用程序(请参阅 下载 部分),Geronimo GBean 将用于抽象化 Pluto 框架的主要组件的公共接口。这些 GBean 随后可以被部署到一个运行中的 Geronimo 实例中,其中 GBean 可用于监视和管理 Pluto 的门户功能。
  Pluto 项目提供了以下组件:用于管理 portlet 的 portlet 容器、用于提供配置服务的专用门户应用程序 Portal Driver、模板框架和用于调用嵌入到容器内的各个 portlet 的框架。Pluto portlet 容器将管理 portlet 调用、portlet 上下文处理、portlet 部署描述符注册功能和 portlet 部署描述符服务。该容器还提供用于扩展自身附加功能的插件框架。
  Pluto portlet 容器公开了一组辅助的强制性服务和可选服务,还有一点值得一提的就是 portlet 与调用方之间的通信。本文中稍后将介绍这些服务。
  图 1 中的图表演示了 Apache Pluto 的主要组件。
  
图 1. Apache Pluto 的架构组件

  Apache Geronimo 简介
  Apache Geronimo 是完全兼容的 Java EE 平台,您可以使用它构建企业级应用程序和服务。Geronimo 基于使用控制反转(Inversion of Control,IoC)技术将组件与服务解耦的架构。这种解耦将建立一个极具可配置性和模块化的运行时环境。Geronimo 还利用 Java Management xtensions (JMX) 和类似的专有受管 bean 框架,使 Geronimo 成为易于监视、配置和管理的平台。
  Geronimo 使用给定的一系列汇编模块进行引导,这些模块通过一个轻量级内核组件进行内部连接和管理。Geronimo 模块是由一组类(依赖性、其他模块和序列化配置状态)组成的随机组件。Geronimo 内核将在 Geronimo 实例启动时装入并汇编模块。模块将决定运行时 Geronimo 子系统的功能和每个 Geronimo 子系统所需的依赖性。Geronimo 运行时中的所有核心服务都被部署为模块。
  模块是使用称为部署计划 或计划 的 XML 文档描述的。Geronimo 中的最终部署计划是由初始部署计划、Maven Project Object Model (POM) 文件和 Maven project.properties 文件的组合组成。图 2 显示了如何处理这些文件来创建最终的部署计划。
  
图 2. Geronimo 部署计划


  计划的内容是由 XML 模式文档(XML Schema Document,XSD)约束的。值得一提的是,计划将定义模块 ID,模块的依赖性、模块的环境属性、模块所提供的服务和模块的 GBean。
  清单 1 中的示例演示了一个简单的 Geronimo 部署计划。
  
清单 1. 简单的 Geronimo 部署计划

<?xmlversion="1.0"encoding="UTF-8"?>
<modulexmlns="http://geronimo.apache.org/xml/ns/deployment-1.1">
<environment>
<moduleId>
<groupId>geronimo</groupId>
<artifactId>simple</artifactId>
<version>1.0.0</version>
<type>car</type>
</moduleId>
<dependencies>
<dependency>
<groupId>geronimo</groupId>
<artifactId>j2ee-server</artifactId>
<type>car</type>
</dependency>
</dependencies>
<hidden-classes/>
<non-overridable-classes/>
</environment>

<gbeanname="SimpleService"class="com.example.myservices.MyServiceGBean">
<attributename="prop1">12345</attribute>
<attributename="prop2">Thisisthevalueforproperty2</attribute>
</gbean>
</module>



  当类似于清单 1 中的计划的部署计划被构建过程转换后,将用一个惟一名称创建配置归档(Configuration Archive,CAR)文件。为清单 1 中的配置生成的惟一名称是 geronimo/simple-1.0.0/car。
  Geronimo CAR 文件
  CAR 文件是自动生成的 Java Archive (JAR) 文件,其中包含部署计划和任何辅助资源的序列化状态。序列化部署计划包含在 CAR 的 META-INF 目录中名为 config.ser 的文件中。CAR 文件都是通过 Geronimo 的 Maven 打包插件由构建过程创建的。
  Geronimo 存储库
  Geronimo 存储库 存储了工件的数据和注册表,通常构建为文件系统中上的目录层次结构。二进制版本的 Geronimo 将提供名为 repository 的目录,该目录中包含组成核心 Geronimo 平台的模块的所有依赖性。
  Geronimo 工件 是随机实体,例如 JAR 文件、Web Archive (WAR) 文件、CAR 文件等等,该工件被使用 Geronimo Web 控制台或命令行部署和带有 Geronimo 发行版的构建工具添加到 Geronimo 存储库中。
  下载和安装 Apache Geronimo
  从 参考资料 部分列出的站点中下载 Geronimo 平台,并且将文件解压缩到称为 {GERONIMO_HOME} 的目录中。在下载并解压缩 Geronimo 发行版之后,请执行 Geronimo 安装的 {GERONIMO_HOME}/bin/ 目录中的启动脚本。您应当会看到类似图 3 所示的控制台窗口。
  
图 3. Geronimo 启动


  启动控制台将显示装入和启动的许多模块、连接器和应用程序并从中创建 Geronimo 运行时环境。您也可以使用 Geronimo 安装的 {GERONIMO_HOME}/bin/ 目录中的停止脚本来停止 Geronimo 运行时。
  Geronimo 所使用的 Pluto 服务
  Geronimo 1.1.1 将使用 Pluto 1.0.1 作为其管理控制台的门户环境。在此门户环境中,当 Web 控制台初始化时,将定义并装入门户容器所需要的服务和门户驱动器所使用的服务。
  下面是为 Geronimo 的启用了 Pluto 的 Web 控制台定义的标准服务列表:


[*]
配置服务 —— ConfigService 接口表示关于 Geronimo 的 Pluto 门户配置的信息。
[*]
工厂管理器服务 —— FactoryManagerService 接口表示用于管理在 Pluto 容器启动的过程中注册的工厂寿命的功能。
[*]
日志服务 —— LogManagerService 接口表示定义 Pluto 门户驱动器的日志记录实现的功能。
[*]
Portlet 定义注册服务 —— PortletDefinitionRegistryService 接口表示 Web 控制台门户中可用的所有 portlet 和 portlet 应用程序。此服务将提供和管理关于 Web 控制台 portlet 和 portlet 应用程序的信息。
[*]
Portlet 实体注册服务 —— PortletEntityRegistryService 接口表示 Web 控制台门户中可用的所有 portlet 和 portlet 应用程序实例的存储库。
[*]
页面注册服务 —— PageRegistryService 接口表示构成 Geronimo Web 控制台的页面、窗口和 portlet 条目的注册表。
  在本文中,您将创建 GBean 和实用程序,用于向在 Geronimo 运行时环境中运行的管理框架公开这些 Pluto 服务。
  管理 Pluto 门户环境
  在开始管理 Pluto 环境之前,您需要下载 Pluto 框架的源文件(有关链接,请参阅 参考资料 部分)。将文件下载并解压缩到引用为 {PLUTO_HOME} 的目录。
  表示前面提及的 Pluto 服务的对象实例可以被在同一个 servlet 上下文内作为 Web 控制台 Web 应用程序的组件检索。这将允许访问能够被 Geronimo GBean 包装的配置信息。
  Pluto 门户环境的配置信息将被 org.apache.pluto.portalImpl.services.ServiceManager 类中存储的对象引用并被使用 ServiceManager 类的 getService 方法检索。必须将对 org.apache.pluto.portalImpl.services.config.ConfigService 类的引用作为参数传递给 ServiceManager 类的 getService 方法才能检索 ConfigService 组件的实例。
  ConfigService 组件的实例可用后,您可以将此组件打包成一个标准的 Geronimo GBean 并使其可用于 Pluto 管理环境。清单 2 演示了如何由 Geronimo GBean 表示 ConfigService 信息。
  
清单 2. 作为 Geronimo GBean 的 ConfigService

publicclassConfigServiceGBean
implementsGBeanLifecycle
...{
publicstaticfinalGBeanInfoGBEAN_INFO;

static
...{
GBeanInfoBuilderinfoBuilder=
newGBeanInfoBuilder("ConfigServiceGBean",ConfigServiceGBean.class);

infoBuilder.addAttribute("parameters",
org.apache.pluto.portalImpl.util.Parameters.class,
true);

infoBuilder.addOperation("getParameters");
infoBuilder.addOperation("setString",newClass[]...{String.class,
String.class});
infoBuilder.addOperation("getString",newClass[]...{String.class});
infoBuilder.addOperation("getInteger",newClass[]...{String.class});
infoBuilder.addOperation("getBoolean",newClass[]...{String.class});
infoBuilder.addOperation("paramKeys");

GBEAN_INFO=infoBuilder.getBeanInfo();
}

publicstaticGBeanInfogetGBeanInfo()
...{
returnGBEAN_INFO;
}

privateorg.apache.pluto.portalImpl.services.config.ConfigServiceImpl
configServiceImpl=null;

publicConfigServiceGBean()
...{
try
...{
ClassconfigServiceCls=
Class.forName("org.apache.pluto.portalImpl.services.config.ConfigService");
org.apache.pluto.portalImpl.services.ServiceconfigService=
org.apache.pluto.portalImpl.services.ServiceManager.getService(configServiceCls);
if(configService!=null)
...{
configServiceImpl=
(org.apache.pluto.portalImpl.services.config.ConfigServiceImpl)
configService;
}
}
catch(Exceptione)
...{
System.err.println("ExceptioninConfigServiceGBean:"+e);
}
}

publicorg.apache.pluto.portalImpl.util.ParametersgetParameters()
...{
returnconfigServiceImpl.getParameters();
}

publicjava.util.IteratorparamKeys()
...{
returnconfigServiceImpl.getParameters().keys();
}

publicStringgetString(Stringname)
...{
returnconfigServiceImpl.getString(name);
}

publicvoidsetString(Stringname,Stringvalue)
...{
configServiceImpl.getParameters().setString(name,value);
}

publicIntegergetInteger(Stringname)
...{
returnconfigServiceImpl.getInteger(name);
}

publicBooleangetBoolean(Stringname)
...{
returnconfigServiceImpl.getBoolean(name);
}

publicvoiddoFail()
...{
System.err.println(getClass().getName()+"failed");
}

publicvoiddoStart()
throwsException
...{
System.out.println("Starting"+getClass().getName());
}

publicvoiddoStop()
throwsException
...{
System.out.println("Stopping"+getClass().getName());
}
}



  在为 ConfigService 组件创建了标准 Geronimo GBean 后,必须由 Geronimo 内核装入和启动它。您可以使用 org.apache.geronimo.kernel.KernelRegistry 类的 getSingleKernel 方法检索 Geronimo 内核。
  通过对内核的引用,可以使用 GBeanData 实例描述 GBean。该 GBean 随后被内核装入和启动,如清单 3 中所示:
  
清单 3. 使用 GBeanManager 装入和启动 GBean

publicclassGBeanManager
...{
publicstaticvoidloadAndStartGBean(ClassgBeanCls,
GBeanInfogBeanInfo,
StringserviceType)
...{
java.net.URIgBeanURI=
java.net.URI.create("devworks/"+gBeanCls.getName()+"/1.0.0/?service="
+serviceType);
org.apache.geronimo.gbean.AbstractNameabstractName=
neworg.apache.geronimo.gbean.AbstractName(gBeanURI);

org.apache.geronimo.gbean.GBeanDatagBeanData=
neworg.apache.geronimo.gbean.GBeanData(abstractName,gBeanInfo);
System.out.println("LoadedgBeanDataforclass:"+gBeanCls.getName());

org.apache.geronimo.kernel.KernelgeronimoKernel=
org.apache.geronimo.kernel.KernelRegistry.getSingleKernel();
System.out.println("Foundkernel:"+geronimoKernel.getKernelName());

ClassLoaderclsLoader=Thread.currentThread().getContextClassLoader();

try
...{
geronimoKernel.loadGBean(gBeanData,clsLoader);
System.out.println("LoadedgBean:"+gBeanCls.getName());
}
catch(GBeanAlreadyExistsExceptione)
...{
System.out.println("GBean["+gBeanCls.getName()+"]alreadyloaded");
}

try
...{
geronimoKernel.startGBean(gBeanCls);
System.out.println("StartedgBean:"+gBeanCls.getName());
}
catch(GBeanNotFoundExceptione)
...{
System.err.println("GBean["+gBeanCls.getName()+"]notfound");
}
}

publicstaticvoidstopAndUnloadGBean(ClassgBeanCls)
...{
org.apache.geronimo.kernel.KernelgeronimoKernel=
org.apache.geronimo.kernel.KernelRegistry.getSingleKernel();
System.out.println("Foundkernel:"+geronimoKernel.getKernelName());

try
...{
geronimoKernel.stopGBean(gBeanCls);
System.out.println("StoppedgBean:"+gBeanCls.getName());
}
catch(GBeanNotFoundExceptione)
...{
System.err.println("GBean["+gBeanCls.getName()+"]notfound");
return;
}

try
...{
geronimoKernel.unloadGBean(gBeanCls);
System.out.println("UnloadedgBean:"+gBeanCls.getName());
}
catch(GBeanNotFoundExceptione)
...{
System.err.println("GBean["+gBeanCls.getName()+"]notfound");
return;
}
}

publicstaticObjectgetGBean(ClassgBeanCls)
throwsGBeanNotFoundException
...{
org.apache.geronimo.kernel.KernelgeronimoKernel=
org.apache.geronimo.kernel.KernelRegistry.getSingleKernel();
System.out.println("Foundkernel:"+geronimoKernel.getKernelName());

returngeronimoKernel.getGBean(gBeanCls);
}
}




  在将 ConfigService 组件打包到 Geronimo GBean 中并由内核装入和启动之后,JavaServer Page (JSP) 组件或 servlet 可以使用 GBean 来访问 ConfigService 组件所管理的信息。
  清单 4 中的 JSP 示例演示了如何检索 ConfigService GBean 以及如何使用它获得和设定 ConfigService 组件所管理的信息。
  
清单 4. ConfigService GBean 的管理页面

<h3>PlutoAdminonGeronimo:ConfigService</h3>
<%
try
...{
com.devworks.pluto.gbeans.GBeanManager.loadAndStartGBean(
com.devworks.pluto.gbeans.ConfigServiceGBean.class,
com.devworks.pluto.gbeans.ConfigServiceGBean.GBEAN_INFO,
"config");

ObjectgbeanObj=
com.devworks.pluto.gbeans.GBeanManager.getGBean(
com.devworks.pluto.gbeans.ConfigServiceGBean.class);
if(gbeanObj!=null)
...{
com.devworks.pluto.gbeans.ConfigServiceGBeanconfigServiceGBean=
(com.devworks.pluto.gbeans.ConfigServiceGBean)gbeanObj;

java.util.EnumerationreqParams=request.getParameterNames();
while(reqParams.hasMoreElements())
...{
StringparamName=(String)reqParams.nextElement();
StringnewParamValue=request.getParameter(paramName);
StringoldParamValue=configServiceGBean.getString(paramName);
if(newParamValue.equalsIgnoreCase(oldParamValue)==false)
...{
System.out.println("Settingparam:"+paramName+"tovalue:"
+newParamValue);
configServiceGBean.setString(paramName,newParamValue);
}
}

out.println("<formname='configForm'method='post'"
+"action='ConfigServiceAdmin.jsp'><table>");
java.util.Iteratorkeys=configServiceGBean.paramKeys();
while(keys.hasNext())
...{
StringparamKey=keys.next().toString();
StringparamValue=configServiceGBean.getString(paramKey);
out.println("<tr><td>Param"+paramKey+"</td>"
+"<td><inputtype='text'name='"+paramKey
+"'value='"+paramValue+"'/></td>"
+"<td><inputtype='submit'value='submit'/></td></tr>");
}
out.println("</table>");

com.devworks.pluto.gbeans.GBeanManager.stopAndUnloadGBean(
com.devworks.pluto.gbeans.ConfigServiceGBean.class);
}
else
...{
out.println("UnabletofindConfigServiceGBean<br/>");
}
}
catch(Exceptione)
...{
e.printStackTrace(System.out);
out.println("<br/>Exception:"+e);
}
%>



  您可以访问其他服务所管理的信息,例如 portlet 定义注册服务或 portlet 实体注册服务,使用相同的技术把每个组件打包成 GBean。这些 GBean 随后可以被内核装入并启动并被诸如 JSP 或 servlet 之类的管理组件引用(要获得演示这些概念的源代码,请参阅 参考资料 部分)。
  配置用户和角色
  安全角色引用(由 org.apache.pluto.om.common.SecurityRoleRef 实例表示)将决定是否为每个 portlet 请求把用户映射为指定角色。采取标准 Java 2 Platform, Enterprise Edition (J2EE) 和 Java EE 安全措施,通过应用每个 portlet 定义内存储的安全角色引用集内配置的安全信息,确定在特殊 portlet 的上下文中提供给验证用户的权限。
  portlet 实体注册服务 GBean 用于为给定 portlet 定义检索和修改安全角色引用。与 ConfigService GBean 一样,将创建静态 GBeanInfo 对象并使其可用于静态 getGBeanInfo 方法,如清单 5 中所示:
  
清单 5. portlet 实体注册服务 GBean 的 GBeanInfo

publicclassPortletEntityRegistryServiceGBean
implementsGBeanLifecycle
...{
publicstaticfinalGBeanInfoGBEAN_INFO;

static
...{
GBeanInfoBuilderinfoBuilder=
newGBeanInfoBuilder("PortletEntityRegistryServiceGBean",
PortletEntityRegistryServiceGBean.class);

infoBuilder.addOperation("getPortletEntityKeys");
infoBuilder.addOperation("getPortletEntityID",
newClass[]...{String.class});
infoBuilder.addOperation("getPortletEntityWindowList",
newClass[]...{String.class});
infoBuilder.addOperation("getPortletEntityDefName",
newClass[]...{String.class});
infoBuilder.addOperation("getPortletEntityDefAppID",
newClass[]...{String.class});
infoBuilder.addOperation("getPortletEntityDefAppContext",
newClass[]...{String.class});
infoBuilder.addOperation("getSecurityRoleRefs",
newClass[]...{String.class});
infoBuilder.addOperation("setSecurityRoleRefs",
newClass[]...{String.class,
org.apache.pluto.om.common.SecurityRoleRefSet.class});

GBEAN_INFO=infoBuilder.getBeanInfo();
}

publicstaticGBeanInfogetGBeanInfo()
...{
returnGBEAN_INFO;
}



  GBeanInfo 对象所定义的每项操作是使用 org.apache.pluto.portalImpl.services.ServiceManager 类中存储的对象实例实现的,并且是使用 ServiceManager 类的 getService 方法检索的。在类似于 ConfigService GBean 的方式中,必须把对 org.apache.pluto.portalImpl.services.portletentityregistry.PortletEntityRegistryService 类的引用作为参数传递给 ServiceManager 类的 getService 方法才能检索 PortletEntityRegistryService 组件的实例。
  当 PortletEntityRegistryService 组件的实例可用并且公开为标准 Geronimo GBean 后,可以使 portlet 的安全角色信息可用于 Pluto 管理环境,如清单 6 中的 GBean 方法所示:
  
清单 6. portlet 实体注册服务 GBean 所提供的安全角色信息

publicorg.apache.pluto.om.common.SecurityRoleRefSet
getSecurityRoleRefs(StringentityKey)
...{
org.apache.pluto.portalImpl.om.portlet.impl.PortletDefinitionImpl
portletDefinitionImpl=getPortletDefImpl(entityKey);
if(portletDefinitionImpl==null)
...{
returnnull;
}

returnportletDefinitionImpl.getCastorInitSecurityRoleRefs();
}

publicvoidsetSecurityRoleRefs(StringentityKey,
org.apache.pluto.om.common.SecurityRoleRefSetsecurityRoleRefSet)
...{
org.apache.pluto.portalImpl.om.portlet.impl.PortletDefinitionImpl
portletDefinitionImpl=getPortletDefImpl(entityKey);
if(portletDefinitionImpl==null)
...{
return;
}

portletDefinitionImpl.setCastorInitSecurityRoleRefs(securityRoleRefSet);
}



  当把所需的服务打包成 GBean 并使其可用于内核后,您可以使用它们监视和管理门户应用程序,请看下一部分的介绍。
  监视和管理门户应用程序
  要使用前述 GBean,必须在 Web 控制台应用程序所在的上下文中使用这些 GBean。您将通过把 JSP、servlet 和/或 Java 类添加到 Web 控制台 CAR 文件中来完成操作。对于 Jetty Web 控制台,您可以在位于 Geronimo/webconsole-jetty/1.1.1/car 目录的 Geronimo 存储库中找到 CAR 文件。Web 控制台的 Web 应用程序位于名为 framework.war 的 .war 文件中,该文件位于 CAR 目录中。
  要使用先前定义的 GBean 把 Pluto 管理功能添加到 Geronimo 中,请创建名为 plutoadmin 的 framework.war 的新子目录。在 plutoadmin 目录中,放置可在样例代码中找到的 JSP(请参阅 下载 部分)。这些 JSP 提供了 GBeanManager 类来访问 GBean。
  在用所需的 JSP 和其他 Web 资源(以及每次对 plutoadmin 资源所做的修改)填充了 plutoadmin 目录后,您必须使用 Geronimo deployer 实用程序重新启动 Web 控制台 CAR 文件,如清单 7 中所示:
  
清单 7. 重新启动 Web 控制台 CAR 文件的命令行




                           
C:/<GERONIMO_HOME>/bin>deploy --user system --password manager restart /
geronimo/webconsole-jetty/1.1.1/car




  清单 8 中显示了此命令行的结果。
  
清单 8. 重新启动 Web 控制台 CAR 文件的结果




                           
Restarted geronimo/webconsole-jetty/1.1.1/car
`-> standard.war
`-> framework.war




  现在把 Web 浏览器指向 http://localhost:8080/console/plutoadmin/ 以访问 Pluto 管理页面。提供了本文中所述的每项主要服务的链接。您可以研究每个链接及其关联的 GBean。
  结束语Apache Geronimo 将使用 Apache Pluto 作为其管理控制台的门户环境。使用 Geronimo 的受管 bean 框架,可以把 Pluto 服务打包并提供给组件和服务,以允许提供灵活且功能强大的环境来管理 Pluto 组件和服务。
  下载
  




描述
名字
大小
下载方法


本文的样例代码
os-ag-geronpluto.zip
104KB
HTTP








关于下载方法的信息





  参考资料
  学习



[*]您可以参阅本文在 developerWorks 全球站点上的 英文原文。
[*]浏览并研究 Apache Pluto 项目。
[*]研究 JSR-000168 Portlet Specification。
[*]访问 developerWorks Apache Geronimo 项目区,以获取文档、教程和其他资源以帮助您开始使用 Geronimo 进行开发。
[*]访问 developerWorks 的 Get started now with Apache Geronimo 部分,查找对于初学者和有经验的用户都有帮助的参考资料。
[*]查阅 IBM® Support for Apache Geronimo 提供的参考资料,让您能够在世界级的 IBM 支持下开发 Geronimo 应用程序。
[*]访问 developerWorks 开放源码专区,获得丰富的 how-to 信息、工具和项目更新,帮助您使用开放源码技术进行开发,并与 IBM 产品结合使用。
[*]随时关注 developerWorks 的 技术事件和网络广播。
[*]浏览在 developerWorks Open source 专区中可获取的所有 Apache 文章 和 Apache 免费教程。
[*]浏览 Safari 书店 中关于这些内容及其他技术主题的书籍
页: [1]
查看完整版本: 在 Geronimo 中管理 Apache Pluto