Skip to content

Commit

Permalink
Merge pull request #857 from bstansberry/WFCORE-781
Browse files Browse the repository at this point in the history
[WFCORE-781] Add ability to use capability-provided integrations from… … services and DUPs
  • Loading branch information
bstansberry committed Jul 4, 2015
2 parents 9679062 + e5e1cb5 commit 8a12f32
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 10 deletions.
Expand Up @@ -30,6 +30,7 @@
import org.jboss.as.controller.access.Caller;
import org.jboss.as.controller.access.Environment;
import org.jboss.as.controller.access.ResourceAuthorization;
import org.jboss.as.controller.capability.CapabilityServiceSupport;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.client.MessageSeverity;
import org.jboss.as.controller.notification.Notification;
Expand Down Expand Up @@ -969,6 +970,17 @@ public interface OperationContext extends ExpressionResolver {
*/
ServiceName getCapabilityServiceName(String capabilityBaseName, String dynamicPart, Class<?> serviceType);

/**
* Gets a support object that allows service implementations installed from this context to
* integrate with capabilities.
*
* @return the support object. Will not return {@code null}
*
* * @throws java.lang.IllegalStateException if {@link #getCurrentStage() the current stage} is {@link Stage#MODEL}.
* Service integration is not supported in the model stage.
*/
CapabilityServiceSupport getCapabilityServiceSupport();

/**
* Whether normally this operation would require a runtime step. It returns {@code true in the following cases}
* <ul>
Expand Down
Expand Up @@ -77,6 +77,7 @@
import org.jboss.as.controller.access.TargetAttribute;
import org.jboss.as.controller.access.TargetResource;
import org.jboss.as.controller.audit.AuditLogger;
import org.jboss.as.controller.capability.CapabilityServiceSupport;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.capability.registry.CapabilityContext;
import org.jboss.as.controller.capability.registry.CapabilityId;
Expand Down Expand Up @@ -1477,6 +1478,13 @@ private void rejectUserDomainServerUpdates() {
}
}

@Override
public CapabilityServiceSupport getCapabilityServiceSupport() {
assert isControllingThread();
assertCapabilitiesAvailable(currentStage);
return new CapabilityServiceSupportImpl(managementModel);
}


private boolean isModelUpdateRejectionRequired() {
if (requiresModelUpdateAuthorization == null) {
Expand Down Expand Up @@ -2579,4 +2587,42 @@ public boolean equals(Object o) {
return true;
}
}

private static class CapabilityServiceSupportImpl implements CapabilityServiceSupport {
private final ManagementModel managementModel;

private CapabilityServiceSupportImpl(ManagementModel managementModel) {
this.managementModel = managementModel;
}

@Override
public <T> T getCapabilityRuntimeAPI(String capabilityName, Class<T> apiType) throws NoSuchCapabilityException {
try {
return managementModel.getCapabilityRegistry().getCapabilityRuntimeAPI(capabilityName, CapabilityContext.GLOBAL, apiType);
} catch (IllegalStateException e) {
if (managementModel.getCapabilityRegistry().hasCapability(capabilityName, CapabilityContext.GLOBAL)) {
// Must have been some other problem
throw e;
}
}
throw new NoSuchCapabilityException(capabilityName);
}

@Override
public <T> T getCapabilityRuntimeAPI(String capabilityBaseName, String dynamicPart, Class<T> apiType) throws NoSuchCapabilityException {
String fullName = RuntimeCapability.buildDynamicCapabilityName(capabilityBaseName, dynamicPart);
return getCapabilityRuntimeAPI(fullName, apiType);
}

@Override
public ServiceName getCapabilityServiceName(String capabilityName) {
return ServiceName.parse(capabilityName);
}

@Override
public ServiceName getCapabilityServiceName(String capabilityBaseName, String dynamicPart) {
return getCapabilityServiceName(capabilityBaseName).append(dynamicPart);
}
}

}
Expand Up @@ -30,6 +30,7 @@
import org.jboss.as.controller.access.AuthorizationResult;
import org.jboss.as.controller.access.ResourceAuthorization;
import org.jboss.as.controller.audit.AuditLogger;
import org.jboss.as.controller.capability.CapabilityServiceSupport;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.client.MessageSeverity;
import org.jboss.as.controller.logging.ControllerLogger;
Expand Down Expand Up @@ -399,6 +400,11 @@ public ServiceName getCapabilityServiceName(String capabilityBaseName, String dy
serviceType, activeStep);
}

@Override
public CapabilityServiceSupport getCapabilityServiceSupport() {
return primaryContext.getCapabilityServiceSupport();
}

@Override
void releaseStepLocks(Step step) {
if(lockStep == step) {
Expand Down
Expand Up @@ -30,6 +30,7 @@
import org.jboss.as.controller.access.Action;
import org.jboss.as.controller.access.AuthorizationResult;
import org.jboss.as.controller.access.ResourceAuthorization;
import org.jboss.as.controller.capability.CapabilityServiceSupport;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.client.MessageSeverity;
import org.jboss.as.controller.logging.ControllerLogger;
Expand Down Expand Up @@ -422,4 +423,9 @@ public ServiceName getCapabilityServiceName(String capabilityName, Class<?> type
public ServiceName getCapabilityServiceName(String capabilityBaseName, String dynamicPart, Class<?> serviceType) {
throw readOnlyContext();
}

@Override
public CapabilityServiceSupport getCapabilityServiceSupport() {
throw readOnlyContext();
}
}
@@ -0,0 +1,100 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2015, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.controller.capability;

import org.jboss.msc.service.ServiceName;

/**
* Provides support for capability integration outside the management layer,
* in service implementations.
* <p>
* Note that use of this interface in no way creates a requirement on the
* referenced capability by the caller.
*
* @author Brian Stansberry
*/
public interface CapabilityServiceSupport {

/**
* Exception thrown when support for an unregistered capability is requested. This is a checked
* exception because {@code CapabilityServiceSupport} is used outside the management layer and
* the requirements for capability availability available in {@link org.jboss.as.controller.OperationContext}
* are not possible. So callers need to be aware of and handle non-existent capabilities.
*/
class NoSuchCapabilityException extends Exception {

static final long serialVersionUID = 1L;

public NoSuchCapabilityException(String message) {
super(message);
}
}

/**
* Gets the runtime API associated with a given capability, if there is one.
* @param capabilityName the name of the capability. Cannot be {@code null}
* @param apiType class of the java type that exposes the API. Cannot be {@code null}
* @param <T> the java type that exposes the API
* @return the runtime API. Will not return {@code null}
*
* @throws NoSuchCapabilityException if no matching capability is registered
* @throws java.lang.IllegalArgumentException if the capability does not provide a runtime API
* @throws java.lang.ClassCastException if the runtime API exposed by the capability cannot be cast to type {code T}
*/
<T> T getCapabilityRuntimeAPI(String capabilityName, Class<T> apiType) throws NoSuchCapabilityException;

/**
* Gets the runtime API associated with a given {@link RuntimeCapability#isDynamicallyNamed() dynamically named}
* capability, if there is one.
*
* @param capabilityBaseName the base name of the capability. Cannot be {@code null}
* @param dynamicPart the dynamic part of the capability name. Cannot be {@code null}
* @param apiType class of the java type that exposes the API. Cannot be {@code null}
* @param <T> the java type that exposes the API
* @return the runtime API. Will not return {@code null}
*
* @throws NoSuchCapabilityException if no matching capability is registered
* @throws java.lang.IllegalArgumentException if the capability does not provide a runtime API
* @throws java.lang.ClassCastException if the runtime API exposed by the capability cannot be cast to type {code T}
*/
<T> T getCapabilityRuntimeAPI(String capabilityBaseName, String dynamicPart, Class<T> apiType) throws NoSuchCapabilityException;

/**
* Gets the name of a service associated with a given capability. This method does not confirm that the
* capability is currently registered.
*
* @param capabilityName the name of the capability. Cannot be {@code null}
* @return the name of the service. Will not return {@code null}
*/
ServiceName getCapabilityServiceName(String capabilityName);

/**
* Gets the name of a service associated with a given {@link RuntimeCapability#isDynamicallyNamed() dynamically named}
* capability. This method does not confirm that the capability is currently registered.
*
* @param capabilityBaseName the base name of the capability. Cannot be {@code null}
* @param dynamicPart the dynamic part of the capability name. Cannot be {@code null}
* @return the name of the service. Will not return {@code null}
*/
ServiceName getCapabilityServiceName(String capabilityBaseName, String dynamicPart);
}
Expand Up @@ -43,6 +43,7 @@
import org.jboss.as.controller.access.Caller;
import org.jboss.as.controller.access.Environment;
import org.jboss.as.controller.access.ResourceAuthorization;
import org.jboss.as.controller.capability.CapabilityServiceSupport;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.client.MessageSeverity;
import org.jboss.as.controller.notification.Notification;
Expand Down Expand Up @@ -550,6 +551,11 @@ public ServiceName getCapabilityServiceName(String capabilityBaseName, String dy
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
public CapabilityServiceSupport getCapabilityServiceSupport() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
public void emit(Notification notification) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
Expand Down
Expand Up @@ -76,6 +76,7 @@
import org.jboss.as.controller.access.Environment;
import org.jboss.as.controller.access.ResourceAuthorization;
import org.jboss.as.controller.access.management.AccessConstraintDefinition;
import org.jboss.as.controller.capability.CapabilityServiceSupport;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.client.MessageSeverity;
import org.jboss.as.controller.client.OperationAttachments;
Expand Down Expand Up @@ -684,6 +685,11 @@ public ServiceName getCapabilityServiceName(String capabilitBaseyName, String dy
return null;
}

@Override
public CapabilityServiceSupport getCapabilityServiceSupport() {
return null;
}

@Override
public void emit(Notification notification) {
// no-op
Expand Down
Expand Up @@ -29,6 +29,7 @@
import java.util.jar.Manifest;

import org.jboss.as.controller.ServiceVerificationHandler;
import org.jboss.as.controller.capability.CapabilityServiceSupport;
import org.jboss.as.controller.services.path.PathManager;
import org.jboss.as.server.deployment.annotation.CompositeIndex;
import org.jboss.as.server.deployment.module.AdditionalModuleSpecification;
Expand Down Expand Up @@ -204,11 +205,14 @@ public final class Attachments {
public static final AttachmentKey<Map<String, MountedDeploymentOverlay>> DEPLOYMENT_OVERLAY_LOCATIONS = AttachmentKey.create(Map.class);

/**
* Support for getting and creating resource models on a deployments resource.
* Support for getting and creating resource models on a deployment's resource.
*/
public static final AttachmentKey<DeploymentResourceSupport> DEPLOYMENT_RESOURCE_SUPPORT = AttachmentKey.create(DeploymentResourceSupport.class);


/**
* Support for integrating with services and other runtime API provided by managed capabilities.
*/
public static final AttachmentKey<CapabilityServiceSupport> CAPABILITY_SERVICE_SUPPORT = AttachmentKey.create(CapabilityServiceSupport.class);

//
// VALIDATE
Expand Down
Expand Up @@ -133,7 +133,8 @@ public void handleResult(OperationContext.ResultAction resultAction, OperationCo
}

public static void doDeploy(final OperationContext context, final String deploymentUnitName, final String managementName,
final Resource deploymentResource, final ImmutableManagementResourceRegistration registration, final ManagementResourceRegistration mutableRegistration, final AbstractVaultReader vaultReader, final ContentItem... contents) {
final Resource deploymentResource, final ImmutableManagementResourceRegistration registration,
final ManagementResourceRegistration mutableRegistration, final AbstractVaultReader vaultReader, final ContentItem... contents) {
final ServiceName deploymentUnitServiceName = Services.deploymentUnitName(deploymentUnitName);

final ServiceTarget serviceTarget = context.getServiceTarget();
Expand All @@ -149,7 +150,8 @@ public static void doDeploy(final OperationContext context, final String deploym
}
DeploymentOverlayIndex overlays = DeploymentOverlayIndex.createDeploymentOverlayIndex(context);

final RootDeploymentUnitService service = new RootDeploymentUnitService(deploymentUnitName, managementName, null, registration, mutableRegistration, deploymentResource, vaultReader, overlays);
final RootDeploymentUnitService service = new RootDeploymentUnitService(deploymentUnitName, managementName, null,
registration, mutableRegistration, deploymentResource, context.getCapabilityServiceSupport(), vaultReader, overlays);
final ServiceController<DeploymentUnit> deploymentUnitController = serviceTarget.addService(deploymentUnitServiceName, service)
.addDependency(Services.JBOSS_DEPLOYMENT_CHAINS, DeployerChains.class, service.getDeployerChainsInjector())
.addDependency(DeploymentMountProvider.SERVICE_NAME, DeploymentMountProvider.class, service.getServerDeploymentRepositoryInjector())
Expand Down
Expand Up @@ -23,6 +23,7 @@
package org.jboss.as.server.deployment;

import org.jboss.as.controller.ServiceVerificationHandler;
import org.jboss.as.controller.capability.CapabilityServiceSupport;
import org.jboss.as.controller.registry.ImmutableManagementResourceRegistration;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.controller.registry.Resource;
Expand All @@ -48,30 +49,35 @@ final class RootDeploymentUnitService extends AbstractDeploymentUnitService {
private final DeploymentUnit parent;
private final ImmutableManagementResourceRegistration registration;
private final ManagementResourceRegistration mutableRegistration;
private Resource resource;
private final Resource resource;
private final CapabilityServiceSupport capabilityServiceSupport;
private final AbstractVaultReader vaultReader;
private final DeploymentOverlayIndex deploymentOverlays;

/**
* Construct a new instance.
*
* @param name the deployment unit simple name
* @param name the deployment unit simple name
* @param managementName the deployment's domain-wide unique name
* @param parent the parent deployment unit
* @param registration the registration
* @param mutableRegistration the mutable registration
* @param resource the model
* @param capabilityServiceSupport support for capability integration
* @param vaultReader the vault reader
* @param deploymentOverlays the deployment overlays
*/
public RootDeploymentUnitService(final String name, final String managementName, final DeploymentUnit parent, final ImmutableManagementResourceRegistration registration, final ManagementResourceRegistration mutableRegistration, Resource resource, final AbstractVaultReader vaultReader, DeploymentOverlayIndex deploymentOverlays) {
public RootDeploymentUnitService(final String name, final String managementName, final DeploymentUnit parent,
final ImmutableManagementResourceRegistration registration, final ManagementResourceRegistration mutableRegistration,
final Resource resource, final CapabilityServiceSupport capabilityServiceSupport,
final AbstractVaultReader vaultReader, DeploymentOverlayIndex deploymentOverlays) {
assert name != null : "name is null";
this.name = name;
this.managementName = managementName;
this.parent = parent;
this.registration = registration;
this.mutableRegistration = mutableRegistration;
this.resource = resource;
this.capabilityServiceSupport = capabilityServiceSupport;
this.vaultReader = vaultReader;
this.deploymentOverlays = deploymentOverlays;
}
Expand All @@ -85,6 +91,7 @@ protected DeploymentUnit createAndInitializeDeploymentUnit(final ServiceRegistry
deploymentUnit.putAttachment(DeploymentResourceSupport.MUTABLE_REGISTRATION_ATTACHMENT, mutableRegistration);
deploymentUnit.putAttachment(DeploymentResourceSupport.DEPLOYMENT_RESOURCE, resource);
deploymentUnit.putAttachment(Attachments.DEPLOYMENT_RESOURCE_SUPPORT, new DeploymentResourceSupport(deploymentUnit));
deploymentUnit.putAttachment(Attachments.CAPABILITY_SERVICE_SUPPORT, capabilityServiceSupport);
deploymentUnit.putAttachment(Attachments.VAULT_READER_ATTACHMENT_KEY, vaultReader);
deploymentUnit.putAttachment(Attachments.DEPLOYMENT_OVERLAY_INDEX, deploymentOverlays);
deploymentUnit.putAttachment(Attachments.PATH_MANAGER, pathManagerInjector.getValue());
Expand Down

0 comments on commit 8a12f32

Please sign in to comment.