4 Replies Latest reply on Jan 12, 2007 5:00 PM by Scott Stark

    ServiceMetaData parsing needs to be pulled out of ServiceDep

    Scott Stark Master

      An issue I have run into with testing deployment and editing of data sources via the profile service is that the metadata attachments associated with a service deployment is not getting parsed unti the real deployer is run during the component traversal. The ServiceDeployment attachment services is not being populated until here:

      Thread [main] (Suspended (breakpoint at line 98 in ServiceDeploymentDeployer$ServiceDeploymentVisitor))
       ServiceDeploymentDeployer$ServiceDeploymentVisitor.deploy(DeploymentUnit, ServiceDeployment) line: 98
       ServiceDeploymentDeployer$ServiceDeploymentVisitor.deploy(DeploymentUnit, Object) line: 75
       ServiceDeploymentDeployer(AbstractRealDeployer<T>).deploy(DeploymentUnit) line: 89
       ServiceDeploymentDeployer(AbstractComponentDeployer<D,C>).deploy(DeploymentUnit) line: 72
       ServiceDeploymentDeployer(AbstractSimpleDeployer).commitDeploy(DeploymentUnit) line: 52
       DeployerWrapper.commitDeploy(DeploymentUnit) line: 165
       MainDeployerImpl.commitDeploy(Deployer, DeploymentContext, Set<DeploymentContext>) line: 557
       MainDeployerImpl.process(int, int) line: 495
       ProfileServiceBootstrap.loadProfile(String) line: 352
       ProfileServiceBootstrap.bootstrap() line: 248
       ProfileServiceBootstrap(AbstractBootstrap).run() line: 89
       ServerImpl.doStart() line: 403
       ServerImpl.start() line: 342
       Main.boot(String[]) line: 210
       Main$1.run() line: 508
       Thread.run() line: 595
      


      In order for the profile service to be able to build a pojo metadata model of a deployment that can be overriden by tool edits, all metadata that is subject to admin edits needs to be available before the Deployer.CLASSLOADER_DEPLOYER level of deployers have processed the deployment. The basic logic is:

       // Associate the raw deployment with the profile
       VirtualFile deployment = (raw deployment pushed by the user)
       AbstractDeploymentContext ctx = new AbstractDeploymentContext(deployment);
       profile.addDeployment(ctx, phase);
      
       // Process the base deployment to obtain the pojo metadata view
       mainDeployer.addDeploymentContext(ctx);
       Collection<DeploymentContext> ctxs = mainDeployer.process(-1, Deployer.CLASSLOADER_DEPLOYER);
       checkIncomplete();
       for (DeploymentContext d : ctxs)
       {
       // Save the pojo metadata view of the raw deployment in the profile
       profile.updateDeployment(d, phase);
       }
      
       // Determine the pojo metadata properties that can be edited
       Map<String, ManagedObject> mos = mainDeployer.getManagedObjects(ctx);
       // ManagedObject edits map an override set of pojo metadata stored in the profile via an update interceptor aspect
      


      Subsequent deployment of deployment with edits starts at the Deployer.CLASSLOADER_DEPLOYER level of deployers, bypassing all of the metadata processing deployer as the associated DeploymentContext.getPredeterminedManagedObjects() has been populated from the admin edits store in the profile.

      There is also another issue with the granularity of the Map<String, ManagedObject> for a deployment like a service descriptor. For this you have a single attachment of type ServiceDeployment which contains the ServiceMetaData for the mbeans, which contains the attributes that correspond to the ManagedProperty objects one would edit. The simplest view of a datasource would just have the jndi name and jdbc url as ManagedPropertys. What the admin tool needs to see is an inverted view where it gets a set of ManagedPropertys to edit, and these changes get mapped onto the attachment settings. While this can be setup inside the server via aspects, when a remote tool queries the properties and edits them, the aspects are lost. Essentially the same issue as entity beans becoming detached. Either I need to leverage logic similar to what hibernate does, or have an xpath like attribute in a ManagedProperty that allows the tool to submit a set of changed ManagedPropertys that can be applied to the deployment attachment attribute by navigating from the attachment root to the correct attachment property.

      For now I'm going to create a fake datasource deployer to allow all of the profile service usecases to be fleshed out to finalize the apis.

        • 1. Re: ServiceMetaData parsing needs to be pulled out of Servic
          Scott Stark Master

          After the mc call this morning I realize that the problem with building the stable metadata view that the ManagedObject view maps to is that the ServiceMetaData is not what should be used. Adrian pointed out that all we have today is the dom model of the *-ds.xml in terms of an implementation independent model of a datasource. I'll spend a litte time on trying to use that, otherwise I will create a fake datasource deployer with a simple pojo model.

          • 2. Re: ServiceMetaData parsing needs to be pulled out of Servic
            Bill Burke Master

             

            What the admin tool needs to see is an inverted view where it gets a set of ManagedPropertys to edit, and these changes get mapped onto the attachment settings. While this can be setup inside the server via aspects, when a remote tool queries the properties and edits them, the aspects are lost. Essentially the same issue as entity beans becoming detached. Either I need to leverage logic similar to what hibernate does, or have an xpath like attribute in a ManagedProperty that allows the tool to submit a set of changed ManagedPropertys that can be applied to the deployment attachment attribute by navigating from the attachment root to the correct attachment property.


            Ok. I'm commenting based on reading just this thread and looking a bit at your code in org.jboss.test.profileservice.p0, so don't be too annoyed if I'm missing something....


            IMO, an admin tool is going to need a complete structural view of ManagedObjects/DeploymentContexts to be able to display a generic UI to the user. For example, the UI might look like this:

            <DeploymentContext name="MyApp.ear">
             <!-- default security domain for ear -->
             <ManagedObject name="Security">
             <ManagedProperty name="SecurityDomain" value="other"/>
             </ManagedObject>
             <DeploymentContext name="MyEjb.jar">
             <!-- default security domain for application -->
             <ManagedObject name="Security">
             <ManagedProperty name="SecurityDomain" value="UNMODIFIED"/>
             </ManagedObject>
             <DeploymentContext name="jboss.ejb:ejbName=BankDAOBean">
             <!-- default security domain for application -->
             <ManagedObject name="Security">
             <ManagedProperty name="SecurityDomain" value="UNMODIFIED"/>
             </ManagedObject>
             </DeploymentContext>
             </DeploymentContext>
            </DeploymentContext>
            


            Since the admin tool would have knowledge of structure, why not have a set of management deployers or another specific management() callback on the Deployer SPI? The admin tool would send back a list of ManagedProperties with structural information attached.

            Lets use the modification of a security-domain of an EJB on the above as an example. Admin tool would change the name of the ManagedProperty and send this back to the MainDeployer:

            
            <DeploymentContext name="MyApp.ear">
             <DeploymentContext name="MyEjb.jar">
             <DeploymentContext name="jboss.ejb:ejbName=BankDAOBean">
             <ManagedObject name="Security">
             <ManagedProperty name="SecurityDomain" value="CorporateDomain"/>
             </ManagedObject>
             </DeploymentContext>
             </DeploymentContext>
            </DeploymentContext>
            
            


            MainDeployer would navigate to the specific DeploymentContext and push the Update object to a set of deployers. Each deployer decides what it wants to do with the update. The EjbSecurityDeployer would be in this list. It would take the change, lookup the specific SecurityDomain and reset it on the EJBContainer.

            The maindeployer would also attach the Update to the DeploymentContext. If an Update with the same ManagedObject and Property is there, the old one is removed. If the UPdate is persistable, the mainDeployer adds it to the Profile.

            At server restart, the EjbDeployer would merge any persisted Updates into its metamodel.

            Now what if the admin tool updated the EAR's default security domain?

            
            <DeploymentContext name="MyApp.ear">
             <ManagedObject name="Security">
             <ManagedProperty name="SecurityDomain" value="CorporateDomain"/>
             </ManagedObject>
            </DeploymentContext>
            
            


            The way this would work would be that the MainDeployer would see that there are child DeploymentContexts and try to "deploy" the change to each and every child context. The EjbSecurityDeployer would do something like this:

            {
             public void managementEvent(ManagedUpdate update, DeploymentContext context) {
             if (update.getName() != "Security) return;
            
             boolean isThisContextUpdated = update.getDeploymentContext == context;
            
             EJBDeployment deployment = context.getMetaData(EJBDeployment.class);
             if (deployment != null)
             {
             // we are at the "ejb.jar" context deployment level.
             deployment.setSecurityDomain(update.getProperty("security-domain").getValue());
             return;
             }
            
             EJBContainer container = context.getMetaData(EJBContainer.class);
             if (container != null) {
             String newSecurityDomain = update.getProperty("security-domain").getValue();
             // we are at the EJBContainer level
            
             if (isThisContextUpdated)
             {
             // the admin tool has updated the same DeploymentContext as the EJBContainer
             container.updateSecurityDomain(newSecurityDomain);
             }
             else
             {
             // the admin tool has updated the ejb.jar context or the EAR's context, so only
             // set if our securitydomain is null
             if (container.getSecurityDomain() == null) container.updateSecurityDomain(newSecurityDomain);
             }
             }
            }
            






            • 3. Re: ServiceMetaData parsing needs to be pulled out of Servic
              Bill Burke Master

              What this model does is instead of trying to handle everything generically it pushes management to a set of pluggable "deployers" that can either be generic themselves, or be specific to a particular component type. This gives the developer a lot of flexibility in handling ManagedObjects.

              • 4. Re: ServiceMetaData parsing needs to be pulled out of Servic
                Scott Stark Master

                We already have a set of pluggable deployers with a pojo view of the deployment model. The callback to deployers is the ManagedObjectBuilder that a deployer can implement to provide its ManagedObject view.

                This morning we talked about the need for a structural view of the deployment that the ManagementView needs to expose. With that the api is largely what you are talking about. We also need a deployment type view to query for the managed objects for deployments of a given type.