/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.glassfish.admin.amxtest.config;
import com.sun.appserv.management.base.QueryMgr;
import com.sun.appserv.management.config.CustomMBeanConfig;
import com.sun.appserv.management.config.DomainConfig;
import com.sun.appserv.management.config.PropertiesAccess;
import com.sun.appserv.management.helper.RefHelper;
import com.sun.appserv.management.util.misc.CollectionUtil;
import org.glassfish.admin.amxtest.AMXTestBase;
import javax.management.ObjectName;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
*/
public final class CustomMBeanConfigTest
extends AMXTestBase {
// built-into server already; use the name; we can't rely on the server jars
private static final String IMPL_CLASSNAME = "org.glassfish.admin.amx.mbean.TestDummy";
private static final String TEST_NAME_BASE = "custom";
private static final String TEST_TYPE = "CustomMBeanConfigTest";
public CustomMBeanConfigTest() {
if (checkNotOffline("ensureDefaultInstance")) {
ensureDefaultInstance(getDomainConfig());
}
}
public static String
getDefaultInstanceName() {
return getDefaultInstanceName("CustomMBeanConfig");
}
public static CustomMBeanConfig
ensureDefaultInstance(final DomainConfig domainConfig) {
CustomMBeanConfig result =
domainConfig.getResourcesConfig().getCustomMBeanConfigMap().get(getDefaultInstanceName());
if (result == null) {
result = createInstance(
domainConfig,
getDefaultInstanceName(),
createProps());
}
return result;
}
public static CustomMBeanConfig
createInstance(
final DomainConfig domainConfig,
final String name,
final Map<String, String> optional) {
final CustomMBeanConfig custom =
domainConfig.getResourcesConfig().createCustomMBeanConfig(name, IMPL_CLASSNAME,
createObjectName(name),
"false",
optional);
return custom;
}
public Map<String, CustomMBeanConfig>
getCustomMBeanConfigs() {
return getDomainConfig().getResourcesConfig().getCustomMBeanConfigMap();
}
private void
_testGetAll() {
final Map<String, CustomMBeanConfig> all = getCustomMBeanConfigs();
assert (all != null);
}
private void
sanityCheck(final CustomMBeanConfig config) {
final String objectName = config.getObjectNameInConfig();
final String implClassname = config.getImplClassname();
}
private synchronized void
_testAttrs() {
final Map<String, CustomMBeanConfig> all = getCustomMBeanConfigs();
if (all.size() != 0) {
// everything is already tested generically, but we'll
// do some basic sanity checks here
for (final CustomMBeanConfig config : all.values()) {
sanityCheck(config);
}
} else {
warning("CustomMBeanConfigTest: No custom MBeans to test");
}
}
/**
Create some dummy properties for creating a CustomMBeanConfig
*/
private static Map<String, String>
createProps() {
final String PRP = PropertiesAccess.PROPERTY_PREFIX; // shorten
final Map<String, String> optional = new HashMap<String, String>();
// these must be available in test MBean
optional.put(PRP + "Attr1", "hello");
optional.put(PRP + "Attr2", "world");
return optional;
}
private static String
createObjectName(final String name) {
return CustomMBeanConfig.JMX_DOMAIN + ":name=" + name +
",type=" + TEST_TYPE;
}
public synchronized CustomMBeanConfig
create(
final DomainConfig domainConfig,
final String name,
final Map<String, String> optional) {
return createInstance(domainConfig, name, optional);
}
public synchronized void
verifyPropsAdded(
final CustomMBeanConfig config,
final Map<String, String> props) {
for (final String key : props.keySet()) {
if (key.startsWith(PropertiesAccess.PROPERTY_PREFIX)) {
final String specifiedValue = props.get(key).toString();
final String propName = key.substring(
PropertiesAccess.PROPERTY_PREFIX.length(), key.length());
final String actualValue = config.getPropertyConfigMap().get(propName).getValue();
assert (specifiedValue.equals(actualValue));
}
}
}
private void
removeCustomMBean(final String name) {
getDomainConfig().getResourcesConfig().removeCustomMBeanConfig(name);
}
private Set<ObjectName>
getRegisteredCustoms() {
final QueryMgr queryMgr = getQueryMgr();
final Set<ObjectName> mbeans =
queryMgr.queryPatternObjectNameSet(CustomMBeanConfig.JMX_DOMAIN, "type=" + TEST_TYPE);
return mbeans;
}
private void
unregisterAnyTestMBeans() {
final Set<ObjectName> customs = getRegisteredCustoms();
for (final ObjectName objectName : customs) {
if (TEST_TYPE.equals(objectName.getKeyProperty("type"))) {
try {
getMBeanServerConnection().unregisterMBean(objectName);
printVerbose("unregistered: " + objectName);
}
catch (Exception e) {
}
}
}
}
public synchronized void
testCreateRemove() {
if (!checkNotOffline("testCreateRemove")) {
return;
}
final DomainConfig domainConfig = getDomainConfig();
final Map<String, String> optional = createProps();
final Set<CustomMBeanConfig> created = new HashSet<CustomMBeanConfig>();
final Map<String, CustomMBeanConfig> existing =
getDomainConfig().getResourcesConfig().getCustomMBeanConfigMap();
unregisterAnyTestMBeans();
final Set<ObjectName> customsBefore = getRegisteredCustoms();
if (customsBefore.size() != 0) {
printVerbose("custom MBeans already registered:\n" +
CollectionUtil.toString(customsBefore, "\n"));
}
final int NUM = 3;
for (int i = 0; i < NUM; ++i) {
final String testName = TEST_NAME_BASE + i;
if (existing.containsKey(testName)) {
RefHelper.removeAllRefsTo(existing.get(testName), true);
// leftover from a failed test...
removeCustomMBean(testName);
}
final CustomMBeanConfig config =
create(domainConfig, TEST_NAME_BASE + i, optional);
//printVerbose( "created: " + Util.getObjectName( config ) );
assert (getCustomMBeanConfigs().get(config.getName()) == config);
created.add(config);
sanityCheck(config);
verifyPropsAdded(config, optional);
}
_testGetAll();
_testAttrs();
for (final CustomMBeanConfig config : created) {
//printVerbose( "removing: " + Util.getObjectName( config ) );
final String name = config.getName();
removeCustomMBean(name);
assert (getCustomMBeanConfigs().get(name) == null);
}
_testGetAll();
mySleep(100);
final Set<ObjectName> customsAfter = getRegisteredCustoms();
customsAfter.removeAll(customsBefore);
if (customsAfter.size() != 0) {
warning("after removing custom MBeans, " +
"they are still registered (not an AMX bug):\n" +
CollectionUtil.toString(customsAfter, "\n"));
}
unregisterAnyTestMBeans();
}
}