ServiceComponent.java
上传用户:xfwatch
上传日期:2020-12-14
资源大小:872k
文件大小:16k
源码类别:

中间件编程

开发平台:

Java

  1. /*
  2.  * RHQ Management Platform
  3.  * Copyright (C) 2005-2008 Red Hat, Inc.
  4.  * All rights reserved.
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation version 2 of the License.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19. package org.rhq.plugins.blacktie;
  20. import java.io.InputStream;
  21. import java.io.StringWriter;
  22. import java.util.List;
  23. import java.util.Properties;
  24. import java.util.Set;
  25. import javax.management.MBeanServerConnection;
  26. import javax.management.ObjectName;
  27. import javax.management.remote.JMXConnector;
  28. import javax.management.remote.JMXConnectorFactory;
  29. import javax.management.remote.JMXServiceURL;
  30. import javax.xml.transform.OutputKeys;
  31. import javax.xml.transform.Transformer;
  32. import javax.xml.transform.TransformerException;
  33. import javax.xml.transform.TransformerFactory;
  34. import javax.xml.transform.dom.DOMSource;
  35. import javax.xml.transform.stream.StreamResult;
  36. import org.apache.commons.logging.Log;
  37. import org.apache.commons.logging.LogFactory;
  38. import org.jboss.blacktie.jatmibroker.core.conf.XMLEnvHandler;
  39. import org.jboss.blacktie.jatmibroker.core.conf.XMLParser;
  40. import org.rhq.core.domain.configuration.Configuration;
  41. import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
  42. import org.rhq.core.domain.content.PackageType;
  43. import org.rhq.core.domain.content.transfer.DeployPackageStep;
  44. import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
  45. import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
  46. import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
  47. import org.rhq.core.domain.measurement.AvailabilityType;
  48. import org.rhq.core.domain.measurement.MeasurementDataNumeric;
  49. import org.rhq.core.domain.measurement.MeasurementReport;
  50. import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
  51. import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
  52. import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
  53. import org.rhq.core.pluginapi.content.ContentFacet;
  54. import org.rhq.core.pluginapi.content.ContentServices;
  55. import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
  56. import org.rhq.core.pluginapi.inventory.CreateResourceReport;
  57. import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
  58. import org.rhq.core.pluginapi.inventory.ResourceComponent;
  59. import org.rhq.core.pluginapi.inventory.ResourceContext;
  60. import org.rhq.core.pluginapi.measurement.MeasurementFacet;
  61. import org.rhq.core.pluginapi.operation.OperationFacet;
  62. import org.rhq.core.pluginapi.operation.OperationResult;
  63. import org.w3c.dom.Element;
  64. /**
  65.  * This can be the start of your own custom plugin's server component. Review
  66.  * the javadoc for {@link ResourceComponent} and all the facet interfaces to
  67.  * learn what you can do in your resource component. This component has a lot of
  68.  * methods in it because it implements all possible facets. If your resource
  69.  * does not support, for example, configuration, you can remove the
  70.  * {@link ConfigurationFacet} from the <code>implements</code> clause and remove
  71.  * all method implementations that that facet required.
  72.  * 
  73.  * <p>
  74.  * You should not only read the javadoc in each of this class' methods, but you
  75.  * should also read the javadocs linked by their "see" javadoc tags since those
  76.  * additional javadocs will contain a good deal of additional information you
  77.  * will need to know.
  78.  * </p>
  79.  * 
  80.  * @author John Mazzitelli
  81.  */
  82. public class ServiceComponent implements ResourceComponent, MeasurementFacet,
  83. OperationFacet, ConfigurationFacet, ContentFacet, DeleteResourceFacet,
  84. CreateChildResourceFacet {
  85. private final Log log = LogFactory.getLog(ServiceComponent.class);
  86. /**
  87.  * Represents the resource configuration of the custom product being
  88.  * managed.
  89.  */
  90. private Configuration resourceConfiguration;
  91. private ResourceContext resourceContext;
  92. private MBeanServerConnection beanServerConnection;
  93. private String serverName = null;
  94. private String serviceName = null;
  95. private ObjectName blacktieAdmin = null;
  96. private String[]  times = null;
  97. /**
  98.  * This is called when your component has been started with the given
  99.  * context. You normally initialize some internal state of your component as
  100.  * well as attempt to make a stateful connection to your managed resource.
  101.  * 
  102.  * @see ResourceComponent#start(ResourceContext)
  103.  */
  104. public void start(ResourceContext context) {
  105. try {
  106. Properties prop = new Properties();
  107. XMLEnvHandler handler = new XMLEnvHandler(prop);
  108. XMLParser xmlenv = new XMLParser(handler, "btconfig.xsd");
  109. xmlenv.parse("btconfig.xml");
  110. JMXServiceURL u = new JMXServiceURL((String) prop.get("JMXURL"));
  111. JMXConnector c = JMXConnectorFactory.connect(u);
  112. beanServerConnection = c.getMBeanServerConnection();
  113. serviceName = context.getResourceKey();
  114. blacktieAdmin = new ObjectName("jboss.blacktie:service=Admin");
  115. // get name from MBean
  116. serverName = (String) beanServerConnection.invoke(blacktieAdmin,
  117. "getServerName", new Object[] { serviceName },
  118. new String[] { "java.lang.String" });
  119. } catch (Exception e) {
  120. log.error("start server " + serviceName + " plugin error with " + e);
  121. }
  122. log.debug("start resource: " + serviceName);
  123. }
  124. /**
  125.  * This is called when the component is being stopped, usually due to the
  126.  * plugin container shutting down. You can perform some cleanup here; though
  127.  * normally not much needs to be done here.
  128.  * 
  129.  * @see ResourceComponent#stop()
  130.  */
  131. public void stop() {
  132. }
  133. /**
  134.  * All resource components must be able to tell the plugin container if the
  135.  * managed resource is available or not. This method is called by the plugin
  136.  * container when it needs to know if the managed resource is actually up
  137.  * and available.
  138.  * 
  139.  * @see ResourceComponent#getAvailability()
  140.  */
  141. public AvailabilityType getAvailability() {
  142. AvailabilityType status = AvailabilityType.DOWN;
  143. try {
  144. ObjectName objName = new ObjectName(
  145. "jboss.messaging.destination:service=Queue,name=" + 
  146. serviceName);
  147. beanServerConnection.getAttribute(objName, "ConsumerCount");
  148. status = AvailabilityType.UP;
  149. } catch (Exception e) {
  150. }
  151. return status;
  152. }
  153. /**
  154.  * The plugin container will call this method when your resource component
  155.  * has been scheduled to collect some measurements now. It is within this
  156.  * method that you actually talk to the managed resource and collect the
  157.  * measurement data that is has emitted.
  158.  * 
  159.  * @see MeasurementFacet#getValues(MeasurementReport, Set)
  160.  */
  161. public void getValues(MeasurementReport report,
  162. Set<MeasurementScheduleRequest> requests) {
  163. for (MeasurementScheduleRequest request : requests) {
  164. String name = request.getName();
  165. try {
  166. if (name.equals("messageCounter")) {
  167. Number value = (Long)beanServerConnection.invoke(blacktieAdmin, 
  168. "getServiceCounter",
  169. new Object[] { serverName, serviceName}, 
  170. new String[] {"java.lang.String", "java.lang.String"});
  171. report.addData(new MeasurementDataNumeric(request, value
  172. .doubleValue()));
  173. } else if (name.equals("errorCounter")) {
  174. Number value = (Long)beanServerConnection.invoke(blacktieAdmin, 
  175. "getErrorCounter",
  176. new Object[] { serverName, serviceName}, 
  177. new String[] {"java.lang.String", "java.lang.String"});
  178. report.addData(new MeasurementDataNumeric(request, value
  179. .doubleValue()));
  180. } else if (name.equals("minResponseTime")) {
  181. String responseTime = (String)beanServerConnection.invoke(blacktieAdmin, 
  182. "getResponseTime",
  183. new Object[] { serverName, serviceName}, 
  184. new String[] {"java.lang.String", "java.lang.String"});
  185. times = responseTime.split(",");
  186. Number value = Long.parseLong(times[0]);
  187. report.addData(new MeasurementDataNumeric(request, value
  188. .doubleValue()));
  189. } else if (name.equals("avgResponseTime")) {
  190. if(times != null) {
  191. Number value = Long.parseLong(times[1]);
  192. report.addData(new MeasurementDataNumeric(request, value
  193. .doubleValue()));
  194. }
  195. } else if (name.equals("maxResponseTime")) {
  196. if(times != null) {
  197. Number value = Long.parseLong(times[2]);
  198. report.addData(new MeasurementDataNumeric(request, value
  199. .doubleValue()));
  200. }
  201. } else if (name.equals("queueDepth")) {
  202. Number value = (Integer)beanServerConnection.invoke(blacktieAdmin, 
  203. "getQueueDepth",
  204. new Object[] { serverName, serviceName}, 
  205. new String[] {"java.lang.String", "java.lang.String"});
  206. report.addData(new MeasurementDataNumeric(request, value
  207. .doubleValue()));
  208. }
  209. } catch (Exception e) {
  210. log.error("Failed to obtain measurement [" + name
  211. + "]. Cause: " + e);
  212. e.printStackTrace();
  213. }
  214. }
  215. return;
  216. }
  217. /**
  218.  * The plugin container will call this method when it wants to invoke an
  219.  * operation on your managed resource. Your plugin will connect to the
  220.  * managed resource and invoke the analogous operation in your own custom
  221.  * way.
  222.  * 
  223.  * @see OperationFacet#invokeOperation(String, Configuration)
  224.  */
  225. public OperationResult invokeOperation(String name, Configuration params) {
  226. OperationResult result = new OperationResult();
  227. int id = Integer.parseInt(params.getSimpleValue("id", "0"));
  228. if (name.equals("advertise") || name.equals("unadvertise")) {
  229. if(serviceName == null) {
  230. result.setErrorMessage("service name can not empty");
  231. } else {
  232. try{
  233. Boolean r =  (Boolean)beanServerConnection.invoke(blacktieAdmin, 
  234. name,
  235. new Object[] { serverName, serviceName}, 
  236. new String[] {"java.lang.String", "java.lang.String"});
  237. if(r){
  238. result.setSimpleResult(name + " OK");
  239. } else {
  240. result.setErrorMessage(name + " FAIL");
  241. }
  242. } catch (Exception e) {
  243. log.error("call " + name + " service " + serviceName
  244. + " failed with " + e);
  245. result.setErrorMessage("call " + name + " service " + serviceName
  246. + " failed with " + e);
  247. }
  248. }
  249. } else if (name.equals("listServiceStatus")) {
  250. try {
  251. Element status;
  252. if(id == 0) {
  253. status = (Element)beanServerConnection.invoke(blacktieAdmin, 
  254. "listServiceStatus",
  255. new Object[] { serverName, serviceName}, 
  256. new String[] {"java.lang.String", "java.lang.String"});
  257. } else {
  258. status = (Element)beanServerConnection.invoke(blacktieAdmin, 
  259. "listServiceStatusById",
  260. new Object[] { serverName, id, serviceName}, 
  261. new String[] {"java.lang.String", "int", "java.lang.String"});
  262. }
  263. if (status != null) {
  264. try {
  265. // Set up the output transformer
  266. TransformerFactory transfac = TransformerFactory.newInstance();
  267. Transformer trans = transfac.newTransformer();
  268. trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
  269. trans.setOutputProperty(OutputKeys.INDENT, "yes");
  270. StringWriter sw = new StringWriter();
  271. StreamResult sr = new StreamResult(sw);
  272. DOMSource source = new DOMSource(status);
  273. trans.transform(source, sr);
  274. result.setSimpleResult(sw.toString());
  275. } catch (TransformerException e) {
  276. log.error(e);
  277. }
  278. } else {
  279. result.setErrorMessage("no service status");
  280. }
  281. } catch (Exception e) {
  282. log.error("call status failed with "+ e);
  283. result.setErrorMessage("call status failed with "+ e);
  284. }
  285. } else if (name.equals("getServiceCounter")) {
  286. try {
  287. if(serviceName == null) {
  288. result.setErrorMessage("service name can not empty");
  289. } else {
  290. Long counter;
  291. if(id == 0) {
  292. counter = (Long)beanServerConnection.invoke(blacktieAdmin, 
  293. "getServiceCounter",
  294. new Object[] { serverName, serviceName}, 
  295. new String[] {"java.lang.String", "java.lang.String"});
  296. } else {
  297. counter = (Long)beanServerConnection.invoke(blacktieAdmin, 
  298. "getServiceCounterById",
  299. new Object[] { serverName, id, serviceName}, 
  300. new String[] {"java.lang.String", "int", "java.lang.String"});
  301. }
  302. result.setSimpleResult(counter.toString());
  303. }
  304. } catch (Exception e) {
  305. log.error("call get counter of " + serviceName 
  306. + " failed with " + e);
  307. result.setErrorMessage("call get counter of " + serviceName 
  308. + " failed with " + e);
  309. }
  310. }
  311. return result;
  312. }
  313. /**
  314.  * The plugin container will call this method and it needs to obtain the
  315.  * current configuration of the managed resource. Your plugin will obtain
  316.  * the managed resource's configuration in your own custom way and populate
  317.  * the returned Configuration object with the managed resource's
  318.  * configuration property values.
  319.  * 
  320.  * @see ConfigurationFacet#loadResourceConfiguration()
  321.  */
  322. public Configuration loadResourceConfiguration() {
  323. // here we simulate the loading of the managed resource's configuration
  324. if (resourceConfiguration == null) {
  325. // for this example, we will create a simple dummy configuration to
  326. // start with.
  327. // note that it is empty, so we're assuming there are no required
  328. // configs in the plugin descriptor.
  329. resourceConfiguration = new Configuration();
  330. }
  331. Configuration config = resourceConfiguration;
  332. return config;
  333. }
  334. /**
  335.  * The plugin container will call this method when it has a new
  336.  * configuration for your managed resource. Your plugin will re-configure
  337.  * the managed resource in your own custom way, setting its configuration
  338.  * based on the new values of the given configuration.
  339.  * 
  340.  * @see ConfigurationFacet#updateResourceConfiguration(ConfigurationUpdateReport)
  341.  */
  342. public void updateResourceConfiguration(ConfigurationUpdateReport report) {
  343. // this simulates the plugin taking the new configuration and
  344. // reconfiguring the managed resource
  345. resourceConfiguration = report.getConfiguration().deepCopy();
  346. report.setStatus(ConfigurationUpdateStatus.SUCCESS);
  347. }
  348. /**
  349.  * When this is called, the plugin is responsible for scanning its managed
  350.  * resource and look for content that need to be managed for that resource.
  351.  * This method should only discover packages of the given package type.
  352.  * 
  353.  * @see ContentFacet#discoverDeployedPackages(PackageType)
  354.  */
  355. public Set<ResourcePackageDetails> discoverDeployedPackages(PackageType type) {
  356. return null;
  357. }
  358. /**
  359.  * The plugin container calls this method when new packages need to be
  360.  * deployed/installed on resources.
  361.  * 
  362.  * @see ContentFacet#deployPackages(Set, ContentServices)
  363.  */
  364. public DeployPackagesResponse deployPackages(
  365. Set<ResourcePackageDetails> packages,
  366. ContentServices contentServices) {
  367. return null;
  368. }
  369. /**
  370.  * When a remote client wants to see the actual data content for an
  371.  * installed package, this method will be called. This method must return a
  372.  * stream of data containing the full content of the package.
  373.  * 
  374.  * @see ContentFacet#retrievePackageBits(ResourcePackageDetails)
  375.  */
  376. public InputStream retrievePackageBits(ResourcePackageDetails packageDetails) {
  377. return null;
  378. }
  379. /**
  380.  * This is the method that is used when the component has to create the
  381.  * installation steps and their results.
  382.  * 
  383.  * @see ContentFacet#generateInstallationSteps(ResourcePackageDetails)
  384.  */
  385. public List<DeployPackageStep> generateInstallationSteps(
  386. ResourcePackageDetails packageDetails) {
  387. return null;
  388. }
  389. /**
  390.  * This is called when the actual content of packages should be deleted from
  391.  * the managed resource.
  392.  * 
  393.  * @see ContentFacet#removePackages(Set)
  394.  */
  395. public RemovePackagesResponse removePackages(
  396. Set<ResourcePackageDetails> packages) {
  397. return null;
  398. }
  399. /**
  400.  * When called, the plugin container is asking the plugin to create a new
  401.  * managed resource. The new resource's details need to be added to the
  402.  * given report.
  403.  * 
  404.  * @see CreateChildResourceFacet#createResource(CreateResourceReport)
  405.  */
  406. public CreateResourceReport createResource(CreateResourceReport report) {
  407. return null;
  408. }
  409. /**
  410.  * When called, the plugin container is asking the plugin to delete a
  411.  * managed resource.
  412.  * 
  413.  * @see DeleteResourceFacet#deleteResource()
  414.  */
  415. public void deleteResource() {
  416. }
  417. }