6 Replies Latest reply on Jun 2, 2009 11:20 AM by emuckenhuber

    Does KernelBusRuntimeComponentDispatcher handle lifecycle op

    starksm64

      If an operation is invoked on the KernelBusRuntimeComponentDispatcher and passed down to its KernelBus implementation, and that operation corresponds to a component lifecycle operation such as start/stop, is this being handled correctly in terms of dependencies?

        • 1. Re: Does KernelBusRuntimeComponentDispatcher handle lifecycl
          starksm64

          So the answer is yes, and the current BasicKernelBus implementation that the KernelBusRuntimeComponentDispatcher uses has caused an issue described in https://jira.jboss.org/jira/browse/JBAS-6960.

          The problem is that once a stop has been issued to a component, its no longer in the installed state and an attempt to call start on the component fails because the BasicKernelBus.execute method is only looking for installed contexts.

          We have not properly considered invoking operations that correspond to lifecycle operations. We need to decide how allow for exposed lifecycle operations to be used.

          Right now we can know whether a ManagedOperation has been tagged as a lifecycle operation, but there is no information about what context state transition it applies to.

          • 2. Re: Does KernelBusRuntimeComponentDispatcher handle lifecycl
            alesj

             

            "scott.stark@jboss.org" wrote:

            "scott.stark@jboss.org" wrote:

            If an operation is invoked on the KernelBusRuntimeComponentDispatcher and passed down to its KernelBus implementation, and that operation corresponds to a component lifecycle operation such as start/stop, is this being handled correctly in terms of dependencies?

            So the answer is yes

            If I understand the question right, the answer should be _no_.

            As apart from invoking that property/attribute or method/operation,
            we don't do anything extra wrt dependencies.
            It might be an impl detail of the service you're invoking,
            but we simply do reflection invocation or in case of mbeans "talk" to mbean server.

            But it shouldn't be too big of a problem to properly react to lifecycle methods/ops.
            Since all the info we need is already in underlying Bean/ServiceMetaData,
            we would only require additional abstraction on top of InvokeDispatchContext.

            e.g. do start
            KernelControllerContext --> BeanMetaData --> Start LifecycleMetadata
            * if already past start == ignore
            * else try to move to Start state, (optionally) fail if not being able to get there

            • 3. Re: Does KernelBusRuntimeComponentDispatcher handle lifecycl
              starksm64

               

              "alesj" wrote:

              If I understand the question right, the answer should be _no_.

              As apart from invoking that property/attribute or method/operation,
              we don't do anything extra wrt dependencies.
              It might be an impl detail of the service you're invoking,

              It must be the component context then as the component is being moved out of the installed state.

              "alesj" wrote:

              But it shouldn't be too big of a problem to properly react to lifecycle methods/ops.
              Since all the info we need is already in underlying Bean/ServiceMetaData,
              we would only require additional abstraction on top of InvokeDispatchContext.

              e.g. do start
              KernelControllerContext --> BeanMetaData --> Start LifecycleMetadata
              * if already past start == ignore
              * else try to move to Start state, (optionally) fail if not being able to get there

              Ok, that is what we need.


              • 4. Re: Does KernelBusRuntimeComponentDispatcher handle lifecycl
                alesj

                 

                "scott.stark@jboss.org" wrote:

                "alesj" wrote:

                e.g. do start
                KernelControllerContext --> BeanMetaData --> Start LifecycleMetadata
                * if already past start == ignore
                * else try to move to Start state, (optionally) fail if not being able to get there

                Ok, that is what we need.

                Done under:
                - https://jira.jboss.org/jira/browse/JBKERNEL-32

                This is in the trunk, so can you give 2.2.0-SNAPSHOT a spin.
                (I've already deployed it in our snapshot repo)

                • 5. Re: Does KernelBusRuntimeComponentDispatcher handle lifecycl
                  alesj

                  And I've implemented this for the ServiceControllerContext:

                   public ControllerState lifecycleInvocation(String name, Object[] parameters, String[] signature) throws Throwable
                   {
                   if (lifecycleInfo == null)
                   lifecycleInfo = new LifecycleInfo(this);
                  
                   return lifecycleInfo.lifecycleInvocation(name, signature);
                   }
                  
                  public class LifecycleInfo
                  {
                   private ServiceControllerContext context;
                   private Map<String, StateInfo> lifecycleOps;
                  
                   public LifecycleInfo(ServiceControllerContext context) throws Throwable
                   {
                   if (context == null)
                   throw new IllegalArgumentException("Null context");
                  
                   this.context = context;
                   // build possible lifecycle ops
                   lifecycleOps = new HashMap<String, StateInfo>();
                   lifecycleOps.put("create", new StateInfo(false, true, ControllerState.CREATE));
                   lifecycleOps.put("start", new StateInfo(false, true, ControllerState.START));
                   lifecycleOps.put("stop", new StateInfo(false, false, ControllerState.CREATE));
                   lifecycleOps.put("destroy", new StateInfo(false, false, ControllerState.CONFIGURED));
                  
                   ServiceController controller = context.getServiceController();
                   MBeanServer server = controller.getMBeanServer();
                   if (server != null)
                   {
                   MBeanInfo info = server.getMBeanInfo(context.getObjectName());
                   MBeanOperationInfo[] ops = info.getOperations();
                   if (ops != null)
                   {
                   for (MBeanOperationInfo op : ops)
                   {
                   String name = op.getName();
                  
                   StateInfo flag = lifecycleOps.get(name);
                   if (flag == null)
                   {
                   continue;
                   }
                  
                   // Validate that is a no-arg void return type method
                   if (op.getReturnType().equals("void") == false)
                   {
                   continue;
                   }
                   if (op.getSignature().length != 0)
                   {
                   continue;
                   }
                  
                   flag.opExists = true;
                   }
                   }
                   }
                   }
                  
                   /**
                   * Is this invocation a lifecycle invocation.
                   *
                   * Return state value to which this context should be moved
                   * or return current state if we're already past the lifecycle state
                   * or null if the invocation is actually not a lifecycle invocation.
                   *
                   * @param opName operation name
                   * @param signature method's parameter types / signatures
                   * @return state to which we should move this context, or null if this is not lifecycle invocation
                   * @throws Throwable for any error
                   */
                   public ControllerState lifecycleInvocation(String opName, String[] signature) throws Throwable
                   {
                   if (signature != null && signature.length > 0)
                   return null;
                  
                   StateInfo flag = lifecycleOps.get(opName);
                   if (flag == null || flag.opExists == false)
                   return null;
                  
                   Controller controller = context.getController();
                   ControllerStateModel model = controller.getStates();
                   ControllerState state = context.getState();
                   if (flag.installPhase)
                   {
                   if (model.isAfterState(flag.state, state))
                   return flag.state;
                   else
                   return state;
                   }
                   else
                   {
                   if (model.isBeforeState(flag.state, state))
                   return flag.state;
                   else
                   return state;
                   }
                   }
                  
                   /**
                   * State info holder.
                   */
                   private class StateInfo
                   {
                   boolean opExists;
                   boolean installPhase;
                   ControllerState state;
                  
                   private StateInfo(boolean opExists, boolean installPhase, ControllerState state)
                   {
                   this.opExists = opExists;
                   this.installPhase = installPhase;
                   this.state = state;
                   }
                   }
                  }
                  


                  Or should there be some more logic to it?
                  e.g. handling 'jbossInternalLifecycle'

                  • 6. Re: Does KernelBusRuntimeComponentDispatcher handle lifecycl
                    emuckenhuber

                     

                    "alesj" wrote:

                    Or should there be some more logic to it?
                    e.g. handling 'jbossInternalLifecycle'


                    I think that should be fine the way it is. I briefly tested that with a MC snapshot - and it seems to work fine.
                    So this should be solved once we get a MC update and the patch to ServiceControllerContext.