You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2018/02/06 22:36:42 UTC
[geode] branch develop updated: GEODE-4389: Ensure that region
template creation does not require callback classes on the locator (#1390)
This is an automated email from the ASF dual-hosted git repository.
jensdeppe pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new ff1b8c7 GEODE-4389: Ensure that region template creation does not require callback classes on the locator (#1390)
ff1b8c7 is described below
commit ff1b8c7bdb8b02b015b6e233cadc6ae68cc33a54
Author: Jens Deppe <jd...@pivotal.io>
AuthorDate: Tue Feb 6 14:36:39 2018 -0800
GEODE-4389: Ensure that region template creation does not require callback classes on the locator (#1390)
---
.../internal/cli/commands/CreateRegionCommand.java | 56 ++++++--
.../functions/FetchRegionAttributesFunction.java | 61 ++++++--
.../cli/functions/RegionAttributesWrapper.java | 108 ++++++++++++++
.../sanctioned-geode-core-serializables.txt | 1 +
.../cli/commands/CreateRegionCommandDUnitTest.java | 155 +++++++++++++++++++++
5 files changed, 356 insertions(+), 25 deletions(-)
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java
index d71e8de..012da67 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java
@@ -53,6 +53,7 @@ import org.apache.geode.management.internal.cli.LogWrapper;
import org.apache.geode.management.internal.cli.domain.ClassName;
import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
import org.apache.geode.management.internal.cli.functions.FetchRegionAttributesFunction;
+import org.apache.geode.management.internal.cli.functions.RegionAttributesWrapper;
import org.apache.geode.management.internal.cli.functions.RegionCreateFunction;
import org.apache.geode.management.internal.cli.functions.RegionFunctionArgs;
import org.apache.geode.management.internal.cli.i18n.CliStrings;
@@ -203,8 +204,6 @@ public class CreateRegionCommand implements GfshCommand {
RegionFunctionArgs functionArgs = new RegionFunctionArgs();
functionArgs.setRegionPath(regionPath);
functionArgs.setIfNotExists(ifNotExists || skipIfExists);
- functionArgs.setKeyConstraint(keyConstraint);
- functionArgs.setValueConstraint(valueConstraint);
functionArgs.setStatisticsEnabled(statisticsEnabled);
functionArgs.setEntryExpirationIdleTime(entryExpirationIdleTime, entryExpirationIdleTimeAction);
functionArgs.setEntryExpirationTTL(entryExpirationTTL, entryExpirationTTLAction);
@@ -238,22 +237,22 @@ public class CreateRegionCommand implements GfshCommand {
regionPath));
}
functionArgs.setRegionShortcut(regionShortcut);
- } else if (templateRegion != null) {
+ } else { // templateRegion != null
if (!regionExists(cache, templateRegion)) {
return ResultBuilder.createUserErrorResult(CliStrings.format(
CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH_FOR_0_REGIONPATH_1_NOT_FOUND,
CliStrings.CREATE_REGION__USEATTRIBUTESFROM, templateRegion));
}
- regionAttributes = getRegionAttributes(cache, templateRegion);
+ RegionAttributesWrapper<?, ?> wrappedAttributes = getRegionAttributes(cache, templateRegion);
- if (regionAttributes == null) {
+ if (wrappedAttributes == null) {
return ResultBuilder.createGemFireErrorResult(CliStrings.format(
CliStrings.CREATE_REGION__MSG__COULD_NOT_RETRIEVE_REGION_ATTRS_FOR_PATH_0_VERIFY_REGION_EXISTS,
templateRegion));
}
- if (regionAttributes.getPartitionAttributes() == null
+ if (wrappedAttributes.getRegionAttributes().getPartitionAttributes() == null
&& functionArgs.hasPartitionAttributes()) {
return ResultBuilder.createUserErrorResult(CliStrings.format(
CliStrings.CREATE_REGION__MSG__OPTION_0_CAN_BE_USED_ONLY_FOR_PARTITIONEDREGION,
@@ -262,13 +261,42 @@ public class CreateRegionCommand implements GfshCommand {
templateRegion));
}
functionArgs.setTemplateRegion(templateRegion);
- functionArgs.setRegionAttributes(regionAttributes);
+
+ // These attributes will have the actual callback fields (if previously present) nulled out.
+ functionArgs.setRegionAttributes(wrappedAttributes.getRegionAttributes());
+
+ functionArgs
+ .setCacheListeners(wrappedAttributes.getCacheListenerClasses().toArray(new ClassName[0]));
+ functionArgs.setCacheWriter(wrappedAttributes.getCacheWriterClass());
+ functionArgs.setCacheLoader(wrappedAttributes.getCacheLoaderClass());
+ functionArgs.setCompressor(wrappedAttributes.getCompressorClass());
+ functionArgs.setKeyConstraint(wrappedAttributes.getKeyConstraintClass());
+ functionArgs.setValueConstraint(wrappedAttributes.getValueConstraintClass());
+ }
+
+ if (cacheListener != null) {
+ functionArgs.setCacheListeners(cacheListener);
}
- functionArgs.setCacheListeners(cacheListener);
- functionArgs.setCacheLoader(cacheLoader);
- functionArgs.setCacheWriter(cacheWriter);
- functionArgs.setCompressor(compressor);
+ if (cacheLoader != null) {
+ functionArgs.setCacheLoader(cacheLoader);
+ }
+
+ if (cacheWriter != null) {
+ functionArgs.setCacheWriter(cacheWriter);
+ }
+
+ if (compressor != null) {
+ functionArgs.setCompressor(compressor);
+ }
+
+ if (keyConstraint != null) {
+ functionArgs.setKeyConstraint(keyConstraint);
+ }
+
+ if (valueConstraint != null) {
+ functionArgs.setValueConstraint(valueConstraint);
+ }
DistributedSystemMXBean dsMBean = getDSMBean(cache);
// validating colocation
@@ -388,13 +416,13 @@ public class CreateRegionCommand implements GfshCommand {
return false;
}
- RegionAttributes getRegionAttributes(InternalCache cache, String regionPath) {
+ RegionAttributesWrapper getRegionAttributes(InternalCache cache, String regionPath) {
if (!isClusterWideSameConfig(cache, regionPath)) {
throw new IllegalStateException(CliStrings.format(
CliStrings.CREATE_REGION__MSG__USE_ATTRIBUTES_FORM_REGIONS_EXISTS_BUT_DIFFERENT_SCOPE_OR_DATAPOLICY_USE_DESCRIBE_REGION_FOR_0,
regionPath));
}
- RegionAttributes attributes = null;
+ RegionAttributesWrapper attributes = null;
// First check whether the region exists on a this manager, if yes then no
// need to use FetchRegionAttributesFunction to fetch RegionAttributes
@@ -425,7 +453,7 @@ public class CreateRegionCommand implements GfshCommand {
regionPath, th.getMessage()));
} else { // has to be RegionAttributes
@SuppressWarnings("unchecked") // to avoid warning :(
- RegionAttributes regAttr = ((RegionAttributes) object);
+ RegionAttributesWrapper regAttr = ((RegionAttributesWrapper) object);
if (attributes == null) {
attributes = regAttr;
break;
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction.java
index 4fd7bb9..584f558 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction.java
@@ -14,19 +14,23 @@
*/
package org.apache.geode.management.internal.cli.functions;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
import org.apache.logging.log4j.Logger;
import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.Cache;
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.RegionAttributes;
+import org.apache.geode.cache.CacheListener;
import org.apache.geode.cache.execute.Function;
import org.apache.geode.cache.execute.FunctionContext;
import org.apache.geode.internal.InternalEntity;
+import org.apache.geode.internal.cache.AbstractRegion;
import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.management.internal.cli.domain.ClassName;
import org.apache.geode.management.internal.cli.i18n.CliStrings;
import org.apache.geode.management.internal.security.ResourcePermissions;
import org.apache.geode.security.ResourcePermission;
@@ -58,8 +62,8 @@ public class FetchRegionAttributesFunction implements Function, InternalEntity {
throw new IllegalArgumentException(
CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH);
}
- RegionAttributes<?, ?> result = getRegionAttributes(cache, regionPath);
- context.getResultSender().lastResult(result);
+ RegionAttributesWrapper regionAttributesWrapper = getRegionAttributes(cache, regionPath);
+ context.getResultSender().lastResult(regionAttributesWrapper);
} catch (IllegalArgumentException e) {
if (logger.isDebugEnabled()) {
logger.debug(e.getMessage(), e);
@@ -69,19 +73,54 @@ public class FetchRegionAttributesFunction implements Function, InternalEntity {
}
@SuppressWarnings("deprecation")
- public static <K, V> RegionAttributes<K, V> getRegionAttributes(Cache cache, String regionPath) {
- Region<K, V> foundRegion = cache.getRegion(regionPath);
+ public static RegionAttributesWrapper getRegionAttributes(Cache cache, String regionPath) {
+ AbstractRegion foundRegion = (AbstractRegion) cache.getRegion(regionPath);
if (foundRegion == null) {
throw new IllegalArgumentException(CliStrings.format(
CliStrings.CREATE_REGION__MSG__SPECIFY_VALID_REGION_PATH_FOR_0_REGIONPATH_1_NOT_FOUND,
- new Object[] {CliStrings.CREATE_REGION__USEATTRIBUTESFROM, regionPath}));
+ CliStrings.CREATE_REGION__USEATTRIBUTESFROM, regionPath));
}
- // Using AttributesFactory to get the serializable RegionAttributes
- // Is there a better way?
- AttributesFactory<K, V> afactory = new AttributesFactory<K, V>(foundRegion.getAttributes());
- return afactory.create();
+ AttributesFactory afactory = new AttributesFactory(foundRegion.getAttributes());
+ RegionAttributesWrapper result = new RegionAttributesWrapper();
+
+ CacheListener[] cacheListeners = foundRegion.getCacheListeners();
+ List existingCacheListeners = Arrays.stream(cacheListeners)
+ .map((c) -> new ClassName(c.getClass().getName())).collect(Collectors.toList());
+
+ result.setCacheListenerClasses(existingCacheListeners);
+ afactory.initCacheListeners(null);
+
+ if (foundRegion.getCacheLoader() != null) {
+ result
+ .setCacheLoaderClass(new ClassName<>(foundRegion.getCacheLoader().getClass().getName()));
+ afactory.setCacheLoader(null);
+ }
+
+ if (foundRegion.getCacheWriter() != null) {
+ result
+ .setCacheWriterClass(new ClassName<>(foundRegion.getCacheWriter().getClass().getName()));
+ afactory.setCacheWriter(null);
+ }
+
+ if (foundRegion.getCompressor() != null) {
+ result.setCompressorClass(foundRegion.getCompressor().getClass().getName());
+ afactory.setCompressor(null);
+ }
+
+ if (foundRegion.getKeyConstraint() != null) {
+ result.setKeyConstraintClass(foundRegion.getKeyConstraint().getName());
+ afactory.setKeyConstraint(null);
+ }
+
+ if (foundRegion.getValueConstraint() != null) {
+ result.setValueConstraintClass(foundRegion.getValueConstraint().getName());
+ afactory.setValueConstraint(null);
+ }
+
+ result.setRegionAttributes(afactory.create());
+ return result;
}
@Override
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionAttributesWrapper.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionAttributesWrapper.java
new file mode 100644
index 0000000..b43b4ff
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionAttributesWrapper.java
@@ -0,0 +1,108 @@
+/*
+ * 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 org.apache.geode.management.internal.cli.functions;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.apache.geode.cache.CacheListener;
+import org.apache.geode.cache.CacheLoader;
+import org.apache.geode.cache.CacheWriter;
+import org.apache.geode.cache.RegionAttributes;
+import org.apache.geode.management.internal.cli.domain.ClassName;
+
+/**
+ * This class extracts serializable components from RegionAttributes and represents them simply as
+ * strings. The relevant RegionAttributes fields are nulled out so that Serialzation can occur where
+ * the relevant callbacks do not have classes defined. For example when retrieving a RegionAttribute
+ * from a server to a locator.
+ */
+public class RegionAttributesWrapper<K, V> implements Serializable {
+
+ private static final long serialVersionUID = -5517424520268271436L;
+
+ private RegionAttributes<K, V> regionAttributes;
+
+ private List<ClassName<CacheListener>> cacheListenerClasses;
+
+ private ClassName<CacheLoader> cacheLoaderClass;
+
+ private ClassName<CacheWriter> cacheWriterClass;
+
+ private String compressorClass;
+
+ private String keyConstraintClass;
+
+ private String valueConstraintClass;
+
+ public RegionAttributesWrapper() {}
+
+ public RegionAttributes<K, V> getRegionAttributes() {
+ return regionAttributes;
+ }
+
+ public void setRegionAttributes(RegionAttributes<K, V> regionAttributes) {
+ this.regionAttributes = regionAttributes;
+ }
+
+ public List<ClassName<CacheListener>> getCacheListenerClasses() {
+ return cacheListenerClasses;
+ }
+
+ public void setCacheListenerClasses(List<ClassName<CacheListener>> cacheListenerClasses) {
+ this.cacheListenerClasses = cacheListenerClasses;
+ }
+
+ public ClassName<CacheLoader> getCacheLoaderClass() {
+ return cacheLoaderClass;
+ }
+
+ public void setCacheLoaderClass(ClassName<CacheLoader> cacheLoaderClass) {
+ this.cacheLoaderClass = cacheLoaderClass;
+ }
+
+ public ClassName<CacheWriter> getCacheWriterClass() {
+ return cacheWriterClass;
+ }
+
+ public void setCacheWriterClass(ClassName<CacheWriter> cacheWriterClass) {
+ this.cacheWriterClass = cacheWriterClass;
+ }
+
+ public String getCompressorClass() {
+ return compressorClass;
+ }
+
+ public void setCompressorClass(String compressorClass) {
+ this.compressorClass = compressorClass;
+ }
+
+ public String getKeyConstraintClass() {
+ return keyConstraintClass;
+ }
+
+ public void setKeyConstraintClass(String keyConstraintClass) {
+ this.keyConstraintClass = keyConstraintClass;
+ }
+
+ public String getValueConstraintClass() {
+ return valueConstraintClass;
+ }
+
+ public void setValueConstraintClass(String valueConstraintClass) {
+ this.valueConstraintClass = valueConstraintClass;
+ }
+}
diff --git a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
index 313c3db..d4107e3 100644
--- a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
+++ b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
@@ -555,6 +555,7 @@ org/apache/geode/management/internal/cli/functions/NetstatFunction$NetstatFuncti
org/apache/geode/management/internal/cli/functions/NetstatFunction$NetstatFunctionResult,true,1,compressedBytes:org/apache/geode/management/internal/cli/CliUtil$DeflaterInflaterData,headerInfo:java/lang/String,host:java/lang/String
org/apache/geode/management/internal/cli/functions/RebalanceFunction,true,1
org/apache/geode/management/internal/cli/functions/RegionAlterFunction,true,-4846425364943216425
+org/apache/geode/management/internal/cli/functions/RegionAttributesWrapper,true,-5517424520268271436,cacheListenerClasses:java/util/List,cacheLoaderClass:org/apache/geode/management/internal/cli/domain/ClassName,cacheWriterClass:org/apache/geode/management/internal/cli/domain/ClassName,compressorClass:java/lang/String,keyConstraintClass:java/lang/String,regionAttributes:org/apache/geode/cache/RegionAttributes,valueConstraintClass:java/lang/String
org/apache/geode/management/internal/cli/functions/RegionCreateFunction,true,8746830191680509335
org/apache/geode/management/internal/cli/functions/RegionDestroyFunction,true,9172773671865750685
org/apache/geode/management/internal/cli/functions/RegionFunctionArgs,true,2204943186081037302,asyncEventQueueIds:java/util/Set,cacheListeners:java/util/Set,cacheLoader:org/apache/geode/management/internal/cli/domain/ClassName,cacheWriter:org/apache/geode/management/internal/cli/domain/ClassName,cloningEnabled:java/lang/Boolean,compressor:java/lang/String,concurrencyChecksEnabled:java/lang/Boolean,concurrencyLevel:java/lang/Integer,diskStore:java/lang/String,diskSynchronous:java/lang/Boo [...]
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java
index 66eccd8..02438c3 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommandDUnitTest.java
@@ -181,4 +181,159 @@ public class CreateRegionCommandDUnitTest {
gfsh.executeAndAssertThat("destroy region --name=/COPY").statusIsSuccess();
gfsh.executeAndAssertThat("destroy region --name=/TEMPLATE").statusIsSuccess();
}
+
+ @Test
+ public void ensureOverridingCallbacksFromTemplateDoNotRequireClassesOnLocator() throws Exception {
+ final File prJarFile = new File(tmpDir.getRoot(), "myCacheListener.jar");
+ new JarBuilder().buildJar(prJarFile, getUniversalClassCode("MyCallback"),
+ getUniversalClassCode("MyNewCallback"));
+ gfsh.executeAndAssertThat("deploy --jar=" + prJarFile.getAbsolutePath()).statusIsSuccess();
+
+ String myCallback = "io.pivotal.MyCallback";
+ gfsh.executeAndAssertThat(
+ String
+ .format(
+ "create region --name=/TEMPLATE --type=PARTITION_REDUNDANT "
+ + "--cache-listener=%1$s " + "--cache-loader=%1$s " + "--cache-writer=%1$s "
+ + "--compressor=%1$s " + "--key-constraint=%1$s " + "--value-constraint=%1$s",
+ myCallback))
+ .statusIsSuccess();
+
+ String myNewCallback = "io.pivotal.MyNewCallback";
+ gfsh.executeAndAssertThat(String
+ .format("create region --name=/COPY --template-region=/TEMPLATE " + "--cache-listener=%1$s "
+ + "--cache-loader=%1$s " + "--cache-writer=%1$s " + "--compressor=%1$s "
+ + "--key-constraint=%1$s " + "--value-constraint=%1$s", myNewCallback))
+ .statusIsSuccess();
+
+ server1.getVM().invoke(() -> {
+ Region copy = ClusterStartupRule.getCache().getRegion("/COPY");
+
+ assertThat(Arrays.stream(copy.getAttributes().getCacheListeners())
+ .map(c -> c.getClass().getName()).collect(Collectors.toSet()))
+ .containsExactly(myNewCallback);
+
+ assertThat(copy.getAttributes().getCacheLoader().getClass().getName())
+ .isEqualTo(myNewCallback);
+
+ assertThat(copy.getAttributes().getCacheWriter().getClass().getName())
+ .isEqualTo(myNewCallback);
+
+ assertThat(copy.getAttributes().getCompressor().getClass().getName())
+ .isEqualTo(myNewCallback);
+
+ assertThat(copy.getAttributes().getKeyConstraint().getName()).isEqualTo(myNewCallback);
+
+ assertThat(copy.getAttributes().getValueConstraint().getName()).isEqualTo(myNewCallback);
+ });
+
+ gfsh.executeAndAssertThat("destroy region --name=/COPY").statusIsSuccess();
+ gfsh.executeAndAssertThat("destroy region --name=/TEMPLATE").statusIsSuccess();
+ }
+
+ @Test
+ public void ensureNewCallbacksFromTemplateDoNotRequireClassesOnLocator() throws Exception {
+ final File prJarFile = new File(tmpDir.getRoot(), "myCacheListener.jar");
+ new JarBuilder().buildJar(prJarFile, getUniversalClassCode("MyNewCallback"));
+ gfsh.executeAndAssertThat("deploy --jar=" + prJarFile.getAbsolutePath()).statusIsSuccess();
+
+ gfsh.executeAndAssertThat("create region --name=/TEMPLATE --type=PARTITION_REDUNDANT")
+ .statusIsSuccess();
+
+ String myNewCallback = "io.pivotal.MyNewCallback";
+ gfsh.executeAndAssertThat(String
+ .format("create region --name=/COPY --template-region=/TEMPLATE " + "--cache-listener=%1$s "
+ + "--cache-loader=%1$s " + "--cache-writer=%1$s " + "--compressor=%1$s "
+ + "--key-constraint=%1$s " + "--value-constraint=%1$s", myNewCallback))
+ .statusIsSuccess();
+
+ server1.getVM().invoke(() -> {
+ Region copy = ClusterStartupRule.getCache().getRegion("/COPY");
+
+ assertThat(Arrays.stream(copy.getAttributes().getCacheListeners())
+ .map(c -> c.getClass().getName()).collect(Collectors.toSet()))
+ .containsExactly(myNewCallback);
+
+ assertThat(copy.getAttributes().getCacheLoader().getClass().getName())
+ .isEqualTo(myNewCallback);
+
+ assertThat(copy.getAttributes().getCacheWriter().getClass().getName())
+ .isEqualTo(myNewCallback);
+
+ assertThat(copy.getAttributes().getCompressor().getClass().getName())
+ .isEqualTo(myNewCallback);
+
+ assertThat(copy.getAttributes().getKeyConstraint().getName()).isEqualTo(myNewCallback);
+
+ assertThat(copy.getAttributes().getValueConstraint().getName()).isEqualTo(myNewCallback);
+ });
+
+ gfsh.executeAndAssertThat("destroy region --name=/COPY").statusIsSuccess();
+ gfsh.executeAndAssertThat("destroy region --name=/TEMPLATE").statusIsSuccess();
+ }
+
+ @Test
+ public void ensureOriginalCallbacksFromTemplateDoNotRequireClassesOnLocator() throws Exception {
+ final File prJarFile = new File(tmpDir.getRoot(), "myCacheListener.jar");
+ new JarBuilder().buildJar(prJarFile, getUniversalClassCode("MyCallback"));
+ gfsh.executeAndAssertThat("deploy --jar=" + prJarFile.getAbsolutePath()).statusIsSuccess();
+
+ String myCallback = "io.pivotal.MyCallback";
+ gfsh.executeAndAssertThat(
+ String
+ .format(
+ "create region --name=/TEMPLATE --type=PARTITION_REDUNDANT "
+ + "--cache-listener=%1$s " + "--cache-loader=%1$s " + "--cache-writer=%1$s "
+ + "--compressor=%1$s " + "--key-constraint=%1$s " + "--value-constraint=%1$s",
+ myCallback))
+ .statusIsSuccess();
+
+ gfsh.executeAndAssertThat("create region --name=/COPY --template-region=/TEMPLATE")
+ .statusIsSuccess();
+
+ server1.getVM().invoke(() -> {
+ Region copy = ClusterStartupRule.getCache().getRegion("/COPY");
+
+ assertThat(Arrays.stream(copy.getAttributes().getCacheListeners())
+ .map(c -> c.getClass().getName()).collect(Collectors.toSet()))
+ .containsExactly(myCallback);
+
+ assertThat(copy.getAttributes().getCacheLoader().getClass().getName()).isEqualTo(myCallback);
+
+ assertThat(copy.getAttributes().getCacheWriter().getClass().getName()).isEqualTo(myCallback);
+
+ assertThat(copy.getAttributes().getCompressor().getClass().getName()).isEqualTo(myCallback);
+
+ assertThat(copy.getAttributes().getKeyConstraint().getName()).isEqualTo(myCallback);
+
+ assertThat(copy.getAttributes().getValueConstraint().getName()).isEqualTo(myCallback);
+ });
+
+ gfsh.executeAndAssertThat("destroy region --name=/COPY").statusIsSuccess();
+ gfsh.executeAndAssertThat("destroy region --name=/TEMPLATE").statusIsSuccess();
+ }
+
+ private String getUniversalClassCode(String classname) {
+ String code = "package io.pivotal;" + "import org.apache.geode.cache.CacheLoader;"
+ + "import org.apache.geode.cache.CacheLoaderException;"
+ + "import org.apache.geode.cache.CacheWriter;"
+ + "import org.apache.geode.cache.CacheWriterException;"
+ + "import org.apache.geode.cache.EntryEvent;"
+ + "import org.apache.geode.cache.LoaderHelper;"
+ + "import org.apache.geode.cache.RegionEvent;"
+ + "import org.apache.geode.cache.util.CacheListenerAdapter;"
+ + "import org.apache.geode.compression.Compressor;" + "public class " + classname
+ + " extends CacheListenerAdapter "
+ + "implements CacheWriter, CacheLoader, Compressor, java.io.Serializable {"
+ + "public void beforeUpdate(EntryEvent event) throws CacheWriterException {}"
+ + "public void beforeCreate(EntryEvent event) throws CacheWriterException {}"
+ + "public void beforeDestroy(EntryEvent event) throws CacheWriterException {}"
+ + "public void beforeRegionDestroy(RegionEvent event) throws CacheWriterException {}"
+ + "public void beforeRegionClear(RegionEvent event) throws CacheWriterException {}"
+ + "public Object load(LoaderHelper helper) throws CacheLoaderException { return null; }"
+ + "public byte[] compress(byte[] input) { return new byte[0]; }"
+ + "public byte[] decompress(byte[] input) { return new byte[0]; }" + "}";
+ return code;
+ }
+
}
--
To stop receiving notification emails like this one, please contact
jensdeppe@apache.org.