Skip to content

Commit

Permalink
WFLY-8525 Add capabilities to mail subsystem
Browse files Browse the repository at this point in the history
  • Loading branch information
ctomc committed Apr 6, 2017
1 parent 33abc99 commit d256ab9
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 115 deletions.
Expand Up @@ -27,6 +27,7 @@
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.RestartParentResourceAddHandler;
import org.jboss.as.controller.registry.Resource;
import org.jboss.as.naming.deployment.ContextNames;
import org.jboss.dmr.ModelNode;
import org.jboss.msc.service.ServiceName;
Expand Down Expand Up @@ -66,7 +67,7 @@ protected void recreateParentService(OperationContext context, PathAddress paren

@Override
protected ServiceName getParentServiceName(PathAddress parentAddress) {
return MailSessionAdd.MAIL_SESSION_SERVICE_NAME.append(parentAddress.getLastElement().getValue());
return MailSessionDefinition.SESSION_CAPABILITY.getCapabilityServiceName(parentAddress.getLastElement().getValue());
}

@Override
Expand All @@ -76,4 +77,23 @@ protected void removeServices(OperationContext context, ServiceName parentServic
final ContextNames.BindInfo bindInfo = ContextNames.bindInfoFor(jndiName);
context.removeService(bindInfo.getBinderServiceName());
}

//todo this is workaround for recording capabilities as Restart*Parent* handlers don't handle capabilities yet!
@Override
protected void updateModel(OperationContext context, ModelNode operation) throws OperationFailedException {
super.updateModel(context, operation);
recordCapabilitiesAndRequirements(context, context.readResource(PathAddress.EMPTY_ADDRESS));
}

private void recordCapabilitiesAndRequirements(final OperationContext context, Resource resource) throws OperationFailedException {

context.registerCapability(MailServerDefinition.SERVER_CAPABILITY.fromBaseCapability(context.getCurrentAddress()));

ModelNode model = resource.getModel();
for (AttributeDefinition ad : attributes) {
if (model.hasDefined(ad.getName()) || ad.hasCapabilityRequirements()) {
ad.addCapabilityRequirements(context, resource, model.get(ad.getName()));
}
}
}
}
Expand Up @@ -41,9 +41,11 @@
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.access.constraint.SensitivityClassification;
import org.jboss.as.controller.access.management.SensitiveTargetAccessConstraintDefinition;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.as.controller.registry.AttributeAccess;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.controller.registry.Resource;
import org.jboss.as.controller.security.CredentialReference;
import org.jboss.as.naming.deployment.ContextNames;
import org.jboss.dmr.ModelNode;
Expand All @@ -55,6 +57,14 @@
* @since 7.1.0
*/
class MailServerDefinition extends PersistentResourceDefinition {
static final String OUTBOUND_SOCKET_BINDING_CAPABILITY_NAME = "org.wildfly.network.outbound-socket-binding";
static final String CREDENTIAL_STORE_CAPABILITY = "org.wildfly.security.credential-store";

static final RuntimeCapability<Void> SERVER_CAPABILITY = RuntimeCapability.Builder.of("org.wildfly.mail.session.server", true)
.setDynamicNameMapper(path -> new String[]{
path.getParent().getLastElement().getValue(),
path.getLastElement().getValue()})
.build();

static final SensitivityClassification MAIL_SERVER_SECURITY =
new SensitivityClassification(MailExtension.SUBSYSTEM_NAME, "mail-server-security", false, false, true);
Expand All @@ -69,6 +79,7 @@ class MailServerDefinition extends PersistentResourceDefinition {
.build();

static final SimpleAttributeDefinition OUTBOUND_SOCKET_BINDING_REF_OPTIONAL = SimpleAttributeDefinitionBuilder.create(OUTBOUND_SOCKET_BINDING_REF)
.setCapabilityReference(OUTBOUND_SOCKET_BINDING_CAPABILITY_NAME)
.setRequired(false)
.build();

Expand Down Expand Up @@ -104,6 +115,7 @@ class MailServerDefinition extends PersistentResourceDefinition {
.addAccessConstraint(SensitiveTargetAccessConstraintDefinition.CREDENTIAL)
.addAccessConstraint(MAIL_SERVER_SECURITY_DEF)
.addAlternatives(MailSubsystemModel.PASSWORD)
.setCapabilityReference(CREDENTIAL_STORE_CAPABILITY)
.build();

protected static final SimpleAttributeDefinition PASSWORD =
Expand Down Expand Up @@ -134,10 +146,12 @@ class MailServerDefinition extends PersistentResourceDefinition {
private final List<AttributeDefinition> attributes;

private MailServerDefinition(final PathElement path, AttributeDefinition[] attributes) {
super(path,
MailExtension.getResourceDescriptionResolver(MailSubsystemModel.MAIL_SESSION, MailSubsystemModel.SERVER_TYPE),
new MailServerAdd(attributes),
new MailServerRemove());
super(new Parameters(path,
MailExtension.getResourceDescriptionResolver(MailSubsystemModel.MAIL_SESSION, MailSubsystemModel.SERVER_TYPE))
.setAddHandler(new MailServerAdd(attributes))
.setRemoveHandler(new MailServerRemove(attributes))
.setCapabilities(SERVER_CAPABILITY)
);
this.attributes = Arrays.asList(attributes);
}

Expand All @@ -156,14 +170,17 @@ public void registerAttributes(ManagementResourceRegistration resourceRegistrati
}

private static final class MailServerRemove extends RestartParentResourceRemoveHandler {
private MailServerRemove() {
private final AttributeDefinition[] attributes;
private MailServerRemove(AttributeDefinition ... attributes) {
super(MailSubsystemModel.MAIL_SESSION);
this.attributes = attributes;
}

@Override
protected void updateModel(OperationContext context, ModelNode operation) throws OperationFailedException {
context.readResource(PathAddress.EMPTY_ADDRESS, false); //to make sure resource we are removing exists! it will throw exception.
Resource r = context.readResource(PathAddress.EMPTY_ADDRESS, false); //to make sure resource we are removing exists! it will throw exception.
super.updateModel(context, operation);
recordCapabilitiesAndRequirements(context, r);
}

@Override
Expand All @@ -173,7 +190,7 @@ protected void recreateParentService(OperationContext context, PathAddress paren

@Override
protected ServiceName getParentServiceName(PathAddress parentAddress) {
return MailSessionAdd.MAIL_SESSION_SERVICE_NAME.append(parentAddress.getLastElement().getValue());
return MailSessionDefinition.SESSION_CAPABILITY.getCapabilityServiceName(parentAddress.getLastElement().getValue());
}

@Override
Expand All @@ -183,7 +200,16 @@ protected void removeServices(OperationContext context, ServiceName parentServic
final ContextNames.BindInfo bindInfo = ContextNames.bindInfoFor(jndiName);
context.removeService(bindInfo.getBinderServiceName());
}

//todo workaround until it is supported on abstract classes
private void recordCapabilitiesAndRequirements(OperationContext context, Resource resource) throws OperationFailedException {
context.deregisterCapability(MailServerDefinition.SERVER_CAPABILITY.getDynamicName(context.getCurrentAddress()));
ModelNode model = resource.getModel();
for (AttributeDefinition ad : attributes) {
if (ad != null && (model.hasDefined(ad.getName()) || ad.hasCapabilityRequirements())) {
ad.removeCapabilityRequirements(context, resource, model.get(ad.getName()));
}
}
}

}
}
Expand Up @@ -54,7 +54,7 @@ protected void recreateParentService(OperationContext context, PathAddress paren

@Override
protected ServiceName getParentServiceName(PathAddress parentAddress) {
return MailSessionAdd.MAIL_SESSION_SERVICE_NAME.append(parentAddress.getLastElement().getValue());
return MailSessionDefinition.SESSION_CAPABILITY.getCapabilityServiceName(parentAddress.getLastElement().getValue());
}

@Override
Expand Down
44 changes: 18 additions & 26 deletions mail/src/main/java/org/jboss/as/mail/extension/MailSessionAdd.java
Expand Up @@ -22,7 +22,9 @@

package org.jboss.as.mail.extension;

import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
import static org.jboss.as.mail.extension.MailServerDefinition.OUTBOUND_SOCKET_BINDING_CAPABILITY_NAME;
import static org.jboss.as.mail.extension.MailSessionDefinition.ATTRIBUTES;
import static org.jboss.as.mail.extension.MailSessionDefinition.SESSION_CAPABILITY;
import static org.jboss.as.mail.extension.MailSubsystemModel.CUSTOM;
import static org.jboss.as.mail.extension.MailSubsystemModel.IMAP;
import static org.jboss.as.mail.extension.MailSubsystemModel.POP3;
Expand All @@ -32,7 +34,11 @@

import java.util.Map;

import javax.mail.Session;

import org.jboss.as.controller.AbstractAddStepHandler;
import org.jboss.as.controller.CapabilityServiceBuilder;
import org.jboss.as.controller.CapabilityServiceTarget;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PathAddress;
Expand All @@ -49,7 +55,6 @@
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceTarget;

/**
* @author Tomaz Cerar
Expand All @@ -58,22 +63,13 @@
class MailSessionAdd extends AbstractAddStepHandler {

static final MailSessionAdd INSTANCE = new MailSessionAdd();
public static final ServiceName MAIL_SESSION_SERVICE_NAME = ServiceName.JBOSS.append("mail-session");
@Deprecated
static final ServiceName MAIL_SESSION_SERVICE_NAME = ServiceName.JBOSS.append("mail-session");

protected MailSessionAdd() {
super(ATTRIBUTES);
}

/**
* {@inheritDoc}
*/
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
MailSessionDefinition.JNDI_NAME.validateAndSet(operation, model);
MailSessionDefinition.DEBUG.validateAndSet(operation, model);
MailSessionDefinition.FROM.validateAndSet(operation, model);
}


/**
* Make any runtime changes necessary to effect the changes indicated by the given {@code operation}. E
* <p>
Expand All @@ -88,12 +84,12 @@ protected void populateModel(ModelNode operation, ModelNode model) throws Operat
*/
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
final PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR));
final PathAddress address = context.getCurrentAddress();
ModelNode fullTree = Resource.Tools.readModel(context.readResource(PathAddress.EMPTY_ADDRESS));
installRuntimeServices(context, address, fullTree);
}

static void addCredentialStoreReference(ServerConfig serverConfig, OperationContext context, ModelNode model, ServiceBuilder<?> serviceBuilder, String... modelFilter) throws OperationFailedException {
private static void addCredentialStoreReference(ServerConfig serverConfig, OperationContext context, ModelNode model, ServiceBuilder<?> serviceBuilder, String... modelFilter) throws OperationFailedException {
if (serverConfig != null) {
ModelNode filteredModelNode = model;
if (modelFilter != null && modelFilter.length > 0) {
Expand All @@ -114,16 +110,13 @@ static void addCredentialStoreReference(ServerConfig serverConfig, OperationCont
}

static void installRuntimeServices(OperationContext context, PathAddress address, ModelNode fullModel) throws OperationFailedException {
String name = address.getLastElement().getValue();

final String jndiName = getJndiName(fullModel, context);
final ServiceTarget serviceTarget = context.getServiceTarget();

final CapabilityServiceTarget serviceTarget = context.getCapabilityServiceTarget();

final MailSessionConfig config = from(context, fullModel);
final MailSessionService service = new MailSessionService(config);
final ServiceName serviceName = MAIL_SESSION_SERVICE_NAME.append(name);
final ServiceBuilder<?> mailSessionBuilder = serviceTarget.addService(serviceName, service);

final CapabilityServiceBuilder<Session> mailSessionBuilder = serviceTarget.addCapability(SESSION_CAPABILITY.fromBaseCapability(address.getLastElement().getValue()), service);
addOutboundSocketDependency(service, mailSessionBuilder, config.getImapServer());
addCredentialStoreReference(config.getImapServer(), context, fullModel, mailSessionBuilder, MailSubsystemModel.IMAP_SERVER_PATH.getKey(), MailSubsystemModel.IMAP_SERVER_PATH.getValue());
addOutboundSocketDependency(service, mailSessionBuilder, config.getPop3Server());
Expand All @@ -136,6 +129,7 @@ static void installRuntimeServices(OperationContext context, PathAddress address
}
addCredentialStoreReference(server, context, fullModel, mailSessionBuilder, MailSubsystemModel.CUSTOM_SERVER_PATH.getKey(), server.getProtocol());
}
mailSessionBuilder.addAliases(MAIL_SESSION_SERVICE_NAME.append(address.getLastElement().getValue()));


final ManagedReferenceFactory valueManagedReferenceFactory = new MailSessionManagedReferenceFactory(service);
Expand Down Expand Up @@ -193,12 +187,10 @@ public static String getJndiName(final String rawJndiName) {
return jndiName;
}


private static void addOutboundSocketDependency(MailSessionService service, ServiceBuilder<?> mailSessionBuilder, ServerConfig server) {
private static void addOutboundSocketDependency(MailSessionService service, CapabilityServiceBuilder<?> mailSessionBuilder, ServerConfig server) {
if (server != null) {
final String ref = server.getOutgoingSocketBinding();
mailSessionBuilder.addDependency(OutboundSocketBinding.OUTBOUND_SOCKET_BINDING_BASE_SERVICE_NAME.append(ref),
OutboundSocketBinding.class, service.getSocketBindingInjector(ref));
mailSessionBuilder.addCapabilityRequirement(OUTBOUND_SOCKET_BINDING_CAPABILITY_NAME, OutboundSocketBinding.class, service.getSocketBindingInjector(ref), ref);
}
}

Expand Down
Expand Up @@ -25,6 +25,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.mail.Session;

import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.PersistentResourceDefinition;
Expand All @@ -34,28 +35,22 @@
import org.jboss.as.controller.access.constraint.ApplicationTypeConfig;
import org.jboss.as.controller.access.management.AccessConstraintDefinition;
import org.jboss.as.controller.access.management.ApplicationTypeAccessConstraintDefinition;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;

/**
* @author Tomaz Cerar
* @created 19.12.11 21:04
* @created 19.12.11
*/
class MailSessionDefinition extends PersistentResourceDefinition {

static final MailSessionDefinition INSTANCE = new MailSessionDefinition();
static final RuntimeCapability<Void> SESSION_CAPABILITY = RuntimeCapability.Builder.of("org.wildfly.mail.session", true, Session.class)
.build();

private final List<AccessConstraintDefinition> accessConstraints;

private MailSessionDefinition() {
super(MailExtension.MAIL_SESSION_PATH,
MailExtension.getResourceDescriptionResolver(MailSubsystemModel.MAIL_SESSION),
MailSessionAdd.INSTANCE,
new ServiceRemoveStepHandler(MailSessionAdd.MAIL_SESSION_SERVICE_NAME, MailSessionAdd.INSTANCE));
ApplicationTypeConfig atc = new ApplicationTypeConfig(MailExtension.SUBSYSTEM_NAME, MailSubsystemModel.MAIL_SESSION);
accessConstraints = new ApplicationTypeAccessConstraintDefinition(atc).wrapAsList();
}
private final List<AccessConstraintDefinition> accessConstraints;

protected static final SimpleAttributeDefinition JNDI_NAME =
new SimpleAttributeDefinitionBuilder(MailSubsystemModel.JNDI_NAME, ModelType.STRING, false)
Expand All @@ -75,7 +70,7 @@ private MailSessionDefinition() {
.setRestartAllServices()
.build();

private static final AttributeDefinition[] ATTRIBUTES = {DEBUG, JNDI_NAME, FROM};
static final AttributeDefinition[] ATTRIBUTES = {DEBUG, JNDI_NAME, FROM};

private static final List<MailServerDefinition> CHILDREN = Arrays.asList(
// /subsystem=mail/mail-session=java:/Mail/server=imap
Expand All @@ -89,6 +84,19 @@ private MailSessionDefinition() {

);

static final MailSessionDefinition INSTANCE = new MailSessionDefinition();

private MailSessionDefinition() {
super(new Parameters(MailExtension.MAIL_SESSION_PATH,
MailExtension.getResourceDescriptionResolver(MailSubsystemModel.MAIL_SESSION))
.setAddHandler(MailSessionAdd.INSTANCE)
.setRemoveHandler(new ServiceRemoveStepHandler(MailSessionDefinition.SESSION_CAPABILITY.getCapabilityServiceName(), MailSessionAdd.INSTANCE))
.setCapabilities(SESSION_CAPABILITY)
);
ApplicationTypeConfig atc = new ApplicationTypeConfig(MailExtension.SUBSYSTEM_NAME, MailSubsystemModel.MAIL_SESSION);
accessConstraints = new ApplicationTypeAccessConstraintDefinition(atc).wrapAsList();
}

@Override
public void registerAttributes(final ManagementResourceRegistration rootResourceRegistration) {
MailServerWriteAttributeHandler handler = new MailServerWriteAttributeHandler(ATTRIBUTES);
Expand Down

0 comments on commit d256ab9

Please sign in to comment.