Skip to content

Commit 086885c

Browse files
GEODE-10093 - Fixed attr issue in Delta Session (#7405) (#7411)
* GEODE-10093 - Fixed attr issue in Delta Session (cherry picked from commit e040759)
1 parent f574632 commit 086885c

2 files changed

Lines changed: 110 additions & 3 deletions

File tree

extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/AbstractDeltaSessionIntegrationTest.java

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717

1818
import static org.apache.geode.cache.RegionShortcut.PARTITION;
1919
import static org.assertj.core.api.Assertions.assertThat;
20+
import static org.mockito.ArgumentMatchers.any;
21+
import static org.mockito.ArgumentMatchers.anyBoolean;
22+
import static org.mockito.ArgumentMatchers.eq;
2023
import static org.mockito.Mockito.mock;
2124
import static org.mockito.Mockito.spy;
25+
import static org.mockito.Mockito.times;
2226
import static org.mockito.Mockito.verify;
2327
import static org.mockito.Mockito.verifyNoMoreInteractions;
2428
import static org.mockito.Mockito.when;
@@ -35,11 +39,15 @@
3539
import org.junit.Rule;
3640
import org.junit.Test;
3741
import org.mockito.ArgumentCaptor;
42+
import org.mockito.InOrder;
43+
import org.mockito.Mockito;
3844

3945
import org.apache.geode.cache.Region;
4046
import org.apache.geode.internal.util.BlobHelper;
4147
import org.apache.geode.modules.session.catalina.callback.SessionExpirationCacheListener;
48+
import org.apache.geode.modules.session.catalina.internal.DeltaSessionDestroyAttributeEvent;
4249
import org.apache.geode.modules.session.catalina.internal.DeltaSessionStatistics;
50+
import org.apache.geode.modules.session.catalina.internal.DeltaSessionUpdateAttributeEvent;
4351
import org.apache.geode.test.junit.rules.ServerStarterRule;
4452

4553
public abstract class AbstractDeltaSessionIntegrationTest<DeltaSessionManagerT extends DeltaSessionManager<?>, DeltaSessionT extends DeltaSession> {
@@ -107,4 +115,94 @@ public void serializedAttributesNotLeakedWhenSessionInvalidated() throws IOExcep
107115
verifyNoMoreInteractions(listener);
108116
assertThat(event.getValue().getValue()).isEqualTo(value1);
109117
}
118+
119+
@Test
120+
public void setNewAttributeWithNullValueInvokesRemove() {
121+
final HttpSessionAttributeListener listener = mock(HttpSessionAttributeListener.class);
122+
when(context.getApplicationEventListeners()).thenReturn(new Object[] {listener});
123+
when(manager.isBackingCacheAvailable()).thenReturn(true);
124+
125+
final DeltaSessionT session = spy(newSession(manager));
126+
session.setId(KEY, false);
127+
session.setValid(true);
128+
session.setOwner(manager);
129+
130+
final String name = "attribute";
131+
final Object nullValue = null;
132+
133+
session.setAttribute(name, nullValue);
134+
assertThat(session.getAttributes().size()).isEqualTo(0);
135+
136+
verify(session).queueAttributeEvent(any(DeltaSessionDestroyAttributeEvent.class), anyBoolean());
137+
verify(session, times(0)).queueAttributeEvent(any(DeltaSessionUpdateAttributeEvent.class),
138+
anyBoolean());
139+
verify(session).removeAttribute(eq(name));
140+
}
141+
142+
@Test
143+
public void setExistingAttributeWithNullValueInvokesRemove() {
144+
final HttpSessionAttributeListener listener = mock(HttpSessionAttributeListener.class);
145+
when(context.getApplicationEventListeners()).thenReturn(new Object[] {listener});
146+
when(manager.isBackingCacheAvailable()).thenReturn(true);
147+
148+
final DeltaSessionT session = spy(newSession(manager));
149+
session.setId(KEY, false);
150+
session.setValid(true);
151+
session.setOwner(manager);
152+
153+
final String name = "attribute";
154+
final Object value = "value";
155+
final Object nullValue = null;
156+
157+
session.setAttribute(name, value);
158+
assertThat(session.getAttributes().size()).isEqualTo(1);
159+
160+
session.setAttribute(name, nullValue);
161+
assertThat(session.getAttributes().size()).isEqualTo(0);
162+
163+
164+
InOrder inOrder = Mockito.inOrder(session);
165+
inOrder.verify(session).queueAttributeEvent(any(DeltaSessionUpdateAttributeEvent.class),
166+
anyBoolean());
167+
inOrder.verify(session).removeAttribute(eq(name));
168+
inOrder.verify(session).queueAttributeEvent(any(DeltaSessionDestroyAttributeEvent.class),
169+
anyBoolean());
170+
}
171+
172+
@Test
173+
public void getAttributeWithNullValueReturnsNull() throws IOException, ClassNotFoundException {
174+
final HttpSessionAttributeListener listener = mock(HttpSessionAttributeListener.class);
175+
when(context.getApplicationEventListeners()).thenReturn(new Object[] {listener});
176+
when(manager.isBackingCacheAvailable()).thenReturn(true);
177+
178+
final DeltaSessionT session = spy(newSession(manager));
179+
session.setId(KEY, false);
180+
session.setValid(true);
181+
session.setOwner(manager);
182+
183+
final String name = "attribute";
184+
final Object value = null;
185+
186+
final byte[] serializedValue1 = BlobHelper.serializeToBlob(value);
187+
// simulates initial deserialized state with serialized attribute values.
188+
session.getAttributes().put(name, serializedValue1);
189+
190+
assertThat(session.getAttribute(name)).isNull();
191+
}
192+
193+
@Test
194+
public void getAttributeWithNullNameReturnsNull() throws IOException, ClassNotFoundException {
195+
final HttpSessionAttributeListener listener = mock(HttpSessionAttributeListener.class);
196+
when(context.getApplicationEventListeners()).thenReturn(new Object[] {listener});
197+
when(manager.isBackingCacheAvailable()).thenReturn(true);
198+
199+
final DeltaSessionT session = spy(newSession(manager));
200+
session.setId(KEY, false);
201+
session.setValid(true);
202+
session.setOwner(manager);
203+
204+
final String name = null;
205+
206+
assertThat(session.getAttribute(name)).isNull();
207+
}
110208
}

extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ public void setAttribute(String name, Object value, boolean notify) {
253253

254254
synchronized (changeLock) {
255255
// Serialize the value
256-
byte[] serializedValue = serialize(value);
256+
final byte[] serializedValue = value == null ? null : serialize(value);
257257

258258
// Store the attribute locally
259259
if (preferDeserializedForm) {
@@ -265,7 +265,9 @@ public void setAttribute(String name, Object value, boolean notify) {
265265
super.setAttribute(name, serializedValue, true);
266266
}
267267

268-
if (serializedValue == null) {
268+
// super.setAttribute above performed a removeAttribute for a value which was null once
269+
// deserialized.
270+
if (value == null) {
269271
return;
270272
}
271273

@@ -331,6 +333,9 @@ protected void setAttributeInternal(String name, Object value) {
331333

332334
@Override
333335
public Object getAttribute(String name) {
336+
if (name == null) {
337+
return null;
338+
}
334339
checkBackingCacheAvailable();
335340
Object value = deserializeAttribute(name, super.getAttribute(name), preferDeserializedForm);
336341

@@ -352,6 +357,10 @@ private Object deserializeAttribute(final String name, final Object value, final
352357
if (value instanceof byte[]) {
353358
try {
354359
final Object deserialized = BlobHelper.deserializeBlob((byte[]) value);
360+
if (deserialized == null) {
361+
removeAttributeInternal(name, false);
362+
return null;
363+
}
355364
if (store) {
356365
setAttributeInternal(name, deserialized);
357366
}
@@ -477,7 +486,7 @@ private void initializeRegion(DeltaSessionManager<?> sessionManager) {
477486
}
478487
}
479488

480-
private void queueAttributeEvent(DeltaSessionAttributeEvent event,
489+
void queueAttributeEvent(DeltaSessionAttributeEvent event,
481490
boolean checkAddToCurrentGatewayDelta) {
482491
// Add to current gateway delta if necessary
483492
if (checkAddToCurrentGatewayDelta) {

0 commit comments

Comments
 (0)