14 Replies Latest reply on Oct 11, 2007 8:25 AM by alesj

    Getting runtime component name from attachment

    alesj

      Is there a better way of doing this:

      public class BasicMetaDataNameProvider implements MetaDataNameProvider
      {
       public Object getRuntimeComponentName(Serializable attachment)
       {
       if (attachment instanceof BeanMetaData)
       {
       BeanMetaData beanMetaData = (BeanMetaData)attachment;
       return beanMetaData.getName();
       }
       else if (attachment instanceof ServiceMetaData)
       {
       ServiceMetaData serviceMetaData = (ServiceMetaData)attachment;
       return serviceMetaData.getObjectName().getCanonicalName();
       }
       throw new IllegalArgumentException("Cannot handle attachment of type: " + attachment.getClass());
       }
      }
      


      Since I quickly stumbled upon this:
      java.lang.IllegalArgumentException: Cannot handle attachment of type: class org.jboss.resource.metadata.mcf.LocalDataSourceDeploymentMetaData
       at org.jboss.profileservice.management.BasicMetaDataNameProvider.getRuntimeComponentName(BasicMetaDataNameProvider.java:49)
       at org.jboss.profileservice.management.KernelBusRuntimeComponentDispatcher.dispatch(KernelBusRuntimeComponentDispatcher.java:52)
       at org.jboss.profileservice.management.ManagementViewImpl.updateComponent(ManagementViewImpl.java:659)
      

      And by looking at LocalDataSourceDeploymentMetaData, I didn't see anything that would resemble some component's name.
      Only if I pulled out what is under its jndi name?

        • 1. Re: Getting runtime component name from attachment

          Can you explain what MetaDataNameProvider is trying to do?

          Your solution is far from OO.

          If this is in the deployers, then you should be doing it from the components,
          each component deployer decides its own name for the components.

          String componentName = deploymentUnit.getName();

          If this is from the ManagedObject stuff then the name should be provided by the
          ManagedObjectCreator in the ManagedObject somewhere.

          In fact, it should be on each ManagedProperty since there is no guarantee
          one ManagedObject maps to one context on the bus.
          e.g. The DataSource maps to four JMX MBeans (ConnectionManager, ConnectionPool,
          ConnectionFactory, JNDIBinder).

          • 2. Re: Getting runtime component name from attachment
            alesj

             

            "adrian@jboss.org" wrote:

            Your solution is far from OO.

            :-)
            This was initial testing rubbish.

            "adrian@jboss.org" wrote:

            In fact, it should be on each ManagedProperty since there is no guarantee
            one ManagedObject maps to one context on the bus.
            e.g. The DataSource maps to four JMX MBeans (ConnectionManager, ConnectionPool, ConnectionFactory, JNDIBinder).

            Yup, my thoughts exactly.
            But was somehow surprised this wasn't already the case.
            public @interface ManagementProperty
            {
             /** The description */
             String description() default ManagementConstants.GENERATED;
            
             /** The external name of the property. If undefined its taken
             * from the property the annotation is on.
             */
             String name() default AnnotationDefaults.EMPTY_STRING;
            
             /** The internal name of the property as it relates to metadata */
             String mappedName() default AnnotationDefaults.EMPTY_STRING;
            
             /** Whether this property is mandatory */
             boolean mandatory() default false;
            
             /** Whether to create a managed object for the property */
             boolean managed() default false;
            
             /** Whether to ignore this property */
             boolean ignored() default false;
            
             /** The views this property should be used in */
             ViewUse[] use() default {ViewUse.CONFIGURATION};
            
             /** The class to use for the ManagedProperty implementation */
             Class<? extends ManagedProperty> propertyFactory() default NULL_PROPERTY_FACTORY.class;
             /** The class to use for the ManagedProperty Fields implementation */
             Class<? extends Fields> fieldsFactory() default NULL_FIELDS_FACTORY.class;
             /** The constraints, allowed values populator factory */
             Class<? extends ManagedPropertyConstraintsPopulatorFactory> constraintsFactory()
             default NULL_CONSTRAINTS.class;
            
            }
            


            How should this be added?
            Human touch only or is there something 'we' can do/deduct?

            Only deduction I see is what you suggested - if it isn't on the MP, then it should be taken from MO, which was set by MOC.

            • 3. Re: Getting runtime component name from attachment

               

              "alesj" wrote:

              Yup, my thoughts exactly.
              But was somehow surprised this wasn't already the case.


              The link to the Bus didn't exist until you created it. ;-)


              Only deduction I see is what you suggested - if it isn't on the MP, then it should be taken from MO, which was set by MOC.


              That sounds correct (and logical :-) to me.

              • 4. Re: Getting runtime component name from attachment
                alesj

                Any initial thoughs/directions on ManagedObjectCreator JBMICROCONT-181 critique?

                Since after my initial look at getting runtime component name in OO fashion, looks like that is direction I have to take/implement.

                • 5. Re: Getting runtime component name from attachment
                  starksm64

                  To summarize what we talked about this morning(here), MO is the server side view. We should just add a component name to the ManagedObject interface, along with a ManagementRuntimeRef annotation that can be used to identify which property defines the component name:

                  public interface ManagedObject extends Serializable
                  {
                   /**
                   * Get the runtime component name
                   * @see {@linkplain ManagementRuntimeRef}
                   * @return name of runtime component if one exists, null if no component exists.
                   */
                   String getComponentName();
                  ...
                  


                  Beyond that its just a question of how the property value is translated into the getComponentName() value. By default it could just be the property value. It could be another plugin api to obtain the name for a given attachment type/property name at the deployer or AbstractManagedObjectFactory level to go beyond this.

                  Clients do not deal with ManagedObjects. They deal with ManagedDeployment/ManagedComponents. A ManagedComponent is an extension of ManagedObject currently, so if we want to be clean, either the common client side api could be factored into a common base interface, or ManagedComponent could just be a trimmed down client view of ManagedObject.


                  • 6. Re: Getting runtime component name from attachment
                    ccrouch

                    So the ProfileServiceUnitTestcase would be using ManagedDeployment/ManagedComponents?

                    • 7. Re: Getting runtime component name from attachment
                      alesj

                       

                      "charles.crouch@jboss.com" wrote:
                      So the ProfileServiceUnitTestcase would be using ManagedDeployment/ManagedComponents?

                      It is already using just those. ;-)

                      The question is should the MComp be stripped down - since now it extends MO.

                      • 8. Re: Getting runtime component name from attachment
                        alesj

                         

                        "scott.stark@jboss.org" wrote:
                        To summarize what we talked about this morning(here), MO is the server side view. We should just add a component name to the ManagedObject interface, along with a ManagementRuntimeRef annotation that can be used to identify which property defines the component name:

                        public interface ManagedObject extends Serializable
                        {
                         /**
                         * Get the runtime component name
                         * @see {@linkplain ManagementRuntimeRef}
                         * @return name of runtime component if one exists, null if no component exists.
                         */
                         String getComponentName();
                        ...
                        


                        I'll hack this part tomorrow in the morning.

                        "scott.stark@jboss.org" wrote:

                        Beyond that its just a question of how the property value is translated into the getComponentName() value. By default it could just be the property value. It could be another plugin api to obtain the name for a given attachment type/property name at the deployer or AbstractManagedObjectFactory level to go beyond this.

                        I think some kind of translator could be added to AbstractManagedObjectFactory - e.g. translate ObjectName to ObjectName.getCanonicalName.
                        Or it can already be a part of @ManagementRuntimeRef.

                        "scott.stark@jboss.org" wrote:

                        Clients do not deal with ManagedObjects. They deal with ManagedDeployment/ManagedComponents. A ManagedComponent is an extension of ManagedObject currently, so if we want to be clean, either the common client side api could be factored into a common base interface, or ManagedComponent could just be a trimmed down client view of ManagedObject.

                        I think we can have a common interface which both MO and MC would extend, stripping some details from MC.
                        I'll push in the initial common interface, and you can still refactor it later.

                        • 9. Re: Getting runtime component name from attachment
                          alesj

                           

                          "alesj" wrote:

                          Or it can already be a part of @ManagementRuntimeRef.

                          Transformer hook added to the annotation.
                          And we also check if a transformer was registered for the PropertyInfo.getType in AbstractManagedObjectFactory.

                          "alesj" wrote:

                          I think we can have a common interface which both MO and MC would extend, stripping some details from MC.
                          I'll push in the initial common interface, and you can still refactor it later.

                          I added ManagedCommon (not very inspired name).
                          It holds propertys that looked to me that could belong to both interfaces + getting the tests pass. :-)

                          • 10. Re: Getting runtime component name from attachment
                            alesj

                            I guess this is a bug:

                             AbstractManagedObjectFactory:
                            
                             public MetaValue getValue(BeanInfo beanInfo, ManagedProperty property, Serializable object)
                             {
                             ...
                             // Look for a ManagementObjectID
                             ManagementObjectID id = (ManagementObjectID) property.getAnnotations().get(ManagementObjectID.class.getName());
                            


                            I guess it should be:
                             // Look for a ManagementObjectRef
                             ManagementObjectRef ref = (ManagementObjectRef) property.getAnnotations().get(ManagementObjectRef.class.getName());
                             String moName = (ref != null ? ref.name() : value.getClass().getName());
                            


                            • 11. Re: Getting runtime component name from attachment
                              alesj

                              I this what we want?

                               @ManagementProperty(name="max-pool-size", managed = true)
                               @ManagementObjectRef(name = "JBossManagedConnectionPool", type = "LocalTx")
                               public void setMaxSize(int maxSize)
                               {
                               this.maxPoolSize = maxSize;
                               }
                              

                              Since this way we override the underlying simple values of the attachment metadata with information about managed object ref.

                              "adrian@jboss.org" wrote:
                              In fact, it should be on each ManagedProperty since there is no guarantee
                              one ManagedObject maps to one context on the bus.
                              e.g. The DataSource maps to four JMX MBeans (ConnectionManager, ConnectionPool,
                              ConnectionFactory, JNDIBinder).

                              How else to bind a property with a runtime component that is not mapped to declared MO's runtime component (if exists)?
                              And at the same time preserve the underlying attachment's values.


                              • 12. Re: Getting runtime component name from attachment
                                starksm64

                                No, each ManagedProperty maps to a ManagedObject that corresponds to a runtime component when its marked with the runtime=true field of @ManagementObject. The name value of the @ManagementObjectRef is really not useful since your are binding this at the class level. Its typically used with a ManagedProperty that provides the name to tie the runtime ManagedObject to the root ManagedObject.

                                 @ManagementObjectRef(type = "LocalTx")
                                 public String getJndiName()
                                 {
                                 // The full ManagedObject name is name=getJndiName(),type="LocalTx"
                                 }
                                



                                • 13. Re: Getting runtime component name from attachment
                                  alesj

                                  This would/does produce a CCE with the current code:

                                  In AbstractManagedObjectFactory.getValue

                                  Property is not managed, so we resolve to a simple metattype

                                   if (managed)
                                   {
                                   TypeInfo typeInfo = propertyInfo.getType();
                                   if( typeInfo.isArray() || typeInfo.isCollection() )
                                   metaType = new ArrayMetaType(1, MANAGED_OBJECT_META_TYPE);
                                   else
                                   metaType = MANAGED_OBJECT_META_TYPE;
                                   }
                                   else
                                   {
                                   metaType = metaTypeFactory.resolve(propertyInfo.getType());
                                   }
                                  


                                  And since metatype is not managed we push in simple value
                                   return metaValueFactory.create(value, propertyInfo.getType());
                                  


                                  But on the ManagementViewImpl.processManagedObject

                                  // See if this is a ManagementObjectRef
                                   ManagementObjectRef ref = (ManagementObjectRef) pannotations.get(ManagementObjectRef.class.getName());
                                   if ( ref != null )
                                   {
                                   // The reference key is the prop value + ref.type()
                                   log.debug("Property("+prop.getName()+") references: "+ref);
                                   SimpleValue refValue = (SimpleValue) prop.getValue();
                                   String refName = (String) refValue.getValue();
                                   if (refName == null)
                                   refName = ref.name();
                                   String targetKey = refName + "/" + ref.type();
                                  


                                  refValue.getValue() is an Integer, since our property returned max-pool-size. :-)

                                  • 14. Re: Getting runtime component name from attachment
                                    alesj

                                    OK, just saw that my initial impl was a total crap.
                                    But I also saw that we already have an attachment aware interface - InstanceClassFactory.

                                    I can just add a getComponentName method there.
                                    And I'll still leave the @ManagedRuntimeRef if a mbean/service explicitly marks some property as component name provider.