/* * RHQ Management Platform * Copyright (C) 2005-2012 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.common.jbossas.client.controller; import org.jboss.as.controller.client.ModelControllerClient; import org.jboss.dmr.ModelNode; /** * Provides convenience methods associated with Infinispan cache management. * * @author Jay Shaughnessy * @author John Mazzitelli */ public class InfinispanJBossASClient extends JBossASClient { public static final String SUBSYSTEM_INFINISPAN = "infinispan"; public static final String CACHE_CONTAINER = "cache-container"; public static final String LOCAL_CACHE = "local-cache"; public InfinispanJBossASClient(ModelControllerClient client) { super(client); } /** * Checks to see if there is already a cache container with the given name. * * @param cacheContainerName the name to check * @return true if there is a cache container with the given name already in existence */ public boolean isCacheContainer(String cacheContainerName) throws Exception { Address addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_INFINISPAN); String haystack = CACHE_CONTAINER; return null != findNodeInList(addr, haystack, cacheContainerName); } /** * Checks to see if there is already a local cache with the given name. * * @param cacheContainerName the parent container * @param localCacheName the name to check * @return true if there is a local cache with the given name already in existence */ public boolean isLocalCache(String cacheContainerName, String localCacheName) throws Exception { if (!isCacheContainer(cacheContainerName)) { return false; } Address addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_INFINISPAN, CACHE_CONTAINER, cacheContainerName); String haystack = LOCAL_CACHE; return null != findNodeInList(addr, haystack, localCacheName); } /** * Returns a ModelNode that can be used to create a cache container configuration for * subsequent cache configuration. Callers are free to tweak the request that is returned, * if they so choose, before asking the client to execute the request. * <p> * The JNDI name will be java:jboss/infinispan/<cacheContainerName> * </p> * * @param name the name of the cache container * @param defaultCacheName the name of the default cache. The referenced cache must be * subsequently created. * * @return the request to create the cache container configuration. */ public ModelNode createNewCacheContainerRequest(String name, String defaultCacheName) { String dmrTemplate = "" // + "{" // + "\"default-cache-name\" => \"%s\" ," // + "\"jndi-name\" => \"%s\" " // + "}"; String jndiName = "java:jboss/infinispan/" + name; String dmr = String.format(dmrTemplate, defaultCacheName, jndiName); Address addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_INFINISPAN, CACHE_CONTAINER, name); final ModelNode result = ModelNode.fromString(dmr); result.get(OPERATION).set(ADD); result.get(ADDRESS).set(addr.getAddressNode()); return result; } /** * Returns a ModelNode that can be used to create a local cache. Callers are free to tweak the * request that is returned, if they so choose, before asking the client to execute the request. * * @param localCacheName * @param transactionMode if null, defaults to "NONE" * @param evictionStrategy if null, defaults to "LRU" * @param evictionMaxEntries if null, defaults to 50000 * @param expirationLifespan if null, defaults to -1 * @param expirationMaxIdle if null, defaults to 100000 * @param isolationLevel if null, defaults to REPEATABLE_READ (currently ignored) * * @return the request that can be used to create the local cache * @Throws IllegalArgumentException if cacheContainerName does not correspond to a defined container */ public ModelNode createNewLocalCacheRequest(String cacheContainerName, String localCacheName, String transactionMode, String evictionStrategy, Long evictionMaxEntries, Long expirationLifeSpan, Long expirationMaxIdle, String isolationLevel) throws Exception { if (!isCacheContainer(cacheContainerName)) { throw new IllegalArgumentException("cache-container does not exist [" + cacheContainerName + "]"); } ModelNode[] result = new ModelNode[4]; // The cache Address addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_INFINISPAN, CACHE_CONTAINER, cacheContainerName, LOCAL_CACHE, localCacheName); String dmrTemplate = "" // + "{" // + "\"isolation-level\" => \"%s\" " // TODO (jshaughn): ignored, why? + "}"; String dmr = String.format(dmrTemplate, // ((null == isolationLevel) ? "REPEATABLE_READ" : isolationLevel)); result[0] = ModelNode.fromString(dmr); result[0].get(OPERATION).set(ADD); result[0].get(ADDRESS).set(addr.getAddressNode()); // The cache eviction addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_INFINISPAN, CACHE_CONTAINER, cacheContainerName, LOCAL_CACHE, localCacheName, "eviction", "EVICTION"); dmrTemplate = "" // + "{" // + "\"strategy\" => \"%s\" ," // + "\"max-entries\" => %dL " // + "}"; dmr = String.format(dmrTemplate, // ((null == evictionStrategy) ? "LRU" : evictionStrategy), // ((null == evictionMaxEntries) ? 50000L : evictionMaxEntries)); result[1] = ModelNode.fromString(dmr); result[1].get(OPERATION).set(ADD); result[1].get(ADDRESS).set(addr.getAddressNode()); // The cache expiration addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_INFINISPAN, CACHE_CONTAINER, cacheContainerName, LOCAL_CACHE, localCacheName, "expiration", "EXPIRATION"); dmrTemplate = "" // + "{" // + "\"max-idle\" => %dL ," // + "\"lifespan\" => %dL " + "}"; dmr = String.format(dmrTemplate, // ((null == expirationMaxIdle) ? 100000L : expirationMaxIdle), ((null == expirationLifeSpan) ? -1L : expirationLifeSpan)); result[2] = ModelNode.fromString(dmr); result[2].get(OPERATION).set(ADD); result[2].get(ADDRESS).set(addr.getAddressNode()); // The cache transaction addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_INFINISPAN, CACHE_CONTAINER, cacheContainerName, LOCAL_CACHE, localCacheName, "transaction", "TRANSACTION"); dmrTemplate = "" // + "{" // + "\"mode\" => \"%s\" " // + "}"; dmr = String.format(dmrTemplate, // ((null == transactionMode) ? "NONE" : transactionMode)); result[3] = ModelNode.fromString(dmr); result[3].get(OPERATION).set(ADD); result[3].get(ADDRESS).set(addr.getAddressNode()); return createBatchRequest(result); } }