You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by jb...@apache.org on 2020/06/19 17:39:15 UTC
[geode] branch develop updated: GEODE-8221: Commits session data
prior to sending output to browser (#5246)
This is an automated email from the ASF dual-hosted git repository.
jbarrett 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 9939cc0 GEODE-8221: Commits session data prior to sending output to browser (#5246)
9939cc0 is described below
commit 9939cc0f2f1caad051bd104a0a06a4e1737d3830
Author: Jacob Barrett <jb...@pivotal.io>
AuthorDate: Fri Jun 19 10:38:46 2020 -0700
GEODE-8221: Commits session data prior to sending output to browser (#5246)
* Refactors abstraction of CommitSessionValve.
* Wraps Coyote OutputBuffer to commit sessions when data is sent to client.
---
extensions/geode-modules-test/build.gradle | 15 +-
...AbstractCommitSessionValveIntegrationTest.java} | 42 +-
.../AbstractSessionValveIntegrationTest.java | 0
extensions/geode-modules-tomcat7/build.gradle | 1 +
.../CommitSessionValveIntegrationTest.java | 57 ++
.../catalina/Tomcat7CommitSessionOutputBuffer.java | 53 ++
.../catalina/Tomcat7CommitSessionValve.java | 58 ++
.../catalina/Tomcat7DeltaSessionManager.java | 12 +-
.../Tomcat7CommitSessionOutputBufferTest.java | 63 +++
.../catalina/Tomcat7CommitSessionValveTest.java | 98 ++++
extensions/geode-modules-tomcat8/build.gradle | 108 ++--
.../CommitSessionValveIntegrationTest.java | 57 ++
.../modules/session/catalina/DeltaSession8.java | 1 +
.../catalina/Tomcat8CommitSessionOutputBuffer.java | 60 ++
.../catalina/Tomcat8CommitSessionValve.java | 59 ++
.../catalina/Tomcat8DeltaSessionManager.java | 8 +-
.../Tomcat8CommitSessionOutputBufferTest.java | 77 +++
.../catalina/Tomcat8CommitSessionValveTest.java | 98 ++++
extensions/geode-modules-tomcat9/build.gradle | 15 +-
.../CommitSessionValveIntegrationTest.java | 52 ++
.../catalina/Tomcat9CommitSessionOutputBuffer.java | 53 ++
.../catalina/Tomcat9CommitSessionValve.java | 58 ++
.../catalina/Tomcat9DeltaSessionManager.java | 7 +-
.../Tomcat9CommitSessionOutputBufferTest.java | 60 ++
.../catalina/Tomcat9CommitSessionValveTest.java | 94 ++++
.../catalina/AbstractCommitSessionValve.java | 83 +++
.../session/catalina/CommitSessionValve.java | 69 ---
.../session/catalina/DeltaSessionManager.java | 9 +-
.../session/catalina/SessionCommitter.java} | 26 +-
.../catalina/Tomcat6CommitSessionValve.java} | 26 +-
.../catalina/Tomcat6DeltaSessionManager.java | 7 +-
geode-assembly/geode-assembly-test/build.gradle | 2 +
.../integrationTest/resources/assembly_content.txt | 6 +-
geode-core/build.gradle | 612 ++++++++++-----------
34 files changed, 1534 insertions(+), 512 deletions(-)
diff --git a/extensions/geode-modules-test/build.gradle b/extensions/geode-modules-test/build.gradle
index 9b9ee95..936c5f6 100644
--- a/extensions/geode-modules-test/build.gradle
+++ b/extensions/geode-modules-test/build.gradle
@@ -20,17 +20,20 @@ import org.apache.geode.gradle.plugins.DependencyConstraints
apply from: "${rootDir}/${scriptDir}/standard-subproject-configuration.gradle"
-
dependencies {
- compile(platform(project(':boms:geode-all-bom')))
- compile(project(':extensions:geode-modules')) {
+ implementation(platform(project(':boms:geode-all-bom')))
+ implementation(project(':extensions:geode-modules')) {
// Remove everything related to Tomcat 6.x
exclude group: 'org.apache.tomcat'
}
- compile(project(':geode-core'))
+ implementation(project(':geode-core'))
implementation(project(':geode-logging'))
- compile(project(':geode-junit')) {
+ implementation(project(':geode-junit')) {
+ exclude module: 'geode-core'
+ }
+
+ implementation(project(':geode-dunit')) {
exclude module: 'geode-core'
}
@@ -44,10 +47,10 @@ dependencies {
// this version of httpunit contains very outdated xercesImpl
exclude group: 'xerces'
}
+ implementation('pl.pragmatists:JUnitParams')
compileOnly('org.apache.tomcat:catalina-ha:' + DependencyConstraints.get('tomcat6.version')) {
exclude module: 'annotations-api'
- exclude module: 'coyote'
exclude module: 'tribes'
}
}
diff --git a/extensions/geode-modules/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/AbstractCommitSessionValveIntegrationTest.java
similarity index 83%
rename from extensions/geode-modules/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java
rename to extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/AbstractCommitSessionValveIntegrationTest.java
index c7e056e..7849d99 100644
--- a/extensions/geode-modules/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/AbstractCommitSessionValveIntegrationTest.java
@@ -19,7 +19,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -35,35 +34,34 @@ import org.apache.catalina.Manager;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.juli.logging.Log;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.apache.geode.cache.RegionShortcut;
@RunWith(JUnitParamsRunner.class)
-public class CommitSessionValveIntegrationTest extends AbstractSessionValveIntegrationTest {
- private Request request;
- private Response response;
- private TestValve testValve;
- private CommitSessionValve commitSessionValve;
- private DeltaSessionFacade deltaSessionFacade;
-
- @Before
- public void setUp() {
- request = spy(Request.class);
- response = spy(Response.class);
+public abstract class AbstractCommitSessionValveIntegrationTest<CommitSessionValveT extends AbstractCommitSessionValve<CommitSessionValveT>>
+ extends AbstractSessionValveIntegrationTest {
+ protected Request request;
+ protected Response response;
+ protected final TestValve testValve;
+ protected final CommitSessionValveT commitSessionValve;
+ protected DeltaSessionFacade deltaSessionFacade;
+
+ public AbstractCommitSessionValveIntegrationTest() {
testValve = new TestValve(false);
- commitSessionValve = new CommitSessionValve();
+ commitSessionValve = createCommitSessionValve();
commitSessionValve.setNext(testValve);
}
- protected void parameterizedSetUp(RegionShortcut regionShortcut) {
+ protected abstract CommitSessionValveT createCommitSessionValve();
+
+ @Override
+ protected void parameterizedSetUp(final RegionShortcut regionShortcut) {
super.parameterizedSetUp(regionShortcut);
deltaSessionFacade = new DeltaSessionFacade(deltaSession);
- when(request.getContext()).thenReturn(mock(Context.class));
// Valve use the context to log messages
when(deltaSessionManager.getTheContext()).thenReturn(mock(Context.class));
@@ -73,7 +71,7 @@ public class CommitSessionValveIntegrationTest extends AbstractSessionValveInteg
@Test
@Parameters({"REPLICATE", "PARTITION"})
public void invokeShouldCallNextChainedValveAndDoNothingWhenSessionManagerDoesNotBelongToGeode(
- RegionShortcut regionShortcut) throws IOException, ServletException {
+ final RegionShortcut regionShortcut) throws IOException, ServletException {
parameterizedSetUp(regionShortcut);
when(request.getContext().getManager()).thenReturn(mock(Manager.class));
@@ -85,7 +83,7 @@ public class CommitSessionValveIntegrationTest extends AbstractSessionValveInteg
@Test
@Parameters({"REPLICATE", "PARTITION"})
public void invokeShouldCallNextChainedValveAndDoNothingWhenSessionManagerBelongsToGeodeButSessionDoesNotExist(
- RegionShortcut regionShortcut) throws IOException, ServletException {
+ final RegionShortcut regionShortcut) throws IOException, ServletException {
parameterizedSetUp(regionShortcut);
doReturn(null).when(request).getSession(false);
when(request.getContext().getManager()).thenReturn(deltaSessionManager);
@@ -99,7 +97,7 @@ public class CommitSessionValveIntegrationTest extends AbstractSessionValveInteg
@Test
@Parameters({"REPLICATE", "PARTITION"})
public void invokeShouldCallNextChainedValveAndDoNothingWhenSessionManagerBelongsToGeodeAndSessionExistsButIsNotValid(
- RegionShortcut regionShortcut) throws IOException, ServletException {
+ final RegionShortcut regionShortcut) throws IOException, ServletException {
parameterizedSetUp(regionShortcut);
doReturn(false).when(deltaSession).isValid();
doReturn(deltaSessionFacade).when(request).getSession(false);
@@ -114,7 +112,7 @@ public class CommitSessionValveIntegrationTest extends AbstractSessionValveInteg
@Test
@Parameters({"REPLICATE", "PARTITION"})
public void invokeShouldCallNextChainedValveAndCommitTheExistingValidSessionWhenSessionManagerBelongsToGeode(
- RegionShortcut regionShortcut) throws IOException, ServletException {
+ final RegionShortcut regionShortcut) throws IOException, ServletException {
parameterizedSetUp(regionShortcut);
deltaSessionManager.addSessionToTouch(TEST_SESSION_ID);
doReturn(deltaSessionFacade).when(request).getSession(false);
@@ -129,9 +127,9 @@ public class CommitSessionValveIntegrationTest extends AbstractSessionValveInteg
@Test
@Parameters({"REPLICATE", "PARTITION"})
public void invokeShouldCommitTheExistingValidSessionWhenSessionManagerBelongsToGeodeEvenWhenTheNextChainedValveThrowsAnException(
- RegionShortcut regionShortcut) {
+ final RegionShortcut regionShortcut) {
parameterizedSetUp(regionShortcut);
- TestValve exceptionValve = new TestValve(true);
+ final TestValve exceptionValve = new TestValve(true);
commitSessionValve.setNext(exceptionValve);
deltaSessionManager.addSessionToTouch(TEST_SESSION_ID);
doReturn(deltaSessionFacade).when(request).getSession(false);
diff --git a/extensions/geode-modules/src/integrationTest/java/org/apache/geode/modules/session/catalina/AbstractSessionValveIntegrationTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/AbstractSessionValveIntegrationTest.java
similarity index 100%
rename from extensions/geode-modules/src/integrationTest/java/org/apache/geode/modules/session/catalina/AbstractSessionValveIntegrationTest.java
rename to extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/AbstractSessionValveIntegrationTest.java
diff --git a/extensions/geode-modules-tomcat7/build.gradle b/extensions/geode-modules-tomcat7/build.gradle
index bb3e677..eb94f5b 100644
--- a/extensions/geode-modules-tomcat7/build.gradle
+++ b/extensions/geode-modules-tomcat7/build.gradle
@@ -18,6 +18,7 @@ import org.apache.geode.gradle.plugins.DependencyConstraints
*/
apply from: "${rootDir}/${scriptDir}/standard-subproject-configuration.gradle"
+apply from: "${rootDir}/${scriptDir}/warnings.gradle"
evaluationDependsOn(":geode-core")
diff --git a/extensions/geode-modules-tomcat7/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java b/extensions/geode-modules-tomcat7/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java
new file mode 100644
index 0000000..b64e862
--- /dev/null
+++ b/extensions/geode-modules-tomcat7/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.modules.session.catalina;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.coyote.OutputBuffer;
+import org.apache.juli.logging.Log;
+import org.junit.Before;
+
+public class CommitSessionValveIntegrationTest
+ extends AbstractCommitSessionValveIntegrationTest<Tomcat7CommitSessionValve> {
+
+ @Before
+ public void setUp() {
+ final Context context = mock(Context.class);
+ doReturn(mock(Log.class)).when(context).getLogger();
+
+ request = mock(Request.class);
+ doReturn(context).when(request).getContext();
+
+ final OutputBuffer outputBuffer = mock(OutputBuffer.class);
+
+ final org.apache.coyote.Response coyoteResponse = new org.apache.coyote.Response();
+ coyoteResponse.setOutputBuffer(outputBuffer);
+
+ response = new Response();
+ response.setConnector(mock(Connector.class));
+ response.setRequest(request);
+ response.setCoyoteResponse(coyoteResponse);
+ }
+
+
+ @Override
+ protected Tomcat7CommitSessionValve createCommitSessionValve() {
+ return new Tomcat7CommitSessionValve();
+ }
+
+}
diff --git a/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionOutputBuffer.java b/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionOutputBuffer.java
new file mode 100644
index 0000000..fcf01b2
--- /dev/null
+++ b/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionOutputBuffer.java
@@ -0,0 +1,53 @@
+/*
+ * 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.modules.session.catalina;
+
+import java.io.IOException;
+
+import org.apache.coyote.OutputBuffer;
+import org.apache.coyote.Response;
+import org.apache.tomcat.util.buf.ByteChunk;
+
+/**
+ * Delegating {@link OutputBuffer} that commits sessions on write through. Output data is buffered
+ * ahead of this object and flushed through this interface when full or explicitly flushed.
+ */
+class Tomcat7CommitSessionOutputBuffer implements OutputBuffer {
+
+ private final SessionCommitter sessionCommitter;
+ private final OutputBuffer delegate;
+
+ public Tomcat7CommitSessionOutputBuffer(final SessionCommitter sessionCommitter,
+ final OutputBuffer delegate) {
+ this.sessionCommitter = sessionCommitter;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public int doWrite(final ByteChunk chunk, final Response response) throws IOException {
+ sessionCommitter.commit();
+ return delegate.doWrite(chunk, response);
+ }
+
+ @Override
+ public long getBytesWritten() {
+ return delegate.getBytesWritten();
+ }
+
+ OutputBuffer getDelegate() {
+ return delegate;
+ }
+}
diff --git a/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionValve.java b/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionValve.java
new file mode 100644
index 0000000..f6a4839
--- /dev/null
+++ b/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionValve.java
@@ -0,0 +1,58 @@
+/*
+ * 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.modules.session.catalina;
+
+import java.lang.reflect.Field;
+
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.coyote.OutputBuffer;
+
+public class Tomcat7CommitSessionValve
+ extends AbstractCommitSessionValve<Tomcat7CommitSessionValve> {
+
+ private static final Field outputBufferField;
+
+ static {
+ try {
+ outputBufferField = org.apache.coyote.Response.class.getDeclaredField("outputBuffer");
+ outputBufferField.setAccessible(true);
+ } catch (final NoSuchFieldException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ Response wrapResponse(final Response response) {
+ final org.apache.coyote.Response coyoteResponse = response.getCoyoteResponse();
+ final OutputBuffer delegateOutputBuffer = getOutputBuffer(coyoteResponse);
+ if (!(delegateOutputBuffer instanceof Tomcat7CommitSessionOutputBuffer)) {
+ final Request request = response.getRequest();
+ final OutputBuffer sessionCommitOutputBuffer =
+ new Tomcat7CommitSessionOutputBuffer(() -> commitSession(request), delegateOutputBuffer);
+ coyoteResponse.setOutputBuffer(sessionCommitOutputBuffer);
+ }
+ return response;
+ }
+
+ static OutputBuffer getOutputBuffer(final org.apache.coyote.Response coyoteResponse) {
+ try {
+ return (OutputBuffer) outputBufferField.get(coyoteResponse);
+ } catch (final IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
diff --git a/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7DeltaSessionManager.java b/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7DeltaSessionManager.java
index e965cc5..b6d304a 100644
--- a/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7DeltaSessionManager.java
+++ b/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7DeltaSessionManager.java
@@ -20,14 +20,15 @@ import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.LifecycleState;
import org.apache.catalina.session.StandardSession;
-import org.apache.catalina.util.LifecycleSupport;
-public class Tomcat7DeltaSessionManager extends DeltaSessionManager {
+public class Tomcat7DeltaSessionManager extends DeltaSessionManager<Tomcat7CommitSessionValve> {
/**
* The <code>LifecycleSupport</code> for this component.
*/
- protected LifecycleSupport lifecycle = new LifecycleSupport(this);
+ @SuppressWarnings("deprecation")
+ protected org.apache.catalina.util.LifecycleSupport lifecycle =
+ new org.apache.catalina.util.LifecycleSupport(this);
/**
* Prepare for the beginning of active use of the public methods of this component. This method
@@ -165,4 +166,9 @@ public class Tomcat7DeltaSessionManager extends DeltaSessionManager {
return new DeltaSession7(this);
}
+ @Override
+ protected Tomcat7CommitSessionValve createCommitSessionValve() {
+ return new Tomcat7CommitSessionValve();
+ }
+
}
diff --git a/extensions/geode-modules-tomcat7/src/test/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionOutputBufferTest.java b/extensions/geode-modules-tomcat7/src/test/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionOutputBufferTest.java
new file mode 100644
index 0000000..20facaf
--- /dev/null
+++ b/extensions/geode-modules-tomcat7/src/test/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionOutputBufferTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.modules.session.catalina;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+
+import org.apache.coyote.OutputBuffer;
+import org.apache.coyote.Response;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.junit.Test;
+import org.mockito.InOrder;
+
+public class Tomcat7CommitSessionOutputBufferTest {
+
+ final SessionCommitter sessionCommitter = mock(SessionCommitter.class);
+ final OutputBuffer delegate = mock(OutputBuffer.class);
+
+ final Tomcat7CommitSessionOutputBuffer commitSesssionOutputBuffer =
+ new Tomcat7CommitSessionOutputBuffer(sessionCommitter, delegate);
+
+ @Test
+ public void doWrite() throws IOException {
+ final ByteChunk byteChunk = new ByteChunk();
+ final Response response = new Response();
+
+ commitSesssionOutputBuffer.doWrite(byteChunk, response);
+
+ final InOrder inOrder = inOrder(sessionCommitter, delegate);
+ inOrder.verify(sessionCommitter).commit();
+ inOrder.verify(delegate).doWrite(byteChunk, response);
+ inOrder.verifyNoMoreInteractions();
+ }
+
+
+ @Test
+ public void getBytesWritten() {
+ when(delegate.getBytesWritten()).thenReturn(42L);
+
+ assertThat(commitSesssionOutputBuffer.getBytesWritten()).isEqualTo(42L);
+
+ final InOrder inOrder = inOrder(sessionCommitter, delegate);
+ inOrder.verify(delegate).getBytesWritten();
+ inOrder.verifyNoMoreInteractions();
+ }
+}
diff --git a/extensions/geode-modules-tomcat7/src/test/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionValveTest.java b/extensions/geode-modules-tomcat7/src/test/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionValveTest.java
new file mode 100644
index 0000000..c9be9b2
--- /dev/null
+++ b/extensions/geode-modules-tomcat7/src/test/java/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionValveTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.modules.session.catalina;
+
+import static org.apache.geode.modules.session.catalina.Tomcat7CommitSessionValve.getOutputBuffer;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.coyote.OutputBuffer;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+
+
+public class Tomcat7CommitSessionValveTest {
+
+ private final Tomcat7CommitSessionValve valve = new Tomcat7CommitSessionValve();
+ private final OutputBuffer outputBuffer = mock(OutputBuffer.class);
+ private Response response;
+ private org.apache.coyote.Response coyoteResponse;
+
+ @Before
+ public void before() {
+ final Connector connector = mock(Connector.class);
+
+ final Context context = mock(Context.class);
+
+ final Request request = mock(Request.class);
+ doReturn(context).when(request).getContext();
+
+ coyoteResponse = new org.apache.coyote.Response();
+ coyoteResponse.setOutputBuffer(outputBuffer);
+
+ response = new Response();
+ response.setConnector(connector);
+ response.setRequest(request);
+ response.setCoyoteResponse(coyoteResponse);
+ }
+
+ @Test
+ public void wrappedOutputBufferForwardsToDelegate() throws IOException {
+ wrappedOutputBufferForwardsToDelegate(new byte[] {'a', 'b', 'c'});
+ }
+
+ @Test
+ public void recycledResponseObjectDoesNotWrapAlreadyWrappedOutputBuffer() throws IOException {
+ wrappedOutputBufferForwardsToDelegate(new byte[] {'a', 'b', 'c'});
+ response.recycle();
+ reset(outputBuffer);
+ wrappedOutputBufferForwardsToDelegate(new byte[] {'d', 'e', 'f'});
+ }
+
+ private void wrappedOutputBufferForwardsToDelegate(final byte[] bytes) throws IOException {
+ final OutputStream outputStream =
+ valve.wrapResponse(response).getResponse().getOutputStream();
+ outputStream.write(bytes);
+ outputStream.flush();
+
+ final ArgumentCaptor<ByteChunk> byteChunk = ArgumentCaptor.forClass(ByteChunk.class);
+
+ final InOrder inOrder = inOrder(outputBuffer);
+ inOrder.verify(outputBuffer).doWrite(byteChunk.capture(), any());
+ inOrder.verifyNoMoreInteractions();
+
+ final OutputBuffer wrappedOutputBuffer = getOutputBuffer(coyoteResponse);
+ assertThat(wrappedOutputBuffer).isInstanceOf(Tomcat7CommitSessionOutputBuffer.class);
+ assertThat(((Tomcat7CommitSessionOutputBuffer) wrappedOutputBuffer).getDelegate())
+ .isNotInstanceOf(Tomcat7CommitSessionOutputBuffer.class);
+
+ assertThat(byteChunk.getValue().getBytes()).contains(bytes);
+ }
+}
diff --git a/extensions/geode-modules-tomcat8/build.gradle b/extensions/geode-modules-tomcat8/build.gradle
index 0303583..ad7f483 100644
--- a/extensions/geode-modules-tomcat8/build.gradle
+++ b/extensions/geode-modules-tomcat8/build.gradle
@@ -17,72 +17,76 @@ import org.apache.geode.gradle.plugins.DependencyConstraints
* limitations under the License.
*/
+plugins {
+ id 'me.champeau.gradle.jmh' version '0.4.8'
+}
+
apply from: "${rootDir}/${scriptDir}/standard-subproject-configuration.gradle"
+apply from: "${rootDir}/${scriptDir}/warnings.gradle"
evaluationDependsOn(":geode-core")
-
dependencies {
- compile(platform(project(':boms:geode-all-bom')))
- distributedTestImplementation('junit:junit')
- implementation('mx4j:mx4j')
- distributedTestImplementation(project(':geode-logging'))
- testImplementation('org.httpunit:httpunit')
- testImplementation('org.apache.tomcat:tomcat-jaspic-api:' + DependencyConstraints.get('tomcat8.version'))
- testImplementation('org.httpunit:httpunit')
- testImplementation('junit:junit')
- testImplementation('org.assertj:assertj-core')
- testImplementation('org.mockito:mockito-core')
- testImplementation(project(':extensions:geode-modules-test'))
- distributedTestImplementation('org.httpunit:httpunit')
- distributedTestImplementation('org.apache.tomcat:tomcat-jaspic-api:' + DependencyConstraints.get('tomcat8.version'))
- distributedTestImplementation('org.springframework:spring-core')
- compile(project(':geode-core'))
- compile(project(':extensions:geode-modules')) {
- exclude group: 'org.apache.tomcat'
- }
- testImplementation(project(':extensions:geode-modules')) {
- exclude group: 'org.apache.tomcat'
- }
+ compile(platform(project(':boms:geode-all-bom')))
+ distributedTestImplementation('junit:junit')
+ implementation('mx4j:mx4j')
+ distributedTestImplementation(project(':geode-logging'))
+ testImplementation('org.httpunit:httpunit')
+ testImplementation('org.apache.tomcat:tomcat-jaspic-api:' + DependencyConstraints.get('tomcat8.version'))
+ testImplementation('org.httpunit:httpunit')
+ testImplementation('junit:junit')
+ testImplementation('org.assertj:assertj-core')
+ testImplementation('org.mockito:mockito-core')
+ testImplementation(project(':extensions:geode-modules-test'))
+ distributedTestImplementation('org.httpunit:httpunit')
+ distributedTestImplementation('org.apache.tomcat:tomcat-jaspic-api:' + DependencyConstraints.get('tomcat8.version'))
+ distributedTestImplementation('org.springframework:spring-core')
+ compile(project(':geode-core'))
+ compile(project(':extensions:geode-modules')) {
+ exclude group: 'org.apache.tomcat'
+ }
+ testImplementation(project(':extensions:geode-modules')) {
+ exclude group: 'org.apache.tomcat'
+ }
- implementation('org.apache.tomcat:tomcat-catalina:' + DependencyConstraints.get('tomcat8.version')) {
- exclude module: 'tomcat-annotations-api'
- exclude module: 'tomcat-servlet-api'
- }
- implementation('org.apache.tomcat:tomcat-coyote:' + DependencyConstraints.get('tomcat8.version')) {
- exclude module: 'tomcat-servlet-api'
- }
- implementation('org.apache.tomcat:tomcat-juli:' + DependencyConstraints.get('tomcat8.version'))
- implementation('javax.servlet:javax.servlet-api')
+ implementation('org.apache.tomcat:tomcat-catalina:' + DependencyConstraints.get('tomcat8.version')) {
+ exclude module: 'tomcat-annotations-api'
+ exclude module: 'tomcat-servlet-api'
+ }
+ implementation('org.apache.tomcat:tomcat-coyote:' + DependencyConstraints.get('tomcat8.version')) {
+ exclude module: 'tomcat-servlet-api'
+ }
+ implementation('org.apache.tomcat:tomcat-juli:' + DependencyConstraints.get('tomcat8.version'))
+ implementation('javax.servlet:javax.servlet-api')
- integrationTestImplementation(project(':geode-dunit')) {
- exclude module: 'geode-core'
- }
- integrationTestImplementation(project(':geode-junit')) {
- exclude module: 'geode-core'
- }
- integrationTestImplementation(project(':extensions:geode-modules-test'))
- integrationTestRuntimeOnly('xerces:xercesImpl')
- integrationTestRuntimeOnly('javax.annotation:javax.annotation-api')
+ integrationTestImplementation(project(':geode-dunit')) {
+ exclude module: 'geode-core'
+ }
+ integrationTestImplementation(project(':geode-junit')) {
+ exclude module: 'geode-core'
+ }
+ integrationTestImplementation(project(':extensions:geode-modules-test'))
+ integrationTestRuntimeOnly('xerces:xercesImpl')
+ integrationTestRuntimeOnly('javax.annotation:javax.annotation-api')
- distributedTestImplementation(project(':geode-dunit')) {
- exclude module: 'geode-core'
- }
+ distributedTestImplementation(project(':geode-dunit')) {
+ exclude module: 'geode-core'
+ }
- distributedTestImplementation(project(':geode-junit')) {
- exclude module: 'geode-core'
- }
- distributedTestImplementation(project(':extensions:geode-modules-test'))
+ distributedTestImplementation(project(':geode-junit')) {
+ exclude module: 'geode-core'
+ }
+ distributedTestImplementation(project(':extensions:geode-modules-test'))
- distributedTestRuntimeOnly('xerces:xercesImpl')
- distributedTestRuntimeOnly('javax.annotation:javax.annotation-api')
+ distributedTestRuntimeOnly('xerces:xercesImpl')
+ distributedTestRuntimeOnly('javax.annotation:javax.annotation-api')
}
eclipse.classpath.file {
- whenMerged { classpath ->
- classpath.entries.removeAll { entry -> entry.path.contains('geode-modules/build')}
- }
+ whenMerged { classpath ->
+ classpath.entries.removeAll { entry -> entry.path.contains('geode-modules/build') }
+ }
}
diff --git a/extensions/geode-modules-tomcat8/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java b/extensions/geode-modules-tomcat8/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java
new file mode 100644
index 0000000..79df936
--- /dev/null
+++ b/extensions/geode-modules-tomcat8/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.modules.session.catalina;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.coyote.OutputBuffer;
+import org.apache.juli.logging.Log;
+import org.junit.Before;
+
+public class CommitSessionValveIntegrationTest
+ extends AbstractCommitSessionValveIntegrationTest<Tomcat8CommitSessionValve> {
+
+ @Before
+ public void setUp() {
+ final Context context = mock(Context.class);
+ doReturn(mock(Log.class)).when(context).getLogger();
+
+ request = mock(Request.class);
+ doReturn(context).when(request).getContext();
+
+ final OutputBuffer outputBuffer = mock(OutputBuffer.class);
+
+ final org.apache.coyote.Response coyoteResponse = new org.apache.coyote.Response();
+ coyoteResponse.setOutputBuffer(outputBuffer);
+
+ response = new Response();
+ response.setConnector(mock(Connector.class));
+ response.setRequest(request);
+ response.setCoyoteResponse(coyoteResponse);
+ }
+
+
+ @Override
+ protected Tomcat8CommitSessionValve createCommitSessionValve() {
+ return new Tomcat8CommitSessionValve();
+ }
+
+}
diff --git a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession8.java b/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession8.java
index a17fdde..c2ea5c5 100644
--- a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession8.java
+++ b/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession8.java
@@ -12,6 +12,7 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
+
package org.apache.geode.modules.session.catalina;
import org.apache.catalina.Manager;
diff --git a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionOutputBuffer.java b/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionOutputBuffer.java
new file mode 100644
index 0000000..4197b59
--- /dev/null
+++ b/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionOutputBuffer.java
@@ -0,0 +1,60 @@
+/*
+ * 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.modules.session.catalina;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.apache.coyote.OutputBuffer;
+import org.apache.tomcat.util.buf.ByteChunk;
+
+/**
+ * Delegating {@link OutputBuffer} that commits sessions on write through. Output data is buffered
+ * ahead of this object and flushed through this interface when full or explicitly flushed.
+ */
+class Tomcat8CommitSessionOutputBuffer implements OutputBuffer {
+
+ private final SessionCommitter sessionCommitter;
+ private final OutputBuffer delegate;
+
+ public Tomcat8CommitSessionOutputBuffer(final SessionCommitter sessionCommitter,
+ final OutputBuffer delegate) {
+ this.sessionCommitter = sessionCommitter;
+ this.delegate = delegate;
+ }
+
+ @Deprecated
+ @Override
+ public int doWrite(final ByteChunk chunk) throws IOException {
+ sessionCommitter.commit();
+ return delegate.doWrite(chunk);
+ }
+
+ @Override
+ public int doWrite(final ByteBuffer chunk) throws IOException {
+ sessionCommitter.commit();
+ return delegate.doWrite(chunk);
+ }
+
+ @Override
+ public long getBytesWritten() {
+ return delegate.getBytesWritten();
+ }
+
+ OutputBuffer getDelegate() {
+ return delegate;
+ }
+}
diff --git a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionValve.java b/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionValve.java
new file mode 100644
index 0000000..fe5f65a
--- /dev/null
+++ b/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionValve.java
@@ -0,0 +1,59 @@
+/*
+ * 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.modules.session.catalina;
+
+import java.lang.reflect.Field;
+
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.coyote.OutputBuffer;
+
+public class Tomcat8CommitSessionValve
+ extends AbstractCommitSessionValve<Tomcat8CommitSessionValve> {
+
+ private static final Field outputBufferField;
+
+ static {
+ try {
+ outputBufferField = org.apache.coyote.Response.class.getDeclaredField("outputBuffer");
+ outputBufferField.setAccessible(true);
+ } catch (final NoSuchFieldException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ Response wrapResponse(final Response response) {
+ final org.apache.coyote.Response coyoteResponse = response.getCoyoteResponse();
+ final OutputBuffer delegateOutputBuffer = getOutputBuffer(coyoteResponse);
+ if (!(delegateOutputBuffer instanceof Tomcat8CommitSessionOutputBuffer)) {
+ final Request request = response.getRequest();
+ final OutputBuffer sessionCommitOutputBuffer =
+ new Tomcat8CommitSessionOutputBuffer(() -> commitSession(request), delegateOutputBuffer);
+ coyoteResponse.setOutputBuffer(sessionCommitOutputBuffer);
+ }
+ return response;
+ }
+
+ static OutputBuffer getOutputBuffer(final org.apache.coyote.Response coyoteResponse) {
+ try {
+ return (OutputBuffer) outputBufferField.get(coyoteResponse);
+ } catch (final IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+}
diff --git a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8DeltaSessionManager.java b/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8DeltaSessionManager.java
index 8a32ac0..573bf43 100644
--- a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8DeltaSessionManager.java
+++ b/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8DeltaSessionManager.java
@@ -12,6 +12,7 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
+
package org.apache.geode.modules.session.catalina;
import java.io.IOException;
@@ -22,7 +23,7 @@ import org.apache.catalina.LifecycleState;
import org.apache.catalina.Pipeline;
import org.apache.catalina.session.StandardSession;
-public class Tomcat8DeltaSessionManager extends DeltaSessionManager {
+public class Tomcat8DeltaSessionManager extends DeltaSessionManager<Tomcat8CommitSessionValve> {
/**
* Prepare for the beginning of active use of the public methods of this component. This method
@@ -138,6 +139,11 @@ public class Tomcat8DeltaSessionManager extends DeltaSessionManager {
}
@Override
+ protected Tomcat8CommitSessionValve createCommitSessionValve() {
+ return new Tomcat8CommitSessionValve();
+ }
+
+ @Override
public Context getTheContext() {
return getContext();
}
diff --git a/extensions/geode-modules-tomcat8/src/test/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionOutputBufferTest.java b/extensions/geode-modules-tomcat8/src/test/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionOutputBufferTest.java
new file mode 100644
index 0000000..4efc77b
--- /dev/null
+++ b/extensions/geode-modules-tomcat8/src/test/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionOutputBufferTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.modules.session.catalina;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.apache.coyote.OutputBuffer;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.junit.Test;
+import org.mockito.InOrder;
+
+public class Tomcat8CommitSessionOutputBufferTest {
+
+ final SessionCommitter sessionCommitter = mock(SessionCommitter.class);
+ final OutputBuffer delegate = mock(OutputBuffer.class);
+
+ final Tomcat8CommitSessionOutputBuffer commitSesssionOutputBuffer =
+ new Tomcat8CommitSessionOutputBuffer(sessionCommitter, delegate);
+
+ /**
+ * @deprecated Remove when {@link OutputBuffer} drops this method.
+ */
+ @Deprecated
+ @Test
+ public void doWrite() throws IOException {
+ final ByteChunk byteChunk = new ByteChunk();
+
+ commitSesssionOutputBuffer.doWrite(byteChunk);
+
+ final InOrder inOrder = inOrder(sessionCommitter, delegate);
+ inOrder.verify(sessionCommitter).commit();
+ inOrder.verify(delegate).doWrite(byteChunk);
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ @Test
+ public void testDoWrite() throws IOException {
+ final ByteBuffer byteBuffer = ByteBuffer.allocate(0);
+
+ commitSesssionOutputBuffer.doWrite(byteBuffer);
+
+ final InOrder inOrder = inOrder(sessionCommitter, delegate);
+ inOrder.verify(sessionCommitter).commit();
+ inOrder.verify(delegate).doWrite(byteBuffer);
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ @Test
+ public void getBytesWritten() {
+ when(delegate.getBytesWritten()).thenReturn(42L);
+
+ assertThat(commitSesssionOutputBuffer.getBytesWritten()).isEqualTo(42L);
+
+ final InOrder inOrder = inOrder(sessionCommitter, delegate);
+ inOrder.verify(delegate).getBytesWritten();
+ inOrder.verifyNoMoreInteractions();
+ }
+}
diff --git a/extensions/geode-modules-tomcat8/src/test/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionValveTest.java b/extensions/geode-modules-tomcat8/src/test/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionValveTest.java
new file mode 100644
index 0000000..5cc2f0a
--- /dev/null
+++ b/extensions/geode-modules-tomcat8/src/test/java/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionValveTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.modules.session.catalina;
+
+import static org.apache.geode.modules.session.catalina.Tomcat8CommitSessionValve.getOutputBuffer;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.coyote.OutputBuffer;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+
+
+public class Tomcat8CommitSessionValveTest {
+
+ private final Tomcat8CommitSessionValve valve = new Tomcat8CommitSessionValve();
+ private final OutputBuffer outputBuffer = mock(OutputBuffer.class);
+ private Response response;
+ private org.apache.coyote.Response coyoteResponse;
+
+ @Before
+ public void before() {
+ final Connector connector = mock(Connector.class);
+
+ final Context context = mock(Context.class);
+
+ final Request request = mock(Request.class);
+ doReturn(context).when(request).getContext();
+
+ coyoteResponse = new org.apache.coyote.Response();
+ coyoteResponse.setOutputBuffer(outputBuffer);
+
+ response = new Response();
+ response.setConnector(connector);
+ response.setRequest(request);
+ response.setCoyoteResponse(coyoteResponse);
+ }
+
+ @Test
+ public void wrappedOutputBufferForwardsToDelegate() throws IOException {
+ wrappedOutputBufferForwardsToDelegate(new byte[] {'a', 'b', 'c'});
+ }
+
+ @Test
+ public void recycledResponseObjectDoesNotWrapAlreadyWrappedOutputBuffer() throws IOException {
+ wrappedOutputBufferForwardsToDelegate(new byte[] {'a', 'b', 'c'});
+ response.recycle();
+ reset(outputBuffer);
+ wrappedOutputBufferForwardsToDelegate(new byte[] {'d', 'e', 'f'});
+ }
+
+ private void wrappedOutputBufferForwardsToDelegate(final byte[] bytes) throws IOException {
+ final OutputStream outputStream =
+ valve.wrapResponse(response).getResponse().getOutputStream();
+ outputStream.write(bytes);
+ outputStream.flush();
+
+ final ArgumentCaptor<ByteBuffer> byteBuffer = ArgumentCaptor.forClass(ByteBuffer.class);
+
+ final InOrder inOrder = inOrder(outputBuffer);
+ inOrder.verify(outputBuffer).doWrite(byteBuffer.capture());
+ inOrder.verifyNoMoreInteractions();
+
+ final OutputBuffer wrappedOutputBuffer = getOutputBuffer(coyoteResponse);
+ assertThat(wrappedOutputBuffer).isInstanceOf(Tomcat8CommitSessionOutputBuffer.class);
+ assertThat(((Tomcat8CommitSessionOutputBuffer) wrappedOutputBuffer).getDelegate())
+ .isNotInstanceOf(Tomcat8CommitSessionOutputBuffer.class);
+
+ assertThat(byteBuffer.getValue().array()).contains(bytes);
+ }
+
+}
diff --git a/extensions/geode-modules-tomcat9/build.gradle b/extensions/geode-modules-tomcat9/build.gradle
index a8763a8..dea8c30 100644
--- a/extensions/geode-modules-tomcat9/build.gradle
+++ b/extensions/geode-modules-tomcat9/build.gradle
@@ -18,19 +18,16 @@ import org.apache.geode.gradle.plugins.DependencyConstraints
*/
apply from: "${rootDir}/${scriptDir}/standard-subproject-configuration.gradle"
+apply from: "${rootDir}/${scriptDir}/warnings.gradle"
evaluationDependsOn(":geode-core")
-
dependencies {
compile(platform(project(':boms:geode-all-bom')))
api(project(':extensions:geode-modules')) {
exclude group: 'org.apache.tomcat'
}
-// testImplementation(project(':extensions:geode-modules')) {
-// exclude group: 'org.apache.tomcat'
-// }
implementation('org.apache.tomcat:tomcat-catalina:' + DependencyConstraints.get('tomcat9.version')) {
exclude module: 'tomcat-annotations-api'
@@ -40,7 +37,7 @@ dependencies {
exclude module: 'tomcat-servlet-api'
}
implementation('org.apache.tomcat:tomcat-juli:' + DependencyConstraints.get('tomcat9.version'))
- implementation('javax.servlet:javax.servlet-api:' + '3.1.0')
+ implementation('javax.servlet:javax.servlet-api:4.0.1')
testImplementation('org.httpunit:httpunit')
testImplementation('junit:junit')
@@ -48,15 +45,15 @@ dependencies {
testImplementation('org.mockito:mockito-core')
testImplementation(project(':extensions:geode-modules-test'))
- distributedTestImplementation(project(':extensions:geode-modules-test'))
+ integrationTestImplementation(project(':extensions:geode-modules-test'))
+ integrationTestImplementation('junit:junit')
+ integrationTestImplementation('org.mockito:mockito-core')
- distributedTestRuntimeOnly('xerces:xercesImpl')
- distributedTestRuntimeOnly('javax.annotation:javax.annotation-api')
}
eclipse.classpath.file {
whenMerged { classpath ->
- classpath.entries.removeAll { entry -> entry.path.contains('geode-modules/build')}
+ classpath.entries.removeAll { entry -> entry.path.contains('geode-modules/build') }
}
}
diff --git a/extensions/geode-modules-tomcat9/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java b/extensions/geode-modules-tomcat9/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java
new file mode 100644
index 0000000..c43729a
--- /dev/null
+++ b/extensions/geode-modules-tomcat9/src/integrationTest/java/org/apache/geode/modules/session/catalina/CommitSessionValveIntegrationTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.modules.session.catalina;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.coyote.OutputBuffer;
+import org.apache.juli.logging.Log;
+import org.junit.Before;
+
+public class CommitSessionValveIntegrationTest
+ extends AbstractCommitSessionValveIntegrationTest<Tomcat9CommitSessionValve> {
+
+ @Before
+ public void setUp() {
+ final Context context = mock(Context.class);
+ doReturn(mock(Log.class)).when(context).getLogger();
+
+ request = mock(Request.class);
+ doReturn(context).when(request).getContext();
+
+ final OutputBuffer outputBuffer = mock(OutputBuffer.class);
+
+ final org.apache.coyote.Response coyoteResponse = new org.apache.coyote.Response();
+ coyoteResponse.setOutputBuffer(outputBuffer);
+
+ response = new Response();
+ response.setRequest(request);
+ response.setCoyoteResponse(coyoteResponse);
+ }
+
+ @Override
+ protected Tomcat9CommitSessionValve createCommitSessionValve() {
+ return new Tomcat9CommitSessionValve();
+ }
+}
diff --git a/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionOutputBuffer.java b/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionOutputBuffer.java
new file mode 100644
index 0000000..4e4600b
--- /dev/null
+++ b/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionOutputBuffer.java
@@ -0,0 +1,53 @@
+/*
+ * 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.modules.session.catalina;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.apache.coyote.OutputBuffer;
+
+
+/**
+ * Delegating {@link OutputBuffer} that commits sessions on write through. Output data is buffered
+ * ahead of this object and flushed through this interface when full or explicitly flushed.
+ */
+class Tomcat9CommitSessionOutputBuffer implements OutputBuffer {
+
+ private final SessionCommitter sessionCommitter;
+ private final OutputBuffer delegate;
+
+ public Tomcat9CommitSessionOutputBuffer(final SessionCommitter sessionCommitter,
+ final OutputBuffer delegate) {
+ this.sessionCommitter = sessionCommitter;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public int doWrite(final ByteBuffer chunk) throws IOException {
+ sessionCommitter.commit();
+ return delegate.doWrite(chunk);
+ }
+
+ @Override
+ public long getBytesWritten() {
+ return delegate.getBytesWritten();
+ }
+
+ OutputBuffer getDelegate() {
+ return delegate;
+ }
+}
diff --git a/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionValve.java b/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionValve.java
new file mode 100644
index 0000000..925b0d2
--- /dev/null
+++ b/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionValve.java
@@ -0,0 +1,58 @@
+/*
+ * 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.modules.session.catalina;
+
+import java.lang.reflect.Field;
+
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.coyote.OutputBuffer;
+
+public class Tomcat9CommitSessionValve
+ extends AbstractCommitSessionValve<Tomcat9CommitSessionValve> {
+
+ private static final Field outputBufferField;
+
+ static {
+ try {
+ outputBufferField = org.apache.coyote.Response.class.getDeclaredField("outputBuffer");
+ outputBufferField.setAccessible(true);
+ } catch (final NoSuchFieldException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ Response wrapResponse(final Response response) {
+ final org.apache.coyote.Response coyoteResponse = response.getCoyoteResponse();
+ final OutputBuffer delegateOutputBuffer = getOutputBuffer(coyoteResponse);
+ if (!(delegateOutputBuffer instanceof Tomcat9CommitSessionOutputBuffer)) {
+ final Request request = response.getRequest();
+ final OutputBuffer sessionCommitOutputBuffer =
+ new Tomcat9CommitSessionOutputBuffer(() -> commitSession(request), delegateOutputBuffer);
+ coyoteResponse.setOutputBuffer(sessionCommitOutputBuffer);
+ }
+ return response;
+ }
+
+ static OutputBuffer getOutputBuffer(final org.apache.coyote.Response coyoteResponse) {
+ try {
+ return (OutputBuffer) outputBufferField.get(coyoteResponse);
+ } catch (final IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
diff --git a/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9DeltaSessionManager.java b/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9DeltaSessionManager.java
index ac9ac2c..5c7e47d 100644
--- a/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9DeltaSessionManager.java
+++ b/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9DeltaSessionManager.java
@@ -22,7 +22,7 @@ import org.apache.catalina.LifecycleState;
import org.apache.catalina.Pipeline;
import org.apache.catalina.session.StandardSession;
-public class Tomcat9DeltaSessionManager extends DeltaSessionManager {
+public class Tomcat9DeltaSessionManager extends DeltaSessionManager<Tomcat9CommitSessionValve> {
/**
* Prepare for the beginning of active use of the public methods of this component. This method
@@ -138,6 +138,11 @@ public class Tomcat9DeltaSessionManager extends DeltaSessionManager {
}
@Override
+ protected Tomcat9CommitSessionValve createCommitSessionValve() {
+ return new Tomcat9CommitSessionValve();
+ }
+
+ @Override
public Context getTheContext() {
return getContext();
}
diff --git a/extensions/geode-modules-tomcat9/src/test/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionOutputBufferTest.java b/extensions/geode-modules-tomcat9/src/test/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionOutputBufferTest.java
new file mode 100644
index 0000000..0ec3a00
--- /dev/null
+++ b/extensions/geode-modules-tomcat9/src/test/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionOutputBufferTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.modules.session.catalina;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.apache.coyote.OutputBuffer;
+import org.junit.Test;
+import org.mockito.InOrder;
+
+public class Tomcat9CommitSessionOutputBufferTest {
+
+ final SessionCommitter sessionCommitter = mock(SessionCommitter.class);
+ final OutputBuffer delegate = mock(OutputBuffer.class);
+
+ final Tomcat9CommitSessionOutputBuffer commitSesssionOutputBuffer =
+ new Tomcat9CommitSessionOutputBuffer(sessionCommitter, delegate);
+
+ @Test
+ public void testDoWrite() throws IOException {
+ final ByteBuffer byteBuffer = ByteBuffer.allocate(0);
+
+ commitSesssionOutputBuffer.doWrite(byteBuffer);
+
+ final InOrder inOrder = inOrder(sessionCommitter, delegate);
+ inOrder.verify(sessionCommitter).commit();
+ inOrder.verify(delegate).doWrite(byteBuffer);
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ @Test
+ public void getBytesWritten() {
+ when(delegate.getBytesWritten()).thenReturn(42L);
+
+ assertThat(commitSesssionOutputBuffer.getBytesWritten()).isEqualTo(42L);
+
+ final InOrder inOrder = inOrder(sessionCommitter, delegate);
+ inOrder.verify(delegate).getBytesWritten();
+ inOrder.verifyNoMoreInteractions();
+ }
+}
diff --git a/extensions/geode-modules-tomcat9/src/test/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionValveTest.java b/extensions/geode-modules-tomcat9/src/test/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionValveTest.java
new file mode 100644
index 0000000..32095a2
--- /dev/null
+++ b/extensions/geode-modules-tomcat9/src/test/java/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionValveTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.modules.session.catalina;
+
+import static org.apache.geode.modules.session.catalina.Tomcat9CommitSessionValve.getOutputBuffer;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.coyote.OutputBuffer;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+
+
+public class Tomcat9CommitSessionValveTest {
+
+ private final Tomcat9CommitSessionValve valve = new Tomcat9CommitSessionValve();
+ private final OutputBuffer outputBuffer = mock(OutputBuffer.class);
+ private Response response;
+ private org.apache.coyote.Response coyoteResponse;
+
+ @Before
+ public void before() {
+ final Context context = mock(Context.class);
+
+ final Request request = mock(Request.class);
+ doReturn(context).when(request).getContext();
+
+ coyoteResponse = new org.apache.coyote.Response();
+ coyoteResponse.setOutputBuffer(outputBuffer);
+
+ response = new Response();
+ response.setRequest(request);
+ response.setCoyoteResponse(coyoteResponse);
+ }
+
+ @Test
+ public void wrappedOutputBufferForwardsToDelegate() throws IOException {
+ wrappedOutputBufferForwardsToDelegate(new byte[] {'a', 'b', 'c'});
+ }
+
+ @Test
+ public void recycledResponseObjectDoesNotWrapAlreadyWrappedOutputBuffer() throws IOException {
+ wrappedOutputBufferForwardsToDelegate(new byte[] {'a', 'b', 'c'});
+ response.recycle();
+ reset(outputBuffer);
+ wrappedOutputBufferForwardsToDelegate(new byte[] {'d', 'e', 'f'});
+ }
+
+ private void wrappedOutputBufferForwardsToDelegate(final byte[] bytes) throws IOException {
+ final OutputStream outputStream =
+ valve.wrapResponse(response).getResponse().getOutputStream();
+ outputStream.write(bytes);
+ outputStream.flush();
+
+ final ArgumentCaptor<ByteBuffer> byteBuffer = ArgumentCaptor.forClass(ByteBuffer.class);
+
+ final InOrder inOrder = inOrder(outputBuffer);
+ inOrder.verify(outputBuffer).doWrite(byteBuffer.capture());
+ inOrder.verifyNoMoreInteractions();
+
+ final OutputBuffer wrappedOutputBuffer = getOutputBuffer(coyoteResponse);
+ assertThat(wrappedOutputBuffer).isInstanceOf(Tomcat9CommitSessionOutputBuffer.class);
+ assertThat(((Tomcat9CommitSessionOutputBuffer) wrappedOutputBuffer).getDelegate())
+ .isNotInstanceOf(Tomcat9CommitSessionOutputBuffer.class);
+
+ assertThat(byteBuffer.getValue().array()).contains(bytes);
+ }
+
+}
diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/AbstractCommitSessionValve.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/AbstractCommitSessionValve.java
new file mode 100644
index 0000000..fece1af
--- /dev/null
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/AbstractCommitSessionValve.java
@@ -0,0 +1,83 @@
+/*
+ * 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.modules.session.catalina;
+
+import static org.apache.geode.util.internal.UncheckedUtils.uncheckedCast;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Manager;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.valves.ValveBase;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+public abstract class AbstractCommitSessionValve<SelfT extends AbstractCommitSessionValve<?>>
+ extends ValveBase {
+
+ private static final Log log = LogFactory.getLog(AbstractCommitSessionValve.class);
+
+ protected static final String info =
+ "org.apache.geode.modules.session.catalina.CommitSessionValve/1.0";
+
+ AbstractCommitSessionValve() {
+ log.info("Initialized");
+ }
+
+ @Override
+ public void invoke(final Request request, final Response response)
+ throws IOException, ServletException {
+ try {
+ getNext().invoke(request, wrapResponse(response));
+ } finally {
+ commitSession(request);
+ }
+ }
+
+ /**
+ * Commit session only if DeltaSessionManager is in place.
+ *
+ * @param request to commit session from.
+ */
+ protected static <SelfT extends AbstractCommitSessionValve<?>> void commitSession(
+ final Request request) {
+ final Context context = request.getContext();
+ final Manager manager = context.getManager();
+ if (manager instanceof DeltaSessionManager) {
+ final DeltaSessionFacade session = (DeltaSessionFacade) request.getSession(false);
+ if (session != null) {
+ final DeltaSessionManager<SelfT> deltaSessionManager = uncheckedCast(manager);
+ if (session.isValid()) {
+ deltaSessionManager.removeTouchedSession(session.getId());
+ session.commit();
+ if (log.isDebugEnabled()) {
+ log.debug(session + ": Committed.");
+ }
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug(session + ": Not valid so not committing.");
+ }
+ }
+ }
+ }
+ }
+
+ abstract Response wrapResponse(final Response response);
+
+}
diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/CommitSessionValve.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/CommitSessionValve.java
deleted file mode 100644
index 1da58b7..0000000
--- a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/CommitSessionValve.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.modules.session.catalina;
-
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-
-import org.apache.catalina.Manager;
-import org.apache.catalina.connector.Request;
-import org.apache.catalina.connector.Response;
-import org.apache.catalina.valves.ValveBase;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
-
-public class CommitSessionValve extends ValveBase {
-
- private static final Log log = LogFactory.getLog(CommitSessionValve.class);
-
- protected static final String info =
- "org.apache.geode.modules.session.catalina.CommitSessionValve/1.0";
-
- CommitSessionValve() {
- log.info("Initialized");
- }
-
- @Override
- public void invoke(Request request, Response response) throws IOException, ServletException {
- // Get the Manager
- Manager manager = request.getContext().getManager();
- DeltaSessionFacade session;
-
- // Invoke the next Valve
- try {
- getNext().invoke(request, response);
- } finally {
- // Commit and if the correct Manager was found
- if (manager instanceof DeltaSessionManager) {
- session = (DeltaSessionFacade) request.getSession(false);
- DeltaSessionManager dsm = ((DeltaSessionManager) manager);
- if (session != null) {
- if (session.isValid()) {
- dsm.removeTouchedSession(session.getId());
- session.commit();
- if (dsm.getTheContext().getLogger().isDebugEnabled()) {
- dsm.getTheContext().getLogger().debug(session + ": Committed.");
- }
- } else {
- if (dsm.getTheContext().getLogger().isDebugEnabled()) {
- dsm.getTheContext().getLogger().debug(session + ": Not valid so not committing.");
- }
- }
- }
- }
- }
- }
-}
diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionManager.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionManager.java
index a0ffca9..c1dddc6 100644
--- a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionManager.java
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionManager.java
@@ -65,7 +65,8 @@ import org.apache.geode.modules.util.ContextMapper;
import org.apache.geode.modules.util.RegionConfiguration;
import org.apache.geode.modules.util.RegionHelper;
-public abstract class DeltaSessionManager extends ManagerBase
+public abstract class DeltaSessionManager<CommitSessionValveT extends AbstractCommitSessionValve>
+ extends ManagerBase
implements Lifecycle, PropertyChangeListener, SessionManager {
static final String catalinaBaseSystemProperty = "catalina.base";
@@ -93,7 +94,7 @@ public abstract class DeltaSessionManager extends ManagerBase
private Valve jvmRouteBinderValve;
- private Valve commitSessionValve;
+ private CommitSessionValveT commitSessionValve;
private SessionCache sessionCache;
@@ -603,10 +604,12 @@ public abstract class DeltaSessionManager extends ManagerBase
if (getLogger().isDebugEnabled()) {
getLogger().debug(this + ": Registering CommitSessionValve");
}
- commitSessionValve = new CommitSessionValve();
+ commitSessionValve = createCommitSessionValve();
getPipeline().addValve(commitSessionValve);
}
+ protected abstract CommitSessionValveT createCommitSessionValve();
+
protected void unregisterCommitSessionValve() {
if (getLogger().isDebugEnabled()) {
getLogger().debug(this + ": Unregistering CommitSessionValve");
diff --git a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession8.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/SessionCommitter.java
similarity index 60%
copy from extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession8.java
copy to extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/SessionCommitter.java
index a17fdde..5af9aa2 100644
--- a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession8.java
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/SessionCommitter.java
@@ -12,28 +12,16 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
-package org.apache.geode.modules.session.catalina;
-
-import org.apache.catalina.Manager;
+package org.apache.geode.modules.session.catalina;
-@SuppressWarnings("serial")
-public class DeltaSession8 extends DeltaSession {
- /**
- * Construct a new <code>Session</code> associated with no <code>Manager</code>. The
- * <code>Manager</code> will be assigned later using {@link #setOwner(Object)}.
- */
- @SuppressWarnings("unused")
- public DeltaSession8() {
- super();
- }
+/**
+ * Lambda interface for committing session data.
+ */
+interface SessionCommitter {
/**
- * Construct a new Session associated with the specified Manager.
- *
- * @param manager The manager with which this Session is associated
+ * Invoked to commit session data.
*/
- DeltaSession8(Manager manager) {
- super(manager);
- }
+ void commit();
}
diff --git a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession8.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/Tomcat6CommitSessionValve.java
similarity index 59%
copy from extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession8.java
copy to extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/Tomcat6CommitSessionValve.java
index a17fdde..b27fe65 100644
--- a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession8.java
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/Tomcat6CommitSessionValve.java
@@ -12,28 +12,16 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
-package org.apache.geode.modules.session.catalina;
-import org.apache.catalina.Manager;
+package org.apache.geode.modules.session.catalina;
+import org.apache.catalina.connector.Response;
-@SuppressWarnings("serial")
-public class DeltaSession8 extends DeltaSession {
- /**
- * Construct a new <code>Session</code> associated with no <code>Manager</code>. The
- * <code>Manager</code> will be assigned later using {@link #setOwner(Object)}.
- */
- @SuppressWarnings("unused")
- public DeltaSession8() {
- super();
- }
+@Deprecated
+public final class Tomcat6CommitSessionValve extends AbstractCommitSessionValve {
- /**
- * Construct a new Session associated with the specified Manager.
- *
- * @param manager The manager with which this Session is associated
- */
- DeltaSession8(Manager manager) {
- super(manager);
+ @Override
+ protected Response wrapResponse(Response response) {
+ return response;
}
}
diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/Tomcat6DeltaSessionManager.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/Tomcat6DeltaSessionManager.java
index 555f09e..1abceb9 100644
--- a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/Tomcat6DeltaSessionManager.java
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/Tomcat6DeltaSessionManager.java
@@ -21,7 +21,7 @@ import org.apache.catalina.util.LifecycleSupport;
* @deprecated Tomcat 6 has reached its end of life and support for Tomcat 6 will be removed
* from a future Geode release.
*/
-public class Tomcat6DeltaSessionManager extends DeltaSessionManager {
+public class Tomcat6DeltaSessionManager extends DeltaSessionManager<Tomcat6CommitSessionValve> {
/**
* The <code>LifecycleSupport</code> for this component.
@@ -131,4 +131,9 @@ public class Tomcat6DeltaSessionManager extends DeltaSessionManager {
public void removeLifecycleListener(LifecycleListener listener) {
this.lifecycle.removeLifecycleListener(listener);
}
+
+ @Override
+ protected Tomcat6CommitSessionValve createCommitSessionValve() {
+ return new Tomcat6CommitSessionValve();
+ }
}
diff --git a/geode-assembly/geode-assembly-test/build.gradle b/geode-assembly/geode-assembly-test/build.gradle
index 40c01cb..a53fdb1 100755
--- a/geode-assembly/geode-assembly-test/build.gradle
+++ b/geode-assembly/geode-assembly-test/build.gradle
@@ -25,9 +25,11 @@ dependencies {
compileOnly(project(':extensions:geode-modules-test'))
compileOnly(project(':geode-core'))
compileOnly(project(':geode-pulse'))
+ compileOnly(project(':geode-junit'))
implementation(project(':geode-logging'))
implementation(project(':geode-membership'))
implementation('javax.servlet:javax.servlet-api')
+ implementation('org.apache.commons:commons-lang3')
compileOnly(project(':geode-tcp-server'))
compileOnly('com.fasterxml.jackson.core:jackson-databind')
compileOnly('commons-io:commons-io')
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index 7ed9ce1..bec9cce 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -837,7 +837,11 @@ javadoc/org/apache/geode/modules/session/catalina/AbstractCacheLifecycleListener
javadoc/org/apache/geode/modules/session/catalina/AbstractSessionCache.html
javadoc/org/apache/geode/modules/session/catalina/ClientServerCacheLifecycleListener.html
javadoc/org/apache/geode/modules/session/catalina/ClientServerSessionCache.html
-javadoc/org/apache/geode/modules/session/catalina/CommitSessionValve.html
+javadoc/org/apache/geode/modules/session/catalina/AbstractCommitSessionValve.html
+javadoc/org/apache/geode/modules/session/catalina/Tomcat6CommitSessionValve.html
+javadoc/org/apache/geode/modules/session/catalina/Tomcat7CommitSessionValve.html
+javadoc/org/apache/geode/modules/session/catalina/Tomcat8CommitSessionValve.html
+javadoc/org/apache/geode/modules/session/catalina/Tomcat9CommitSessionValve.html
javadoc/org/apache/geode/modules/session/catalina/DeltaSession.html
javadoc/org/apache/geode/modules/session/catalina/DeltaSession7.html
javadoc/org/apache/geode/modules/session/catalina/DeltaSession8.html
diff --git a/geode-core/build.gradle b/geode-core/build.gradle
index 6822133..1f3c407 100755
--- a/geode-core/build.gradle
+++ b/geode-core/build.gradle
@@ -16,7 +16,7 @@
*/
plugins {
- id 'me.champeau.gradle.jmh' version '0.4.8'
+ id 'me.champeau.gradle.jmh' version '0.4.8'
}
apply from: "${rootDir}/${scriptDir}/standard-subproject-configuration.gradle"
@@ -26,95 +26,95 @@ apply from: "${project.projectDir}/../gradle/publish-java.gradle"
apply from: "${project.projectDir}/../gradle/pmd.gradle"
sourceSets {
- jca {
- compileClasspath += configurations.compileClasspath
- runtimeClasspath += configurations.runtimeClasspath
- }
+ jca {
+ compileClasspath += configurations.compileClasspath
+ runtimeClasspath += configurations.runtimeClasspath
+ }
}
idea {
- module {
- testSourceDirs += project.tasks.generateIntegrationTestGrammarSource.outputs.files
- testSourceDirs += project.tasks.generateDistributedTestGrammarSource.outputs.files
- testSourceDirs += project.tasks.generatePerformanceTestGrammarSource.outputs.files
- testSourceDirs += project.tasks.generateUpgradeTestGrammarSource.outputs.files
- }
+ module {
+ testSourceDirs += project.tasks.generateIntegrationTestGrammarSource.outputs.files
+ testSourceDirs += project.tasks.generateDistributedTestGrammarSource.outputs.files
+ testSourceDirs += project.tasks.generatePerformanceTestGrammarSource.outputs.files
+ testSourceDirs += project.tasks.generateUpgradeTestGrammarSource.outputs.files
+ }
}
def generatedResources = "$buildDir/generated-resources/main"
sourceSets {
- main {
- output.dir(generatedResources, builtBy: 'createVersionPropertiesFile')
- }
- test {
- output.dir(generatedResources, builtBy: 'createVersionPropertiesFile')
- }
+ main {
+ output.dir(generatedResources, builtBy: 'createVersionPropertiesFile')
+ }
+ test {
+ output.dir(generatedResources, builtBy: 'createVersionPropertiesFile')
+ }
}
sourceSets {
// This works around resource-look up between integrationTest and test source-sets.
// See GEODE-5803 / GEODE-5882
- test.resources.srcDirs.each { testResourceSrc ->
- integrationTest.resources.srcDir {
- testResourceSrc
+ test.resources.srcDirs.each { testResourceSrc ->
+ integrationTest.resources.srcDir {
+ testResourceSrc
+ }
}
- }
}
// Creates the version properties file and writes it to the classes dir
task createVersionPropertiesFile(dependsOn: ':writeBuildInfo') {
- def propertiesFile = file(generatedResources + "/org/apache/geode/internal/GemFireVersion.properties")
- def scmInfoFile = rootProject.tasks.writeBuildInfo.outputs.files
+ def propertiesFile = file(generatedResources + "/org/apache/geode/internal/GemFireVersion.properties")
+ def scmInfoFile = rootProject.tasks.writeBuildInfo.outputs.files
- inputs.files {
- scmInfoFile
- }
- outputs.files {
- propertiesFile
- }
+ inputs.files {
+ scmInfoFile
+ }
+ outputs.files {
+ propertiesFile
+ }
- doLast {
- def scmInfo = new Properties()
- new FileInputStream(scmInfoFile.singleFile).withStream { fis ->
- scmInfo.load(fis)
- }
+ doLast {
+ def scmInfo = new Properties()
+ new FileInputStream(scmInfoFile.singleFile).withStream { fis ->
+ scmInfo.load(fis)
+ }
- def props = [
- "Product-Name" : productName,
- "Product-Version" : version,
- "Build-Id" : "${System.env.USER} ${buildId}".toString(),
- "Build-Date" : new Date().format('yyyy-MM-dd HH:mm:ss Z'),
- "Build-Platform" : "${System.properties['os.name']} ${System.properties['os.version']} ${System.properties['os.arch']}".toString(),
- "Build-Java-Vendor" : System.properties['java.vendor'],
- "Build-Java-Version": System.properties['java.version']
- ] as Properties
- props.putAll(scmInfo)
-
- propertiesFile.getParentFile().mkdirs()
- new FileOutputStream(propertiesFile).withStream { fos ->
- props.store(fos, '')
+ def props = [
+ "Product-Name" : productName,
+ "Product-Version" : version,
+ "Build-Id" : "${System.env.USER} ${buildId}".toString(),
+ "Build-Date" : new Date().format('yyyy-MM-dd HH:mm:ss Z'),
+ "Build-Platform" : "${System.properties['os.name']} ${System.properties['os.version']} ${System.properties['os.arch']}".toString(),
+ "Build-Java-Vendor" : System.properties['java.vendor'],
+ "Build-Java-Version": System.properties['java.version']
+ ] as Properties
+ props.putAll(scmInfo)
+
+ propertiesFile.getParentFile().mkdirs()
+ new FileOutputStream(propertiesFile).withStream { fos ->
+ props.store(fos, '')
+ }
}
- }
}
ext.moduleName = group + '.core'
jar {
- from sourceSets.main.output
- from sourceSets.jca.output
+ from sourceSets.main.output
+ from sourceSets.jca.output
- exclude 'org/apache/geode/internal/i18n/StringIdResourceBundle_ja.txt'
- exclude 'org/apache/geode/admin/doc-files/ds4_0.dtd'
+ exclude 'org/apache/geode/internal/i18n/StringIdResourceBundle_ja.txt'
+ exclude 'org/apache/geode/admin/doc-files/ds4_0.dtd'
- inputs.property("moduleName", moduleName)
- manifest {
- attributes('Automatic-Module-Name': moduleName)
- }
+ inputs.property("moduleName", moduleName)
+ manifest {
+ attributes('Automatic-Module-Name': moduleName)
+ }
}
@@ -129,304 +129,304 @@ repeatUpgradeTest {
}
task raJar(type: Jar, dependsOn: classes) {
- description 'Assembles the jar archive that contains the JCA classes'
- from sourceSets.jca.output
- exclude 'org/apache/geode/ra/**'
- archiveName 'ra.jar'
+ description 'Assembles the jar archive that contains the JCA classes'
+ from sourceSets.jca.output
+ exclude 'org/apache/geode/ra/**'
+ archiveName 'ra.jar'
}
task jcaJar(type: Jar, dependsOn: raJar) {
- description 'Assembles the jar archive that contains the JCA bundle'
- baseName 'geode-jca'
- extension 'rar'
- metaInf { from 'src/jca/ra.xml' }
- from raJar.archivePath
+ description 'Assembles the jar archive that contains the JCA bundle'
+ baseName 'geode-jca'
+ extension 'rar'
+ metaInf { from 'src/jca/ra.xml' }
+ from raJar.archivePath
}
configurations {
- //declaring new configuration that will be used to associate with artifacts
- archives
+ //declaring new configuration that will be used to associate with artifacts
+ archives
- classesOutput {
- extendsFrom api
- description 'a dependency that exposes the compiled classes'
- }
+ classesOutput {
+ extendsFrom api
+ description 'a dependency that exposes the compiled classes'
+ }
- jmh {
- extendsFrom testImplementation
- }
+ jmh {
+ extendsFrom testImplementation
+ }
}
dependencies {
- //These bom dependencies are used to constrain the versions of the dependencies listed below
- api(platform(project(':boms:geode-all-bom')))
- compileOnly(platform(project(':boms:geode-all-bom')))
- testCompileOnly(platform(project(':boms:geode-all-bom')))
- // As plugin configurations that do not extend from compile,
- // we must explicitly impose version constraints on these configurations.
- antlr platform(project(':boms:geode-all-bom'))
- jcaAnnotationProcessor(platform(project(':boms:geode-all-bom')))
+ //These bom dependencies are used to constrain the versions of the dependencies listed below
+ api(platform(project(':boms:geode-all-bom')))
+ compileOnly(platform(project(':boms:geode-all-bom')))
+ testCompileOnly(platform(project(':boms:geode-all-bom')))
+ // As plugin configurations that do not extend from compile,
+ // we must explicitly impose version constraints on these configurations.
+ antlr platform(project(':boms:geode-all-bom'))
+ jcaAnnotationProcessor(platform(project(':boms:geode-all-bom')))
- //A dependency that contains the compiled output of the source. What is this for?
- classesOutput sourceSets.main.output
+ //A dependency that contains the compiled output of the source. What is this for?
+ classesOutput sourceSets.main.output
- // Source Dependencies
- //------------------------------------------------------------
+ // Source Dependencies
+ //------------------------------------------------------------
- // The antlr configuration is used by the antlr plugin, which compiles grammar
- // files used by the query engine
- antlr 'antlr:antlr'
+ // The antlr configuration is used by the antlr plugin, which compiles grammar
+ // files used by the query engine
+ antlr 'antlr:antlr'
- // External
- //------------------------------------------------------------
+ // External
+ //------------------------------------------------------------
- //Commons IO is used in persistence and management
- api('commons-io:commons-io')
+ //Commons IO is used in persistence and management
+ api('commons-io:commons-io')
- //tools.jar seems to be used by gfsh is some cases to control processes using
- //the sun attach API? But this code path may not even be used?
- compileOnly(files("${System.getProperty('java.home')}/../lib/tools.jar"))
+ //tools.jar seems to be used by gfsh is some cases to control processes using
+ //the sun attach API? But this code path may not even be used?
+ compileOnly(files("${System.getProperty('java.home')}/../lib/tools.jar"))
- //Find bugs is used in multiple places in the code to suppress findbugs warnings
- compileOnly('com.github.stephenc.findbugs:findbugs-annotations')
- testCompileOnly('com.github.stephenc.findbugs:findbugs-annotations')
+ //Find bugs is used in multiple places in the code to suppress findbugs warnings
+ compileOnly('com.github.stephenc.findbugs:findbugs-annotations')
+ testCompileOnly('com.github.stephenc.findbugs:findbugs-annotations')
- //Spring web is used for SerializableObjectHttpMessageConverter
- implementation('org.springframework:spring-web')
- // find bugs leaks in from spring, needed to remove warnings.
- compileOnly('com.google.code.findbugs:jsr305')
+ //Spring web is used for SerializableObjectHttpMessageConverter
+ implementation('org.springframework:spring-web')
+ // find bugs leaks in from spring, needed to remove warnings.
+ compileOnly('com.google.code.findbugs:jsr305')
- //Jgroups is a core component of our membership system.
- implementation('org.jgroups:jgroups')
+ //Jgroups is a core component of our membership system.
+ implementation('org.jgroups:jgroups')
- //Antlr is used by the query engine.
- implementation('antlr:antlr')
+ //Antlr is used by the query engine.
+ implementation('antlr:antlr')
- //Jackson annotations is used in gfsh
- implementation('com.fasterxml.jackson.core:jackson-annotations')
+ //Jackson annotations is used in gfsh
+ implementation('com.fasterxml.jackson.core:jackson-annotations')
- //Jackson databind is used in gfsh, and also in pdx
- implementation('com.fasterxml.jackson.core:jackson-databind')
+ //Jackson databind is used in gfsh, and also in pdx
+ implementation('com.fasterxml.jackson.core:jackson-databind')
- //Commons validator is used to validate inet addresses in membership
- implementation('commons-validator:commons-validator')
+ //Commons validator is used to validate inet addresses in membership
+ implementation('commons-validator:commons-validator')
- //javax.activation is runtime dependency for gfsh with java 11 (used by gfsh-over-http)
- runtimeOnly('com.sun.activation:javax.activation')
+ //javax.activation is runtime dependency for gfsh with java 11 (used by gfsh-over-http)
+ runtimeOnly('com.sun.activation:javax.activation')
- //jaxb is used by cluster configuration
- implementation('javax.xml.bind:jaxb-api')
+ //jaxb is used by cluster configuration
+ implementation('javax.xml.bind:jaxb-api')
- //jaxb is used by cluster configuration
- implementation('com.sun.xml.bind:jaxb-impl')
+ //jaxb is used by cluster configuration
+ implementation('com.sun.xml.bind:jaxb-impl')
- //istack appears to be used only by jaxb, not in our code. jaxb doesn't
- //declare this as required dependency though. It's unclear if this is needed
- //Runtime
- runtimeOnly('com.sun.istack:istack-commons-runtime') {
- exclude group: '*'
- }
+ //istack appears to be used only by jaxb, not in our code. jaxb doesn't
+ //declare this as required dependency though. It's unclear if this is needed
+ //Runtime
+ runtimeOnly('com.sun.istack:istack-commons-runtime') {
+ exclude group: '*'
+ }
- //Commons lang is used in many different places in core
- implementation('org.apache.commons:commons-lang3')
+ //Commons lang is used in many different places in core
+ implementation('org.apache.commons:commons-lang3')
- //Commons modeler is used by the (deprecated) admin API
- implementation('commons-modeler:commons-modeler') {
- exclude module: 'commons-logging-api'
- exclude module: 'mx4j-jmx'
- exclude module: 'xml-apis'
- ext.optional = true
- }
+ //Commons modeler is used by the (deprecated) admin API
+ implementation('commons-modeler:commons-modeler') {
+ exclude module: 'commons-logging-api'
+ exclude module: 'mx4j-jmx'
+ exclude module: 'xml-apis'
+ ext.optional = true
+ }
- //micrometer is used for micrometer based metrics from geode geode
- api('io.micrometer:micrometer-core')
+ //micrometer is used for micrometer based metrics from geode geode
+ api('io.micrometer:micrometer-core')
- //FastUtil contains optimized collections that are used in multiple places in core
- implementation('it.unimi.dsi:fastutil')
+ //FastUtil contains optimized collections that are used in multiple places in core
+ implementation('it.unimi.dsi:fastutil')
- //Mail API is used by the deprecated admin API
- implementation('javax.mail:javax.mail-api') {
- ext.optional = true
- }
+ //Mail API is used by the deprecated admin API
+ implementation('javax.mail:javax.mail-api') {
+ ext.optional = true
+ }
+
+ //The resource-API is used by the JCA support.
+ api('javax.resource:javax.resource-api')
+
+
+ //MX4J is used by the old admin API
+ implementation('mx4j:mx4j') {
+ ext.optional = true
+ }
+
+ //MX4J remote is used by the old admin API
+ implementation('mx4j:mx4j-remote') {
+ ext.optional = true
+ }
- //The resource-API is used by the JCA support.
- api('javax.resource:javax.resource-api')
-
-
- //MX4J is used by the old admin API
- implementation('mx4j:mx4j') {
- ext.optional = true
- }
-
- //MX4J remote is used by the old admin API
- implementation('mx4j:mx4j-remote') {
- ext.optional = true
- }
-
- //MX4J tools is used by the old admin API
- implementation('mx4j:mx4j-tools') {
- ext.optional = true
- }
-
- //JNA is used for locking memory and preallocating disk files.
- implementation('net.java.dev.jna:jna')
- implementation('net.java.dev.jna:jna-platform')
-
- //JOptSimple is used by gfsh. A couple of usages have leaked into DiskStore
- implementation('net.sf.jopt-simple:jopt-simple')
-
- //Log4j is used everywhere
- implementation('org.apache.logging.log4j:log4j-api')
-
-
- implementation('io.swagger:swagger-annotations') {
- ext.optional = true
- }
-
- runtimeOnly(project(':geode-http-service')) {
- ext.optional = true
- }
-
- //Snappy is used for compressing values, if enabled
- implementation('org.iq80.snappy:snappy') {
- ext.optional = true
- }
-
- //Shiro is used for security checks throughout geode-core
- //API - Shiro is exposed in geode's ResourcePermission class
- api('org.apache.shiro:shiro-core')
-
- //Classgraph is used by the gfsh cli, and also for function deployment (which happens in a server
- //in response to a gfsh command)
- implementation('io.github.classgraph:classgraph')
-
- //RMIIO is used for uploading jar files and copying them between locator an servers
- implementation('com.healthmarketscience.rmiio:rmiio')
-
- //Geode-common has annotations and other pieces used geode-core
- api(project(':geode-common'))
- implementation(project(':geode-logging'))
- implementation(project(':geode-membership'))
- implementation(project(':geode-unsafe'))
- implementation(project(':geode-serialization'))
- implementation(project(':geode-tcp-server'))
-
- //geode-management currently has pieces of the public API
- //copied into it, so it is an API dependency
- api(project(':geode-management'))
-
-
- jcaCompile(sourceSets.main.output)
-
- testImplementation(project(':geode-junit')) {
- exclude module: 'geode-core'
- }
- testImplementation(project(':geode-concurrency-test'))
- testImplementation('org.apache.bcel:bcel')
- testImplementation('org.assertj:assertj-core')
- testImplementation('org.mockito:mockito-core')
- testImplementation('com.pholser:junit-quickcheck-core')
- testImplementation('org.powermock:powermock-core')
- testImplementation('org.powermock:powermock-module-junit4')
- testImplementation('org.powermock:powermock-api-mockito2')
- testImplementation('pl.pragmatists:JUnitParams')
- testImplementation('com.tngtech.archunit:archunit-junit4')
-
- testImplementation(files("${System.getProperty('java.home')}/../lib/tools.jar"))
-
- testRuntime('commons-collections:commons-collections')
- testRuntime('commons-configuration:commons-configuration')
- testRuntime('commons-io:commons-io')
- testRuntime('commons-validator:commons-validator')
- testRuntime('com.pholser:junit-quickcheck-generators')
- testRuntime(project(path: ':geode-old-versions', configuration: 'testOutput'))
-
- integrationTestImplementation(project(':geode-gfsh'))
- integrationTestImplementation(project(':geode-junit')) {
- exclude module: 'geode-core'
- }
- integrationTestImplementation(project(':geode-dunit')) {
- exclude module: 'geode-core'
- }
- integrationTestImplementation(project(':geode-log4j')) {
- exclude module: 'geode-core'
- }
- integrationTestImplementation(project(':geode-concurrency-test'))
- integrationTestImplementation('org.apache.bcel:bcel')
- integrationTestImplementation('org.apache.logging.log4j:log4j-core')
- integrationTestImplementation('org.powermock:powermock-core')
- integrationTestImplementation('org.powermock:powermock-module-junit4')
- integrationTestImplementation('org.powermock:powermock-api-mockito2')
- integrationTestImplementation('pl.pragmatists:JUnitParams')
- integrationTestImplementation('com.tngtech.archunit:archunit-junit4')
-
-
- integrationTestRuntimeOnly('org.apache.derby:derby')
- integrationTestRuntimeOnly('xerces:xercesImpl')
-
- distributedTestImplementation(project(':geode-gfsh'))
- distributedTestImplementation(project(':geode-junit')) {
- exclude module: 'geode-core'
- }
- distributedTestImplementation(project(':geode-dunit')) {
- exclude module: 'geode-core'
- }
- distributedTestImplementation(project(':geode-log4j')) {
- exclude module: 'geode-core'
- }
- distributedTestImplementation('pl.pragmatists:JUnitParams')
- distributedTestImplementation('com.jayway.jsonpath:json-path-assert')
- distributedTestImplementation('net.openhft:compiler')
-
- distributedTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'testOutput'))
- distributedTestRuntimeOnly('org.apache.derby:derby')
-
-
- upgradeTestImplementation(project(':geode-dunit')) {
- exclude module: 'geode-core'
- }
-
- upgradeTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'testOutput'))
- upgradeTestRuntimeOnly(project(':geode-log4j'))
-
-
- performanceTestImplementation(project(':geode-junit')) {
- exclude module: 'geode-core'
- }
- performanceTestImplementation(project(':geode-log4j'))
+ //MX4J tools is used by the old admin API
+ implementation('mx4j:mx4j-tools') {
+ ext.optional = true
+ }
+
+ //JNA is used for locking memory and preallocating disk files.
+ implementation('net.java.dev.jna:jna')
+ implementation('net.java.dev.jna:jna-platform')
+
+ //JOptSimple is used by gfsh. A couple of usages have leaked into DiskStore
+ implementation('net.sf.jopt-simple:jopt-simple')
+
+ //Log4j is used everywhere
+ implementation('org.apache.logging.log4j:log4j-api')
+
+
+ implementation('io.swagger:swagger-annotations') {
+ ext.optional = true
+ }
+
+ runtimeOnly(project(':geode-http-service')) {
+ ext.optional = true
+ }
+
+ //Snappy is used for compressing values, if enabled
+ implementation('org.iq80.snappy:snappy') {
+ ext.optional = true
+ }
+
+ //Shiro is used for security checks throughout geode-core
+ //API - Shiro is exposed in geode's ResourcePermission class
+ api('org.apache.shiro:shiro-core')
+
+ //Classgraph is used by the gfsh cli, and also for function deployment (which happens in a server
+ //in response to a gfsh command)
+ implementation('io.github.classgraph:classgraph')
+
+ //RMIIO is used for uploading jar files and copying them between locator an servers
+ implementation('com.healthmarketscience.rmiio:rmiio')
+
+ //Geode-common has annotations and other pieces used geode-core
+ api(project(':geode-common'))
+ implementation(project(':geode-logging'))
+ implementation(project(':geode-membership'))
+ implementation(project(':geode-unsafe'))
+ implementation(project(':geode-serialization'))
+ implementation(project(':geode-tcp-server'))
+
+ //geode-management currently has pieces of the public API
+ //copied into it, so it is an API dependency
+ api(project(':geode-management'))
+
+
+ jcaCompile(sourceSets.main.output)
+
+ testImplementation(project(':geode-junit')) {
+ exclude module: 'geode-core'
+ }
+ testImplementation(project(':geode-concurrency-test'))
+ testImplementation('org.apache.bcel:bcel')
+ testImplementation('org.assertj:assertj-core')
+ testImplementation('org.mockito:mockito-core')
+ testImplementation('com.pholser:junit-quickcheck-core')
+ testImplementation('org.powermock:powermock-core')
+ testImplementation('org.powermock:powermock-module-junit4')
+ testImplementation('org.powermock:powermock-api-mockito2')
+ testImplementation('pl.pragmatists:JUnitParams')
+ testImplementation('com.tngtech.archunit:archunit-junit4')
+
+ testImplementation(files("${System.getProperty('java.home')}/../lib/tools.jar"))
+
+ testRuntime('commons-collections:commons-collections')
+ testRuntime('commons-configuration:commons-configuration')
+ testRuntime('commons-io:commons-io')
+ testRuntime('commons-validator:commons-validator')
+ testRuntime('com.pholser:junit-quickcheck-generators')
+ testRuntime(project(path: ':geode-old-versions', configuration: 'testOutput'))
+
+ integrationTestImplementation(project(':geode-gfsh'))
+ integrationTestImplementation(project(':geode-junit')) {
+ exclude module: 'geode-core'
+ }
+ integrationTestImplementation(project(':geode-dunit')) {
+ exclude module: 'geode-core'
+ }
+ integrationTestImplementation(project(':geode-log4j')) {
+ exclude module: 'geode-core'
+ }
+ integrationTestImplementation(project(':geode-concurrency-test'))
+ integrationTestImplementation('org.apache.bcel:bcel')
+ integrationTestImplementation('org.apache.logging.log4j:log4j-core')
+ integrationTestImplementation('org.powermock:powermock-core')
+ integrationTestImplementation('org.powermock:powermock-module-junit4')
+ integrationTestImplementation('org.powermock:powermock-api-mockito2')
+ integrationTestImplementation('pl.pragmatists:JUnitParams')
+ integrationTestImplementation('com.tngtech.archunit:archunit-junit4')
+
+
+ integrationTestRuntimeOnly('org.apache.derby:derby')
+ integrationTestRuntimeOnly('xerces:xercesImpl')
+
+ distributedTestImplementation(project(':geode-gfsh'))
+ distributedTestImplementation(project(':geode-junit')) {
+ exclude module: 'geode-core'
+ }
+ distributedTestImplementation(project(':geode-dunit')) {
+ exclude module: 'geode-core'
+ }
+ distributedTestImplementation(project(':geode-log4j')) {
+ exclude module: 'geode-core'
+ }
+ distributedTestImplementation('pl.pragmatists:JUnitParams')
+ distributedTestImplementation('com.jayway.jsonpath:json-path-assert')
+ distributedTestImplementation('net.openhft:compiler')
+
+ distributedTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'testOutput'))
+ distributedTestRuntimeOnly('org.apache.derby:derby')
+
+
+ upgradeTestImplementation(project(':geode-dunit')) {
+ exclude module: 'geode-core'
+ }
+
+ upgradeTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'testOutput'))
+ upgradeTestRuntimeOnly(project(':geode-log4j'))
+
+
+ performanceTestImplementation(project(':geode-junit')) {
+ exclude module: 'geode-core'
+ }
+ performanceTestImplementation(project(':geode-log4j'))
}
jmh {
- duplicateClassesStrategy = 'warn'
- include = project.hasProperty('jmh.include') ? project.getProperties().get('jmh.include') : '.*'
- profilers = project.hasProperty('jmh.profilers') ? project.getProperties().get('jmh.profilers').tokenize() : []
- threads = project.hasProperty('jmh.threads') ? project.getProperties().get('jmh.threads') : null
+ duplicateClassesStrategy = 'warn'
+ include = project.hasProperty('jmh.include') ? project.getProperties().get('jmh.include') : '.*'
+ profilers = project.hasProperty('jmh.profilers') ? project.getProperties().get('jmh.profilers').tokenize() : []
+ threads = project.hasProperty('jmh.threads') ? project.getProperties().get('jmh.threads') : null
}
jmhJar {
- inputs.files(project.sourceSets.main.output, project.sourceSets.test.output)
- from {
- [configurations.jmh, configurations.jmhRuntime, configurations.runtimeClasspath].collect {
- it.asFileTree.collect {
- it
+ inputs.files(project.sourceSets.main.output, project.sourceSets.test.output)
+ from {
+ [configurations.jmh, configurations.jmhRuntime, configurations.runtimeClasspath].collect {
+ it.asFileTree.collect {
+ it
+ }
+ }.flatten().unique().collect {
+ it.isDirectory() ? it : zipTree(it)
}
- }.flatten().unique().collect {
- it.isDirectory() ? it : zipTree(it)
- }
- }
- exclude(['META-INF/*.SF'])
- exclude('META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat')
- exclude('*.jar')
+ }
+ exclude(['META-INF/*.SF'])
+ exclude('META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat')
+ exclude('*.jar')
}
tasks.eclipse.dependsOn(generateGrammarSource)
distributedTest {
- // Some tests have inner tests that should be ignored
- exclude "**/*\$*.class"
+ // Some tests have inner tests that should be ignored
+ exclude "**/*\$*.class"
}
rootProject.generate.dependsOn(generateGrammarSource)