1 2 Previous Next 24 Replies Latest reply on Dec 11, 2008 7:33 PM by alesj

    Deploying Ears and Wars through ProfileService

      We need a way to

      1) List deployed apps (ears/wars),
      2) Deploy apps (ears/wars),
      3) Undeploy apps(ears/wars),
      4) Get the availability status of the deployed app

      through the ProfileService.

      For deploying apps, we need to pass a URL for the location of the ear or war.
      We need to find out if the deployment or undeployment was successful or failed
      And if it failed what was the reason for the failure.

      Questions
      1. What should be passed to the ProfileService so that it can deploy the archive?
      2. Should this invocation be asynchronous, or make it the caller's responsibility to determine if they want it asynch or not?
      3. If it is async, what lifecycle/callback mechanism should be created?
      4. Should the status of the deploy/undeploy be a MetaType/MetaValue?

      Thanks

        • 1. Re: Deploying Ears and Wars through ProfileService
          dmlloyd

          Forgive my probable ignorance, but why limit it to EARs and WARs? Surely any kind of deployment could be done this way, in principle?

          • 2. Re: Deploying Ears and Wars through ProfileService

             

            "david.lloyd@jboss.com" wrote:
            Forgive my probable ignorance, but why limit it to EARs and WARs? Surely any kind of deployment could be done this way, in principle?


            It's not limited, but for the Management Console v 1.0 we want to make sure we have at least Ears/Wars. :)

            Thanks

            • 3. Re: Deploying Ears and Wars through ProfileService
              starksm64

              The jsr88 api has decent status object for its deployment api:

              javax.enterprise.deploy.spi.status.ProgressObject:

              public interface ProgressObject
              {
               // Constants -----------------------------------------------------
              
               // Public --------------------------------------------------------
              
               /**
               * Retrieve the status of the deployment
               *
               * @return the status
               */
               DeploymentStatus getDeploymentStatus();
              
               /**
               * Retrieve the resulting target module ids
               *
               * @return the module ids
               */
               TargetModuleID[] getResultTargetModuleIDs();
              
               /**
               * Return the client configuration associated with the module
               *
               * @param id the module id
               * @return the client configuration or null if none exists
               */
               ClientConfiguration getClientConfiguration(TargetModuleID id);
              
               /**
               * Is cancel supported
               *
               * @return true when cancel is supported, false otherwise
               */
               boolean isCancelSupported();
              
               /**
               * Cancels the deployment
               *
               * @throws OperationUnsupportedException when cancel is not supported
               */
               void cancel() throws OperationUnsupportedException;
              
               /**
               * Is stop supported
               *
               * @return true when stop is supported, false otherwise
               */
               boolean isStopSupported();
              
               /**
               * Stops the deployment
               *
               * @throws OperationUnsupportedException when stop is not supported
               */
               void stop() throws OperationUnsupportedException;
              
               /**
               * Add a progress listener
               *
               * @param listener the listener
               */
               void addProgressListener(ProgressListener listener);
              
               /**
               * Remove a progress listener
               *
               * @param listener the listener
               */
               void removeProgressListener(ProgressListener listener);
              }
              


              We would drop the getClientConfiguration. TargetModuleID,DeploymentStatus,Target are:

              public interface TargetModuleID
              {
               // Constants -----------------------------------------------------
              
               // Public --------------------------------------------------------
              
               /**
               * Get the target
               *
               * @return the target
               */
               Target getTarget();
              
               /**
               * Get the module id
               *
               * @return the id
               */
               String getModuleID();
              
               /**
               * The URL for a web module
               *
               * @return the url
               */
               String getWebURL();
              
               /**
               * Return the identifier of this module
               *
               * @return the identifier
               */
               String toString();
              
               /**
               * The parent of this module
               *
               * @return the parent or null if there is no parent
               */
               TargetModuleID getParentTargetModuleID();
              
               /**
               * Get the child modules
               *
               * @return an array of child modules or null if there are no children
               */
               TargetModuleID[] getChildTargetModuleID();
              }
              public interface DeploymentStatus
              {
               // Constants -----------------------------------------------------
              
               // Public --------------------------------------------------------
              
               /**
               * Get the state of the deployment
               *
               * @return the state
               */
               StateType getState();
              
               /**
               * The deployment command
               *
               * @return the command
               */
               CommandType getCommand();
              
               /**
               * The action of this deployment
               *
               * @return the action
               */
               ActionType getAction();
              
               /**
               * Get the message
               *
               * @return the message
               */
               String getMessage();
              
               /**
               * Is the deployment complete
               *
               * @return true when complete, false otherwise
               */
               boolean isCompleted();
              
               /**
               * Has the deployment failed
               *
               * @return true when failed, false otherwise
               */
               boolean isFailed();
              
               /**
               * Is the deployment in progress
               *
               * @return true when in progress, false otherwise
               */
               boolean isRunning();
              }
               */
              public interface Target
              {
               // Constants -----------------------------------------------------
              
               // Public --------------------------------------------------------
              
               /**
               * Get the target's name
               *
               * @return the name
               */
               String getName();
              
               /**
               * Get the target's description
               *
               * @return the description
               */
               String getDescription();
              
              }
              



              • 4. Re: Deploying Ears and Wars through ProfileService
                starksm64

                The TargetModuleID[] should be replaced with our ManagedDeployment though, but it would have to be a future object as it cannot be built until the deployment is complete.

                The addition to ManagementView could just be:

                 /**
                 *
                 * @param name phase unique name
                 * @param phase the phase this deployment applies to
                 * @param contentURL content for obtaining the deployment archive
                 * @return DeploymentProgress
                 */
                 public DeploymentProgress addDeployment(String name, DeploymentPhase phase,
                 URL contentURL);
                


                • 5. Re: Deploying Ears and Wars through ProfileService
                  starksm64

                  This is in progress with an update to the api checked in under:
                  https://svn.jboss.org/repos/jbossas/trunk/system/src/main/org/jboss/deployers/spi/management/deploy

                  I need to finish the prototype implementation before I can say the api is usable. That should be done by Monday.

                  • 6. Re: Deploying Ears and Wars through ProfileService
                    starksm64

                    See the latest api in the server trunk along with the org.jboss.test.profileservice.test.DeployUnitTestCase which has tests for deploying an ear, war, sar, and mbeans archive. Currently only the mcbeans archive has any content and illustrates the api basics:

                     public void testMCBeansDeployment()
                     throws Exception
                     {
                     URL contentURL = super.getDeployURL("testMCBeansDeployment.beans");
                    
                     // Distribute the content
                     DeploymentManager mgtView = getDeploymentManager();
                     DeploymentProgress progress = mgtView.distribute("testMCBeansDeployment.beans", DeploymentPhase.APPLICATION, contentURL);
                     progress.addProgressListener(this);
                     progress.run();
                     DeploymentStatus status = progress.getDeploymentStatus();
                     assertTrue("DeploymentStatus.isCompleted", status.isCompleted());
                     // It should not be running yet
                     assertFalse("DeploymentStatus.isRunning", status.isRunning());
                     assertFalse("DeploymentStatus.isFailed", status.isFailed());
                    
                     // Now start the deployment
                     progress = mgtView.start("testMCBeansDeployment.beans", DeploymentPhase.APPLICATION);
                     progress.addProgressListener(this);
                     progress.run();
                     status = progress.getDeploymentStatus();
                     assertTrue("DeploymentStatus.isCompleted", status.isCompleted());
                     assertTrue("DeploymentStatus.isRunning", status.isRunning());
                     assertFalse("DeploymentStatus.isFailed", status.isFailed());
                     }
                    


                    The currently implementation does upload the content, but its being started by the hot deployment service behavior, so its not the two step process it should be.

                    This api differs from the jsr88 javaee deployment manager in that the targets(servers) to which a deployment manager applies are implicit rather than explicit. Its also different in that you obtain the DeploymentManager interface from jndi which implies some type of running server. We probably need a DeploymentManagerFactory to allow for different modes of operation.

                    Take a look at the api and let me know if it fits with the jon notions of profile content management.


                    • 7. Re: Deploying Ears and Wars through ProfileService

                      So this is different than what you posted a couple posts before? :D


                      // Distribute the content
                       DeploymentManager mgtView = getDeploymentManager();
                      


                      So different here in that it is a different Manager rather than in the ManagementView class.

                      Is it possible to get the DeploymentManager from the ManagementView class, like mgtView.getDeploymentManager(), instead of a jndi lookup. (I think you mentioned a lookup was required)

                       DeploymentProgress progress = mgtView.distribute("testMCBeansDeployment.beans", DeploymentPhase.APPLICATION, contentURL);
                       progress.addProgressListener(this);
                       progress.run();
                      


                      So, a listener to get callbacks on the lifecycle of the deploying? What does that interface look like, actually I can just look it up.

                      But the run() goes how far, in the case of a war file?

                       DeploymentStatus status = progress.getDeploymentStatus();
                       assertTrue("DeploymentStatus.isCompleted", status.isCompleted());
                       // It should not be running yet
                       assertFalse("DeploymentStatus.isRunning", status.isRunning());
                       assertFalse("DeploymentStatus.isFailed", status.isFailed());
                      


                      This confused me just a tad, if only the file has been "copied" but hasn't been fully deployed and started, how is it completed==true. Unless the definition of completed is just that the file has been fully "copied"

                       // Now start the deployment
                       progress = mgtView.start("testMCBeansDeployment.beans", DeploymentPhase.APPLICATION);
                       progress.addProgressListener(this);
                       progress.run();
                       status = progress.getDeploymentStatus();
                       assertTrue("DeploymentStatus.isCompleted", status.isCompleted());
                       assertTrue("DeploymentStatus.isRunning", status.isRunning());
                       assertFalse("DeploymentStatus.isFailed", status.isFailed());
                      


                      OK, so by looking at this code, it just looks like all the steps of "deploying" a war are all covered so that any management console can keep track of the entire process, instead of a "one swooping step to follow" from a management perspective.

                      Overall, We are pretty flexible in "mapping" the process to fit into the JON plugin notion. So I don't forsee any issue with how you set this up, as usual it is pretty clean and easy to understand.

                      Mark

                      • 8. Re: Deploying Ears and Wars through ProfileService

                         


                        Is it possible to get the DeploymentManager from the ManagementView class, like mgtView.getDeploymentManager(), instead of a jndi lookup. (I think you mentioned a lookup was required)


                        OK, found it in the ProfileService class. One question answered. :D

                        Mark

                        • 9. Re: Deploying Ears and Wars through ProfileService

                          So, all that code is just for mcbean deployments, whereas ear deployments only need the distribute method.

                          Mark

                          • 10. Re: Deploying Ears and Wars through ProfileService

                            Is there an api yet to discovery the ears and wars already deployed?

                            The KnownComponentTypes doesn't define an ear or war type to use to query the ManagementView.

                            Mark

                            • 11. Re: Deploying Ears and Wars through ProfileService
                              starksm64

                               

                              "mark.spritzler" wrote:

                              So, a listener to get callbacks on the lifecycle of the deploying? What does that interface look like, actually I can just look it up.

                              But the run() goes how far, in the case of a war file?


                              The listener interface just receives ProgressEvents:
                              public interface ProgressListener
                              {
                               void progressEvent(ProgressEvent eventInfo);
                              }
                              

                              which is a DeployentID(identifies the deployment) and a DeploymentStatus which provides what target, command, status of command being performed is. There is no difference in the distribute behavior for an mcbeans deployment vs an ear/war. I will be introducing a describe/prepare command as discussed with Brian as part of the farming support in this thread:
                              http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4151467

                              "mark.spritzler" wrote:

                               DeploymentStatus status = progress.getDeploymentStatus();
                               assertTrue("DeploymentStatus.isCompleted", status.isCompleted());
                               // It should not be running yet
                               assertFalse("DeploymentStatus.isRunning", status.isRunning());
                               assertFalse("DeploymentStatus.isFailed", status.isFailed());
                              


                              This confused me just a tad, if only the file has been "copied" but hasn't been fully deployed and started, how is it completed==true. Unless the definition of completed is just that the file has been fully "copied"

                              completed==true indicates the completion of the command being run. Right now there are the following commands:
                              package org.jboss.deployers.spi.management.deploy;
                              public interface DeploymentStatus
                              {
                               public enum StateType {
                               UPLOADING, DEPLOYING, RUNNING, COMPLETED, FAILED, CANCELLED
                               }
                               public enum CommandType {
                               DISTRIBUTE, // Copies the raw deployment contents to a profile repository
                               START, // Runs the deployment through the full MC deployment states all the way to INSTALLED
                               STOP, // Uninstalls the deployment from the MC but leaves the deployment in the profile repository
                               UNDEPLOY, // Removes the deployment from the profile repository
                               REDEPLOY // Uninstalls the deployment, updates the profile repository and installs the deployment.
                               }
                              

                              and a DESCRIBE/PREPARE command will be added. It will validate that the deployment can be successfully configured to the MC DESCRIBED state which is where all dependencies have been resolved.

                              "mark.spritzler" wrote:

                               // Now start the deployment
                               progress = mgtView.start("testMCBeansDeployment.beans", DeploymentPhase.APPLICATION);
                               progress.addProgressListener(this);
                               progress.run();
                               status = progress.getDeploymentStatus();
                               assertTrue("DeploymentStatus.isCompleted", status.isCompleted());
                               assertTrue("DeploymentStatus.isRunning", status.isRunning());
                               assertFalse("DeploymentStatus.isFailed", status.isFailed());
                              


                              OK, so by looking at this code, it just looks like all the steps of "deploying" a war are all covered so that any management console can keep track of the entire process, instead of a "one swooping step to follow" from a management perspective.

                              Overall, We are pretty flexible in "mapping" the process to fit into the JON plugin notion. So I don't forsee any issue with how you set this up, as usual it is pretty clean and easy to understand.

                              So the earlier jbossas notions of a single deploy process that included copying/making the deployment available and running are broken up into 3 command steps now:
                              1. DISTRIBUTE - make the deployment contents available to the profile repository(ies). There may be multiple if clustered. You should comment on the farming thread with regard to what clustering exists at the JON level and how that might conflict/use any native profile service cluster notions.
                              2. DESCRIBE - validate that the deployment can be run through the deploy process to the MC DESCRIBED state to validate that all references/dependencies can be satisfied. Failure here should return a detailed description of what dependencies are missing.
                              3. START - complete the deployment processing to bring the deployment components to the MC INSTALLED state.

                              There is no guarantee one can successfully go from DESCRIBED to INSTALLED, so failure to start also needs to provide detailed info on the problems. Charles and I talked about that having invalid deployments as part of the unit test would be needed to make sure the problems are adequately reported to the admin tool layer.


                              • 12. Re: Deploying Ears and Wars through ProfileService
                                starksm64

                                 

                                "mark.spritzler" wrote:
                                So, all that code is just for mcbean deployments, whereas ear deployments only need the distribute method.

                                No, every deployment type will need the 3 steps: DISTRIBUTE, DESCRIBE, START. If you don't care to validate the dependencies we should allow START alone in place of DESCRIBE+START.


                                • 13. Re: Deploying Ears and Wars through ProfileService
                                  starksm64

                                   

                                  "mark.spritzler" wrote:
                                  Is there an api yet to discovery the ears and wars already deployed?

                                  The KnownComponentTypes doesn't define an ear or war type to use to query the ManagementView.

                                  Mark

                                  It does not exist yet, and could be part of the JBAS-5529 issue, but it should be implemented using the ManagementView.getDeploymentNamesForType method:
                                   /**
                                   * Get the names of the deployment in the profile that have the
                                   * given deployment type.
                                   * @param type - the deployment type
                                   * @return the names
                                   */
                                   public Set<String> getDeploymentNamesForType(String type);
                                  


                                  The issue is that the ear/war/ejb-jar/client-jar deployment classifications are not component types that correspond to runtime components with a ManagedComponent. They are classifications of ManagedDeployments. So I think what we really need is a KnownDeploymentTypes enum with the standard jbossas deployment types listed. I have added another subtask for this:
                                  http://jira.jboss.com/jira/browse/JBAS-5557




                                  • 14. Re: Deploying Ears and Wars through ProfileService

                                    With 5557 resolved? Is the org.jboss.deployers.spi.management.KnownDeploymentTypes

                                    checked in to the deployers? I don't seem to see the enum yet, and I just updated and rebuilt trunk.

                                    Thanks

                                    Mark

                                    1 2 Previous Next