Skip to content

Commit

Permalink
AS7-6120 Minor threads subsystem expression fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
bstansberry authored and jaikiran committed Jan 3, 2013
1 parent 9ce9d00 commit 9e92fa8
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public class ObjectTypeAttributeDefinition extends SimpleAttributeDefinition {
private final AttributeDefinition[] valueTypes;
private final String suffix;

protected ObjectTypeAttributeDefinition(final String name, final AttributeDefinition[] valueTypes, final boolean allowNull,
final ParameterCorrector corrector) {
this(name, name, null, valueTypes, allowNull, null, corrector, null, null, null, false, null);
}

protected ObjectTypeAttributeDefinition(final String name, final String xmlName, final String suffix, final AttributeDefinition[] valueTypes, final boolean allowNull,
final ParameterValidator validator, final ParameterCorrector corrector, final String[] alternatives, final String[] requires,
final AttributeMarshaller attributeMarshaller, final boolean resourceOnly, final DeprecationData deprecated, final AttributeAccess.Flag... flags) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* Copyright 2013, 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.
*
Expand All @@ -22,114 +22,69 @@

package org.jboss.as.threads;

import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIPTION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.EXPRESSIONS_ALLOWED;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REQUIRED;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TYPE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE_TYPE;
import static org.jboss.as.controller.parsing.ParseUtils.missingRequired;
import static org.jboss.as.controller.parsing.ParseUtils.requireNoNamespaceAttribute;
import static org.jboss.as.controller.parsing.ParseUtils.unexpectedAttribute;
import static org.jboss.as.threads.CommonAttributes.KEEPALIVE_TIME;
import static org.jboss.as.threads.CommonAttributes.TIME;
import static org.jboss.as.threads.CommonAttributes.UNIT;

import java.util.EnumSet;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.xml.stream.XMLStreamException;

import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.ObjectTypeAttributeDefinition;
import org.jboss.as.controller.PropagatingCorrector;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.descriptions.ResourceDescriptionResolver;
import org.jboss.as.controller.operations.validation.ParameterValidator;
import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
import org.jboss.as.controller.operations.validation.EnumValidator;
import org.jboss.as.controller.parsing.ParseUtils;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import org.jboss.staxmapper.XMLExtendedStreamReader;

/**
* {@link AttributeDefinition} a thread pool resource's keepalive-time attribute.
* {@link AttributeDefinition} for a thread pool resource's keepalive-time attribute.
*
* @author Brian Stansberry (c) 2011 Red Hat Inc.
*/
class KeepAliveTimeAttributeDefinition extends SimpleAttributeDefinition {
class KeepAliveTimeAttributeDefinition extends ObjectTypeAttributeDefinition {

KeepAliveTimeAttributeDefinition() {
super(CommonAttributes.KEEPALIVE_TIME, ModelType.OBJECT, true,
PropagatingCorrector.INSTANCE, new ParameterValidator() {
@Override
public void validateParameter(String parameterName, ModelNode value) throws OperationFailedException {
if (value.getType() == ModelType.UNDEFINED) {
return;
}
if (value.getType() != ModelType.OBJECT) {
throw ThreadsMessages.MESSAGES.invalidKeepAliveType(parameterName, ModelType.OBJECT, value, value.getType());
}
final Set<String> keys = value.keys();
if (keys.size() != 2) {
throw ThreadsMessages.MESSAGES.invalidKeepAliveKeys(parameterName, TIME, UNIT, keys);
}
if (!keys.contains(TIME)) {
throw ThreadsMessages.MESSAGES.missingKeepAliveTime(TIME, parameterName);
}
if (!keys.contains(UNIT)) {
throw ThreadsMessages.MESSAGES.missingKeepAliveUnit(UNIT, parameterName);
}
}
private static final SimpleAttributeDefinition KEEPALIVE_TIME_TIME = new SimpleAttributeDefinitionBuilder(CommonAttributes.TIME, ModelType.LONG, false)
.setAllowExpression(true)
.build();

@Override
public void validateResolvedParameter(String parameterName, ModelNode value) throws OperationFailedException {
validateParameter(parameterName, value);
}
}
);
}
private static final SimpleAttributeDefinition KEEPALIVE_TIME_UNIT = new SimpleAttributeDefinitionBuilder(CommonAttributes.UNIT, ModelType.STRING, false)
.setAllowExpression(true)
.setValidator(new EnumValidator<TimeUnit>(TimeUnit.class, false, true))
.build();

@Override
public ModelNode addResourceAttributeDescription(ModelNode resourceDescription, ResourceDescriptionResolver resolver,
Locale locale, ResourceBundle bundle) {
final ModelNode result = super.addResourceAttributeDescription(resourceDescription, resolver, locale, bundle);
addAttributeValueTypeDescription(result, resolver, locale, bundle);
return result;
KeepAliveTimeAttributeDefinition() {
super(CommonAttributes.KEEPALIVE_TIME, new AttributeDefinition[]{KEEPALIVE_TIME_TIME, KEEPALIVE_TIME_UNIT}, true,
PropagatingCorrector.INSTANCE);
}

@Override
public ModelNode addOperationParameterDescription(ModelNode resourceDescription, String operationName,
ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
final ModelNode result = super.addOperationParameterDescription(resourceDescription, operationName, resolver, locale, bundle);
addOperationParameterValueTypeDescription(result, operationName, resolver, locale, bundle);
return result;
}

private void addAttributeValueTypeDescription(ModelNode result, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
addNoTextValueTypeDescription(result);
result.get(VALUE_TYPE, TIME, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(KEEPALIVE_TIME, locale, bundle, TIME));
result.get(VALUE_TYPE, UNIT, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(KEEPALIVE_TIME, locale, bundle, UNIT));
protected void addValueTypeDescription(ModelNode node, String prefix, ResourceBundle bundle, final ResourceDescriptionResolver resolver, Locale locale) {
// Swap out the resolver to use the threadpool.common keys
ResourceDescriptionResolver override = new StandardResourceDescriptionResolver("threadpool.common", "", getClass().getClassLoader()) {
@Override
public ResourceBundle getResourceBundle(Locale locale) {
return resolver.getResourceBundle(locale);
}
};
super.addValueTypeDescription(node, prefix, bundle, override, locale);
}

private void addOperationParameterValueTypeDescription(ModelNode result, String operationName, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
addNoTextValueTypeDescription(result);
result.get(VALUE_TYPE, TIME, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, KEEPALIVE_TIME, locale, bundle, TIME));
result.get(VALUE_TYPE, UNIT, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, KEEPALIVE_TIME, locale, bundle, UNIT));
}
public void parseAndSetParameter(final ModelNode operation, final XMLExtendedStreamReader reader) throws XMLStreamException {

private void addNoTextValueTypeDescription(final ModelNode node) {
node.get(VALUE_TYPE, TIME, TYPE).set(ModelType.LONG);
node.get(VALUE_TYPE, TIME, REQUIRED).set(true);
node.get(VALUE_TYPE, TIME, EXPRESSIONS_ALLOWED).set(true);
node.get(VALUE_TYPE, UNIT, TYPE).set(ModelType.STRING);
node.get(VALUE_TYPE, UNIT, REQUIRED).set(true);
}
ModelNode model = new ModelNode();

public void parseAndSetParameter(final ModelNode operation, final XMLExtendedStreamReader reader) throws XMLStreamException {
final int attrCount = reader.getAttributeCount();
TimeUnit unit = null;
ModelNode duration = null;
Set<Attribute> required = EnumSet.of(Attribute.TIME, Attribute.UNIT);
for (int i = 0; i < attrCount; i++) {
requireNoNamespaceAttribute(reader, i);
Expand All @@ -138,11 +93,11 @@ public void parseAndSetParameter(final ModelNode operation, final XMLExtendedStr
required.remove(attribute);
switch (attribute) {
case TIME: {
duration = ParseUtils.parsePossibleExpression(value);
KEEPALIVE_TIME_TIME.parseAndSetParameter(value, model, reader);
break;
}
case UNIT: {
unit = Enum.valueOf(TimeUnit.class, value.toUpperCase(Locale.ENGLISH));
KEEPALIVE_TIME_UNIT.parseAndSetParameter(value, model, reader);
break;
}
default:
Expand All @@ -153,13 +108,9 @@ public void parseAndSetParameter(final ModelNode operation, final XMLExtendedStr
if (!required.isEmpty()) {
throw missingRequired(reader, required);
}
assert unit != null;
assert duration != null;

ParseUtils.requireNoContent(reader);
ModelNode model = new ModelNode();
model.get(TIME).set(duration);
model.get(UNIT).set(unit.toString());

operation.get(getName()).set(model);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@
package org.jboss.as.threads;


import java.util.concurrent.TimeUnit;

import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.ObjectTypeAttributeDefinition;
import org.jboss.as.controller.PropagatingCorrector;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.client.helpers.MeasurementUnit;
import org.jboss.as.controller.operations.validation.EnumValidator;
import org.jboss.as.controller.operations.validation.IntRangeValidator;
import org.jboss.as.controller.registry.AttributeAccess;
import org.jboss.dmr.ModelNode;
Expand All @@ -49,6 +54,19 @@ public interface PoolAttributeDefinitions {
.setValidator(new IntRangeValidator(0, Integer.MAX_VALUE, false, true)).setAllowExpression(true).build();

KeepAliveTimeAttributeDefinition KEEPALIVE_TIME = new KeepAliveTimeAttributeDefinition();
// SimpleAttributeDefinition KEEPALIVE_TIME_TIME = new SimpleAttributeDefinitionBuilder(CommonAttributes.TIME, ModelType.LONG, false)
// .setAllowExpression(true)
// .build();
//
// SimpleAttributeDefinition KEEPALIVE_TIME_UNIT = new SimpleAttributeDefinitionBuilder(CommonAttributes.UNIT, ModelType.STRING, false)
// .setAllowExpression(true)
// .setValidator(new EnumValidator<TimeUnit>(TimeUnit.class, false, true))
// .build();
//
// ObjectTypeAttributeDefinition KEEPALIVE_TIME = ObjectTypeAttributeDefinition.Builder.of(CommonAttributes.KEEPALIVE_TIME, KEEPALIVE_TIME_TIME, KEEPALIVE_TIME_UNIT)
// .setAllowNull(true)
// .setCorrector(PropagatingCorrector.INSTANCE)
// .build();

SimpleAttributeDefinition CORE_THREADS = new SimpleAttributeDefinitionBuilder(CommonAttributes.CORE_THREADS, ModelType.INT, true)
.setValidator(new IntRangeValidator(0, Integer.MAX_VALUE, true, true)).setAllowExpression(true).build();
Expand All @@ -60,11 +78,17 @@ public interface PoolAttributeDefinitions {
.setValidator(new IntRangeValidator(0, Integer.MAX_VALUE, false, true)).setAllowExpression(true).setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES).build();

SimpleAttributeDefinition ALLOW_CORE_TIMEOUT = new SimpleAttributeDefinitionBuilder(CommonAttributes.ALLOW_CORE_TIMEOUT, ModelType.BOOLEAN, true)
.setDefaultValue(new ModelNode().set(false)).build();
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();

SimpleAttributeDefinition GROUP_NAME = new SimpleAttributeDefinition(CommonAttributes.GROUP_NAME, ModelType.STRING, true);
SimpleAttributeDefinition GROUP_NAME = new SimpleAttributeDefinitionBuilder(CommonAttributes.GROUP_NAME, ModelType.STRING, true)
.setAllowExpression(true)
.build();

SimpleAttributeDefinition THREAD_NAME_PATTERN = new SimpleAttributeDefinition(CommonAttributes.THREAD_NAME_PATTERN, ModelType.STRING, true);
SimpleAttributeDefinition THREAD_NAME_PATTERN = new SimpleAttributeDefinitionBuilder(CommonAttributes.THREAD_NAME_PATTERN, ModelType.STRING, true)
.setAllowExpression(true)
.build();

SimpleAttributeDefinition PRIORITY = new SimpleAttributeDefinition(CommonAttributes.PRIORITY, CommonAttributes.PRIORITY, null,
ModelType.INT, true, true, MeasurementUnit.NONE, new IntRangeValidator(Thread.MIN_PRIORITY, Thread.MAX_PRIORITY, true, true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.io.IOException;

import org.jboss.as.subsystem.test.AbstractSubsystemBaseTest;
import org.junit.Test;

/**
* @author <a href="mailto:tomaz.cerar@redhat.com">Tomaz Cerar</a> (c) 2012 Red Hat Inc.
Expand All @@ -40,4 +41,9 @@ public ThreadsSubsystem11Test() {
protected String getSubsystemXml() throws IOException {
return readResource("threads-subsystem-1_1.xml");
}

@Test
public void testExpressions() throws Exception {
standardSubsystemTest("expressions.xml");
}
}
42 changes: 42 additions & 0 deletions threads/src/test/resources/org/jboss/as/threads/expressions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<subsystem xmlns="urn:jboss:domain:threads:1.1">
<thread-factory name="test-factory" group-name="${test.exp:Thread Group}" thread-name-pattern="${test.exp:%G - %t}" priority="${test.exp:6}"/>
<unbounded-queue-thread-pool name="test-pool">
<max-threads count="${prop.max-thread-count:100}"/>
<keepalive-time time="${test.exp:1000}" unit="${test.exp:milliseconds}"/>
<thread-factory name="test-factory"/>
</unbounded-queue-thread-pool>
<bounded-queue-thread-pool name="test-pool" allow-core-timeout="${test.exp:true}">
<core-threads count="${test.exp:200}"/>
<queue-length count="${test.exp:300}"/>
<max-threads count="${test.exp:100}"/>
<keepalive-time time="${test.exp:1000}" unit="${test.exp:milliseconds}"/>
<thread-factory name="test-factory"/>
<handoff-executor name="other"/>
</bounded-queue-thread-pool>
<blocking-bounded-queue-thread-pool name="test-pool" allow-core-timeout="${test.exp:true}">
<core-threads count="${test.exp:200}"/>
<queue-length count="${test.exp:300}"/>
<max-threads count="${test.exp:100}"/>
<keepalive-time time="${test.exp:1000}" unit="${test.exp:milliseconds}"/>
<thread-factory name="test-factory"/>
</blocking-bounded-queue-thread-pool>
<queueless-thread-pool name="other">
<max-threads count="${test.exp:1}"/>
</queueless-thread-pool>
<queueless-thread-pool name="test-pool">
<max-threads count="${prop.max-thread-count:100}"/>
<keepalive-time time="${test.exp:1000}" unit="${test.exp:milliseconds}"/>
<thread-factory name="test-factory"/>
<handoff-executor name="other"/>
</queueless-thread-pool>
<blocking-queueless-thread-pool name="test-pool">
<max-threads count="${prop.max-thread-count:100}"/>
<keepalive-time time="${test.exp:1000}" unit="${test.exp:milliseconds}"/>
<thread-factory name="test-factory"/>
</blocking-queueless-thread-pool>
<scheduled-thread-pool name="test-pool">
<max-threads count="${prop.max-thread-count:10}"/>
<keepalive-time time="${prop.keep-alive-time:1000}" unit="${test.exp:milliseconds}"/>
<thread-factory name="test-factory"/>
</scheduled-thread-pool>
</subsystem>

0 comments on commit 9e92fa8

Please sign in to comment.