Skip to content

Commit 5be709c

Browse files
GEODE-4295: convert loaded PdxInstance (apache#1453)
If a loader returns a PdxInstance, and if the cache has pdx-read-serialized false, then the PdxInstance is now deserialized by calling PdxInstance.getObject. So a "get" of a loaded PdxInstance will now only be a PdxInstance if pdx-read-serialized is true or if PdxInstance.getObject returns a PdxInstance.
1 parent 7c5cd35 commit 5be709c

File tree

7 files changed

+117
-12
lines changed

7 files changed

+117
-12
lines changed

geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java

+9
Original file line numberDiff line numberDiff line change
@@ -5289,4 +5289,13 @@ public void invokeRegionEntrySynchronizationListenersAfterSynchronization(
52895289
}
52905290
}
52915291
}
5292+
5293+
@Override
5294+
public Object convertPdxInstanceIfNeeded(Object obj) {
5295+
Object result = obj;
5296+
if (!this.getPdxReadSerialized() && obj instanceof PdxInstance) {
5297+
result = ((PdxInstance) obj).getObject();
5298+
}
5299+
return result;
5300+
}
52925301
}

geode-core/src/main/java/org/apache/geode/internal/cache/HARegion.java

+1-7
Original file line numberDiff line numberDiff line change
@@ -363,13 +363,7 @@ protected Object findObjectInSystem(KeyInfo keyInfo, boolean isCreate, TXStateIn
363363
Assert.assertTrue(!hasServerProxy());
364364
CacheLoader loader = basicGetLoader();
365365
if (loader != null) {
366-
final LoaderHelper loaderHelper =
367-
loaderHelperFactory.createLoaderHelper(key, aCallbackArgument,
368-
false /* netSearchAllowed */, true /* netloadallowed */, null/* searcher */);
369-
try {
370-
value = loader.load(loaderHelper);
371-
} finally {
372-
}
366+
value = callCacheLoader(loader, key, aCallbackArgument);
373367

374368
if (value != null) {
375369
try {

geode-core/src/main/java/org/apache/geode/internal/cache/InternalCache.java

+9
Original file line numberDiff line numberDiff line change
@@ -346,4 +346,13 @@ void invokeRegionEntrySynchronizationListenersAfterSynchronization(
346346
Set<AsyncEventQueue> getAsyncEventQueues(boolean visibleOnly);
347347

348348
void closeDiskStores();
349+
350+
/**
351+
* If obj is a PdxInstance and pdxReadSerialized is not true
352+
* then convert obj by calling PdxInstance.getObject.
353+
*
354+
* @return either the original obj if no conversion was needed;
355+
* or the result of calling PdxInstance.getObject on obj.
356+
*/
357+
Object convertPdxInstanceIfNeeded(Object obj);
349358
}

geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java

+12-5
Original file line numberDiff line numberDiff line change
@@ -2770,14 +2770,11 @@ protected Object findObjectInSystem(KeyInfo keyInfo, boolean isCreate, TXStateIn
27702770
// copy into local var to prevent race condition
27712771
CacheLoader loader = basicGetLoader();
27722772
if (loader != null) {
2773-
final LoaderHelper loaderHelper =
2774-
this.loaderHelperFactory.createLoaderHelper(key, aCallbackArgument,
2775-
false /* netSearchAllowed */, true /* netloadAllowed */, null /* searcher */);
2773+
fromServer = false;
27762774
CachePerfStats stats = getCachePerfStats();
27772775
long statStart = stats.startLoad();
27782776
try {
2779-
value = loader.load(loaderHelper);
2780-
fromServer = false;
2777+
value = callCacheLoader(loader, key, aCallbackArgument);
27812778
} finally {
27822779
stats.endLoad(statStart);
27832780
}
@@ -2863,6 +2860,16 @@ protected Object findObjectInSystem(KeyInfo keyInfo, boolean isCreate, TXStateIn
28632860
return value;
28642861
}
28652862

2863+
@SuppressWarnings({"rawtypes", "unchecked"})
2864+
protected Object callCacheLoader(CacheLoader loader, final Object key,
2865+
final Object aCallbackArgument) {
2866+
LoaderHelper loaderHelper = this.loaderHelperFactory.createLoaderHelper(key, aCallbackArgument,
2867+
false /* netSearchAllowed */, true /* netloadAllowed */, null /* searcher */);
2868+
Object result = loader.load(loaderHelper);
2869+
result = this.getCache().convertPdxInstanceIfNeeded(result);
2870+
return result;
2871+
}
2872+
28662873
protected boolean isMemoryThresholdReachedForLoad() {
28672874
return this.memoryThresholdReached.get();
28682875
}

geode-core/src/main/java/org/apache/geode/internal/cache/SearchLoadAndWriteProcessor.java

+4
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,7 @@ private Object doLocalLoad(CacheLoader loader, boolean netSearchAllowed)
790790
long statStart = stats.startLoad();
791791
try {
792792
obj = loader.load(loaderHelper);
793+
obj = this.region.getCache().convertPdxInstanceIfNeeded(obj);
793794
} finally {
794795
stats.endLoad(statStart);
795796
}
@@ -2226,6 +2227,9 @@ private void doLoad(ClusterDistributionManager dm) {
22262227
long start = stats.startLoad();
22272228
try {
22282229
Object o = loader.load(loaderHelper);
2230+
// no need to call convertPdxInstanceIfNeeded since we are serializing
2231+
// this into the NetLoadRequestMessage. The loaded object will be deserialized
2232+
// on the other side and have the correct form in that member.
22292233
Assert.assertTrue(o != Token.INVALID && o != Token.LOCAL_INVALID);
22302234
NetLoadReplyMessage.sendMessage(NetLoadRequestMessage.this.getSender(), processorId,
22312235
o, dm, loaderHelper.getArgument(), null, false, false);

geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java

+5
Original file line numberDiff line numberDiff line change
@@ -2265,4 +2265,9 @@ public void invokeRegionEntrySynchronizationListenersAfterSynchronization(
22652265
List<InitialImageOperation.Entry> entriesToSynchronize) {
22662266
throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
22672267
}
2268+
2269+
@Override
2270+
public Object convertPdxInstanceIfNeeded(Object obj) {
2271+
throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
2272+
}
22682273
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
3+
* agreements. See the NOTICE file distributed with this work for additional information regarding
4+
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
5+
* "License"); you may not use this file except in compliance with the License. You may obtain a
6+
* copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software distributed under the License
11+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12+
* or implied. See the License for the specific language governing permissions and limitations under
13+
* the License.
14+
*/
15+
package org.apache.geode.pdx;
16+
17+
import static com.googlecode.catchexception.CatchException.catchException;
18+
import static com.googlecode.catchexception.CatchException.caughtException;
19+
import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
20+
import static org.assertj.core.api.Assertions.assertThat;
21+
22+
import org.junit.After;
23+
import org.junit.Before;
24+
import org.junit.Test;
25+
import org.junit.experimental.categories.Category;
26+
27+
import org.apache.geode.cache.Cache;
28+
import org.apache.geode.cache.CacheFactory;
29+
import org.apache.geode.cache.CacheLoader;
30+
import org.apache.geode.cache.CacheLoaderException;
31+
import org.apache.geode.cache.LoaderHelper;
32+
import org.apache.geode.cache.Region;
33+
import org.apache.geode.cache.RegionShortcut;
34+
import org.apache.geode.test.junit.categories.IntegrationTest;
35+
import org.apache.geode.test.junit.categories.SerializationTest;
36+
37+
@Category({IntegrationTest.class, SerializationTest.class})
38+
public class PdxInstanceLoaderIntegrationTest {
39+
40+
private Cache cache;
41+
42+
@Before
43+
public void setUp() {}
44+
45+
@After
46+
public void tearDown() {
47+
cache.close();
48+
}
49+
50+
private class PdxInstanceLoader implements CacheLoader {
51+
@Override
52+
public void close() {}
53+
54+
@Override
55+
public Object load(LoaderHelper helper) throws CacheLoaderException {
56+
return cache.createPdxInstanceFactory("no class name").create();
57+
}
58+
}
59+
60+
@Test
61+
public void loadOfPdxInstanceWithReadSerializedFalseAttemptsToDeserialize() {
62+
cache = new CacheFactory().set(MCAST_PORT, "0").setPdxReadSerialized(false).create();
63+
Region region = cache.createRegionFactory(RegionShortcut.LOCAL)
64+
.setCacheLoader(new PdxInstanceLoader()).create("region");
65+
catchException(region).get("key");
66+
assertThat((Exception) caughtException()).isInstanceOf(PdxSerializationException.class);
67+
}
68+
69+
@Test
70+
public void loadOfPdxInstanceWithReadSerializedTrueReturnsPdxInstance() {
71+
cache = new CacheFactory().set(MCAST_PORT, "0").setPdxReadSerialized(true).create();
72+
Region region = cache.createRegionFactory(RegionShortcut.LOCAL)
73+
.setCacheLoader(new PdxInstanceLoader()).create("region");
74+
Object obj = region.get("key");
75+
assertThat(obj).isInstanceOf(PdxInstance.class);
76+
}
77+
}

0 commit comments

Comments
 (0)