1 2 3 Previous Next 32 Replies Latest reply on Feb 29, 2008 4:24 AM by adrian.brock

    Facade Questions

    alesj

      Moving this to the forum:

      "johnbailey" wrote:

      I am still trying to get a grasp of how the Facade will be used.
      After the forum post, I think I understand the bundles will be loaded
      into the MC like any other deployment, but will have meta-data taken
      from the manifest to drive some of the wiring for classloading. I
      like the idea that a Bundle facade can reference any deployment
      regardless of whether it came from an OSGI bundle from the start. So
      that being said, who will be referencing the Bundles? I can see how
      the BundleActivator deployer creates the BundleContext, which creates
      the BundleImpl. The BundleContext is created with a DeploymentUnit,
      which has an attachment of the DeploymentControllerContext, correct?
      From Adrian's comments, it seems the Bundle is a Facade over the
      DeploymentControllerContext. So if Bundle.start is called, it would
      actually change the state of the ControllerContex, but who would ever
      do this?

      I have created some tests that use a JarStructure deployer and the
      OSGI Manifest and BundleActivator to deploy an OSGI based JAR. The MC
      will deploy the JAR and the BundleActivator as well as invoking the
      start start opperation on the BundleActivator. I can see how this
      will allow the BundleActivator to register services into the MC using
      the BundleContext, but in this process the Bundle isn't used, which
      makes sense as the Bundle is just a Deployment to the MC with
      additional wiring constraints. So why would I get access to the
      Bundle? If so it just seems like I would get the ControllerContext
      and create the Bundle from there?

      Am I making any sense? I am getting a really good understanding of
      the MC and deployments, but I guess I need a clearer understanding of
      how a client would use the Facade? Is there a client type we are
      looking to support?


        • 1. Re: Facade Questions

           

          "johnbailey" wrote:

          Am I making any sense? I am getting a really good understanding of
          the MC and deployments, but I guess I need a clearer understanding of
          how a client would use the Facade? Is there a client type we are
          looking to support?


          The use case is people wanting to use the OSGi api to control deployments
          which is spec defined rather than the JBoss specific api.


          • 2. Re: Facade Questions
            johnbailey

            Ok. I will start on the facade assuming there will be at least a DeploymentUnit available. If the Unit has an attached ControllerContext, it will delegate to the attached version, otherwise it will create a DeployentContollerContext. Does this seem like the correct approach?

            It seems like the BundleContext will need access to the DeploymentUnit in order to create ServiceReferences, which I see as components of the Deployment. Make sense?

            • 3. Re: Facade Questions

               

              "johnbailey" wrote:
              Ok. I will start on the facade assuming there will be at least a DeploymentUnit available. If the Unit has an attached ControllerContext, it will delegate to the attached version, otherwise it will create a DeployentContollerContext. Does this seem like the correct approach?


              They will always be available. The only time you need to create them
              in the OSGi layer is in the BundleContext::installBundle() methods
              which you will do indirectly by delegating to the main deployer.


              It seems like the BundleContext will need access to the DeploymentUnit in order to create ServiceReferences, which I see as components of the Deployment. Make sense?


              Yes, ServiceReferences are deployment components that
              are installed as "ServiceReferenceControllerContexts" into the MC.

              They're really just facades on top of any ControllerContext.

              This allows us to expose MBeans and POJOs (using the same facade)
              as OSGi services and also potentially dependency inject OSGi
              services into mbeans and pojos.

              Ales can tell you which parts are already done and what the classes
              are really called, the devil is always in the details. ;-)

              • 4. Re: Facade Questions
                johnbailey

                Great. Thanks for the info. I will focus on the initial work with the Bundle facade first, and then move on to the ServiceReference registration once the basic Bundle work is complete.



                • 5. Re: Facade Questions
                  johnbailey

                  Assuming the DeploymentControllerContext is always available to the Bundle, can we also assume the DeploymentControllerContext has also been installed into the Controller? Looking through the DeployersImpl the DeploymentControllerContext is created, installed into the controller, attached to the DeploymentContext, and moved through all known states for the DeployersImpl.

                  So if the Bundle.start method delegates to the DeploymentControllerContext.changeState(...), would it look something like this:

                  public void start() throws BundleException
                   {
                   DeploymentControllerContext deploymentControllerContext = getControllerContext();
                   DeploymentContext deploymentContext = deploymentControllerContext.getDeploymentContext();
                  
                   // Go through the states in order
                   List<ControllerState> states = getControllerContext().getController().getStates();
                   for (ControllerState state : states)
                   {
                   if (DeploymentState.ERROR.equals(deploymentContext.getState()) == false)
                   {
                   try
                   {
                   deploymentControllerContext.getController().change(getControllerContext(), state);
                   }
                   catch (Throwable t)
                   {
                   deploymentContext.setState(DeploymentState.ERROR);
                   deploymentContext.setProblem(t);
                   }
                   }
                   }
                  
                   }
                  


                  Also, I have completed some other work on the Facade, should I document it on the existing 'OSGI Facade' JIRA http://jira.jboss.com/jira/browse/JBOSGI-8, or create a more detailed task?

                  • 6. Re: Facade Questions
                    alesj

                     

                    "johnbailey" wrote:

                    So if the Bundle.start method delegates to the DeploymentControllerContext.changeState(...), would it look something like this:

                    I don't think you need to move step-by-step.
                    Simply change the state to INSTALLED.

                    And in the code, you need to rethrow the caught Throwable as a BundleException.
                    "johnbailey" wrote:

                    Also, I have completed some other work on the Facade, should I document it on the existing 'OSGI Facade' JIRA http://jira.jboss.com/jira/browse/JBOSGI-8, or create a more detailed task?

                    First post your findings here on the forum.
                    And we'll see if they need more detailed JIRAs.

                    • 7. Re: Facade Questions
                      johnbailey

                      Makes sense. I wasn't sure if it would be in a state that would allow it to move directly to INSTALLED.

                      The getState method will simply map the ControllerState to an equivelent Bundle State. Are the following resonable?

                       ControllerState controllerState = getControllerContext().getState();
                       if (ControllerState.ERROR.equals(controllerState))
                       {
                       bundleState = Bundle.INSTALLED; // Seems strange, but see javadoc
                       }
                       else if (ControllerState.NOT_INSTALLED.equals(controllerState))
                       {
                       bundleState = Bundle.UNINSTALLED;
                       }
                       else if (ControllerState.PRE_INSTALL.equals(controllerState)
                       || ControllerState.DESCRIBED.equals(controllerState))
                       {
                       bundleState = Bundle.INSTALLED;
                       }
                       else if (ControllerState.INSTANTIATED.equals(controllerState)
                       || ControllerState.CONFIGURED.equals(controllerState)
                       || ControllerState.CREATE.equals(controllerState))
                       {
                       bundleState = Bundle.RESOLVED;
                       }
                       else if (ControllerState.START.equals(controllerState))
                       {
                       bundleState = Bundle.STARTING;
                       }
                       else if (ControllerState.INSTALLED.equals(controllerState))
                       {
                       bundleState = Bundle.ACTIVE;
                       }
                      


                      Want to make sure I get this correct.

                      • 8. Re: Facade Questions
                        johnbailey

                        Couple more questions:

                        1. What is the best way to get the location of the deployed asset (jar, etc..). I see the name of the VFSFile in the name of the DeploymentContext, but I want to make sure the location returned will always be a valid path to the asset. The Bundle Facade needs to return the location as well as search for entries without a classloader (Bundle.getEntry, Bundle.getEntryPaths)

                        2. Will we be supporting the OSGI AdminPermission checks?

                        3. Is there an existing Id that can be used for the Bundle ID? It needs to be unique, and I don't want to create a new scheme if there is something in place to use.


                        • 9. Re: Facade Questions
                          alesj

                           

                          "johnbailey" wrote:
                          Makes sense. I wasn't sure if it would be in a state that would allow it to move directly to INSTALLED.

                          You can always try to move it to any state from any state (except error state).
                          But it doesn't mean it will actually move there - e.g. still some unresolved dependencies 'blocking' the transition.

                          "johnbailey" wrote:

                          The getState method will simply map the ControllerState to an equivelent Bundle State. Are the following resonable?

                           ControllerState controllerState = getControllerContext().getState();
                           if (ControllerState.ERROR.equals(controllerState))
                           {
                           bundleState = Bundle.INSTALLED; // Seems strange, but see javadoc
                           }
                           else if (ControllerState.NOT_INSTALLED.equals(controllerState))
                           {
                           bundleState = Bundle.UNINSTALLED;
                           }
                           else if (ControllerState.PRE_INSTALL.equals(controllerState)
                           || ControllerState.DESCRIBED.equals(controllerState))
                           {
                           bundleState = Bundle.INSTALLED;
                           }
                           else if (ControllerState.INSTANTIATED.equals(controllerState)
                           || ControllerState.CONFIGURED.equals(controllerState)
                           || ControllerState.CREATE.equals(controllerState))
                           {
                           bundleState = Bundle.RESOLVED;
                           }
                           else if (ControllerState.START.equals(controllerState))
                           {
                           bundleState = Bundle.STARTING;
                           }
                           else if (ControllerState.INSTALLED.equals(controllerState))
                           {
                           bundleState = Bundle.ACTIVE;
                           }
                          


                          Let's make this more OO. ;-)
                          e.g.
                          List<BundleState2ControllerState> states ...
                          ...
                          for(BundleState2ControllerState bs2cs : states)
                          {
                           if (bs2cs.getControllerState().equals(state))
                           return bs2cs.getBundleState();
                          }
                          throw new IllegalArgumentException("No such matching BS2CS.");
                          


                          • 10. Re: Facade Questions
                            alesj

                             

                            "johnbailey" wrote:

                            1. What is the best way to get the location of the deployed asset (jar, etc..). I see the name of the VFSFile in the name of the DeploymentContext, but I want to make sure the location returned will always be a valid path to the asset. The Bundle Facade needs to return the location as well as search for entries without a classloader (Bundle.getEntry, Bundle.getEntryPaths)

                            The DeploymentContext should really be VFSDeploymentContext.
                            And that one has all the hooks you need.

                            "johnbailey" wrote:

                            2. Will we be supporting the OSGI AdminPermission checks?

                            We should. But it's not a priority.
                            I still need to look at that more thoroughly.

                            "johnbailey" wrote:

                            3. Is there an existing Id that can be used for the Bundle ID? It needs to be unique, and I don't want to create a new scheme if there is something in place to use.

                            Underlying context name should do.
                            That's how module's get their name.
                             private static String determineContextName(DeploymentUnit unit)
                             {
                             if (unit == null)
                             throw new IllegalArgumentException("Null unit");
                             ControllerContext context = unit.getAttachment(ControllerContext.class);
                             if (context == null)
                             throw new IllegalStateException("Deployment has no controller context");
                             return (String) context.getName();
                             }
                            


                            • 11. Re: Facade Questions
                              alesj

                               

                              "johnbailey" wrote:
                              Are the following resonable?
                               ControllerState controllerState = getControllerContext().getState();
                               if (ControllerState.ERROR.equals(controllerState))
                               {
                               bundleState = Bundle.INSTALLED; // Seems strange, but see javadoc
                               }
                              


                              Can you post javadoc?
                              Not that I don't trust you, but just lazy to do own lookup. ;-)
                              Other look OK.

                              And since the controller states to bundle states mapping is 'growing function', you can do a simple function which will determine bundle state according to the controller state index value.
                              Hence not needing that List impl that I proposed earlier.

                              • 12. Re: Facade Questions
                                johnbailey

                                 

                                "alesj" wrote:

                                Can you post javadoc?
                                Not that I don't trust you, but just lazy to do own lookup. ;-)


                                public static final int INSTALLED
                                
                                 The bundle is installed but not yet resolved.
                                
                                 A bundle is in the INSTALLED state when it has been installed in the Framework but is not or cannot be resolved.
                                
                                 This state is visible if the bundle's code dependencies are not resolved. The Framework may attempt to resolve an INSTALLED bundle's code dependencies and move the bundle to the RESOLVED state.
                                


                                Should we thrown an Exception instead? From the possible states (UNINSTALLED,INSTALLED,RESOLVED, STARTING, STOPPING, ACTIVE), INSTALLED seems to be the default. I was origionally thinking UNINSTALLED, but it is valid only after the Bundle has been uninstalled.

                                public static final int UNINSTALLED
                                
                                 The bundle is uninstalled and may not be used.
                                
                                 The UNINSTALLED state is only visible after a bundle is uninstalled; the bundle is in an unusable state but references to the Bundle object may still be available and used for introspection.


                                • 13. Re: Facade Questions
                                  alesj

                                  When mapping Controller states to bundle states, you should consider DeploymentStages, since those are probably the one's we're after.
                                  Those mentioned before are POJO centric.

                                  I would do something like this:
                                  ERROR --> UNINSTALLED
                                  NOT_INSTALLED --> INSTALLED (this one looks funny, but it's technically ok :-)
                                  CLASSLOADING --> RESOLVED
                                  REAL --> STARTING / STOPPING
                                  INSTALLED --> ACTIVE

                                  • 14. Re: Facade Questions
                                    johnbailey

                                    I was looking at that as well. That seems a cleaner fit knowing the mappings you posted. I will use this moving forward.

                                    On another note, if we are going to support using the facade for any deployment even ones not originating in a OSGI Bundle, we can not assume the OSGIMetaData will be attached to the DeploymentContext. In this case, we will need to create the headers given the other MetaData available, correct?



                                    1 2 3 Previous Next