http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/util/concurrent/DefaultThreadPoolExecutor.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/util/concurrent/DefaultThreadPoolExecutor.java b/core/src/flex/messaging/util/concurrent/DefaultThreadPoolExecutor.java deleted file mode 100644 index 3298507..0000000 --- a/core/src/flex/messaging/util/concurrent/DefaultThreadPoolExecutor.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package flex.messaging.util.concurrent; - -import flex.messaging.log.Log; -import flex.messaging.log.LogCategories; - -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.RejectedExecutionException; - -/** - * Implements {@link Executor} and extends the <code>ThreadPoolExecutor</code> provided by the - * Java 1.4.x-friendly backport of the <code>java.util.concurrent</code> API. - * - * - */ -public class DefaultThreadPoolExecutor extends ThreadPoolExecutor implements Executor -{ - //-------------------------------------------------------------------------- - // - // Constructors - // - //-------------------------------------------------------------------------- - - /** - * Constructs a <code>DefaultThreadPoolExecutor</code> with configuration that - * matches the return from {@link java.util.concurrent.Executors#newCachedThreadPool()}. - */ - public DefaultThreadPoolExecutor() - { - super(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue()); - } - - /** - * @see java.util.concurrent.ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue) - */ - public DefaultThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) - { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); - } - - /** - * @see java.util.concurrent.ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue, java.util.concurrent.RejectedExecutionHandler) - */ - public DefaultThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler) - { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler); - } - - /** - * @see java.util.concurrent.ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue, java.util.concurrent.ThreadFactory) - */ - public DefaultThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory) - { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); - } - - /** - * @see java.util.concurrent.ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue, java.util.concurrent.ThreadFactory, java.util.concurrent.RejectedExecutionHandler) - */ - public DefaultThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) - { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); - } - - //-------------------------------------------------------------------------- - // - // Variables - // - //-------------------------------------------------------------------------- - - /** - * Instance-level lock. - */ - private final Object lock = new Object(); - - //-------------------------------------------------------------------------- - // - // Properties - // - //-------------------------------------------------------------------------- - - //---------------------------------- - // failedExecutionHandler - //---------------------------------- - - private FailedExecutionHandler handler; - - /** - * @see Executor#getFailedExecutionHandler() - */ - public FailedExecutionHandler getFailedExecutionHandler() - { - synchronized (lock) - { - return handler; - } - } - - /** - * @see Executor#setFailedExecutionHandler(FailedExecutionHandler) - */ - public void setFailedExecutionHandler(FailedExecutionHandler value) - { - synchronized (lock) - { - handler = value; - } - } - - //-------------------------------------------------------------------------- - // - // Overridden Public Methods - // - //-------------------------------------------------------------------------- - - /** - * - * This implementation relies on the default <code>RejectedExecutionHandler</code>, {@link java.util.concurrent.ThreadPoolExecutor.AbortPolicy}, which - * throws a <code>RejectedExecutionException</code> if the command cannot be queued for execution. - */ - public void execute(Runnable command) - { - try - { - super.execute(command); - } - catch (RejectedExecutionException e) - { - FailedExecutionHandler handler = getFailedExecutionHandler(); - if (handler != null) - { - handler.failedExecution(command, this, e); - } - else if (Log.isError()) - { - Log.getLogger(LogCategories.EXECUTOR).error("DefaultThreadPoolExecutor hit a RejectedExecutionException but no FailedExecutionHandler is registered to handle the error.", e); - } - } - } -}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/util/concurrent/Executor.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/util/concurrent/Executor.java b/core/src/flex/messaging/util/concurrent/Executor.java deleted file mode 100644 index b8c3507..0000000 --- a/core/src/flex/messaging/util/concurrent/Executor.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package flex.messaging.util.concurrent; - -/** - * This interface allows different Executor implementations to be chosen and used - * without creating a direct dependency upon <code>java.util.concurrent.Executor</code> - * added in Java 1.5, the Java 1.4.x-friendly backport of the <code>java.util.concurrent</code> APIs - * which has a different package structure, or alternative work execution frameworks such as - * IBM WebSphere 5's <code>com.ibm.websphere.asynchbeans.WorkManager</code> or the - * <code>commonj.work.WorkManager</code> available in IBM WebSphere 6, BEA WebLogic 9 or - * other application servers that support the <code>commonj</code> API. - * Implementations should notify clients of any failure with executing a command by invoking - * the callback on the <code>FailedExecutionHandler</code> if one has been set. - * - * @see java.util.concurrent.Executor - * - */ -public interface Executor -{ - /** - * Executes the given command at some time in the future. - * The command may execute in a new thread, in a pooled thread, or in the calling thread, at the - * discretion of the <code>Executor</code> implementation. - * Implementation classes are free to throw a <code>RuntimeException</code> if the command can not - * be executed. - * - * @param command The command to execute. - */ - void execute(Runnable command); - - /** - * Returns the current handler for failed executions. - * - * @return The current handler. - */ - FailedExecutionHandler getFailedExecutionHandler(); - - /** - * Sets the handler for failed executions. - * - * @param handler The new handler. - */ - void setFailedExecutionHandler(FailedExecutionHandler handler); -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/util/concurrent/FailedExecutionHandler.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/util/concurrent/FailedExecutionHandler.java b/core/src/flex/messaging/util/concurrent/FailedExecutionHandler.java deleted file mode 100644 index 92753b4..0000000 --- a/core/src/flex/messaging/util/concurrent/FailedExecutionHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package flex.messaging.util.concurrent; - -/** - * This interface defines a callback that can be registered with an {@link Executor} - * to be notified when execution of a <code>Runnable</code> has failed. - */ -public interface FailedExecutionHandler -{ - /** - * Invoked when a <code>Runnable</code> has failed to execute. - * This is most commonly invoked when the <code>Runnable</code> can not be queued - * for execution, but may also be invoked if an uncaught <code>Exception</code> was - * thrown and the <code>Executor</code> implementation has support for catching this - * and notifying via this callback. - * - * @param command The <code>Runnable</code> command that failed to execute. - * @param executor The <code>Executor</code> that was unable to execute the command. - * @param exception The <code>Exception</code> identifying why the command failed to execute. - */ - void failedExecution(Runnable command, Executor executor, Exception exception); -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/util/concurrent/package-info.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/util/concurrent/package-info.java b/core/src/flex/messaging/util/concurrent/package-info.java deleted file mode 100644 index 552a860..0000000 --- a/core/src/flex/messaging/util/concurrent/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package flex.messaging.util.concurrent; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/util/package-info.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/util/package-info.java b/core/src/flex/messaging/util/package-info.java deleted file mode 100644 index c090ecf..0000000 --- a/core/src/flex/messaging/util/package-info.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package flex.messaging.util; http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/validators/ClassDeserializationValidator.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/validators/ClassDeserializationValidator.java b/core/src/flex/messaging/validators/ClassDeserializationValidator.java deleted file mode 100644 index cf07942..0000000 --- a/core/src/flex/messaging/validators/ClassDeserializationValidator.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package flex.messaging.validators; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Pattern; - -import flex.messaging.config.ConfigMap; - -/** - * The <code>ClassDeserializationValidator</code> is provided as a default - * implementation of <code>DeserializationValidator</code> and it simply - * validates the creation of allowed and disallowed classes as specified in - * the configuration. - */ -public class ClassDeserializationValidator implements DeserializationValidator -{ - //-------------------------------------------------------------------------- - // - // Public Static Constants - // - //-------------------------------------------------------------------------- - - public static final String PROPERTY_ALLOW_CLASSES = "allow-classes"; - public static final String PROPERTY_DISALLOW_CLASSES = "disallow-classes"; - public static final String PROPERTY_CLASS_ATTR = "class"; - public static final String PROPERTY_NAME_ATTR = "name"; - - private static final String [] DEFAULT_ALLOW_CLASSES = { - "flex.messaging.*", - "flex.data.*", - "java.lang.Boolean", - "java.lang.Byte", - "java.lang.Character", - "java.lang.Double", - "java.lang.Float", - "java.lang.Integer", - "java.lang.Long", - "java.lang.Object", - "java.lang.Short", - "java.lang.String", - "java.io.Externalizable", - "java.util.*", - "org.w3c.dom.Document", - "\\[B", - "\\[Ljava.lang.Object;" - }; - - //-------------------------------------------------------------------------- - // - // Variables - // - //-------------------------------------------------------------------------- - - /** - * Instance level lock for thread-safe state changes. - */ - protected final Object lock = new Object(); - - /** - * Used to keep track of encountered allow and disallow classes for faster lookup. - */ - private Set<String> allowClasses; - private Set<String> disallowClasses; - - /** - * Used to keep track of allow and disallow class patterns. - */ - private Map<String, Pattern> allowClassPatterns; - private Map<String, Pattern> disallowClassPatterns; - - //-------------------------------------------------------------------------- - // - // Public Methods - // - //-------------------------------------------------------------------------- - - /** - * Adds a class pattern that should be allowed to be created. - * - * @param classNamePattern The name of the class which can be a regular expression. - */ - public void addAllowClassPattern(String classNamePattern) - { - synchronized (lock) - { - if (allowClassPatterns == null) - allowClassPatterns = new HashMap<String, Pattern>(); - - allowClassPatterns.put(classNamePattern, Pattern.compile(classNamePattern)); - - clearClassCache(); - } - } - - /** - * Removes a class pattern that should be allowed to be created.. - * - * @param classNamePattern The name of the class which can be a regular expression. - */ - public void removeAllowClassPattern(String classNamePattern) - { - synchronized (lock) - { - if (allowClassPatterns != null) - allowClassPatterns.remove(classNamePattern); - - clearClassCache(); - } - } - - /** - * Adds a class pattern that should be disallowed to be created. - * - * @param classNamePattern The name of the class which can be a regular expression. - */ - public void addDisallowClassPattern(String classNamePattern) - { - synchronized (lock) - { - if (disallowClassPatterns == null) - disallowClassPatterns = new HashMap<String, Pattern>(); - - disallowClassPatterns.put(classNamePattern, Pattern.compile(classNamePattern)); - - clearClassCache(); - } - } - - /** - * Removes a class pattern that should be disallowed to be created.. - * - * @param classNamePattern The name of the class which can be a regular expression. - */ - public void removeDisallowClassPattern(String classNamePattern) - { - synchronized (lock) - { - if (disallowClassPatterns != null) - disallowClassPatterns.remove(classNamePattern); - - clearClassCache(); - } - } - - /** - * This method is meant to validate the assignment of a value to an index of - * an Array or List instance but this class only deals with class creations, - * therefore this method always returns true. - * - * @param instance The Array or List instance. - * @param index The index at which the value is being assigned. - * @param value The value that is assigned to the index. - * @return True. - */ - public boolean validateAssignment(Object instance, int index, Object value) - { - return true; - } - - /** - * This method is meant to validate the assignment of a property of an instance - * to a value but this class only deals with class creations, therefore this - * method always returns true. - * - * @param instance The instance with the property that is being assigned a new value. - * @param propertyName The name of the property that is being assigned. - * @param value The value that the property is being assigned to. - * @return True. - */ - public boolean validateAssignment(Object instance, String propertyName, Object value) - { - return true; - } - - /** - * Validates the creation of a class as indicated by the allow and disallow - * classes list. If the class is in both allow and disallow classes, - * disallow classes list take precedence. - * - * @param c The class that is being created. - * @return True if the creation is valid. - */ - public boolean validateCreation(Class<?> c) - { - String className = c == null? null : c.getName(); - if (className == null) - return true; - - // First, check against the encountered disallow-classes list. - if (disallowClasses != null && disallowClasses.contains(className)) - return false; - - // Then, check against the encountered allow-classes list. - if (allowClasses != null && allowClasses.contains(className)) - return true; - - // Otherwise, the class was encountered for the first time, need to - // go through the disallow and allow class patterns list. - - // Disallow the class if there's a disallow-classes list, and the class is in that list. - if (disallowClassPatterns != null && !disallowClassPatterns.isEmpty()) - { - for (Pattern pattern : disallowClassPatterns.values()) - { - if (pattern.matcher(className).matches()) - { - addDisallowClass(className); - return false; - } - } - } - - // Disallow the class if there's an allowed-classes list, and the class is NOT in that list. - if (allowClassPatterns != null && !allowClassPatterns.isEmpty()) - { - for (Pattern pattern : allowClassPatterns.values()) - { - if (pattern.matcher(className).matches()) - { - addAllowClass(className); - return true; - } - } - // Disallow the class as it's not in allow-classes list. - addDisallowClass(className); - return false; - } - - // Otherwise allow the class. - addAllowClass(className); - return true; - } - - /** {@inheritDoc} */ - public void initialize(String id, ConfigMap properties) - { - // Apply default allow classes - for (String defaultAllowClassPattern : DEFAULT_ALLOW_CLASSES) - { - addAllowClassPattern(defaultAllowClassPattern); - } - - if (properties == null || properties.size() == 0) - return; - - // Process allow-classes. - ConfigMap allowedClassesMap = properties.getPropertyAsMap(PROPERTY_ALLOW_CLASSES, null); - if (allowedClassesMap != null && !allowedClassesMap.isEmpty()) - { - List<?> names = allowedClassesMap.getPropertyAsList(PROPERTY_CLASS_ATTR, null); - if (names != null && !names.isEmpty()) - { - for (Object element : names) - { - String name = ((ConfigMap)element).getProperty(PROPERTY_NAME_ATTR); - addAllowClassPattern(name); - } - } - } - - // Process disallow-classes. - ConfigMap disallowedClassesMap = properties.getPropertyAsMap(PROPERTY_DISALLOW_CLASSES, null); - if (disallowedClassesMap != null && !disallowedClassesMap.isEmpty()) - { - List<?> names = disallowedClassesMap.getPropertyAsList(PROPERTY_CLASS_ATTR, null); - if (names != null && !names.isEmpty()) - { - for (Object element : names) - { - String name = ((ConfigMap)element).getProperty(PROPERTY_NAME_ATTR); - addDisallowClassPattern(name); - } - } - } - } - - //-------------------------------------------------------------------------- - // - // Protected Methods - // - //-------------------------------------------------------------------------- - - protected void addAllowClass(String className) - { - synchronized (lock) - { - if (allowClasses == null) - allowClasses = new HashSet<String>(); - - if (!allowClasses.contains(className)) - allowClasses.add(className); - } - } - - protected void addDisallowClass(String className) - { - synchronized (lock) - { - if (disallowClasses == null) - disallowClasses = new HashSet<String>(); - - if (!disallowClasses.contains(className)) - disallowClasses.add(className); - } - } - - protected void clearClassCache() - { - if (allowClasses != null) - { - allowClasses.clear(); - } - if (disallowClasses != null) - { - disallowClasses.clear(); - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/validators/DeserializationValidator.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/validators/DeserializationValidator.java b/core/src/flex/messaging/validators/DeserializationValidator.java deleted file mode 100644 index b4dabd0..0000000 --- a/core/src/flex/messaging/validators/DeserializationValidator.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package flex.messaging.validators; - -import flex.messaging.FlexConfigurable; - -/** - * Deserialization validator is registered with the Message broker and provide the - * opportunity to validate the creation of classes and assignment of a property - * of an instance to a value for incoming (client-to-server) deserialization. - */ -public interface DeserializationValidator extends FlexConfigurable -{ - - /** - * Validate the assignment of a value to an index of an Array or List instance. - * - * @param instance The Array or List instance. - * @param index The index at which the value is being assigned. - * @param value The value that is assigned to the index. - * @return True if the assignment is valid. - */ - boolean validateAssignment(Object instance, int index, Object value); - - /** - * Validate the assignment of a property of an instance to a value. - * - * @param instance The instance with the property that is being assigned a new value. - * @param propertyName The name of the property that is being assigned. - * @param value The value that the property is being assigned to. - * @return True if the assignment is valid. - */ - boolean validateAssignment(Object instance, String propertyName, Object value); - - /** - * Validate creation of a class. - * - * @param c The class that is being created. - * @return True if the creation is valid. - */ - boolean validateCreation(Class<?> c); -} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/validators/package-info.java ---------------------------------------------------------------------- diff --git a/core/src/flex/messaging/validators/package-info.java b/core/src/flex/messaging/validators/package-info.java deleted file mode 100644 index 8a07687..0000000 --- a/core/src/flex/messaging/validators/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package flex.messaging.validators; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/main/java/flex/management/BaseControl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/flex/management/BaseControl.java b/core/src/main/java/flex/management/BaseControl.java new file mode 100644 index 0000000..a66a104 --- /dev/null +++ b/core/src/main/java/flex/management/BaseControl.java @@ -0,0 +1,514 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package flex.management; + +import flex.management.runtime.AdminConsoleDisplayRegistrar; +import flex.messaging.FlexContext; + +import java.util.Date; +import java.util.List; +import java.util.ArrayList; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.MalformedObjectNameException; +import javax.management.MBeanRegistration; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; +import javax.servlet.ServletConfig; + +/** + * The implementation of the <code>BaseControlMBean</code> interface. This + * abstract class provides the core functionality that all Flex control MBeans + * require. + * <p> + * Defining concrete implementations of <code>getId()</code> and + * <code>getType()</code> are left to subclasses, but this base class does + * provide access to the parent MBean for each instance. This class also + * implements the <code>MBeanRegistration</code> interface, and it + * automatically stores a reference to the MBean server in each instance upon + * registration. Subclasses may choose to override none, any, or all of the + * methods defined by the <code>MBeanRegistration</code> interface, but any + * overrides should be sure to invoke the overridden method with a call to their + * superclass. + * </p><p> + * The <code>register()</code> method provides a simple and consistent way to + * register instances with the MBean server, and the + * <code>getObjectName()</code> method gaurantees consistent, well-formed + * <code>ObjectName</code>s for all MBean instances.</p> + */ +public abstract class BaseControl implements BaseControlMBean, + MBeanRegistration +{ + /** + * The prefix used for the domain part of control MBean names. + */ + public static final String DOMAIN_PREFIX = "flex.runtime"; + private static final int MALFORMED_OBJECTNAME = 10400; + private static final int UNREG_EXCEPTION = 10401; + private static final int UNREG_NOTFOUND = 10402; + private static final int REG_EXCEPTION = 10403; + private static final int REG_ALREADYEXISTS = 10404; + private static final int REG_NOTCOMPLIANT = 10405; + private static final int DISABLE_MANAGEMENT = 10426; + + protected Date startTimestamp; + private BaseControl parent; + private ObjectName objectName; + private ObjectName registeredObjectName; + private MBeanServer server; + private boolean registered = false; + + private AdminConsoleDisplayRegistrar registrar; + + // Implements flex.management.BaseControlMBean.getId; inherits javadoc + // specification. + public abstract String getId(); + + // Implements flex.management.BaseControlMBean.getType; inherits javadoc + // specification. + public abstract String getType(); + + // Implements flex.management.BaseControlMBean.getParent; inherits javadoc + // specification. + public final ObjectName getParent() + { + return (parent != null) ? parent.getObjectName() : null; + } + + /** + * Returns an identifier for the application that hosts the component that + * this control manages. + * + * @return An identifier for the application that hosts the component this + * control manages. + */ + public String getApplicationId() + { + String id = null; + // Our base implementation attempts to use the current servlet context + // name as our application identifier. + ServletConfig config = FlexContext.getServletConfig(); + if (config != null) + { + id = config.getServletContext().getServletContextName(); + } + return (id != null) ? id.replace(":", "") : ""; + } + + /** + * Set the register object. + * @param registrar the registrar to set + */ + protected void setRegistrar(AdminConsoleDisplayRegistrar registrar) + { + this.registrar = registrar; + } + + /** + * Return the registar object. + * @return the registrar + */ + public AdminConsoleDisplayRegistrar getRegistrar() + { + if ((parent == null) && (this.registrar == null)) + { + return new AdminConsoleDisplayRegistrar(null); + } + + return (this.registrar != null) ? this.registrar : parent.getRegistrar(); + } + + /** + * Constructs a <code>BaseControl</code> instance that references its + * parent; the parent may be null for root control MBeans. + * + * @param parent The parent <code>BaseControl</code> for this instance or + * null if this instance is the root of a control hierarchy. + */ + public BaseControl(BaseControl parent) + { + this.parent = parent; + } + + /** + * Returns the parent <code>BaseControl</code> of this instance. + * + * @return The parent <code>BaseControl</code>. + */ + public final BaseControl getParentControl() + { + return parent; + } + + /** + * The <code>MBeanServer</code> that this instance is registered with. If + * this instance has not been registered this method returns + * <code>null</code>. + * + * @return The <code>MBeanServer</code> that this instance is registered + * with. + */ + public final MBeanServer getMBeanServer() + { + return server; + } + + /** + * Registers this instance with the MBean server. + * + * It may throw ManagementException If an <code>MBeanRegistrationException</code> + * or <code>InstanceAlreadyExistsException</code> is thrown while + * registering this MBean, the typed exception is wrapped in a + * runtime <code>ManagementException</code> and rethrown. + */ + public final void register() + { + if (!registered) + { + MBeanServer server = MBeanServerLocatorFactory.getMBeanServerLocator().getMBeanServer(); + ObjectName name = getObjectName(); + try + { + if (server.isRegistered(name)) + { + server.unregisterMBean(name); + } + + registeredObjectName = server.registerMBean(this, name).getObjectName(); + registered = true; + onRegistrationComplete(); + + } + catch (ManagementException me) + { + throw me; + } + catch (MBeanRegistrationException mre) + { + // Rethrow with useful message if this ever happens. + ManagementException me = new ManagementException(); + me.setMessage(REG_EXCEPTION, new Object[] {name.toString()}); + me.setRootCause(mre); + throw me; + } + catch (InstanceAlreadyExistsException iaee) + { + // If registration is not working at all, inform the user that + // they may + // work around the issue by disabling management (no MBeans will + // be registered). + if (!server.isRegistered(name)) + { + ManagementException me = new ManagementException(); + me.setMessage(DISABLE_MANAGEMENT, new Object[] {name.toString()}); + throw me; + } + else + { + // Rethrow with useful message if this ever happens. + ManagementException me = new ManagementException(); + me.setMessage(REG_ALREADYEXISTS, new Object[] {name.toString()}); + throw me; + } + } + catch (NotCompliantMBeanException ncme) + { + // Rethrow with useful message if this ever happens. + ManagementException me = new ManagementException(); + me.setMessage(REG_NOTCOMPLIANT, new Object[] {name.toString()}); + throw me; + } + catch (InstanceNotFoundException infe) + { + // Rethrow with useful message if this ever happens. + ManagementException me = new ManagementException(); + me.setMessage(UNREG_NOTFOUND, new Object[] {name.toString()}); + throw me; + } + } + } + + /** + * This method is called after the MBean has been registered and after the + * MBean server has returned the registeredObjectName. Classes that need + * access to the actual Object name should override this method rather than + * the postRegister method. + */ + protected void onRegistrationComplete() + { + + } + + /** + * Unregisters this instance from the MBean server if it has been registered + * previously. + */ + public final void unregister() + { + if (registered) + { + // This method may be called when the JVM is being unloaded, so if + // our + // external error strings are loaded as missing, fall back to + // hard-coded + // strings. + try + { + if (server.isRegistered(registeredObjectName)) + { + server.unregisterMBean(registeredObjectName); + } + + registeredObjectName = null; + registered = false; + } + catch (ManagementException me) + { + throw me; + } + catch (MBeanRegistrationException mre) + { + // Rethrow with useful message if this ever happens. + ManagementException me = new ManagementException(); + me.setMessage(UNREG_EXCEPTION, new Object[] {registeredObjectName.toString()}); + if (me.getMessage().indexOf(Integer.toString(UNREG_EXCEPTION)) != -1) + { + me.setMessage("The MBean named, '" + registeredObjectName.toString() + "', could not be unregistered because its preDeregister() method threw an exception."); + } + me.setRootCause(mre); + throw me; + } + catch (InstanceNotFoundException infe) + { + // Rethrow with useful message if this ever happens. + ManagementException me = new ManagementException(); + me.setMessage(UNREG_NOTFOUND, new Object[] {registeredObjectName.toString()}); + if (me.getMessage().indexOf(Integer.toString(UNREG_NOTFOUND)) != -1) + { + me.setMessage("The MBean named, '" + registeredObjectName.toString() + "', could not be unregistered because it is not currently registered."); + } + throw me; + } + } + } + + /** + * Returns the <code>ObjectName</code> for this instance, according to the + * following format: + * <code>{domain}[&#46;{appId}]:type={type}[&#44;{parent type}={parent id}]*[&#44;server={server}]&#63;&#44;id={id}</code>. + * <ul> + * <li><code>domain</code>: The domain specified by the DOMAIN_PREFIX + * constant followed by the application identifier if one is available.</li> + * <li><code>type</code>: The short type name of the resource managed by + * the MBean. + * - The <code>MessageBrokerControlMBean</code> manages + * the <code>flex.messaging.MessageBroker</code> so: + * <code>type=MessageBroker</code> </li> + * <li><code>id</code>: The id value for the resource managed by this + * MBean. If no name or id is available on the resource, an id will be + * fabricated according to this strategy: + * + * <em>id = {type} + N</em> (where N is a numeric increment for instances + * of this type) </li> + * <li>* optional containment keys</li> + * </ul> + * The runtime MBean model is hierarchical, with all MBeans ultimately + * contained by the root <code>MessageBrokerControlMBean</code>. The + * <code>ObjectName</code>s used for these MBeans describe this + * containment in the following fashion. First, the 'type' key for a + * contained MBean indicates the containment hierarchy for the bean. So, the + * <code>ObjectName</code> for an <code>RTMPEndpointControlMBean</code> + * would be: <code>type=MessageBroker.RTMPEndpoint</code> + * + * In addition to the hierarchical 'type' key, the full + * <code>ObjectName</code> for this <code>RTMPEndpointControlMBean</code> + * also contains a containment key: + * <code>MessageBroker=MessageBroker1</code> + * + * Optional containment keys have the format: + * <em>{parent type}={parent name}</em>. A containment key is added for + * each ancestor up to the root of the hierarchy and these keys allow the + * <code>ObjectName</code> for any MBean instance to fully describe its + * specific location in the hierarchy. To complete the example, the full + * <code>ObjectName</code> for the example + * <code>RTMPEndpointControlMBean</code> would be: + * <code>flex:type=MessageBroker.RTMPEndpoint,MessageBroker=MessageBroker1,id=RTMPEndpoint1</code> + * <p> + * If the MBean is registered with the MBean server, this method returns the + * <code>ObjectName</code> that the MBean was registered under and this + * value may contain additional key-value pairs injected by the container or + * MBean server. + * </p> + * + * @return The <code>ObjectName</code> for this instance. + */ + public final ObjectName getObjectName() + { + if (registered) + return registeredObjectName; + + if (objectName == null) + { + StringBuffer buffer = new StringBuffer(); + buffer.append(DOMAIN_PREFIX); + String appId = getApplicationId(); + if (appId != null && appId.length() > 0) + { + buffer.append('.'); + buffer.append(appId); + } + buffer.append(":type="); + // Build hierarchical type value. + List types = new ArrayList(); + List ids = new ArrayList(); + types.add(getType()); + ids.add(getId()); + BaseControl ancestor = parent; + while (ancestor != null) + { + types.add(ancestor.getType()); + ids.add(ancestor.getId()); + ancestor = ancestor.getParentControl(); + } + for (int i = types.size() - 1; i >= 0; --i) + { + buffer.append((String)types.get(i)); + if (i > 0) + { + buffer.append('.'); + } + } + buffer.append(','); + // Add containment keys. + for (int i = ids.size() - 1; i >= 1; --i) + { + buffer.append((String)types.get(i)); + buffer.append('='); + buffer.append((String)ids.get(i)); + buffer.append(','); + } + buffer.append("id="); + buffer.append(getId()); + String name = buffer.toString(); + // TODO: Seth: add server identifier key if we're running in a + // cluster? + try + { + objectName = new ObjectName(name); + } + catch (MalformedObjectNameException mone) + { + // Rethrow with useful message if this ever happens. + ManagementException me = new ManagementException(); + me.setMessage(MALFORMED_OBJECTNAME, new Object[] {name}); + throw me; + } + } + return objectName; + } + + /** + * Implements <code>javax.management.MBeanRegistration.preRegister</code>. + * Allows the MBean to perform any operations it needs before being + * registered in the MBean server. This base implementation stores a + * reference to the MBean server that may be accessed via + * <code>getMBeanServer()</code>. If subclasses override, they must call + * <code>super.preRegister()</code>. + * + * @param server The Mbean server in which the MBean will be registered. + * @param name The object name of the MBean. + * @return The name the MBean will be registered under. + * @throws Exception when the process failed + */ + public ObjectName preRegister(MBeanServer server, ObjectName name) + throws Exception + { + this.server = server; + return (name == null) ? getObjectName() : name; + } + + /** + * Implements <code>javax.management.MBeanRegistration.postRegister</code>. + * Allows the MBean to perform any operations needed after having been + * registered in the MBean server or after the registration has failed. This + * base implementation is a no-op that may be overridden. + * + * @param registrationDone Indicates whether or not the MBean was + * successfully registered in the MBean server. + */ + public void postRegister(Boolean registrationDone) + { + // No-op. + } + + /** + * Implements <code>javax.management.MBeanRegistration.preDeregister</code>. + * Allows the MBean to perform any operations needed after having been + * unregistered in the MBean server. This base implementation is a no-op + * that may be overridden. + * @throws Exception when the process failed + */ + public void preDeregister() throws Exception + { + // No-op. + } + + /** + * Implements <code>javax.management.MBeanRegistration.postDeregister</code>. + * Allows the MBean to perform any operations it needs before being + * unregistered by the MBean server. This base implementation is a no-op + * that may be overridden. + */ + public void postDeregister() + { + // No-op. + } + + /** + * Sets the start timestamp for the managed component. + * + * @param value The start timestamp for the managed component. + */ + public void setStartTimestamp(Date value) + { + startTimestamp = value; + } + + /** + * Returns the difference between a start and end timestamps in + * minutes. Differences of less than one minute are rounded up to + * one minute to avoid frequency calculations reporting infinite + * message frequencies. + * @param startTime The start timestamp in milliseconds. + * @param endTime The end timestamp in milliseconds. + * @return The difference between a start and end timestamps in minutes. + */ + protected double differenceInMinutes(long startTime, long endTime) + { + double minutes = (endTime - startTime) / 60000d; + if (minutes > 1d) + { + return minutes; + } + else + { + return 1d; + } + } +} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/main/java/flex/management/BaseControlMBean.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/flex/management/BaseControlMBean.java b/core/src/main/java/flex/management/BaseControlMBean.java new file mode 100644 index 0000000..d1c4246 --- /dev/null +++ b/core/src/main/java/flex/management/BaseControlMBean.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package flex.management; + +import java.io.IOException; +import javax.management.ObjectName; + +/** + * The base MBean interface for management beans that control aspects of + * Flex behavior on the server. + */ +public interface BaseControlMBean +{ + /** + * Returns the id for this MBean. This is the value that is set for the + * <code>id</code> key in the <code>ObjectName</code> for this MBean. + * + * @return The MBean instance id. + * @throws IOException Throws IOException. + */ + String getId() throws IOException; + + /** + * Returns the type for this MBean. This is the value that is set for the + * <code>type</code> key in the <code>ObjectName</code> for this MBean. + * + * @return The MBean instance type. + * @throws IOException Throws IOException. + */ + String getType() throws IOException; + + /** + * Returns the parent for this MBean. The value is the <code>ObjectName</code> + * for the parent MBean that conceptually contains this MBean instance. If no + * parent exists, this method returns <code>null</code>. + * + * @return The <code>ObjectName</code> for the parent of this MBean instance. + * @throws IOException Throws IOException. + */ + ObjectName getParent() throws IOException; +} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/main/java/flex/management/MBeanLifecycleManager.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/flex/management/MBeanLifecycleManager.java b/core/src/main/java/flex/management/MBeanLifecycleManager.java new file mode 100644 index 0000000..60f1f10 --- /dev/null +++ b/core/src/main/java/flex/management/MBeanLifecycleManager.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package flex.management; + +import flex.messaging.MessageBroker; + +import java.util.Iterator; +import java.util.Set; + +import javax.management.MBeanServer; +import javax.management.ObjectName; + +/** + * Helper class for managing MBean lifecycles externally from the core server + * components where necessary. + */ +public class MBeanLifecycleManager +{ + /** + * Unregisters all runtime MBeans that are registered in the same domain as the + * MessageBrokerControl for the target MessageBroker. + * + * @param broker The MessageBroker component that has been stopped. + */ + public static void unregisterRuntimeMBeans(MessageBroker broker) + { + MBeanServer server = MBeanServerLocatorFactory.getMBeanServerLocator().getMBeanServer(); + ObjectName brokerMBean = broker.getControl().getObjectName(); + String domain = brokerMBean.getDomain(); + try + { + ObjectName pattern = new ObjectName(domain + ":*"); + Set names = server.queryNames(pattern, null); + Iterator iter = names.iterator(); + while (iter.hasNext()) + { + ObjectName on = (ObjectName)iter.next(); + server.unregisterMBean(on); + } + } + catch (Exception e) + { + // We're generally unregistering these during shutdown (possibly JVM shutdown) + // so there's nothing to really do here because we aren't guaranteed access to + // resources like system log files, localized messaging, etc. + } + } + +} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/main/java/flex/management/MBeanServerLocator.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/flex/management/MBeanServerLocator.java b/core/src/main/java/flex/management/MBeanServerLocator.java new file mode 100644 index 0000000..2a08e29 --- /dev/null +++ b/core/src/main/java/flex/management/MBeanServerLocator.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package flex.management; + +import javax.management.MBeanServer; + +/** + * Interface for classes that locate MBeanServers to register MBeans with. + */ +public interface MBeanServerLocator +{ + /** + * Returns the MBeanServer to register our management MBeans with. + * + * @return The MBeanServer to register our management MBeans with. + */ + MBeanServer getMBeanServer(); + +} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/main/java/flex/management/MBeanServerLocatorFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/flex/management/MBeanServerLocatorFactory.java b/core/src/main/java/flex/management/MBeanServerLocatorFactory.java new file mode 100644 index 0000000..29eb1b3 --- /dev/null +++ b/core/src/main/java/flex/management/MBeanServerLocatorFactory.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package flex.management; + +import flex.messaging.log.Log; +import flex.messaging.log.LogCategories; +import flex.messaging.util.ClassUtil; + +/** + * Factory to get a <code>MBeanServerLocator</code>. + */ +public class MBeanServerLocatorFactory +{ + //-------------------------------------------------------------------------- + // + // Private Static Variables + // + //-------------------------------------------------------------------------- + + /** + * The MBeanServerLocator impl to use; lazily init'ed on first access. + */ + private static MBeanServerLocator locator; + + //-------------------------------------------------------------------------- + // + // Public Static Methods + // + //-------------------------------------------------------------------------- + + /** + * Returns a <code>MBeanServerLocator</code> that exposes the <code>MBeanServer</code> to register MBeans with. + * + * @return The <code>MBeanServerLocator</code> that exposes the <code>MBeanServer</code> to register MBeans with. + */ + public static synchronized MBeanServerLocator getMBeanServerLocator() + { + if (locator == null) + { + // Try app-server specific locators. + // WebSphere provides access to its MBeanServer via a custom admin API. + instantiateLocator("flex.management.WebSphereMBeanServerLocator", new String[] {"com.ibm.websphere.management.AdminServiceFactory"}); + + // Sun JRE 1.5 based implementation + if (locator == null) + locator = new PlatformMBeanServerLocator(); + + if (Log.isDebug()) + Log.getLogger(LogCategories.MANAGEMENT_GENERAL).debug("Using MBeanServerLocator: " + locator.getClass().getName()); + } + return locator; + } + + /** + * Release static MBeanServerLocator + * Called on MessageBroker shutdown. + */ + public static void clear() + { + locator = null; + } + + //-------------------------------------------------------------------------- + // + // Private Static Methods + // + //-------------------------------------------------------------------------- + + /** + * Helper method that attempts to load a specific MBeanServerLocator. + * + * @param locatorClassName The classname of the desired MBeanServerLocator. + * @param dependencyClassNames Any additional dependent classnames that the desired locator depends upon + * that should also be tested for availability. + */ + private static void instantiateLocator(String locatorClassName, String[] dependencyClassNames) + { + try + { + if (dependencyClassNames != null) + { + for (int i = 0; i < dependencyClassNames.length; i++) + ClassUtil.createClass(dependencyClassNames[i]); + } + + Class locatorClass = ClassUtil.createClass(locatorClassName); + locator = (MBeanServerLocator)locatorClass.newInstance(); + } + catch (Throwable t) + { + if (Log.isDebug()) + Log.getLogger(LogCategories.MANAGEMENT_MBEANSERVER).debug("Not using MBeanServerLocator: " + locatorClassName + ". Reason: " + t.getMessage()); + } + } + + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + + /** + * Direct instantiation is not allowed. + * Use <code>getMBeanServerLocator()</code> to obtain a <code>MBeanServerLocator</code> + * instance to lookup the proper MBean server to use. + */ + private MBeanServerLocatorFactory() {} + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/main/java/flex/management/Manageable.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/flex/management/Manageable.java b/core/src/main/java/flex/management/Manageable.java new file mode 100644 index 0000000..be7eb4a --- /dev/null +++ b/core/src/main/java/flex/management/Manageable.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package flex.management; + +/** + * Manageability of a class is enabled by implementing this interface. The + * specific level of manageability is defined by the relationship between + * a manageable component and its corresponding control. + */ +public interface Manageable +{ + /** + * Returns <code>true</code> if the component is enabled for management. + * + * @return <code>true</code> if the component is enabled for management. + */ + boolean isManaged(); + + /** + * Enables or disables management for the component. + * + * @param enableManagement <code>true</code> to enable management, <code>false</code> to disable management. + */ + void setManaged(boolean enableManagement); + + /** + * Returns the control MBean used to manage the component. + * + * @return The control MBean used to manage the component. + */ + BaseControl getControl(); + + /** + * Set the control MBean used to manage the component. + * + * @param control The <code>BaseControl</code> MBean used to manage the component. + */ + void setControl(BaseControl control); +} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/main/java/flex/management/ManageableComponent.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/flex/management/ManageableComponent.java b/core/src/main/java/flex/management/ManageableComponent.java new file mode 100644 index 0000000..02cccfc --- /dev/null +++ b/core/src/main/java/flex/management/ManageableComponent.java @@ -0,0 +1,421 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package flex.management; + +import java.util.Date; + +import flex.messaging.FlexComponent; +import flex.messaging.config.ConfigMap; +import flex.messaging.config.ConfigurationException; +import flex.messaging.log.Log; + +/** + * An abstract base class that implements the <code>Manageable</code> and <code>FlexComponent</code> interfaces. + * This is an excellent starting point for a server component that may be instantiated, initialized, started and + * stopped, as well as exposing an optional management interface via a peer MBean. + * <p>Support for changing component properties while the component is + * started should be determined on a per-property basis, and the started property is volatile to ensure consistent + * reads of the start state of the component across threads. This class performs no synchronization and is not safe for modification by multiple concurrent threads + * in the absence of external synchronization. + * </p> + */ +public abstract class ManageableComponent implements Manageable, FlexComponent +{ + //-------------------------------------------------------------------------- + // + // Protected Static Constants + // + //-------------------------------------------------------------------------- + + /** + * Error code for attempting to change a property after starting. + */ + protected static final int PROPERTY_CHANGE_AFTER_STARTUP = 11115; + + /** + * Error code to alert the user that a required component property is null. + */ + protected static final int NULL_COMPONENT_PROPERTY = 11116; + + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + + /** + * Constructs a <code>ManageableComponent</code> instance, specifying + * whether to enable management. + * Enabling management will trigger the creation of a peer MBean that exposes the + * management interface for this component. + * + * @param enableManagement <code>true</code> to enable management, <code>false</code> to disable + * management. + */ + public ManageableComponent(boolean enableManagement) + { + setManaged(enableManagement); + } + + //-------------------------------------------------------------------------- + // + // Public Properties + // + //-------------------------------------------------------------------------- + + //---------------------------------- + // control + //---------------------------------- + + /** + * The peer MBean of the <code>ManageableComponent</code> that exposes a management interface. + */ + protected BaseControl control; + + /** + * (non-JavaDoc) + * @see Manageable#getControl() + */ + public BaseControl getControl() + { + return control; + } + + /** + * (non-JavaDoc) + * @see Manageable#setControl(BaseControl) + */ + public void setControl(BaseControl control) + { + this.control = control; + } + + //---------------------------------- + // id + //---------------------------------- + + /** + * The internal id value of the <code>ManageableComponent</code>. + */ + protected String id; + + /** + * Returns the id of the <code>ManageableComponent</code>. + * + * @return The id of the <code>ManageableComponent</code>. + */ + public String getId() + { + return id; + } + + /** + * Sets the id of the <code>ManageableComponent</code>. The id cannot be + * null and it cannot be changed after startup. + * + * @param id The id of the <code>ManageableComponent</code>. + */ + public void setId(String id) + { + if (isStarted()) + { + blockAssignmentWhileStarted("id"); + } + if (id == null) + { + // Id of a component cannot be null. + blockNullAssignment("id"); + } + this.id = id; + } + + //---------------------------------- + // managed + //---------------------------------- + + /** + * The internal managed flag of the <code>ManageableComponent</code>. + */ + protected volatile boolean managed; + + /** + * (non-JavaDoc) + * @see Manageable#isManaged() + */ + public boolean isManaged() + { + return managed; + } + + /** + * Enables or disables management for the component. Management cannot be + * changed once the component is started and management cannot be + * <code>true</code> if the parent of the component is not managed. + * + * @param enableManagement <code>true</code> to enable management, <code>false</code> to disable management. + */ + public void setManaged(boolean enableManagement) + { + if (isStarted() && control != null) + { + blockAssignmentWhileStarted("managed"); + } + if (enableManagement && parent != null && !parent.isManaged()) + { + if (Log.isWarn()) + { + Log.getLogger(getLogCategory()).warn("Component: '" + id + "' cannot be managed" + + " since its parent is unmanaged."); + } + return; + } + managed = enableManagement; + } + + //---------------------------------- + // parent + //---------------------------------- + + /** + * The internal reference to the parent component (if any) of the <code>ManageableComponent</code>. + */ + protected Manageable parent; + + /** + * Returns the parent of the component. + * + * @return The parent of the component. + */ + public Manageable getParent() + { + return parent; + } + + /** + * Sets the parent of the component. The parent cannot be changed + * after component startup and it cannot be null. + * + * @param parent The parent of the component. + */ + public void setParent(Manageable parent) + { + if (isStarted()) + { + blockAssignmentWhileStarted("parent"); + } + if (parent == null) + { + // Parent of a component cannot be null. + blockNullAssignment("parent"); + } + if (!parent.isManaged() && isManaged()) + { + if (Log.isWarn()) + { + Log.getLogger(getLogCategory()).warn("Component: '" + id + "' cannot be managed" + + " since its parent is unmanaged."); + } + setManaged(false); + } + this.parent = parent; + } + + //---------------------------------- + // started + //---------------------------------- + + /** + * The internal started flag of the <code>ManageableComponent</code>. + */ + protected volatile boolean started; + + /** + * Returns if the component is started or not. + * + * @return <code>true</code> if the component is started. + */ + public boolean isStarted() + { + return started; + } + + /** + * Sets if the component is started. + * + * @param started true if the component is started. + */ + protected void setStarted(boolean started) + { + if (this.started != started) + { + this.started = started; + if (started && control != null) + { + control.setStartTimestamp(new Date()); + } + } + } + + //---------------------------------- + // valid + //---------------------------------- + + /** + * The internal valid flag of the <code>ManageableComponent</code>. + */ + protected boolean valid; + + /** + * Returns if the component is valid. + * + * @return <code>true</code> if the component is valid. + */ + public boolean isValid() + { + return valid; + } + + /** + * Sets if the component is valid. + * + * @param valid true if the comoponent is valid. + */ + protected void setValid(boolean valid) + { + this.valid = valid; + } + + //---------------------------------- + // logCategory + //---------------------------------- + + /** + * Returns the log category of the component. Subclasses must provide an + * implementation that returns their desired log category. + * + * @return The log category of the component. + */ + protected abstract String getLogCategory(); + + //-------------------------------------------------------------------------- + // + // Public Methods + // + //-------------------------------------------------------------------------- + + /** + * Invoked to initialize the <code>ManageableComponent</code>. + * This base implementation calls <code>setId()</code> passing the provided + * id and ignores the properties map argument. + * Subclasses should call <code>super.initialize()</code>. + * + * @param id Id of the <code>ManageableComponent</code>. + * @param properties Properties for the <code>ManageableComponent</code>. + */ + public void initialize(String id, ConfigMap properties) + { + setId(id); + } + + /** + * Validates and starts the component. + * + * Subclasses should call <code>super.start()</code>. + */ + public void start() + { + validate(); + setStarted(true); + } + + /** + * Invalidates and stops the component. + * + * Subclasses should call <code>super.stop()</code>. + */ + public void stop() + { + invalidate(); + setStarted(false); + } + + //-------------------------------------------------------------------------- + // + // Protocted Methods + // + //-------------------------------------------------------------------------- + + /** + * Convenience method that may be used to generate and throw an Exception for an attempt to set the specified property if the + * component is started. + * + * @param propertyName The name of the property being incorrectly assigned; included in the Exception message. + */ + protected void blockAssignmentWhileStarted(String propertyName) + { + ConfigurationException ce = new ConfigurationException(); + ce.setMessage(PROPERTY_CHANGE_AFTER_STARTUP, new Object[]{propertyName}); + throw ce; + } + + /** + * Convenience method that may be used to generate and throw an Exception for an attempt to assign a null value to a property that + * requires non-null values. + * + * @param propertyName The name of the property being incorrectly assigned. + */ + protected void blockNullAssignment(String propertyName) + { + ConfigurationException ce = new ConfigurationException(); + ce.setMessage(NULL_COMPONENT_PROPERTY, new Object[]{propertyName}); + throw ce; + } + + /** + * Invoked from within the <code>stop()</code> method to invalidate the component as part of shutdown. + * This base implementation sets the valid property to false. + * Subclasses should call <code>super.invalidate()</code>. + */ + protected void invalidate() + { + setValid(false); + } + + /** + * Hook method invoked from within the <code>start()</code> method to validate that the component is in a + * startable state. + * This base implementation validates the component by ensuring it has an id and a parent and then sets + * the valid property to true. + * If the component is not in a valid, startable state an Exception is thrown. + * Subclasses should call <code>super.validate()</code>. + */ + protected void validate() + { + if (getId() == null) + { + // Id of a component cannot be null. + blockNullAssignment("id"); + } + if (getParent() == null) + { + // Parent of a component cannot be null. + blockNullAssignment("parent"); + } + setValid(true); + } + +} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/main/java/flex/management/ManagementException.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/flex/management/ManagementException.java b/core/src/main/java/flex/management/ManagementException.java new file mode 100644 index 0000000..593b7f2 --- /dev/null +++ b/core/src/main/java/flex/management/ManagementException.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package flex.management; + +import flex.messaging.MessageException; + +/** + * This exception type is thrown when errors occur generating + * <code>ObjectName</code>s for MBeans, or when registering them or + * accessing them via the MBean server. + */ +public class ManagementException extends MessageException +{ + // Inherits all functionality from MessageException. + static final long serialVersionUID = 1296149563830613956L; +} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/main/java/flex/management/PlatformMBeanServerLocator.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/flex/management/PlatformMBeanServerLocator.java b/core/src/main/java/flex/management/PlatformMBeanServerLocator.java new file mode 100644 index 0000000..c00fe42 --- /dev/null +++ b/core/src/main/java/flex/management/PlatformMBeanServerLocator.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package flex.management; + +import java.lang.management.ManagementFactory; +import javax.management.MBeanServer; + +import flex.messaging.log.Log; +import flex.messaging.log.LogCategories; + +/** + * The platform implementation of an MBeanServerLocator for Java 1.5+. + * This locator exposes the platform MBeanServer. + */ +public class PlatformMBeanServerLocator implements MBeanServerLocator +{ + /** {@inheritDoc} */ + public synchronized MBeanServer getMBeanServer() + { + return ManagementFactory.getPlatformMBeanServer(); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/main/java/flex/management/jmx/Attribute.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/flex/management/jmx/Attribute.java b/core/src/main/java/flex/management/jmx/Attribute.java new file mode 100644 index 0000000..54fe08b --- /dev/null +++ b/core/src/main/java/flex/management/jmx/Attribute.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package flex.management.jmx; + +/** + * Remotable <code>Attribute</code> class that complies with Flash serialization requirements. + */ +public class Attribute +{ + /** + * The name of the attribute. + */ + public String name; + + /** + * The value of the attribute. + */ + public Object value; + + /** + * Constructs an empty <code>Attribute</code> instance. + * + */ + public Attribute() + {} + + /** + * Constructs an <code>Attribute</code> instance based upon a <code>javax.management.Attribute</code> instance. + * + * @param attribute The JMX <code>Attribute</code> to base this instance on. + */ + public Attribute(javax.management.Attribute attribute) + { + name = attribute.getName(); + value = attribute.getValue(); + } + + /** + * Utility method to convert this <code>Attribute</code> instance to a <code>javax.management.Attribute</code> instance. + * + * @return A JMX <code>Attribute</code> based upon this instance. + */ + public javax.management.Attribute toAttribute() + { + return new javax.management.Attribute(name, value); + } +} http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/main/java/flex/management/jmx/MBeanAttributeInfo.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/flex/management/jmx/MBeanAttributeInfo.java b/core/src/main/java/flex/management/jmx/MBeanAttributeInfo.java new file mode 100644 index 0000000..d9c6ba4 --- /dev/null +++ b/core/src/main/java/flex/management/jmx/MBeanAttributeInfo.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package flex.management.jmx; + +/** + * Remotable <code>MBeanAttributeInfo</code> class that complies with Flash serialization requirements. + * The <code>isIs</code> property is not named <code>is</code> because <code>is</code> is + * an ActionScript keyword. + */ +public class MBeanAttributeInfo +{ + /** + * The name of the attribute. + */ + public String name; + + /** + * The class name of the attribute. + */ + public String type; + + /** + * The description of the attribute. + */ + public String description; + + /** + * Whether the attribute can be read. + */ + public boolean readable; + + /** + * Whether the attribute can be written. + */ + public boolean writable; + + /** + * Whether the attribute has an "is" getter. + */ + public boolean isIs; + + /** + * Constructs an empty <code>MBeanAttributeInfo</code> instance. + */ + public MBeanAttributeInfo() + {} + + /** + * Constructs a <code>MBeanAttributeInfo</code> instance based upon a + * <code>javax.management.MBeanAttributeInfo</code> instance. + * + * @param mbeanAttributeInfo The JMX <code>MBeanAttributeInfo</code> instance to base this instance on. + */ + public MBeanAttributeInfo(javax.management.MBeanAttributeInfo mbeanAttributeInfo) + { + name = mbeanAttributeInfo.getName(); + type = mbeanAttributeInfo.getType(); + description = mbeanAttributeInfo.getDescription(); + readable = mbeanAttributeInfo.isReadable(); + writable = mbeanAttributeInfo.isWritable(); + isIs = mbeanAttributeInfo.isIs(); + } + + /** + * Utility method to convert this <code>MBeanAttributeInfo</code> to a + * <code>javax.management.MBeanAttributeInfo</code> instance. + * + * @return A JMX <code>MBeanAttributeInfo</code> based upon this instance. + */ + public javax.management.MBeanAttributeInfo toMBeanAttributeInfo() + { + return new javax.management.MBeanAttributeInfo(name, + type, + description, + readable, + writable, + isIs); + } + +}