JMX コンソールを使用して MBean を作成し、デプロイしてサービスを管理します。 管理タスクを実行できるように、サービス属性と操作を公開します。
JMX コンソールの使用について詳しくは、 JMX コンソールを使用したサーバーリソースの監視.
Apache Felix プラットフォームで、MBean を OSGi サービスとしてデプロイします。 MBean サービスを OSGi サービスレジストリに登録すると、Aries JMX Whiteboard モジュールがその MBean を自動的に MBean サーバーに登録します。これにより、公開属性および操作を公開する JMX コンソールに MBean が表示されます。
CQ5 または CRX リソースを管理するために作成する MBean は、javax.management.DynamicMBean インターフェイスに基づいています。 作成するには、JMX 仕様に規定されている通常のデザインパターンに従います。
管理インターフェイスを定義するだけでなく、OSGi サービスインターフェイスも定義します。 実装クラスは OSGi サービスを実装します。
この com.adobe.granite.jmx.annotation パッケージには、MBean メタデータを JMX コンソールに簡単に提供するための注釈とクラスがいくつか用意されています。 MBean の MBeanInfo オブジェクトに情報を直接追加する代わりに、これらの注釈およびクラスを使用します。
注釈
MBean メタデータを指定するための注釈を管理インターフェイスに追加します。 この情報は、デプロイされる各実装クラスの JMX コンソールに表示されます。 以下の注釈を使用できます ( 詳しくは、 com.adobe.granite.jmx.annotation JavaDocs):
説明: MBean クラスまたはメソッドの説明を提供します。 クラス宣言で使用すると、MBean の JMX コンソールページに説明が表示されます。 メソッドで使用すると、対応する属性または操作のホバーテキストとして説明が表示されます。
Impact:メソッドの影響。有効なパラメーター値は、javax.management.MBeanOperationInfo によって定義されるフィールドです。
名前: 操作パラメータに表示する名前を指定します。 この注釈を使用して、インターフェイスで使用されるメソッドパラメータの実際の名前を上書きします。
OpenTypeInfo: JMX コンソールで複合データまたは表形式データを表すために使用するクラスを指定します。 オープン MBean で使用
表形式の種類情報: 表形式データを表すために使用するクラスに注釈を付けるために使用します。
クラス
インターフェイスに追加した注釈を使用する Dynamic MBean を作成するためのクラスが提供されます。
通常、MBean は、管理する OSGi サービスへの反映です。 Felix プラットフォームでは、他の Java サーバープラットフォームにデプロイする場合と同様に MBean を作成します。 主な違いは、注釈を使用して MBean 情報を指定できる点です。
次のサンプル MBean は、CRX リポジトリに関する情報を提供します。 このインターフェイスでは、Description 注釈を使用して JMX コンソールに情報を提供します。
package com.adobe.example.myapp;
import com.adobe.granite.jmx.annotation.Description;
@Description("Example MBean that exposes repository properties.")
public interface ExampleMBean {
@Description("The name of the repository.")
String getRepositoryName();
@Description("The vendor of the repository.")
String getRepositoryVendor();
@Description("The URL of repository vendor.")
String getVendorUrl();
}
実装クラスは、SlingRepository サービスを使用して CRX リポジトリに関する情報を取得します。
package com.adobe.example.myapp;
import org.apache.felix.scr.annotations.*;
import org.apache.sling.jcr.api.SlingRepository;
import com.adobe.granite.jmx.annotation.AnnotatedStandardMBean;
import javax.management.*;
public class ExampleMBeanImpl extends AnnotatedStandardMBean implements ExampleMBean {
@Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY)
private SlingRepository repository;
public ExampleMBeanImpl() throws NotCompliantMBeanException {
super(ExampleMBean.class);
}
public String getRepositoryName() {
return repository.getDescriptor("jcr.repository.name");
}
public String getRepositoryVendor() {
return repository.getDescriptor("jcr.repository.vendor");
}
public String getVendorUrl() {
return repository.getDescriptor("jcr.repository.vendor.url");
}
}
次の図は、JMX コンソールでのこの MBean のページを示しています。
MBean を OSGi サービスとして登録すると、MBean サーバーに自動的に登録されます。 CQ5 に MBean をインストールするには、他の OSGi サービスと同様に、バンドルに MBean サービスを含めて MBean サービスを書き出します。
OSGi 関連のメタデータに加えて、Aries JMX Whiteboard モジュールが MBean を MBean サーバーに登録するために必要なメタデータも指定する必要があります。
DynamicMBean インターフェイス名: MBean サービスが javax.management.DynamicMBea
n インターフェイスを実装することを宣言します。この宣言によって、サービスが MBean サービスであることが Aries JMX Whiteboard モジュールに通知されます。
MBean ドメインおよびキーのプロパティ: Felix 上で、この情報を MBean の OSGi サービスのプロパティとして提供します。これは、通常 javax.management.ObjectName
オブジェクトの MBean サーバーに提供する情報と同じです。
MBean が単一のサービスの反射である場合は、MBean サービスの 1 つのインスタンスのみが必要です。 この場合、Felix SCR Maven プラグインを使用する場合、MBean 実装クラスで Apache Felix Service Component Runtime(SCR) 注釈を使用して、JMX 関連のメタデータを指定できます。 複数の MBean インスタンスをインスタンス化するには、MBean の OSGi サービスの登録を実行する別のクラスを作成できます。 この場合、JMX 関連のメタデータが実行時に生成されます。
単一の MBean
設計時にすべての属性と操作を定義できる MBean は、MBean 実装クラスの SCR 注釈を使用してデプロイできます。 次の例では、Service
注釈の value
属性によって、サービスが DynamicMBean
インターフェイスを実装することを宣言しています。Property
注釈の name
属性は、JMX ドメインおよびキーのプロパティを指定します。
package com.adobe.example.myapp;
import org.apache.felix.scr.annotations.*;
import org.apache.sling.jcr.api.SlingRepository;
import com.adobe.granite.jmx.annotation.AnnotatedStandardMBean;
import javax.management.*;
@Component(immediate = true)
@Property(name = "jmx.objectname", value="com.adobe.example:type=CRX")
@Service(value = DynamicMBean.class)
public class ExampleMBeanImpl extends AnnotatedStandardMBean implements ExampleMBean {
@Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY)
private SlingRepository repository;
public ExampleMBeanImpl() throws NotCompliantMBeanException {
super(ExampleMBean.class);
}
public String getRepositoryName() {
return repository.getDescriptor("jcr.repository.name");
}
public String getRepositoryVendor() {
return repository.getDescriptor("jcr.repository.vendor");
}
public String getVendorUrl() {
return repository.getDescriptor("jcr.repository.vendor.url");
}
}
複数の MBean サービスインスタンス
管理対象サービスの複数のインスタンスを管理するには、対応する MBean サービスの複数のインスタンスを作成します。 さらに、管理対象インスタンスの開始または終了時に、MBean サービスインスタンスを作成または削除する必要があります。MBean マネージャークラスを作成して、実行時に MBean サービスをインスタンス化し、サービスのライフサイクルを管理することができます。
BundleContext を使用して、MBean を OSGi サービスとして登録します。 JMX 関連の情報を、 BundleContext.registerService
メソッド。
次のコードの例では、ExampleMBean サービスがプログラムによって登録されています。 componentContext オブジェクトは ComponentContext で、BundleContext へのアクセスを提供します。
Dictionary mbeanProps = new Hashtable();
mbeanProps.put("jmx.objectname", "com.adobe.example:type=CRX");
ExampleMBeanImpl mbean = new ExampleMBeanImpl();
ServiceRegistration serviceregistration =
componentContext.getBundleContext().registerService(DynamicMBean.class.getName(), mbean, mbeanProps);
詳しくは、次の節の MBean の例を参照してください。
MBean サービスマネージャーは、サービス設定がリポジトリに格納される場合に役立ちます。 マネージャーは、サービス情報を取得し、それを使用して、対応する MBean を設定および作成できます。 manager クラスは、リポジトリの変更イベントをリッスンし、それに応じて MBean サービスを更新することもできます。
この例の MBean は、リポジトリに保存されている CQ5 ワークフローモデルに関する情報を提供します。 MBean マネージャークラスは、リポジトリに保存されるワークフローモデルに基づいて MBean を作成し、実行時に OSGi サービスを登録します。 この例は、次のメンバーが含まれる 1 つのバンドルで構成されています。
簡単にするために、この例のコードはログを実行せず、スローされた例外に対して反応しません。
WorkflowMBeanManagerImpl には、コンポーネントのアクティベーションメソッドが含まれています。 コンポーネントがアクティブになると、メソッドは次のタスクを実行します。
MBean メタデータは、JMX コンソールに com.adobe.example ドメイン、workflow_model タイプ、プロパティはワークフローモデル設定ノードのパスで表示されます。
このサンプルには、MBean インターフェイスと、com.day.cq.workflow.model.WorkflowModel
インターフェイスを表す実装が必要です。MBean は非常にシンプルなので、この例ではデザインの設定とデプロイメントの側面に焦点を当てることができます。 MBean は、1 つの属性(モデル名)を公開します。
package com.adobe.example.myapp.api;
import com.adobe.granite.jmx.annotation.Description;
@Description("Example MBean that exposes Workflow model properties.")
public interface WorkflowMBean {
@Description("The name of the Workflow model.")
String getModelName();
}
package com.adobe.example.myapp.impl;
import javax.management.NotCompliantMBeanException;
import com.day.cq.workflow.model.WorkflowModel;
import com.adobe.example.myapp.api.WorkflowMBean;
import com.adobe.granite.jmx.annotation.AnnotatedStandardMBean;
public class WorkflowMBeanImpl extends AnnotatedStandardMBean implements WorkflowMBean {
WorkflowModel model;
protected WorkflowMBeanImpl(WorkflowModel inmodel)
throws NotCompliantMBeanException {
super(WorkflowMBean.class);
model=inmodel;
}
public String getModelName() {
return model.getTitle();
}
}
WorkflowMBeanManager サービスには、WorkflowMBean サービスを作成するコンポーネントアクティベーションメソッドが含まれています。 このサービスの実装には、次のメソッドが含まれます。
WorkflowMBeanManager 実装は、コンポーネントがアクティベートされたときに存在するモデル設定用の MBean サービスのみを作成します。 より堅牢な実装では、新しいモデル設定に関するリポジトリイベント、および既存のモデル設定の変更や削除に関するリポジトリイベントをリッスンします。 変更が発生すると、マネージャーは対応する WorkflowMBean サービスを作成、変更または削除できます。
package com.adobe.example.myapp.api;
public interface WorkflowMBeanManager {
}
package com.adobe.example.myapp.impl;
import java.util.*;
import org.apache.felix.scr.annotations.*;
import javax.jcr.Session;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.management.ObjectName;
import org.apache.sling.jcr.api.SlingRepository;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.day.cq.workflow.WorkflowService;
import com.day.cq.workflow.WorkflowSession;
import com.adobe.example.myapp.api.WorkflowMBean;
import com.adobe.example.myapp.api.WorkflowMBeanManager;
/**Instantiates and registers WorkflowMBean services */
@Component(immediate=true)
@Service(value=WorkflowMBeanManager.class)
public class WorkflowMBeanManagerImpl implements WorkflowMBeanManager {
//The ComponentContext provides access to the BundleContext
private ComponentContext componentContext;
//Use the SlingRepository service to read model nodes
@Reference
private SlingRepository repository = null;
//Use the WorkflowService service to create WorkflowModel objects
@Reference
private WorkflowService workflowservice = null;
private Session session;
//Details about model nodes
private static final String MODEL_ROOT ="/etc/workflow/models";
private static final String MODEL_NODE = "model";
private Set<String> modelIds = new HashSet<String>();
//Storage for ServiceRegistrations for MBean services
private Collection<ServiceRegistration> mbeanRegistrations= new Vector<ServiceRegistration>(0,1);
@Activate
protected void activate(ComponentContext ctx) {
//Traverse the repository and load the model nodes
try {
session = repository.loginAdministrative(null);
// load and store model node paths
if (session.nodeExists(MODEL_ROOT)) {
getModelIds(session.getNode(MODEL_ROOT));
}
//Create MBeans for each model
for(String modid: modelIds){
makeMBean(modid);
}
}catch(Exception e){ }
}
/**
* Add JMX domain and key properties to a collection
* Instantiate a WorkflowModel and its WorkflowMBeanImpl object
* Register the MBean OSGi service
*/
private void makeMBean(String modelId) {
// create MBean for the model
try {
Dictionary<String, String> mbeanProps = new Hashtable<String, String>();
//These properties appear on the JMX Console home page
mbeanProps.put("jmx.objectname", "com.adobe.example:type=workflow_model,id=" + ObjectName.quote(modelId));
WorkflowSession wfsession = workflowservice.getWorkflowSession(session);
WorkflowMBeanImpl mbean = new WorkflowMBeanImpl(wfsession.getModel(modelId));
ServiceRegistration serviceregistration = componentContext.getBundleContext().registerService(WorkflowMBean.class.getName(), mbean, mbeanProps);
//Store the ServiceRegistration objects for deactivation
mbeanRegistrations.add(serviceregistration);
} catch (Throwable t) {}
}
/**
* Traverses the repository branch below a given Node. Stores the path of each model node.
*/
private void getModelIds(Node node) throws RepositoryException {
try{
NodeIterator iter = node.getNodes();
while (iter.hasNext()) {
Node n = iter.nextNode();
//Look for "jcr:content" nodes
if (n.getName().equals("jcr:content")) {
//get the path of the model node and save it
if(n.hasNode(MODEL_NODE)){
modelIds.add(n.getNode(MODEL_NODE).getPath());
}
} else{
//Scan child nodes
getModelIds(n);
}
}
}catch(Exception e){ }
}
/**
* Log out of the JCR session and unregister WorkflowMBean services
*/
@Deactivate
protected void deactivate() {
session.logout();
session=null;
for(ServiceRegistration sr:mbeanRegistrations){
sr.unregister();
}
}
}
以下の XML コードをコピーしてプロジェクトの pom.xml ファイルに貼り付け、コンポーネントバンドルを作成できます。POM は、必要な複数のプラグインおよび依存関係を参照します。
プラグイン:
注意: 書き込み時には、maven scr プラグインは Eclipse 用 m2e プラグインと互換性がありません。 ( Felix バグ 3170.) Eclipse IDE を使用するには、Maven をインストールし、コマンドラインインターフェイスを使用してビルドを実行します。
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.adobe.example.myapp</groupId>
<artifactId>workflow-mbean</artifactId>
<version>0.0.2-SNAPSHOT</version>
<name>mbean-simple</name>
<url>www.adobe.com</url>
<description>A simple MBean</description>
<packaging>bundle</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<version>1.7.2</version>
<executions>
<execution>
<id>generate-scr-scrdescriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.3</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>com.adobe.example.myapp.*;version=${project.version}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr.annotations</artifactId>
<version>1.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.api</artifactId>
<version>2.0.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr</artifactId>
<version>1.6.1-R1236132</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.jcr.api</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>com.adobe.granite</groupId>
<artifactId>com.adobe.granite.jmx</artifactId>
<version>0.1.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.day.cq.wcm</groupId>
<artifactId>cq-wcm-mobile-api</artifactId>
<version>5.5.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.day.cq.workflow</groupId>
<artifactId>cq-workflow-api</artifactId>
<version>5.5.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
次のプロファイルを Maven 設定ファイルに追加して、パブリックAdobeリポジトリを使用します。
<profile>
<id>adobe-public</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<releaseRepository-Id>adobe-public-releases</releaseRepository-Id>
<releaseRepository-Name>Adobe Public Releases</releaseRepository-Name>
<releaseRepository-URL>https://repo.adobe.com/nexus/content/groups/public</releaseRepository-URL>
</properties>
<repositories>
<repository>
<id>adobe-public-releases</id>
<name>Adobe Basel Public Repository</name>
<url>https://repo.adobe.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>adobe-public-releases</id>
<name>Adobe Basel Public Repository</name>
<url>https://repo.adobe.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>