1 22 package org.jboss.test.system.controller.legacy; 23 24 import java.beans.PropertyEditor ; 25 import java.beans.PropertyEditorManager ; 26 import java.io.IOException ; 27 import java.io.StringReader ; 28 import java.io.StringWriter ; 29 import java.io.Writer ; 30 import java.util.ArrayList ; 31 import java.util.HashMap ; 32 import java.util.Iterator ; 33 import java.util.List ; 34 import java.util.ListIterator ; 35 import java.util.Properties ; 36 37 import javax.management.Attribute ; 38 import javax.management.InstanceNotFoundException ; 39 import javax.management.MBeanAttributeInfo ; 40 import javax.management.MBeanInfo ; 41 import javax.management.MBeanServer ; 42 import javax.management.ObjectInstance ; 43 import javax.management.ObjectName ; 44 import javax.xml.parsers.DocumentBuilder ; 45 import javax.xml.parsers.DocumentBuilderFactory ; 46 import javax.xml.transform.Transformer ; 47 import javax.xml.transform.TransformerException ; 48 import javax.xml.transform.TransformerFactory ; 49 import javax.xml.transform.dom.DOMSource ; 50 import javax.xml.transform.stream.StreamResult ; 51 52 import org.jboss.deployment.DeploymentException; 53 import org.jboss.logging.Logger; 54 import org.jboss.mx.util.JMXExceptionDecoder; 55 import org.jboss.mx.util.MBeanProxyExt; 56 import org.jboss.mx.util.ObjectNameFactory; 57 import org.jboss.system.ConfigurationException; 58 import org.jboss.system.ServiceBinding; 59 import org.jboss.system.ServiceContext; 60 import org.jboss.util.Classes; 61 import org.jboss.util.StringPropertyReplacer; 62 import org.jboss.util.propertyeditor.PropertyEditors; 63 import org.jboss.util.xml.DOMWriter; 64 import org.jboss.xb.binding.Unmarshaller; 65 import org.jboss.xb.binding.UnmarshallerFactory; 66 import org.jboss.xb.binding.sunday.unmarshalling.SchemaBindingResolver; 67 import org.jboss.xb.binding.sunday.unmarshalling.SingletonSchemaResolverFactory; 68 import org.w3c.dom.Document ; 69 import org.w3c.dom.Element ; 70 import org.w3c.dom.Node ; 71 import org.w3c.dom.NodeList ; 72 import org.w3c.dom.Text ; 73 74 83 public class OldServiceConfigurator 84 { 85 90 static 91 { 92 PropertyEditors.init(); 93 } 94 95 97 98 private final MBeanServer server; 99 100 101 private final OldServiceController serviceController; 102 103 104 private final OldServiceCreator serviceCreator; 105 106 107 private ServiceBinding serviceBinding; 108 109 112 private final Logger log = Logger.getLogger(getClass()); 113 114 116 123 public OldServiceConfigurator(MBeanServer server, 124 OldServiceController serviceController, OldServiceCreator serviceCreator) 125 { 126 this.server = server; 127 this.serviceController = serviceController; 128 this.serviceCreator = serviceCreator; 129 this.serviceBinding = null; 130 } 131 132 134 140 public void setServiceBinding(ServiceBinding serviceBinding) 141 { 142 this.serviceBinding = serviceBinding; 143 } 144 145 155 public List <ObjectName > install(Element config, ObjectName loaderName) throws DeploymentException 156 { 157 List <ObjectName > mbeans = new ArrayList <ObjectName >(); 158 try 159 { 160 if (config.getTagName().equals("mbean")) 161 { 162 internalInstall(config, mbeans, loaderName, true); 163 } 164 else 165 { 166 NodeList nl = config.getChildNodes(); 167 168 for (int i = 0; i < nl.getLength(); i++) 169 { 170 if (nl.item(i).getNodeType() == Node.ELEMENT_NODE) 171 { 172 Element element = (Element ) nl.item(i); 173 if (element.getTagName().equals("mbean")) 174 { 175 Element mbean = (Element ) nl.item(i); 176 internalInstall(mbean, mbeans, loaderName, true); 177 } } } } return mbeans; 182 } 183 catch (Exception e) 184 { 185 for (ListIterator li = mbeans.listIterator(mbeans.size()); li.hasPrevious();) 186 { 187 ObjectName mbean = (ObjectName ) li.previous(); 188 try 189 { 190 serviceCreator.remove(mbean); 191 } 192 catch (Exception n) 193 { 194 log.error("exception removing mbean after failed deployment: " + mbean, n); 195 } 196 } 197 198 if (e instanceof DeploymentException) 199 throw (DeploymentException) e; 200 201 throw new DeploymentException(e); 202 } 203 } 204 205 214 public String getConfiguration(ObjectName [] objectNames) 215 throws Exception 216 { 217 Writer out = new StringWriter (); 218 219 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 220 DocumentBuilder builder = factory.newDocumentBuilder(); 221 Document doc = builder.newDocument(); 222 223 Element serverElement = doc.createElement("server"); 224 225 for (int j = 0; j < objectNames.length; j++) 227 { 228 Element mbeanElement = internalGetConfiguration(doc, objectNames[j]); 229 serverElement.appendChild(mbeanElement); 230 } 231 232 doc.appendChild(serverElement); 233 234 new DOMWriter(out).setPrettyprint(true).print(doc); 236 237 out.close(); 238 239 return out.toString(); 241 } 242 243 245 260 protected void configure(ObjectName objectName, ObjectName loaderName, 261 Element mbeanElement, List <ObjectName > mbeans) 262 throws Exception 263 { 264 266 MBeanInfo info; 267 try 268 { 269 info = server.getMBeanInfo(objectName); 270 } 271 catch (InstanceNotFoundException e) 272 { 273 throw new DeploymentException("trying to configure nonexistent mbean: " + objectName); 275 } 276 catch (Exception e) 277 { 278 throw new DeploymentException("Could not get mbeanInfo", JMXExceptionDecoder.decode(e)); 279 } 281 if (info == null) 282 { 283 throw new DeploymentException("MBeanInfo is null for mbean: " + objectName); 284 } 286 ClassLoader cl = server.getClassLoader(loaderName); 288 MBeanAttributeInfo [] attributes = info.getAttributes(); 290 HashMap <String , MBeanAttributeInfo > attributeMap = new HashMap <String , MBeanAttributeInfo >(); 291 for (int i = 0; i < attributes.length; i++) 292 { 293 MBeanAttributeInfo attr = attributes[i]; 294 attributeMap.put(attr.getName(), attr); 295 } 296 297 NodeList attrs = mbeanElement.getChildNodes(); 298 for (int j = 0; j < attrs.getLength(); j++) 299 { 300 if (attrs.item(j).getNodeType() != Node.ELEMENT_NODE) 302 { 303 continue; 304 } 305 306 Element element = (Element ) attrs.item(j); 307 308 boolean replace = true; 309 310 if (element.getTagName().equals("attribute")) 312 { 313 String attributeName = element.getAttribute("name"); 314 boolean trim = true; 315 String replaceAttr = element.getAttribute("replace"); 316 if (replaceAttr.length() > 0) 317 replace = Boolean.valueOf(replaceAttr).booleanValue(); 318 String trimAttr = element.getAttribute("trim"); 319 if (trimAttr.length() > 0) 320 trim = Boolean.valueOf(trimAttr).booleanValue(); 321 String serialDataType = element.getAttribute("serialDataType"); 322 323 MBeanAttributeInfo attr = attributeMap.get(attributeName); 325 if (attr == null) 326 throw new DeploymentException("No Attribute found with name: " + attributeName); 327 328 if (element.hasChildNodes()) 329 { 330 Object value = null; 331 if (serialDataType.equals("javaBean")) 333 value = parseJavaBeanSerialData(attr, cl, element, replace, trim); 334 else if (serialDataType.equals("jbxb")) 335 value = parseJbxbSerialData(attr, cl, element, replace, trim); 336 else 337 value = parseTextSerialData(attr, cl, element, replace, trim); 338 339 log.debug(attributeName + " set to " + value + " in " + objectName); 340 setAttribute(objectName, new Attribute (attributeName, value)); 341 } 343 } 344 else if (element.getTagName().equals("depends")) 346 { 347 if (!element.hasChildNodes()) 348 { 349 throw new DeploymentException("No ObjectName supplied for depends in " + objectName); 350 } 351 352 String mbeanRefName = element.getAttribute("optional-attribute-name"); 353 if ("".equals(mbeanRefName)) 354 mbeanRefName = null; 355 else 356 mbeanRefName = StringPropertyReplacer.replaceProperties(mbeanRefName); 357 358 String proxyType = element.getAttribute("proxy-type"); 359 if ("".equals(proxyType)) 360 proxyType = null; 361 else 362 proxyType = StringPropertyReplacer.replaceProperties(proxyType); 363 364 ObjectName dependsObjectName = processDependency(objectName, loaderName, element, mbeans, replace); 366 log.debug("considering " + ((mbeanRefName == null) ? "<anonymous>" : mbeanRefName.toString()) + " with object name " + dependsObjectName); 367 368 if (mbeanRefName != null) 369 { 370 Object attribute = dependsObjectName; 371 if (proxyType != null) 372 { 373 if (mbeanRefName == null) 374 throw new DeploymentException("You cannot use a proxy-type without an optional-attribute-name"); 375 if (proxyType.equals("attribute")) 376 { 377 MBeanAttributeInfo attr = attributeMap.get(mbeanRefName); 378 if (attr == null) 379 throw new DeploymentException("No Attribute found with name: " + mbeanRefName); 380 proxyType = attr.getType(); 381 } 382 Class proxyClass = cl.loadClass(proxyType); 383 attribute = MBeanProxyExt.create(proxyClass, dependsObjectName, 384 server, true); 385 } 386 387 setAttribute(objectName, new Attribute (mbeanRefName, attribute)); 389 } } 391 else if (element.getTagName().equals("depends-list")) 393 { 394 String dependsListName = element.getAttribute("optional-attribute-name"); 395 if ("".equals(dependsListName)) 396 { 397 dependsListName = null; 398 } 400 NodeList dependsList = element.getChildNodes(); 401 ArrayList <ObjectName > dependsListNames = new ArrayList <ObjectName >(); 402 for (int l = 0; l < dependsList.getLength(); l++) 403 { 404 if (dependsList.item(l).getNodeType() != Node.ELEMENT_NODE) 405 { 406 continue; 407 } 408 409 Element dependsElement = (Element ) dependsList.item(l); 410 if (dependsElement.getTagName().equals("depends-list-element")) 411 { 412 if (!dependsElement.hasChildNodes()) 413 { 414 throw new DeploymentException("Empty depends-list-element!"); 415 } 417 ObjectName dependsObjectName = processDependency(objectName, loaderName, dependsElement, mbeans, replace); 419 if (!dependsListNames.contains(dependsObjectName)) 420 { 421 dependsListNames.add(dependsObjectName); 422 } } 424 425 } if (dependsListName != null) 427 { 428 setAttribute(objectName, new Attribute (dependsListName, dependsListNames)); 429 } } } 432 433 if (serviceBinding != null) 435 { 436 try 437 { 438 serviceBinding.applyServiceConfig(objectName); 439 } 440 catch (Exception e) 441 { 442 Throwable t = JMXExceptionDecoder.decode(e); 444 log.warn("Failed to apply service binding override", t); 445 } 446 } 447 } 448 449 451 private ObjectName internalInstall(Element mbeanElement, List <ObjectName > mbeans, 452 ObjectName loaderName, boolean replace) throws Exception 453 { 454 ObjectInstance instance = null; 455 ObjectName mbeanName = parseObjectName(mbeanElement, replace); 456 457 instance = serviceCreator.install(mbeanName, loaderName, mbeanElement); 458 459 mbeanName = instance.getObjectName(); 461 462 mbeans.add(mbeanName); 463 if (mbeanName != null) 464 { 465 ServiceContext ctx = serviceController.createServiceContext(mbeanName); 466 try 467 { 468 configure(mbeanName, loaderName, mbeanElement, mbeans); 469 ctx.state = ServiceContext.CONFIGURED; 470 ctx.problem = null; 471 } 472 catch (Throwable e) { 474 ctx.state = ServiceContext.FAILED; 475 ctx.problem = e; 476 log.info("Problem configuring service " + mbeanName, e); 477 } 479 } 480 481 return mbeanName; 482 } 483 484 495 private Object parseTextSerialData(MBeanAttributeInfo attr, ClassLoader cl, 496 Element element, boolean replace, boolean trim) 497 throws Exception 498 { 499 String attributeName = attr.getName(); 501 String attributeText = getElementContent(element, trim, replace); 502 String typeName = attr.getType(); 503 504 Class typeClass = Classes.getPrimitiveTypeForName(typeName); 506 if (typeClass == null) 507 { 508 try 510 { 511 typeClass = cl.loadClass(typeName); 512 } 513 catch (ClassNotFoundException e) 514 { 515 throw new DeploymentException 516 ("Class not found for attribute: " + attributeName, e); 517 } 518 } 519 520 Object value = null; 521 522 525 if (typeClass.equals(Element .class)) 526 { 527 NodeList nl = element.getChildNodes(); 529 for (int i = 0; i < nl.getLength(); i++) 530 { 531 Node n = nl.item(i); 532 if (n.getNodeType() == Node.ELEMENT_NODE) 533 { 534 value = n; 535 break; 536 } 537 } 538 if (replace) 540 { 541 PropertyEditor editor = PropertyEditorManager.findEditor(typeClass); 542 if (editor == null) 543 { 544 log.warn("Cannot perform property replace on Element"); 545 } 546 else 547 { 548 editor.setValue(value); 549 String text = editor.getAsText(); 550 text = StringPropertyReplacer.replaceProperties(text); 551 editor.setAsText(text); 552 value = editor.getValue(); 553 } 554 } 555 } 556 557 if (value == null) 558 { 559 PropertyEditor editor = PropertyEditorManager.findEditor(typeClass); 560 if (editor == null) 561 { 562 throw new DeploymentException 563 ("No property editor for attribute: " + attributeName + 564 "; type=" + typeClass); 565 } 566 567 ClassLoader tcl = Thread.currentThread().getContextClassLoader(); 570 Thread.currentThread().setContextClassLoader(cl); 571 try 572 { 573 editor.setAsText(attributeText); 574 value = editor.getValue(); 575 } 576 finally 577 { 578 Thread.currentThread().setContextClassLoader(tcl); 579 } 580 } 581 return value; 582 } 583 584 595 private Object parseJavaBeanSerialData(MBeanAttributeInfo attr, ClassLoader cl, 596 Element element, boolean replace, boolean trim) 597 throws Exception 598 { 599 String attributeClassName = element.getAttribute("attributeClass"); 601 if( attributeClassName == null || attributeClassName.length() == 0 ) 602 attributeClassName = attr.getType(); 603 Class attributeClass = cl.loadClass(attributeClassName); 604 Object bean = attributeClass.newInstance(); 606 NodeList properties = element.getElementsByTagName("property"); 608 Properties beanProps = new Properties (); 609 for(int n = 0; n < properties.getLength(); n ++) 610 { 611 Node node = properties.item(n); 613 if (node.getNodeType() != Node.ELEMENT_NODE) 614 { 615 continue; 616 } 617 Element property = (Element ) node; 618 String name = property.getAttribute("name"); 619 String value = getElementContent(property, trim, replace); 620 beanProps.setProperty(name, value); 621 } 622 623 PropertyEditors.mapJavaBeanProperties(bean, beanProps); 625 return bean; 626 } 627 628 640 private Object parseJbxbSerialData(MBeanAttributeInfo attr, ClassLoader cl, 641 Element element, boolean replace, boolean trim) 642 throws Exception 643 { 644 StringBuffer buffer = getElementContent(element); 646 647 SchemaBindingResolver resolver = SingletonSchemaResolverFactory.getInstance().getSchemaBindingResolver(); 649 Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller(); 650 StringReader reader = new StringReader (buffer.toString()); 651 Object bean = unmarshaller.unmarshal(reader, resolver); 652 return bean; 653 } 654 655 private ObjectName processDependency(ObjectName container, ObjectName loaderName, 656 Element element, List <ObjectName > mbeans, boolean replace) 657 throws Exception 658 { 659 ObjectName dependsObjectName = null; 660 NodeList nl = element.getChildNodes(); 661 for (int i = 0; i < nl.getLength(); i++) 662 { 663 Node childNode = nl.item(i); 664 if (childNode.getNodeType() == Node.ELEMENT_NODE) 665 { 666 Element child = (Element ) childNode; 667 if (child.getTagName().equals("mbean")) 668 { 669 dependsObjectName = internalInstall(child, mbeans, loaderName, replace); 670 break; 671 } 672 else 673 { 674 throw new DeploymentException("Non mbean child element in depends tag: " + child); 675 } } } 679 if (dependsObjectName == null) 680 { 681 String name = getElementContent(element, true, replace); 682 dependsObjectName = ObjectNameFactory.create(name); 683 } 684 if (dependsObjectName == null) 685 { 686 throw new DeploymentException("No object name found for attribute!"); 687 } 689 serviceController.registerDependency(container, dependsObjectName); 690 691 return dependsObjectName; 692 } 693 694 697 private void setAttribute(ObjectName name, Attribute attr) 698 throws Exception 699 { 700 try 701 { 702 server.setAttribute(name, attr); 703 } 704 catch (Exception e) 705 { 706 throw new DeploymentException("Exception setting attribute " + 707 attr + " on mbean " + name, JMXExceptionDecoder.decode(e)); 708 } 709 } 710 711 private Element internalGetConfiguration(Document doc, ObjectName name) 712 throws Exception 713 { 714 Element mbeanElement = doc.createElement("mbean"); 715 mbeanElement.setAttribute("name", name.toString()); 716 717 MBeanInfo info = server.getMBeanInfo(name); 718 mbeanElement.setAttribute("code", info.getClassName()); 719 MBeanAttributeInfo [] attributes = info.getAttributes(); 720 boolean trace = log.isTraceEnabled(); 721 for (int i = 0; i < attributes.length; i++) 722 { 723 if (trace) 724 log.trace("considering attribute: " + attributes[i]); 725 if (attributes[i].isReadable() && attributes[i].isWritable()) 726 { 727 Element attributeElement = null; 728 if (attributes[i].getType().equals("javax.management.ObjectName")) 729 { 730 attributeElement = doc.createElement("depends"); 731 attributeElement.setAttribute("optional-attribute-name", attributes[i].getName()); 732 } 733 else 734 { 735 attributeElement = doc.createElement("attribute"); 736 attributeElement.setAttribute("name", attributes[i].getName()); 737 } 738 Object value = server.getAttribute(name, attributes[i].getName()); 739 740 if (value != null) 741 { 742 if (value instanceof Element ) 743 { 744 attributeElement.appendChild(doc.importNode((Element ) value, true)); 745 } 746 else 747 { 748 attributeElement.appendChild(doc.createTextNode(value.toString())); 749 } 750 } 751 mbeanElement.appendChild(attributeElement); 752 } 753 } 754 755 ServiceContext sc = serviceController.getServiceContext(name); 756 for (Iterator i = sc.iDependOn.iterator(); i.hasNext();) 757 { 758 ServiceContext needs = (ServiceContext) i.next(); 759 Element dependsElement = doc.createElement("depends"); 760 dependsElement.appendChild(doc.createTextNode(needs.objectName.toString())); 761 mbeanElement.appendChild(dependsElement); 762 } 763 764 return mbeanElement; 765 } 766 767 775 private ObjectName parseObjectName(final Element element, boolean replace) 776 throws Exception 777 { 778 String name = element.getAttribute("name"); 779 780 if (name == null || name.trim().equals("")) 781 { 782 throw new DeploymentException("MBean attribute 'name' must be given."); 783 } 784 785 if (replace) 786 name = StringPropertyReplacer.replaceProperties(name); 787 788 return new ObjectName (name); 789 } 790 791 private String getElementContent(Element element, boolean trim, boolean replace) 792 throws Exception 793 { 794 NodeList nl = element.getChildNodes(); 795 String attributeText = ""; 796 for (int i = 0; i < nl.getLength(); i++) 797 { 798 Node n = nl.item(i); 799 if (n instanceof Text ) 800 { 801 attributeText += ((Text ) n).getData(); 802 } 803 } if (trim) 805 attributeText = attributeText.trim(); 806 if (replace) 807 attributeText = StringPropertyReplacer.replaceProperties(attributeText); 808 return attributeText; 809 } 810 811 823 public static StringBuffer getElementContent(Element element) throws IOException , TransformerException 824 { 825 NodeList children = element.getChildNodes(); 826 Element content = null; 827 for (int n = 0; n < children.getLength(); n++) 828 { 829 Node node = children.item(n); 830 if (node.getNodeType() == Node.ELEMENT_NODE) 831 { 832 content = (Element )node; 833 break; 834 } 835 } 836 if (content == null) 837 return null; 838 839 DOMSource source = new DOMSource (content); 841 TransformerFactory tFactory = TransformerFactory.newInstance(); 842 Transformer transformer = tFactory.newTransformer(); 843 StringWriter sw = new StringWriter (); 844 StreamResult result = new StreamResult (sw); 845 transformer.transform(source, result); 846 sw.close(); 847 return sw.getBuffer(); 848 } 849 } | Popular Tags |