1 2 3 4 Previous Next 54 Replies Latest reply on Oct 4, 2007 12:09 PM by starksm64

    ManagedOperation aspects for the ProfileService.ManagementVi

    alesj

      Scott,

      regarding this JIRA task:
      - http://jira.jboss.com/jira/browse/JBAS-4678

      where to put this code?
      MC or AS?

      Any initial tips or ([pseudo] code) examples on what exactly we want? :-)

        • 1. Re: ManagedOperation aspects for the ProfileService.Manageme
          starksm64

          It has to go into the profileservice project in as as it has the mapping of what the associated runtime component name is. I'm working on a stub example today.

          • 2. Re: ManagedOperation aspects for the ProfileService.Manageme
            starksm64

            I'm having trouble getting the aspect to be applied to the ManagedOperation, so I just wired up the invocation handler without that. What still needs to be implemented

            See ManagementViewImpl.invoke(Invocation inv) and the population of the opMap. You need to be able to map the ManagedOperation metadata to the mc component. For the current operations this will be a jmx mbean given by the ServiceMetaData object name.

            • 3. Re: ManagedOperation aspects for the ProfileService.Manageme
              alesj

              What are the classes to look at - that you mentioned on the call?
              - ProfileServiceUnitTestCase
              - DataSourceOpTestCase?

              • 4. Re: ManagedOperation aspects for the ProfileService.Manageme
                starksm64

                The org.jboss.test.profileservice.test.ProfileServiceUnitTestCase.testDefaultDSOps unit test exercises the ManagedOperation calls for a DataSource component. This is wired up to the point of the invocation showing up in the org.jboss.profileservice.management.ManagementViewImpl.invoke(Invocation inv)method, where the server side ManagedOperation instance is located. What is missing is how to take that ManagedOperation invocation and turn it into an invocation on the runtime component that source the operation, and return the result.

                • 5. Re: ManagedOperation aspects for the ProfileService.Manageme
                  alesj

                  OK, let me see if I get this ManagedOperation invocation. :-)

                  ManagementViewImpl loads profile == prepares Managed objects (props, operations). This means preparing proxies to expose to client via Dispatcher.singleton.

                  Once the ManagedOperation is invoked on the client side, it goes through the ProfileService subsystem via Connector(MBean) over ProfileServiceInvocationHandler which checks if it's actually ManagedOperation invocation (oid starting with ProfileService.ManagedOperation@ as it was set in proxy wrapper), which then delegates to ManagementViewImpl.invoke().

                  What I'm missing is that ManagementViewImpl.createOperationProxies(Set ops) is missing actual runtime component ref (name of the bean/service in MC or the bean/service itself).
                  Or how/where did you intend to get it?
                  Via ManagementObjectID --> ManagedObject.name?

                   ManagementObjectID id = (ManagementObjectID) annotations.get(ManagementObjectID.class.getName());
                   if (id != null)
                   {
                   if (value == null || value.getMetaType().isSimple() == false)
                   {
                   log.warn("Cannot create String name from non-Simple property: "
                   +property+", value="+value);
                   continue;
                   }
                   SimpleValue svalue = (SimpleValue) value;
                   String name = "" + svalue.getValue();
                   managedObject.setName(name);
                   }
                  


                  What we should be adding is aspect(s) for every bean/service that we intend to be managed?
                  So that we know what is the whole chain of events that the actual change triggers, e.g. changing the DS url should flush the pool of connections, create new ones, ...
                  Right?

                  • 6. Re: ManagedOperation aspects for the ProfileService.Manageme
                    starksm64

                    For the ManagementObject that defines the ManagedOperations, the name of the associated runtime component the operations correspond to needs to be keyed to the ManagedOperation so it can be dispatched when invoked. This is not related to the ManagedObject name code you show. Its a function of the metadata attachment associated the ManagedObject with the ManagedOperations. For jmx mbeans, this should be a ServiceMetaData instance, and the objectName property is what defines the runtime component to dispatch the ops to.

                    • 7. Re: ManagedOperation aspects for the ProfileService.Manageme
                      alesj

                      Hmmm ... is this stuff done wrong or I just don't get the concept:

                      java.lang.IllegalStateException: No target found for op: ManagedOperation(name=listFormatttedSubPoolStatistics,description=Obtain a formatted statistics report,impact=ReadOnly)
                       at org.jboss.profileservice.management.ManagementViewImpl.invoke(ManagementViewImpl.java:662)
                       at org.jboss.profileservice.remoting.ProfileServiceInvocationHandler.invoke(ProfileServiceInvocationHandler.java:77)
                       at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:769)
                       at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:573)
                       at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:373)
                       at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:166)
                       at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:163)
                       at org.jboss.remoting.Client.invoke(Client.java:1550)
                       at org.jboss.remoting.Client.invoke(Client.java:530)
                       at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:62)
                       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                       at org.jboss.aspects.remoting.MergeMetaDataInterceptor.invoke(MergeMetaDataInterceptor.java:74)
                       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                       at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:65)
                       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                       at AOPProxy$12.getName(AOPProxy$12.java)
                       at org.jboss.test.profileservice.test.ProfileServiceUnitTestCase.testDefaultDSOps(ProfileServiceUnitTestCase.java:339)
                       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                       at com.intellij.rt.execution.junit.IdeaTestRunner.doRun(IdeaTestRunner.java:69)
                       at com.intellij.rt.execution.junit.IdeaTestRunner.startRunnerWithArgs(IdeaTestRunner.java:24)
                       at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:118)
                       at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
                       at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:74)
                       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                       at org.jboss.aspects.remoting.MergeMetaDataInterceptor.invoke(MergeMetaDataInterceptor.java:74)
                       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                       at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:65)
                       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                       at AOPProxy$12.getName(AOPProxy$12.java)
                       at org.jboss.test.profileservice.test.ProfileServiceUnitTestCase.testDefaultDSOps(ProfileServiceUnitTestCase.java:339)
                      


                      Shouldn't be a 'ManagedOperation.getName' invocation just a simple remote call of the actual server side coresponding ManagedOperation instance's getName method.
                      And only the 'mapping' of the ManagedOperation.invoke(org.jboss.metatype.api.values.MetaValue... metaValues) call should be actually wired onto runtime component?

                      • 8. Re: ManagedOperation aspects for the ProfileService.Manageme
                        starksm64

                        Yes, you have to dispatch the methods as needed. Ops on the ManagedOperation can be handled by the existing remoting wiring. The wiring for invoke to the runtime component is what you need to do such that ManagementViewImpl.invoke does the dispatch.

                        • 9. Re: ManagedOperation aspects for the ProfileService.Manageme
                          alesj

                           

                          "scott.stark@jboss.org" wrote:
                          Yes, you have to dispatch the methods as needed. Ops on the ManagedOperation can be handled by the existing remoting wiring. The wiring for invoke to the runtime component is what you need to do such that ManagementViewImpl.invoke does the dispatch.


                          The code is commited.

                          I've refactored the ManagementViewImpl - no need for opMap --> added ManagedOperationDelegate that holds all the needed information.
                          I've also changed the ProfileServiceInvocationHandler, since there is no need for us to distinguish between ProfileService.ManagedOperation@ and other calls. I've only left the ManagementView result set to a proxy.

                          I added two new interfaces:
                          1) MetaDataNameProvider: extracts component name from MetaData
                          2) RuntimeComponentDispatcher: pushes attachment to MetaDataNameProvider to get the name, looks up the component via 'registry', and dispatches method invocation on the found runtime component

                          Currently there are just default impls:
                          1) Name from BeanMetaData and ServiceMetaData
                          2) MC's Controller dispatch

                          Is this what we've been looking for? :-)

                          • 10. Re: ManagedOperation aspects for the ProfileService.Manageme

                            Ales,

                            The invocation should be going through the KernelBus.
                            But the KernelBus is not up-to-date with respect to your {Attribute|Invoke}DispatchContext

                            • 11. Re: ManagedOperation aspects for the ProfileService.Manageme
                              alesj

                               

                              "adrian@jboss.org" wrote:

                              The invocation should be going through the KernelBus.
                              But the KernelBus is not up-to-date with respect to your {Attribute|Invoke}DispatchContext


                              The only thing that KernelBus currently does is invoke(Object name, TargettedJoinpoint).
                               Object invoke(Object name, TargettedJoinpoint joinPoint) throws Throwable;
                              


                              I can add a
                               Object invoke(Object name, ContextJoinpoint joinPoint) throws Throwable;
                              
                              public interface ContextJoinpoint extends Joinpoint
                              {
                               ControllerContext getContext();
                              
                               void setContext(ControllerContext context);
                              }
                              

                              and then just implement my own ContextJoinpoint that does the {Attribute|Invoke}DispatchContext.

                              Or how to make KernelBus up to date?

                              • 12. Re: ManagedOperation aspects for the ProfileService.Manageme
                                alesj

                                I've added the following code to KernelBus:

                                 public Object invoke(Object name, KernelRegistryEntryJoinpoint joinPoint) throws Throwable
                                 {
                                 KernelRegistryEntry entry = registry.getEntry(name);
                                 if (joinPoint.applyEntry(entry) == false)
                                 throw new IllegalArgumentException("Cannot apply joinpoint " + joinPoint + " to entry " + entry);
                                 return joinPoint.dispatch();
                                 }
                                


                                And the 2 impls:
                                public class InvokeKernelRegistryEntryJoinpoint extends JBossObject implements KernelRegistryEntryJoinpoint
                                {
                                 private String methodName;
                                 private Object[] args;
                                 private String[] signature;
                                 private InvokeDispatchContext context;
                                
                                 public InvokeKernelRegistryEntryJoinpoint(String methodName, Object[] args, String[] signature)
                                 {
                                 this.methodName = methodName;
                                 this.args = args;
                                 this.signature = signature;
                                 }
                                
                                 public boolean applyEntry(KernelRegistryEntry entry)
                                 {
                                 if (entry instanceof InvokeDispatchContext)
                                 {
                                 context = (InvokeDispatchContext)entry;
                                 return true;
                                 }
                                 return false;
                                 }
                                
                                 public Object dispatch() throws Throwable
                                 {
                                 if (context == null)
                                 throw new IllegalArgumentException("Cannot dispatch null context.");
                                 return context.invoke(methodName, args, signature);
                                 }
                                
                                 public String toHumanReadableString()
                                 {
                                 return methodName + "," + context;
                                 }
                                }
                                
                                public class AttributeKernelRegistryEntryJoinpoint extends JBossObject implements KernelRegistryEntryJoinpoint
                                {
                                 private String getterName;
                                 private AttributeDispatchContext context;
                                
                                 public AttributeKernelRegistryEntryJoinpoint(String getterName)
                                 {
                                 this.getterName = getterName;
                                 }
                                
                                 public boolean applyEntry(KernelRegistryEntry entry)
                                 {
                                 if (entry instanceof AttributeDispatchContext)
                                 {
                                 context = (AttributeDispatchContext)entry;
                                 return true;
                                 }
                                 return false;
                                 }
                                
                                 public Object dispatch() throws Throwable
                                 {
                                 if (context == null)
                                 throw new IllegalArgumentException("Cannot dispatch null context.");
                                 return context.get(getterName);
                                 }
                                
                                 public String toHumanReadableString()
                                 {
                                 return getterName + "," + context;
                                 }
                                }
                                
                                


                                I'll change the ManagementView invocation later this evening with the KernelBus invocation.

                                • 13. Re: ManagedOperation aspects for the ProfileService.Manageme
                                  alesj

                                  Scott, is there a way to distinguish between ManagedOperation being a getter or plain method?

                                  • 14. Re: ManagedOperation aspects for the ProfileService.Manageme
                                    starksm64

                                    ManagedOperations are never property getters if that is what you mean. They are bean methods that may return a value.

                                    1 2 3 4 Previous Next