Skip to content

Commit a45cbe9

Browse files
GEODE-10093 - Fixed attr issue in Delta Session (#7405) (#7413)
* GEODE-10093 - Fixed attr issue in Delta Session (cherry picked from commit e040759)
1 parent dede61d commit a45cbe9

File tree

2 files changed

+110
-3
lines changed

2 files changed

+110
-3
lines changed

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
@@ -254,7 +254,7 @@ public void setAttribute(String name, Object value, boolean notify) {
254254

255255
synchronized (changeLock) {
256256
// Serialize the value
257-
byte[] serializedValue = serialize(value);
257+
final byte[] serializedValue = value == null ? null : serialize(value);
258258

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

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

@@ -332,6 +334,9 @@ protected void setAttributeInternal(String name, Object value) {
332334

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

@@ -353,6 +358,10 @@ private Object deserializeAttribute(final String name, final Object value, final
353358
if (value instanceof byte[]) {
354359
try {
355360
final Object deserialized = BlobHelper.deserializeBlob((byte[]) value);
361+
if (deserialized == null) {
362+
removeAttributeInternal(name, false);
363+
return null;
364+
}
356365
if (store) {
357366
setAttributeInternal(name, deserialized);
358367
}
@@ -478,7 +487,7 @@ private void initializeRegion(DeltaSessionManager<?> sessionManager) {
478487
}
479488
}
480489

481-
private void queueAttributeEvent(DeltaSessionAttributeEvent event,
490+
void queueAttributeEvent(DeltaSessionAttributeEvent event,
482491
boolean checkAddToCurrentGatewayDelta) {
483492
// Add to current gateway delta if necessary
484493
if (checkAddToCurrentGatewayDelta) {

0 commit comments

Comments
 (0)