Skip to content

Commit

Permalink
[WFLY-11480]: Possible to remove referenced activemq http-connector.
Browse files Browse the repository at this point in the history
 * Adding support for capabilities in connection factories and transport configurations.
 * Adding support for proper default configuration for external pcf.

Jira: https://issues.jboss.org/browse/WFLY-11480
  • Loading branch information
ehsavoie committed Jan 11, 2019
1 parent 8b97d27 commit b9e7d42
Show file tree
Hide file tree
Showing 21 changed files with 649 additions and 121 deletions.
Expand Up @@ -26,16 +26,24 @@
import java.util.Collection;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.function.Function;

import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.CapabilityReferenceRecorder;
import org.jboss.as.controller.ModelVersion;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.PersistentResourceDefinition;
import org.jboss.as.controller.ReloadRequiredWriteAttributeHandler;
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.capability.DynamicNameMappers;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
import org.jboss.as.controller.registry.AttributeAccess;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.controller.registry.Resource;

/**
* Abstract acceptor resource definition
Expand All @@ -44,19 +52,118 @@
*/
public abstract class AbstractTransportDefinition extends PersistentResourceDefinition {

public static final String CONNECTOR_CAPABILITY_NAME = "org.wildfly.messaging.activemq.connector";
public static final String ACCEPTOR_CAPABILITY_NAME = "org.wildfly.messaging.activemq.acceptor";
private final boolean registerRuntimeOnly;
private final AttributeDefinition[] attrs;
protected final boolean isAcceptor;

private static class TransportCapabilityNameMapper implements Function<PathAddress,String[]> {
private static final TransportCapabilityNameMapper INSTANCE = new TransportCapabilityNameMapper();
private TransportCapabilityNameMapper(){};
@Override
public String[] apply(PathAddress address) {
String[] result = new String[2];
PathAddress serverAddress = MessagingServices.getActiveMQServerPathAddress(address);
if(serverAddress.size() > 0 ) {
result[0] = serverAddress.getLastElement().getValue();
} else {
result[0] = "external";
}
result[1] = address.getLastElement().getValue();
return result;
}
}

public static class TransportCapabilityReferenceRecorder extends CapabilityReferenceRecorder.ResourceCapabilityReferenceRecorder {
private final boolean external;
public TransportCapabilityReferenceRecorder(String baseDependentName, String baseRequirementName, boolean external) {
super(external ? DynamicNameMappers.SIMPLE : DynamicNameMappers.PARENT, baseDependentName, TransportCapabilityNameMapper.INSTANCE, baseRequirementName);
this.external = external;
}

@Override
public void addCapabilityRequirements(OperationContext context, Resource resource, String attributeName, String... attributeValues) {
processCapabilityRequirement(context, attributeName, false, attributeValues);
}

@Override
public void removeCapabilityRequirements(OperationContext context, Resource resource, String attributeName, String... attributeValues) {
processCapabilityRequirement(context, attributeName, true, attributeValues);
}

private void processCapabilityRequirement(OperationContext context, String attributeName, boolean remove, String... attributeValues) {
String dependentName = getDependentName(context.getCurrentAddress());
String requirement = getRequirementName(context.getCurrentAddress());
for (String att : attributeValues) {
String requirementName = RuntimeCapability.buildDynamicCapabilityName(requirement, att);
if (remove) {
context.deregisterCapabilityRequirement(requirementName, dependentName, attributeName);
} else {
context.registerAdditionalCapabilityRequirement(requirementName, dependentName, attributeName);
}
}
}

private String getDependentName(PathAddress address) {
if (external) {
return RuntimeCapability.buildDynamicCapabilityName(getBaseDependentName(), DynamicNameMappers.SIMPLE.apply(address));
}
return RuntimeCapability.buildDynamicCapabilityName(getBaseDependentName(), DynamicNameMappers.PARENT.apply(address));
}

private String getRequirementName(PathAddress address) {
PathAddress serverAddress = MessagingServices.getActiveMQServerPathAddress(address);
if (serverAddress.size() > 0) {
return RuntimeCapability.buildDynamicCapabilityName(getBaseRequirementName(), serverAddress.getLastElement().getValue());
}
return getBaseRequirementName();
}

@Override
public String getBaseRequirementName() {
if (external) {
return super.getBaseRequirementName() + ".external";
}
return super.getBaseRequirementName();
}

@Override
public String[] getRequirementPatternSegments(String dynamicElement, PathAddress registrationAddress) {
String[] dynamicElements;
if (!external) {
dynamicElements = new String[]{"$server"};
} else {
dynamicElements = new String[0];
}
if (dynamicElement != null && !dynamicElement.isEmpty()) {
String[] result = new String[dynamicElements.length + 1];
for (int i = 0; i < dynamicElements.length; i++) {
if (dynamicElements[i].charAt(0) == '$') {
result[i] = dynamicElements[i].substring(1);
} else {
result[i] = dynamicElements[i];
}
}
result[dynamicElements.length] = dynamicElement;
return result;
}
return dynamicElements;
}
}

protected AbstractTransportDefinition(final boolean isAcceptor, final String specificType, final boolean registerRuntimeOnly, AttributeDefinition... attrs) {
super(new Parameters(PathElement.pathElement(specificType),
super(new SimpleResourceDefinition.Parameters(PathElement.pathElement(specificType),
new StandardResourceDescriptionResolver((isAcceptor ? CommonAttributes.ACCEPTOR : CommonAttributes.CONNECTOR),
MessagingExtension.RESOURCE_NAME, MessagingExtension.class.getClassLoader(), true, false) {
@Override
public String getResourceDescription(Locale locale, ResourceBundle bundle) {
return bundle.getString(specificType);
}
})
.setCapabilities(RuntimeCapability.Builder.of(isAcceptor ? ACCEPTOR_CAPABILITY_NAME : CONNECTOR_CAPABILITY_NAME, true)
.setDynamicNameMapper(TransportCapabilityNameMapper.INSTANCE)
.build())
.setAddHandler(new ActiveMQReloadRequiredHandlers.AddStepHandler(attrs))
.setRemoveHandler(new ActiveMQReloadRequiredHandlers.RemoveStepHandler()));
this.isAcceptor = isAcceptor;
Expand All @@ -65,7 +172,7 @@ public String getResourceDescription(Locale locale, ResourceBundle bundle) {
}

protected AbstractTransportDefinition(final boolean isAcceptor, final String specificType, final boolean registerRuntimeOnly, ModelVersion deprecatedSince, AttributeDefinition... attrs) {
super(new Parameters(PathElement.pathElement(specificType),
super(new SimpleResourceDefinition.Parameters(PathElement.pathElement(specificType),
new StandardResourceDescriptionResolver((isAcceptor ? CommonAttributes.ACCEPTOR : CommonAttributes.CONNECTOR),
MessagingExtension.RESOURCE_NAME, MessagingExtension.class.getClassLoader(), true, false) {
@Override
Expand Down
Expand Up @@ -36,8 +36,6 @@
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.as.controller.registry.Resource;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
Expand Down Expand Up @@ -66,9 +64,8 @@ protected void populateModel(OperationContext context, ModelNode operation, fina
protected void performRuntime(final OperationContext context, final ModelNode operation, final ModelNode model) throws OperationFailedException {
final ActiveMQServer server = getActiveMQServer(context, operation);
if(server != null) {
final PathAddress address = PathAddress.pathAddress(operation.require(ModelDescriptionConstants.OP_ADDR));
final AddressSettings settings = createSettings(context, model);
server.getAddressSettingsRepository().addMatch(address.getLastElement().getValue(), settings);
server.getAddressSettingsRepository().addMatch(context.getCurrentAddressValue(), settings);
}
}

Expand Down
Expand Up @@ -86,6 +86,8 @@
import static org.wildfly.extension.messaging.activemq.CommonAttributes.EXTERNAL_JMS_QUEUE;
import static org.wildfly.extension.messaging.activemq.CommonAttributes.EXTERNAL_JMS_TOPIC;

import org.wildfly.extension.messaging.activemq.jms.ExternalPooledConnectionFactoryDefinition;

/**
* Domain extension that integrates Apache ActiveMQ 6.
*
Expand Down Expand Up @@ -226,7 +228,7 @@ public void initialize(ExtensionContext context) {
subsystem.registerSubModel(RemoteTransportDefinition.createConnectorDefinition(registerRuntimeOnly));
subsystem.registerSubModel(new HTTPConnectorDefinition(registerRuntimeOnly));
subsystem.registerSubModel(new ExternalConnectionFactoryDefinition(registerRuntimeOnly));
subsystem.registerSubModel(PooledConnectionFactoryDefinition.INSTANCE);
subsystem.registerSubModel(ExternalPooledConnectionFactoryDefinition.INSTANCE);
subsystem.registerSubModel(new ExternalJMSQueueDefinition(registerRuntimeOnly));
subsystem.registerSubModel(new ExternalJMSTopicDefinition(registerRuntimeOnly));

Expand All @@ -248,6 +250,8 @@ public void initialize(ExtensionContext context) {
if (registerRuntimeOnly) {
final ManagementResourceRegistration deployment = subsystemRegistration.registerDeploymentModel(new SimpleResourceDefinition(
new Parameters(SUBSYSTEM_PATH, getResourceDescriptionResolver("deployed")).setFeature(false)));
deployment.registerSubModel(new ExternalConnectionFactoryDefinition(registerRuntimeOnly));
deployment.registerSubModel(ExternalPooledConnectionFactoryDefinition.DEPLOYMENT_INSTANCE);
deployment.registerSubModel(new ExternalJMSQueueDefinition(registerRuntimeOnly));
deployment.registerSubModel(new ExternalJMSTopicDefinition(registerRuntimeOnly));
final ManagementResourceRegistration deployedServer = deployment.registerSubModel(new SimpleResourceDefinition(
Expand Down
Expand Up @@ -44,7 +44,6 @@
import org.wildfly.extension.messaging.activemq.ha.SharedStoreMasterDefinition;
import org.wildfly.extension.messaging.activemq.ha.SharedStoreSlaveDefinition;
import org.wildfly.extension.messaging.activemq.jms.ConnectionFactoryAttributes;
import org.wildfly.extension.messaging.activemq.jms.PooledConnectionFactoryDefinition;
import org.wildfly.extension.messaging.activemq.jms.bridge.JMSBridgeDefinition;
import org.wildfly.extension.messaging.activemq.jms.legacy.LegacyConnectionFactoryDefinition;

Expand Down Expand Up @@ -97,7 +96,7 @@ public PersistentResourceXMLDescription getParserDescription(){
CommonAttributes.PARAMS);

final PersistentResourceXMLBuilder pooledConnectionFactory =
builder(PooledConnectionFactoryDefinition.INSTANCE.getPathElement())
builder(MessagingExtension.POOLED_CONNECTION_FACTORY_PATH)
.addAttributes(
ConnectionFactoryAttributes.Common.ENTRIES,
// common
Expand Down
Expand Up @@ -37,8 +37,6 @@
import org.jboss.as.controller.AbstractAddStepHandler;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.dmr.ModelNode;
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceController.Mode;
Expand Down Expand Up @@ -66,12 +64,15 @@ private ConnectionFactoryAdd() {
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
final String name = context.getCurrentAddressValue();
final ServiceName activeMQServiceName = MessagingServices.getActiveMQServiceName(PathAddress.pathAddress(operation.get(ModelDescriptionConstants.OP_ADDR)));
final ServiceName activeMQServiceName = MessagingServices.getActiveMQServiceName(context.getCurrentAddress());

final ConnectionFactoryConfiguration configuration = createConfiguration(context, name, model);
final ConnectionFactoryService service = new ConnectionFactoryService(configuration);
final ServiceName serviceName = JMSServices.getConnectionFactoryBaseServiceName(activeMQServiceName).append(name);
ServiceBuilder<?> serviceBuilder = context.getServiceTarget().addService(serviceName, service);
final ServiceName aliasServiceName = JMSServices.getConnectionFactoryBaseServiceName(activeMQServiceName).append(name);
final ServiceName serviceName = ConnectionFactoryDefinition.CAPABILITY.getCapabilityServiceName(context.getCurrentAddress());
ServiceBuilder<?> serviceBuilder = context.getServiceTarget()
.addService(serviceName, service)
.addAliases(aliasServiceName);
serviceBuilder.requires(ActiveMQActivationService.getServiceName(activeMQServiceName));
serviceBuilder.addDependency(JMSServices.getJmsManagerBaseServiceName(activeMQServiceName), JMSServerManager.class, service.getJmsServer());
serviceBuilder.setInitialMode(Mode.PASSIVE);
Expand Down
Expand Up @@ -30,10 +30,12 @@
import static org.jboss.dmr.ModelType.INT;
import static org.jboss.dmr.ModelType.LONG;
import static org.jboss.dmr.ModelType.STRING;
import static org.wildfly.extension.messaging.activemq.AbstractTransportDefinition.CONNECTOR_CAPABILITY_NAME;
import static org.wildfly.extension.messaging.activemq.MessagingExtension.MESSAGING_SECURITY_SENSITIVE_TARGET;
import static org.wildfly.extension.messaging.activemq.jms.ConnectionFactoryAttribute.ConfigType.INBOUND;
import static org.wildfly.extension.messaging.activemq.jms.ConnectionFactoryAttribute.ConfigType.OUTBOUND;
import static org.wildfly.extension.messaging.activemq.jms.ConnectionFactoryAttribute.create;
import static org.wildfly.extension.messaging.activemq.jms.ConnectionFactoryDefinition.CAPABILITY_NAME;

import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
Expand All @@ -50,6 +52,7 @@
import org.jboss.as.controller.operations.validation.StringLengthValidator;
import org.jboss.as.controller.security.CredentialReference;
import org.jboss.dmr.ModelNode;
import org.wildfly.extension.messaging.activemq.AbstractTransportDefinition;
import org.wildfly.extension.messaging.activemq.CommonAttributes;
import org.wildfly.extension.messaging.activemq.InfiniteOrPositiveValidators;

Expand Down Expand Up @@ -168,6 +171,7 @@ interface Common {
.setRequired(true)
.setAttributeParser(AttributeParser.STRING_LIST)
.setAttributeMarshaller(AttributeMarshaller.STRING_LIST)
.setCapabilityReference(new AbstractTransportDefinition.TransportCapabilityReferenceRecorder(CAPABILITY_NAME, CONNECTOR_CAPABILITY_NAME, false))
.setRestartAllServices()
.build();

Expand Down
Expand Up @@ -30,6 +30,9 @@

import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.PersistentResourceDefinition;
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.capability.DynamicNameMappers;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.wildfly.extension.messaging.activemq.CommonAttributes;
import org.wildfly.extension.messaging.activemq.MessagingExtension;
Expand All @@ -43,6 +46,11 @@
*/
public class ConnectionFactoryDefinition extends PersistentResourceDefinition {

static final String CAPABILITY_NAME = "org.wildfly.messaging.activemq.server.connection-factory";
static final RuntimeCapability<Void> CAPABILITY = RuntimeCapability.Builder.of(CAPABILITY_NAME, true, ConnectionFactoryService.class)
.setDynamicNameMapper(DynamicNameMappers.PARENT)
.build();

static final AttributeDefinition[] concat(AttributeDefinition[] common, AttributeDefinition... specific) {
int size = common.length + specific.length;
AttributeDefinition[] result = new AttributeDefinition[size];
Expand All @@ -56,10 +64,11 @@ static final AttributeDefinition[] concat(AttributeDefinition[] common, Attribut
private final boolean registerRuntimeOnly;

public ConnectionFactoryDefinition(final boolean registerRuntimeOnly) {
super(MessagingExtension.CONNECTION_FACTORY_PATH,
MessagingExtension.getResourceDescriptionResolver(CommonAttributes.CONNECTION_FACTORY),
ConnectionFactoryAdd.INSTANCE,
ConnectionFactoryRemove.INSTANCE);
super(new SimpleResourceDefinition.Parameters(MessagingExtension.CONNECTION_FACTORY_PATH,
MessagingExtension.getResourceDescriptionResolver(CommonAttributes.CONNECTION_FACTORY))
.setCapabilities(CAPABILITY)
.setAddHandler(ConnectionFactoryAdd.INSTANCE)
.setRemoveHandler(ConnectionFactoryRemove.INSTANCE));
this.registerRuntimeOnly = registerRuntimeOnly;
}

Expand Down
Expand Up @@ -73,12 +73,14 @@ private ExternalConnectionFactoryAdd() {
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
final String name = context.getCurrentAddressValue();
final ServiceName serviceName = MessagingServices.getActiveMQServiceName(name);
final ServiceName serviceName = ExternalConnectionFactoryDefinition.CAPABILITY.getCapabilityServiceName(context.getCurrentAddress());
boolean ha = HA.resolveModelAttribute(context, model).asBoolean();
final ModelNode discoveryGroupName = Common.DISCOVERY_GROUP.resolveModelAttribute(context, model);
JMSFactoryType jmsFactoryType = ConnectionFactoryType.valueOf(ConnectionFactoryAttributes.Regular.FACTORY_TYPE.resolveModelAttribute(context, model).asString()).getType();
List<String> connectorNames = Common.CONNECTORS.unwrap(context, model);
ServiceBuilder<?> builder = context.getServiceTarget().addService(serviceName);
ServiceBuilder<?> builder = context.getServiceTarget()
.addService(serviceName)
.addAliases(MessagingServices.getActiveMQServiceName(name));
ExternalConnectionFactoryService service;
if (discoveryGroupName.isDefined()) {
// mapping between the {discovery}-groups and the cluster names they use
Expand Down

0 comments on commit b9e7d42

Please sign in to comment.