You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by bs...@apache.org on 2017/08/22 22:36:09 UTC
[07/48] geode git commit: GEODE-3434: Allow the modules to be
interoperable with current and older versions of tomcat 7
GEODE-3434: Allow the modules to be interoperable with current and older versions of tomcat 7
* Modified DeltaSessions to use reflection to handle attributes fields incase an earlier tomcat 7 is used
* Modified DeltaSession7 and DeltaSession8 to extend from DeltaSession
* Added session backward compatibility tests
* Modified aseembly build to download old product installs
* Minor refactor of VersionManager to reuse property file load code
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/f38dff9d
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/f38dff9d
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/f38dff9d
Branch: refs/heads/feature/GEODE-3447
Commit: f38dff9d217a8808117b6fbb2e5f4021ef9c84ce
Parents: 0486700
Author: Jason Huynh <hu...@gmail.com>
Authored: Mon Aug 14 09:02:11 2017 -0700
Committer: Jason Huynh <hu...@gmail.com>
Committed: Thu Aug 17 17:00:14 2017 -0700
----------------------------------------------------------------------
.../modules/session/catalina/DeltaSession7.java | 572 +------------------
.../modules/session/catalina/DeltaSession8.java | 570 +-----------------
.../modules/session/catalina/DeltaSession.java | 50 +-
geode-assembly/build.gradle | 3 +
.../geode/session/tests/ContainerInstall.java | 96 ++--
.../geode/session/tests/TomcatInstall.java | 68 +--
...TomcatSessionBackwardsCompatibilityTest.java | 244 ++++++++
.../test/dunit/standalone/VersionManager.java | 72 ++-
.../standalone/VersionManagerJUnitTest.java | 6 +-
geode-old-versions/build.gradle | 64 ++-
10 files changed, 495 insertions(+), 1250 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/f38dff9d/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession7.java
----------------------------------------------------------------------
diff --git a/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession7.java b/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession7.java
index d7f30bd..f5dfbdc 100644
--- a/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession7.java
+++ b/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession7.java
@@ -14,88 +14,17 @@
*/
package org.apache.geode.modules.session.catalina;
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.AccessController;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import javax.servlet.http.HttpSession;
-
import org.apache.catalina.Manager;
-import org.apache.catalina.realm.GenericPrincipal;
-import org.apache.catalina.security.SecurityUtil;
-import org.apache.catalina.session.StandardSession;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
-
-import org.apache.geode.DataSerializable;
-import org.apache.geode.DataSerializer;
-import org.apache.geode.Delta;
-import org.apache.geode.InvalidDeltaException;
-import org.apache.geode.cache.Region;
-import org.apache.geode.internal.cache.lru.Sizeable;
-import org.apache.geode.internal.util.BlobHelper;
-import org.apache.geode.modules.gatewaydelta.GatewayDelta;
-import org.apache.geode.modules.gatewaydelta.GatewayDeltaEvent;
-import org.apache.geode.modules.session.catalina.internal.DeltaSessionAttributeEvent;
-import org.apache.geode.modules.session.catalina.internal.DeltaSessionAttributeEventBatch;
-import org.apache.geode.modules.session.catalina.internal.DeltaSessionDestroyAttributeEvent;
-import org.apache.geode.modules.session.catalina.internal.DeltaSessionUpdateAttributeEvent;
@SuppressWarnings("serial")
-public class DeltaSession7 extends StandardSession
- implements DataSerializable, Delta, GatewayDelta, Sizeable, DeltaSessionInterface {
-
- private transient Region<String, HttpSession> operatingRegion;
-
- private String sessionRegionName;
-
- private String contextName;
-
- private boolean hasDelta;
-
- private boolean applyRemotely;
-
- private boolean enableGatewayDeltaReplication;
-
- private transient final Object changeLock = new Object();
-
- private final List<DeltaSessionAttributeEvent> eventQueue =
- new ArrayList<DeltaSessionAttributeEvent>();
-
- private transient GatewayDeltaEvent currentGatewayDeltaEvent;
-
- private transient boolean expired = false;
-
- private transient boolean preferDeserializedForm = true;
-
- private byte[] serializedPrincipal;
-
- private final Log LOG = LogFactory.getLog(DeltaSession7.class.getName());
-
- /**
- * The string manager for this package.
- */
- // protected static StringManager STRING_MANAGER =
- // StringManager.getManager("org.apache.geode.modules.session.catalina");
+public class DeltaSession7 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)}.
*/
public DeltaSession7() {
- super(null);
+ super();
}
/**
@@ -105,503 +34,6 @@ public class DeltaSession7 extends StandardSession
*/
public DeltaSession7(Manager manager) {
super(manager);
- setOwner(manager);
- }
-
- /**
- * Return the <code>HttpSession</code> for which this object is the facade.
- */
- @SuppressWarnings("unchecked")
- public HttpSession getSession() {
- if (facade == null) {
- if (SecurityUtil.isPackageProtectionEnabled()) {
- final DeltaSession7 fsession = this;
- facade = (DeltaSessionFacade) AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- return new DeltaSessionFacade(fsession);
- }
- });
- } else {
- facade = new DeltaSessionFacade(this);
- }
- }
- return (facade);
- }
-
- public Principal getPrincipal() {
- if (this.principal == null && this.serializedPrincipal != null) {
- Principal sp = null;
- try {
- sp = (Principal) BlobHelper.deserializeBlob(this.serializedPrincipal);
- } catch (Exception e) {
- StringBuilder builder = new StringBuilder();
- builder.append(this).append(
- ": Serialized principal contains a byte[] that cannot be deserialized due to the following exception");
- ((DeltaSessionManager) getManager()).getLogger().warn(builder.toString(), e);
- return null;
- }
- this.principal = sp;
- if (getManager() != null) {
- DeltaSessionManager mgr = (DeltaSessionManager) getManager();
- if (mgr.getLogger().isDebugEnabled()) {
- mgr.getLogger().debug(this + ": Deserialized principal: " + this.principal);
- }
- }
- }
- return this.principal;
}
- public void setPrincipal(Principal principal) {
- super.setPrincipal(principal);
-
- // Put the session into the region to serialize the principal
- if (getManager() != null) {
- // TODO convert this to a delta
- getManager().add(this);
- DeltaSessionManager mgr = (DeltaSessionManager) getManager();
- if (mgr.getLogger().isDebugEnabled()) {
- mgr.getLogger().debug(this + ": Cached principal: " + principal);
- }
- }
- }
-
- private byte[] getSerializedPrincipal() {
- if (this.serializedPrincipal == null) {
- if (this.principal != null && this.principal instanceof GenericPrincipal) {
- GenericPrincipal gp = (GenericPrincipal) this.principal;
- this.serializedPrincipal = serialize(gp);
- if (manager != null) {
- DeltaSessionManager mgr = (DeltaSessionManager) getManager();
- if (mgr.getLogger().isDebugEnabled()) {
- mgr.getLogger().debug(this + ": Serialized principal: " + gp);
- }
- }
- }
- }
- return this.serializedPrincipal;
- }
-
- protected Region<String, HttpSession> getOperatingRegion() {
- // This region shouldn't be null when it is needed.
- // It should have been set by the setOwner method.
- return this.operatingRegion;
- }
-
- public boolean isCommitEnabled() {
- DeltaSessionManager mgr = (DeltaSessionManager) getManager();
- return mgr.isCommitValveEnabled();
- }
-
- public GatewayDeltaEvent getCurrentGatewayDeltaEvent() {
- return this.currentGatewayDeltaEvent;
- }
-
- public void setCurrentGatewayDeltaEvent(GatewayDeltaEvent currentGatewayDeltaEvent) {
- this.currentGatewayDeltaEvent = currentGatewayDeltaEvent;
- }
-
- @SuppressWarnings("unchecked")
- public void setOwner(Object manager) {
- if (manager instanceof DeltaSessionManager) {
- DeltaSessionManager sessionManager = (DeltaSessionManager) manager;
- this.manager = sessionManager;
- initializeRegion(sessionManager);
- this.hasDelta = false;
- this.applyRemotely = false;
- this.enableGatewayDeltaReplication = sessionManager.getEnableGatewayDeltaReplication();
- this.preferDeserializedForm = sessionManager.getPreferDeserializedForm();
-
- // Initialize transient variables
- if (this.listeners == null) {
- this.listeners = new ArrayList();
- }
-
- if (this.notes == null) {
- this.notes = new Hashtable();
- }
-
- contextName = ((DeltaSessionManager) manager).getContextName();
- } else {
- throw new IllegalArgumentException(this + ": The Manager must be an AbstractManager");
- }
- }
-
- private void checkBackingCacheAvailable() {
- if (!((SessionManager) getManager()).isBackingCacheAvailable()) {
- throw new IllegalStateException("No backing cache server is available.");
- }
- }
-
- public void setAttribute(String name, Object value, boolean notify) {
- checkBackingCacheAvailable();
- synchronized (this.changeLock) {
- // Serialize the value
- byte[] serializedValue = serialize(value);
-
- // Store the attribute locally
- if (this.preferDeserializedForm) {
- super.setAttribute(name, value, true);
- } else {
- super.setAttribute(name, serializedValue, true);
- }
-
- if (serializedValue == null) {
- return;
- }
-
- // Create the update attribute message
- DeltaSessionAttributeEvent event =
- new DeltaSessionUpdateAttributeEvent(name, serializedValue);
- queueAttributeEvent(event, true);
-
- // Distribute the update
- if (!isCommitEnabled()) {
- putInRegion(getOperatingRegion(), true, null);
- }
- }
- }
-
- public void removeAttribute(String name, boolean notify) {
- checkBackingCacheAvailable();
- if (expired) {
- return;
- }
- synchronized (this.changeLock) {
- // Remove the attribute locally
- super.removeAttribute(name, true);
-
- // Create the destroy attribute message
- DeltaSessionAttributeEvent event = new DeltaSessionDestroyAttributeEvent(name);
- queueAttributeEvent(event, true);
-
- // Distribute the update
- if (!isCommitEnabled()) {
- putInRegion(getOperatingRegion(), true, null);
- }
- }
- }
-
- public Object getAttribute(String name) {
- checkBackingCacheAvailable();
- Object value = super.getAttribute(name);
-
- // If the attribute is a byte[] (meaning it came from the server),
- // deserialize it and add it to attributes map before returning it.
- if (value instanceof byte[]) {
- try {
- value = BlobHelper.deserializeBlob((byte[]) value);
- } catch (Exception e) {
- StringBuilder builder = new StringBuilder();
- builder.append(this).append(": Attribute named ").append(name).append(
- " contains a byte[] that cannot be deserialized due to the following exception");
- ((DeltaSessionManager) getManager()).getLogger().warn(builder.toString(), e);
- }
- if (this.preferDeserializedForm) {
- localUpdateAttribute(name, value);
- }
- }
-
- // Touch the session region if necessary. This is an asynchronous operation
- // that prevents the session region from prematurely expiring a session that
- // is only getting attributes.
- ((DeltaSessionManager) getManager()).addSessionToTouch(getId());
-
- return value;
- }
-
- public void invalidate() {
- super.invalidate();
- // getOperatingRegion().destroy(this.id, true); // already done in super (remove)
- ((DeltaSessionManager) getManager()).getStatistics().incSessionsInvalidated();
- }
-
- public void processExpired() {
- DeltaSessionManager manager = (DeltaSessionManager) getManager();
- if (manager != null && manager.getLogger() != null && manager.getLogger().isDebugEnabled()) {
- ((DeltaSessionManager) getManager()).getLogger().debug(this + ": Expired");
- }
-
- // Set expired (so region.destroy is not called again)
- setExpired(true);
-
- // Do expire processing
- super.expire(true);
-
- // Update statistics
- if (manager != null) {
- manager.getStatistics().incSessionsExpired();
- }
- }
-
- @Override
- public void expire(boolean notify) {
- if (notify) {
- getOperatingRegion().destroy(this.getId(), this);
- } else {
- super.expire(false);
- }
- }
-
- public void setMaxInactiveInterval(int interval) {
- super.setMaxInactiveInterval(interval);
- }
-
- public void localUpdateAttribute(String name, Object value) {
- super.setAttribute(name, value, false); // don't do notification since this is a replication
- }
-
- public void localDestroyAttribute(String name) {
- super.removeAttribute(name, false); // don't do notification since this is a replication
- }
-
- public void applyAttributeEvents(Region<String, DeltaSessionInterface> region,
- List<DeltaSessionAttributeEvent> events) {
- for (DeltaSessionAttributeEvent event : events) {
- event.apply(this);
- queueAttributeEvent(event, false);
- }
-
- putInRegion(region, false, true);
- }
-
- private void initializeRegion(DeltaSessionManager sessionManager) {
- // Get the session region name
- this.sessionRegionName = sessionManager.getRegionName();
-
- // Get the operating region.
- // If a P2P manager is used, then this will be a local region fronting the
- // session region if local cache is enabled; otherwise, it will be the
- // session region itself.
- // If a CS manager is used, it will be the session proxy region.
- this.operatingRegion = sessionManager.getSessionCache().getOperatingRegion();
- if (sessionManager.getLogger().isDebugEnabled()) {
- sessionManager.getLogger().debug(this + ": Set operating region: " + this.operatingRegion);
- }
- }
-
- private void queueAttributeEvent(DeltaSessionAttributeEvent event,
- boolean checkAddToCurrentGatewayDelta) {
- // Add to current gateway delta if necessary
- if (checkAddToCurrentGatewayDelta) {
- // If the manager has enabled gateway delta replication and is a P2P
- // manager, the GatewayDeltaForwardCacheListener will be invoked in this
- // VM. Add the event to the currentDelta.
- DeltaSessionManager mgr = (DeltaSessionManager) this.manager;
- if (this.enableGatewayDeltaReplication && mgr.isPeerToPeer()) {
- // If commit is not enabled, add the event to the current batch; else,
- // the current batch will be initialized to the events in the queue will
- // be added at commit time.
- if (!isCommitEnabled()) {
- List<DeltaSessionAttributeEvent> events = new ArrayList<DeltaSessionAttributeEvent>();
- events.add(event);
- this.currentGatewayDeltaEvent =
- new DeltaSessionAttributeEventBatch(this.sessionRegionName, this.id, events);
- }
- }
- }
- this.eventQueue.add(event);
- }
-
- @SuppressWarnings("unchecked")
- private void putInRegion(Region region, boolean applyRemotely, Object callbackArgument) {
- this.hasDelta = true;
- this.applyRemotely = applyRemotely;
- region.put(this.id, this, callbackArgument);
- this.eventQueue.clear();
- }
-
- public void commit() {
- if (!isValidInternal())
- throw new IllegalStateException("commit: Session " + getId() + " already invalidated");
-
- synchronized (this.changeLock) {
- // Jens - there used to be a check to only perform this if the queue is
- // empty, but we want this to always run so that the lastAccessedTime
- // will be updated even when no attributes have been changed.
- DeltaSessionManager mgr = (DeltaSessionManager) this.manager;
- if (this.enableGatewayDeltaReplication && mgr.isPeerToPeer()) {
- setCurrentGatewayDeltaEvent(
- new DeltaSessionAttributeEventBatch(this.sessionRegionName, this.id, this.eventQueue));
- }
- this.hasDelta = true;
- this.applyRemotely = true;
- putInRegion(getOperatingRegion(), true, null);
- this.eventQueue.clear();
- }
- }
-
- public void abort() {
- synchronized (this.changeLock) {
- this.eventQueue.clear();
- }
- }
-
- private void setExpired(boolean expired) {
- this.expired = expired;
- }
-
- public boolean getExpired() {
- return this.expired;
- }
-
- public String getContextName() {
- return contextName;
- }
-
- public boolean hasDelta() {
- return this.hasDelta;
- }
-
- public void toDelta(DataOutput out) throws IOException {
- // Write whether to apply the changes to another DS if necessary
- out.writeBoolean(this.applyRemotely);
-
- // Write the events
- DataSerializer.writeArrayList((ArrayList) this.eventQueue, out);
-
- out.writeLong(this.lastAccessedTime);
- out.writeInt(this.maxInactiveInterval);
- }
-
- public void fromDelta(DataInput in) throws IOException, InvalidDeltaException {
- // Read whether to apply the changes to another DS if necessary
- this.applyRemotely = in.readBoolean();
-
- // Read the events
- List<DeltaSessionAttributeEvent> events = null;
- try {
- events = DataSerializer.readArrayList(in);
- } catch (ClassNotFoundException e) {
- throw new InvalidDeltaException(e);
- }
-
- // This allows for backwards compatibility with 2.1 clients
- if (((InputStream) in).available() > 0) {
- this.lastAccessedTime = in.readLong();
- this.maxInactiveInterval = in.readInt();
- }
-
- // Iterate and apply the events
- for (DeltaSessionAttributeEvent event : events) {
- event.apply(this);
- }
-
- // Add the events to the gateway delta region if necessary
- if (this.enableGatewayDeltaReplication && this.applyRemotely) {
- setCurrentGatewayDeltaEvent(
- new DeltaSessionAttributeEventBatch(this.sessionRegionName, this.id, events));
- }
-
- // Access it to set the last accessed time. End access it to set not new.
- access();
- endAccess();
- }
-
- @Override
- public void toData(DataOutput out) throws IOException {
- // Write the StandardSession state
- DataSerializer.writeString(this.id, out);
- out.writeLong(this.creationTime);
- out.writeLong(this.lastAccessedTime);
- out.writeLong(this.thisAccessedTime);
- out.writeInt(this.maxInactiveInterval);
- out.writeBoolean(this.isNew);
- out.writeBoolean(this.isValid);
- DataSerializer.writeObject(getSerializedAttributes(), out);
- DataSerializer.writeByteArray(getSerializedPrincipal(), out);
-
- // Write the DeltaSession state
- out.writeBoolean(this.enableGatewayDeltaReplication);
- DataSerializer.writeString(this.sessionRegionName, out);
-
- DataSerializer.writeString(this.contextName, out);
- }
-
- @Override
- public void fromData(DataInput in) throws IOException, ClassNotFoundException {
- // Read the StandardSession state
- this.id = DataSerializer.readString(in);
- this.creationTime = in.readLong();
- this.lastAccessedTime = in.readLong();
- this.thisAccessedTime = in.readLong();
- this.maxInactiveInterval = in.readInt();
- this.isNew = in.readBoolean();
- this.isValid = in.readBoolean();
- this.attributes = readInAttributes(in);
- this.serializedPrincipal = DataSerializer.readByteArray(in);
-
- // Read the DeltaSession state
- this.enableGatewayDeltaReplication = in.readBoolean();
- this.sessionRegionName = DataSerializer.readString(in);
-
- // This allows for backwards compatibility with 2.1 clients
- if (((InputStream) in).available() > 0) {
- this.contextName = DataSerializer.readString(in);
- }
-
- // Initialize the transients if necessary
- if (this.listeners == null) {
- this.listeners = new ArrayList<>();
- }
-
- if (this.notes == null) {
- this.notes = new Hashtable<>();
- }
- }
-
- protected ConcurrentMap<String, Object> readInAttributes(final DataInput in)
- throws IOException, ClassNotFoundException {
- return DataSerializer.readObject(in);
- }
-
- @Override
- public int getSizeInBytes() {
- int size = 0;
- for (Enumeration<String> e = getAttributeNames(); e.hasMoreElements();) {
- // Don't use this.getAttribute() because we don't want to deserialize
- // the value.
- Object value = super.getAttribute(e.nextElement());
- if (value instanceof byte[]) {
- size += ((byte[]) value).length;
- }
- }
-
- return size;
- }
-
- @SuppressWarnings({"unchecked", "rawtypes"})
- protected ConcurrentMap<String, byte[]> getSerializedAttributes() {
- // Iterate the values and serialize them if necessary before sending them to the server. This
- // makes the application classes unnecessary on the server.
- ConcurrentMap<String, byte[]> serializedAttributes = new ConcurrentHashMap<String, byte[]>();
- for (Iterator i = this.attributes.entrySet().iterator(); i.hasNext();) {
- Map.Entry<String, Object> entry = (Map.Entry<String, Object>) i.next();
- Object value = entry.getValue();
- byte[] serializedValue = value instanceof byte[] ? (byte[]) value : serialize(value);
- serializedAttributes.put(entry.getKey(), serializedValue);
- }
- return serializedAttributes;
- }
-
- protected byte[] serialize(Object obj) {
- byte[] serializedValue = null;
- try {
- serializedValue = BlobHelper.serializeToBlob(obj);
- } catch (IOException e) {
- StringBuilder builder = new StringBuilder();
- builder.append(this).append(": Object ").append(obj)
- .append(" cannot be serialized due to the following exception");
- ((DeltaSessionManager) getManager()).getLogger().warn(builder.toString(), e);
- }
- return serializedValue;
- }
-
- @Override
- public String toString() {
- return new StringBuilder().append("DeltaSession[").append("id=").append(getId())
- .append("; context=").append(this.contextName).append("; sessionRegionName=")
- .append(this.sessionRegionName).append("; operatingRegionName=")
- .append(getOperatingRegion() == null ? "unset" : getOperatingRegion().getFullPath())
- .append("]").toString();
- }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/f38dff9d/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession8.java
----------------------------------------------------------------------
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 f69382a..f2e797e 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
@@ -14,83 +14,17 @@
*/
package org.apache.geode.modules.session.catalina;
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.AccessController;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import javax.servlet.http.HttpSession;
-
import org.apache.catalina.Manager;
-import org.apache.catalina.realm.GenericPrincipal;
-import org.apache.catalina.security.SecurityUtil;
-import org.apache.catalina.session.StandardSession;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
-
-import org.apache.geode.DataSerializable;
-import org.apache.geode.DataSerializer;
-import org.apache.geode.Delta;
-import org.apache.geode.InvalidDeltaException;
-import org.apache.geode.cache.Region;
-import org.apache.geode.internal.cache.lru.Sizeable;
-import org.apache.geode.internal.util.BlobHelper;
-import org.apache.geode.modules.gatewaydelta.GatewayDelta;
-import org.apache.geode.modules.gatewaydelta.GatewayDeltaEvent;
-import org.apache.geode.modules.session.catalina.internal.DeltaSessionAttributeEvent;
-import org.apache.geode.modules.session.catalina.internal.DeltaSessionAttributeEventBatch;
-import org.apache.geode.modules.session.catalina.internal.DeltaSessionDestroyAttributeEvent;
-import org.apache.geode.modules.session.catalina.internal.DeltaSessionUpdateAttributeEvent;
@SuppressWarnings("serial")
-public class DeltaSession8 extends StandardSession
- implements DataSerializable, Delta, GatewayDelta, Sizeable, DeltaSessionInterface {
-
- private transient Region<String, HttpSession> operatingRegion;
-
- private String sessionRegionName;
-
- private String contextName;
-
- private boolean hasDelta;
-
- private boolean applyRemotely;
-
- private boolean enableGatewayDeltaReplication;
-
- private transient final Object changeLock = new Object();
-
- private final List<DeltaSessionAttributeEvent> eventQueue =
- new ArrayList<DeltaSessionAttributeEvent>();
-
- private transient GatewayDeltaEvent currentGatewayDeltaEvent;
-
- private transient boolean expired = false;
-
- private transient boolean preferDeserializedForm = true;
-
- private byte[] serializedPrincipal;
-
- private final Log LOG = LogFactory.getLog(DeltaSession.class.getName());
-
+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)}.
*/
public DeltaSession8() {
- super(null);
+ super();
}
/**
@@ -100,506 +34,6 @@ public class DeltaSession8 extends StandardSession
*/
public DeltaSession8(Manager manager) {
super(manager);
- setOwner(manager);
- }
-
- /**
- * Return the <code>HttpSession</code> for which this object is the facade.
- */
- @SuppressWarnings("unchecked")
- public HttpSession getSession() {
- if (facade == null) {
- if (SecurityUtil.isPackageProtectionEnabled()) {
- final DeltaSession8 fsession = this;
- facade = (DeltaSessionFacade) AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- return new DeltaSessionFacade(fsession);
- }
- });
- } else {
- facade = new DeltaSessionFacade(this);
- }
- }
- return (facade);
- }
-
- public Principal getPrincipal() {
- if (this.principal == null && this.serializedPrincipal != null) {
-
- Principal sp = null;
- try {
- sp = (Principal) BlobHelper.deserializeBlob(this.serializedPrincipal);
- } catch (Exception e) {
- StringBuilder builder = new StringBuilder();
- builder.append(this).append(
- ": Serialized principal contains a byte[] that cannot be deserialized due to the following exception");
- ((DeltaSessionManager) getManager()).getLogger().warn(builder.toString(), e);
- return null;
- }
- this.principal = sp;
- if (getManager() != null) {
- DeltaSessionManager mgr = (DeltaSessionManager) getManager();
- if (mgr.getLogger().isDebugEnabled()) {
- mgr.getLogger().debug(this + ": Deserialized principal: " + this.principal);
- }
- }
- }
- return this.principal;
- }
-
- public void setPrincipal(Principal principal) {
- super.setPrincipal(principal);
-
- // Put the session into the region to serialize the principal
- if (getManager() != null) {
- getManager().add(this);
- DeltaSessionManager mgr = (DeltaSessionManager) getManager();
- if (mgr.getLogger().isDebugEnabled()) {
- mgr.getLogger().debug(this + ": Cached principal: " + principal);
- }
- }
- }
-
- private byte[] getSerializedPrincipal() {
- if (this.serializedPrincipal == null) {
- if (this.principal != null && this.principal instanceof GenericPrincipal) {
- GenericPrincipal gp = (GenericPrincipal) this.principal;
- this.serializedPrincipal = serialize(gp);
- if (manager != null) {
- DeltaSessionManager mgr = (DeltaSessionManager) getManager();
- if (mgr.getLogger().isDebugEnabled()) {
- mgr.getLogger().debug(this + ": Serialized principal: " + gp);
- }
- }
- }
- }
- return this.serializedPrincipal;
- }
-
- protected Region<String, HttpSession> getOperatingRegion() {
- // This region shouldn't be null when it is needed.
- // It should have been set by the setOwner method.
- return this.operatingRegion;
- }
-
- public boolean isCommitEnabled() {
- DeltaSessionManager mgr = (DeltaSessionManager) getManager();
- return mgr.isCommitValveEnabled();
- }
-
- public GatewayDeltaEvent getCurrentGatewayDeltaEvent() {
- return this.currentGatewayDeltaEvent;
- }
-
- public void setCurrentGatewayDeltaEvent(GatewayDeltaEvent currentGatewayDeltaEvent) {
- this.currentGatewayDeltaEvent = currentGatewayDeltaEvent;
- }
-
- @SuppressWarnings("unchecked")
- public void setOwner(Object manager) {
- if (manager instanceof DeltaSessionManager) {
- DeltaSessionManager sessionManager = (DeltaSessionManager) manager;
- this.manager = sessionManager;
- initializeRegion(sessionManager);
- this.hasDelta = false;
- this.applyRemotely = false;
- this.enableGatewayDeltaReplication = sessionManager.getEnableGatewayDeltaReplication();
- this.preferDeserializedForm = sessionManager.getPreferDeserializedForm();
-
- // Initialize transient variables
- if (this.listeners == null) {
- this.listeners = new ArrayList();
- }
-
- if (this.notes == null) {
- this.notes = new Hashtable();
- }
-
- contextName = ((DeltaSessionManager) manager).getContextName();
- } else {
- throw new IllegalArgumentException(this + ": The Manager must be an AbstractManager");
- }
- }
-
- private void checkBackingCacheAvailable() {
- if (!((SessionManager) getManager()).isBackingCacheAvailable()) {
- throw new IllegalStateException("No backing cache server is available.");
- }
- }
-
- public void setAttribute(String name, Object value, boolean notify) {
- checkBackingCacheAvailable();
- synchronized (this.changeLock) {
- // Serialize the value
- byte[] serializedValue = serialize(value);
-
- // Store the attribute locally
- if (this.preferDeserializedForm) {
- super.setAttribute(name, value, true);
- } else {
- super.setAttribute(name, serializedValue, true);
- }
-
- if (serializedValue == null) {
- return;
- }
-
- // Create the update attribute message
- DeltaSessionAttributeEvent event =
- new DeltaSessionUpdateAttributeEvent(name, serializedValue);
- queueAttributeEvent(event, true);
-
- // Distribute the update
- if (!isCommitEnabled()) {
- putInRegion(getOperatingRegion(), true, null);
- }
- }
- }
-
- public void removeAttribute(String name, boolean notify) {
- checkBackingCacheAvailable();
- if (expired) {
- return;
- }
- synchronized (this.changeLock) {
- // Remove the attribute locally
- super.removeAttribute(name, true);
-
- // Create the destroy attribute message
- DeltaSessionAttributeEvent event = new DeltaSessionDestroyAttributeEvent(name);
- queueAttributeEvent(event, true);
-
- // Distribute the update
- if (!isCommitEnabled()) {
- putInRegion(getOperatingRegion(), true, null);
- }
- }
- }
-
- public Object getAttribute(String name) {
- checkBackingCacheAvailable();
- Object value = super.getAttribute(name);
-
- // If the attribute is a byte[] (meaning it came from the server),
- // deserialize it and add it to attributes map before returning it.
- if (value instanceof byte[]) {
- try {
- value = BlobHelper.deserializeBlob((byte[]) value);
- } catch (Exception e) {
- StringBuilder builder = new StringBuilder();
- builder.append(this).append(": Attribute named ").append(name).append(
- " contains a byte[] that cannot be deserialized due to the following exception");
- ((DeltaSessionManager) getManager()).getLogger().warn(builder.toString(), e);
- }
- if (this.preferDeserializedForm) {
- localUpdateAttribute(name, value);
- }
- }
-
- // Touch the session region if necessary. This is an asynchronous operation
- // that prevents the session region from prematurely expiring a session that
- // is only getting attributes.
- ((DeltaSessionManager) getManager()).addSessionToTouch(getId());
-
- return value;
- }
-
- public void invalidate() {
- super.invalidate();
- // getOperatingRegion().destroy(this.id, true); // already done in super (remove)
- ((DeltaSessionManager) getManager()).getStatistics().incSessionsInvalidated();
- }
-
- public void processExpired() {
- DeltaSessionManager manager = (DeltaSessionManager) getManager();
- if (manager != null && manager.getLogger() != null && manager.getLogger().isDebugEnabled()) {
- ((DeltaSessionManager) getManager()).getLogger().debug(this + ": Expired");
- }
-
- // Set expired (so region.destroy is not called again)
- setExpired(true);
-
- // Do expire processing
- super.expire(true);
-
- // Update statistics
- if (manager != null) {
- manager.getStatistics().incSessionsExpired();
- }
- }
-
- @Override
- public void expire(boolean notify) {
- if (notify) {
- getOperatingRegion().destroy(this.getId(), this);
- } else {
- super.expire(false);
- }
- }
-
- public void setMaxInactiveInterval(int interval) {
- super.setMaxInactiveInterval(interval);
- }
-
- public void localUpdateAttribute(String name, Object value) {
- super.setAttribute(name, value, false); // don't do notification since this is a replication
- }
-
- public void localDestroyAttribute(String name) {
- super.removeAttribute(name, false); // don't do notification since this is a replication
- }
-
- public void applyAttributeEvents(Region<String, DeltaSessionInterface> region,
- List<DeltaSessionAttributeEvent> events) {
- for (DeltaSessionAttributeEvent event : events) {
- event.apply(this);
- queueAttributeEvent(event, false);
- }
-
- putInRegion(region, false, true);
- }
-
- private void initializeRegion(DeltaSessionManager sessionManager) {
- // Get the session region name
- this.sessionRegionName = sessionManager.getRegionName();
-
- // Get the operating region.
- // If a P2P manager is used, then this will be a local region fronting the
- // session region if local cache is enabled; otherwise, it will be the
- // session region itself.
- // If a CS manager is used, it will be the session proxy region.
- this.operatingRegion = sessionManager.getSessionCache().getOperatingRegion();
- if (sessionManager.getLogger().isDebugEnabled()) {
- sessionManager.getLogger().debug(this + ": Set operating region: " + this.operatingRegion);
- }
- }
-
- private void queueAttributeEvent(DeltaSessionAttributeEvent event,
- boolean checkAddToCurrentGatewayDelta) {
- // Add to current gateway delta if necessary
- if (checkAddToCurrentGatewayDelta) {
- // If the manager has enabled gateway delta replication and is a P2P
- // manager, the GatewayDeltaForwardCacheListener will be invoked in this
- // VM. Add the event to the currentDelta.
- DeltaSessionManager mgr = (DeltaSessionManager) this.manager;
- if (this.enableGatewayDeltaReplication && mgr.isPeerToPeer()) {
- // If commit is not enabled, add the event to the current batch; else,
- // the current batch will be initialized to the events in the queue will
- // be added at commit time.
- if (!isCommitEnabled()) {
- List<DeltaSessionAttributeEvent> events = new ArrayList<DeltaSessionAttributeEvent>();
- events.add(event);
- this.currentGatewayDeltaEvent =
- new DeltaSessionAttributeEventBatch(this.sessionRegionName, this.id, events);
- }
- }
- }
- this.eventQueue.add(event);
- }
-
- @SuppressWarnings("unchecked")
- private void putInRegion(Region region, boolean applyRemotely, Object callbackArgument) {
- this.hasDelta = true;
- this.applyRemotely = applyRemotely;
- region.put(this.id, this, callbackArgument);
- this.eventQueue.clear();
- }
-
- public void commit() {
- if (!isValidInternal())
- throw new IllegalStateException("commit: Session " + getId() + " already invalidated");
- // (STRING_MANAGER.getString("deltaSession.commit.ise", getId()));
-
- synchronized (this.changeLock) {
- // Jens - there used to be a check to only perform this if the queue is
- // empty, but we want this to always run so that the lastAccessedTime
- // will be updated even when no attributes have been changed.
- DeltaSessionManager mgr = (DeltaSessionManager) this.manager;
- if (this.enableGatewayDeltaReplication && mgr.isPeerToPeer()) {
- setCurrentGatewayDeltaEvent(
- new DeltaSessionAttributeEventBatch(this.sessionRegionName, this.id, this.eventQueue));
- }
- this.hasDelta = true;
- this.applyRemotely = true;
- putInRegion(getOperatingRegion(), true, null);
- this.eventQueue.clear();
- }
- }
-
- public void abort() {
- synchronized (this.changeLock) {
- this.eventQueue.clear();
- }
- }
-
- private void setExpired(boolean expired) {
- this.expired = expired;
- }
-
- public boolean getExpired() {
- return this.expired;
- }
-
- public String getContextName() {
- return contextName;
- }
-
- public boolean hasDelta() {
- return this.hasDelta;
- }
-
- public void toDelta(DataOutput out) throws IOException {
- // Write whether to apply the changes to another DS if necessary
- out.writeBoolean(this.applyRemotely);
-
- // Write the events
- DataSerializer.writeArrayList((ArrayList) this.eventQueue, out);
-
- out.writeLong(this.lastAccessedTime);
- out.writeInt(this.maxInactiveInterval);
- }
-
- public void fromDelta(DataInput in) throws IOException, InvalidDeltaException {
- // Read whether to apply the changes to another DS if necessary
- this.applyRemotely = in.readBoolean();
-
- // Read the events
- List<DeltaSessionAttributeEvent> events = null;
- try {
- events = DataSerializer.readArrayList(in);
- } catch (ClassNotFoundException e) {
- throw new InvalidDeltaException(e);
- }
-
- // This allows for backwards compatibility with 2.1 clients
- if (((InputStream) in).available() > 0) {
- this.lastAccessedTime = in.readLong();
- this.maxInactiveInterval = in.readInt();
- }
-
- // Iterate and apply the events
- for (DeltaSessionAttributeEvent event : events) {
- event.apply(this);
- }
-
- // Add the events to the gateway delta region if necessary
- if (this.enableGatewayDeltaReplication && this.applyRemotely) {
- setCurrentGatewayDeltaEvent(
- new DeltaSessionAttributeEventBatch(this.sessionRegionName, this.id, events));
- }
-
- // Access it to set the last accessed time. End access it to set not new.
- access();
- endAccess();
- }
-
- @Override
- public void toData(DataOutput out) throws IOException {
- // Write the StandardSession state
- DataSerializer.writeString(this.id, out);
- out.writeLong(this.creationTime);
- out.writeLong(this.lastAccessedTime);
- out.writeLong(this.thisAccessedTime);
- out.writeInt(this.maxInactiveInterval);
- out.writeBoolean(this.isNew);
- out.writeBoolean(this.isValid);
- DataSerializer.writeObject(getSerializedAttributes(), out);
- DataSerializer.writeByteArray(getSerializedPrincipal(), out);
-
- // Write the DeltaSession state
- out.writeBoolean(this.enableGatewayDeltaReplication);
- DataSerializer.writeString(this.sessionRegionName, out);
-
- DataSerializer.writeString(this.contextName, out);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public void fromData(DataInput in) throws IOException, ClassNotFoundException {
- // Read the StandardSession state
- this.id = DataSerializer.readString(in);
- this.creationTime = in.readLong();
- this.lastAccessedTime = in.readLong();
- this.thisAccessedTime = in.readLong();
- this.maxInactiveInterval = in.readInt();
- this.isNew = in.readBoolean();
- this.isValid = in.readBoolean();
- this.attributes = readInAttributes(in);
- this.serializedPrincipal = DataSerializer.readByteArray(in);
-
- // Read the DeltaSession state
- this.enableGatewayDeltaReplication = in.readBoolean();
- this.sessionRegionName = DataSerializer.readString(in);
-
- // This allows for backwards compatibility with 2.1 clients
- if (((InputStream) in).available() > 0) {
- this.contextName = DataSerializer.readString(in);
- }
-
- // Initialize the transients if necessary
- if (this.listeners == null) {
- this.listeners = new ArrayList();
- }
-
- if (this.notes == null) {
- this.notes = new Hashtable();
- }
- }
-
- @Override
- public int getSizeInBytes() {
- int size = 0;
- for (Enumeration<String> e = getAttributeNames(); e.hasMoreElements();) {
- // Don't use this.getAttribute() because we don't want to deserialize
- // the value.
- Object value = super.getAttribute(e.nextElement());
- if (value instanceof byte[]) {
- size += ((byte[]) value).length;
- }
- }
-
- return size;
- }
-
- protected byte[] serialize(Object obj) {
- byte[] serializedValue = null;
- try {
- serializedValue = BlobHelper.serializeToBlob(obj);
- } catch (IOException e) {
- StringBuilder builder = new StringBuilder();
- builder.append(this).append(": Object ").append(obj)
- .append(" cannot be serialized due to the following exception");
- ((DeltaSessionManager) getManager()).getLogger().warn(builder.toString(), e);
- }
- return serializedValue;
- }
-
- @Override
- public String toString() {
- return new StringBuilder().append("DeltaSession[").append("id=").append(getId())
- .append("; context=").append(this.contextName).append("; sessionRegionName=")
- .append(this.sessionRegionName).append("; operatingRegionName=")
- .append(getOperatingRegion() == null ? "unset" : getOperatingRegion().getFullPath())
- .append("]").toString();
- }
-
- @SuppressWarnings({"unchecked", "rawtypes"})
- protected ConcurrentMap<String, byte[]> getSerializedAttributes() {
- // Iterate the values and serialize them if necessary before sending them to the server. This
- // makes the application classes unnecessary on the server.
- ConcurrentMap<String, byte[]> serializedAttributes = new ConcurrentHashMap<String, byte[]>();
- for (Iterator i = this.attributes.entrySet().iterator(); i.hasNext();) {
- Map.Entry<String, Object> entry = (Map.Entry<String, Object>) i.next();
- Object value = entry.getValue();
- byte[] serializedValue = value instanceof byte[] ? (byte[]) value : serialize(value);
- serializedAttributes.put(entry.getKey(), serializedValue);
- }
- return serializedAttributes;
- }
-
- protected ConcurrentMap readInAttributes(final DataInput in)
- throws IOException, ClassNotFoundException {
- return DataSerializer.readObject(in);
}
}
http://git-wip-us.apache.org/repos/asf/geode/blob/f38dff9d/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession.java
----------------------------------------------------------------------
diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession.java
index ac612da..27e5bce 100644
--- a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession.java
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession.java
@@ -40,6 +40,7 @@ import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedAction;
@@ -80,8 +81,18 @@ public class DeltaSession extends StandardSession
private byte[] serializedPrincipal;
+ private static Field cachedField = null;
+
private final Log LOG = LogFactory.getLog(DeltaSession.class.getName());
+ static {
+ try {
+ cachedField = StandardSession.class.getDeclaredField("attributes");
+ cachedField.setAccessible(true);
+ } catch (NoSuchFieldException e) {
+ throw new IllegalStateException(e);
+ }
+ }
/**
* The string manager for this package.
*/
@@ -531,7 +542,7 @@ public class DeltaSession extends StandardSession
this.maxInactiveInterval = in.readInt();
this.isNew = in.readBoolean();
this.isValid = in.readBoolean();
- this.attributes = readInAttributes(in);
+ readInAttributes(in);
this.serializedPrincipal = DataSerializer.readByteArray(in);
// Read the DeltaSession state
@@ -553,8 +564,26 @@ public class DeltaSession extends StandardSession
}
}
- protected Map readInAttributes(final DataInput in) throws IOException, ClassNotFoundException {
- return DataSerializer.readObject(in);
+ private void readInAttributes(DataInput in) throws IOException, ClassNotFoundException {
+ ConcurrentHashMap map = (ConcurrentHashMap) DataSerializer.readObject(in);
+ try {
+ Field field = getAttributesFieldObject();
+ field.set(this, map);
+ } catch (IllegalAccessException e) {
+ logError(e);
+ throw new IllegalStateException(e);
+ }
+ }
+
+ protected Field getAttributesFieldObject() {
+ return cachedField;
+ }
+
+ protected void logError(Exception e) {
+ if (getManager() != null) {
+ DeltaSessionManager mgr = (DeltaSessionManager) getManager();
+ mgr.getLogger().error(e);
+ }
}
@Override
@@ -576,8 +605,8 @@ public class DeltaSession extends StandardSession
protected Map<String, byte[]> getSerializedAttributes() {
// Iterate the values and serialize them if necessary before sending them to the server. This
// makes the application classes unnecessary on the server.
- Map<String, byte[]> serializedAttributes = new ConcurrentHashMap<String, byte[]>();
- for (Iterator i = this.attributes.entrySet().iterator(); i.hasNext();) {
+ Map<String, byte[]> serializedAttributes = new ConcurrentHashMap<>();
+ for (Iterator i = getAttributes().entrySet().iterator(); i.hasNext();) {
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) i.next();
Object value = entry.getValue();
byte[] serializedValue = value instanceof byte[] ? (byte[]) value : serialize(value);
@@ -586,6 +615,17 @@ public class DeltaSession extends StandardSession
return serializedAttributes;
}
+ protected Map getAttributes() {
+ try {
+ Field field = getAttributesFieldObject();
+ Map map = (Map) field.get(this);
+ return map;
+ } catch (IllegalAccessException e) {
+ logError(e);
+ }
+ throw new IllegalStateException("Unable to access attributes field");
+ }
+
protected byte[] serialize(Object obj) {
byte[] serializedValue = null;
try {
http://git-wip-us.apache.org/repos/asf/geode/blob/f38dff9d/geode-assembly/build.gradle
----------------------------------------------------------------------
diff --git a/geode-assembly/build.gradle b/geode-assembly/build.gradle
index a76afdc..e135675 100755
--- a/geode-assembly/build.gradle
+++ b/geode-assembly/build.gradle
@@ -97,6 +97,8 @@ dependencies {
exclude module: 'spring-core'
exclude module: 'commons-logging'
}
+
+ testCompile project(':geode-old-versions')
}
sourceSets {
@@ -430,6 +432,7 @@ build.dependsOn installDist
installDist.dependsOn ':extensions/geode-modules-assembly:dist'
distributedTest.dependsOn ':extensions/session-testing-war:war'
+distributedTest.dependsOn ':geode-old-versions:build'
/**Print the names of all jar files in a fileTree */
def printJars(tree) {
http://git-wip-us.apache.org/repos/asf/geode/blob/f38dff9d/geode-assembly/src/test/java/org/apache/geode/session/tests/ContainerInstall.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/org/apache/geode/session/tests/ContainerInstall.java b/geode-assembly/src/test/java/org/apache/geode/session/tests/ContainerInstall.java
index 9d03417..f9bce0a 100644
--- a/geode-assembly/src/test/java/org/apache/geode/session/tests/ContainerInstall.java
+++ b/geode-assembly/src/test/java/org/apache/geode/session/tests/ContainerInstall.java
@@ -65,7 +65,7 @@ public abstract class ContainerInstall {
public static final String GEODE_BUILD_HOME = System.getenv("GEODE_HOME");
public static final String DEFAULT_INSTALL_DIR = "/tmp/cargo_containers/";
- private static final String DEFAULT_MODULE_LOCATION = GEODE_BUILD_HOME + "/tools/Modules/";
+ protected static final String DEFAULT_MODULE_LOCATION = GEODE_BUILD_HOME + "/tools/Modules/";
public static final String DEFAULT_MODULE_EXTRACTION_DIR = "/tmp/cargo_modules/";
/**
@@ -95,6 +95,11 @@ public abstract class ContainerInstall {
}
}
+ public ContainerInstall(String installDir, String downloadURL, ConnectionType connType,
+ String moduleName) throws IOException {
+ this(installDir, downloadURL, connType, moduleName, DEFAULT_MODULE_LOCATION);
+ }
+
/**
* Base class for handling downloading and configuring J2EE installations
*
@@ -103,18 +108,17 @@ public abstract class ContainerInstall {
* installations.
*
* Subclasses provide installation of specific containers.
- *
+ *
* @param connType Enum representing the connection type of this installation (either client
* server or peer to peer)
* @param moduleName The module name of the installation being setup (i.e. tomcat, appserver,
* etc.)
*/
public ContainerInstall(String installDir, String downloadURL, ConnectionType connType,
- String moduleName) throws IOException {
+ String moduleName, String geodeModuleLocation) throws IOException {
this.connType = connType;
- // Removes previous run stuff (modules, installs, etc.)
- clearPreviousRuns();
+ clearPreviousInstall(installDir);
logger.info("Installing container from URL " + downloadURL);
@@ -125,7 +129,7 @@ public abstract class ContainerInstall {
// Set install home
INSTALL_PATH = installer.getHome();
// Find and extract the module path
- MODULE_PATH = findAndExtractModule(moduleName);
+ MODULE_PATH = findAndExtractModule(geodeModuleLocation, moduleName);
logger.info("Extracted module " + moduleName + " to " + MODULE_PATH);
// Find the session testing war path
WAR_FILE_PATH = findSessionTestingWar();
@@ -148,17 +152,12 @@ public abstract class ContainerInstall {
/**
* Cleans up the installation by deleting the extracted module and downloaded installation folders
*/
- public void clearPreviousRuns() throws IOException {
- File modulesFolder = new File(DEFAULT_MODULE_EXTRACTION_DIR);
- File installsFolder = new File(DEFAULT_INSTALL_DIR);
-
- // Remove default modules extraction from previous runs
- if (modulesFolder.exists()) {
- FileUtils.deleteDirectory(modulesFolder);
- }
- // Remove default installs from previous runs
- if (installsFolder.exists()) {
- FileUtils.deleteDirectory(installsFolder);
+ public void clearPreviousInstall(String installDir) throws IOException {
+ File installFolder = new File(installDir);
+ // Remove installs from previous runs in the same folder
+ if (installFolder.exists()) {
+ logger.info("Deleting previous install folder " + installFolder.getAbsolutePath());
+ FileUtils.deleteDirectory(installFolder);
}
}
@@ -256,7 +255,7 @@ public abstract class ContainerInstall {
/**
* Generates a {@link ServerContainer} from the given {@link ContainerInstall}
- *
+ *
* @param containerDescriptors Additional descriptors used to identify a container
*/
public abstract ServerContainer generateContainer(File containerConfigHome,
@@ -298,15 +297,15 @@ public abstract class ContainerInstall {
/**
* Finds and extracts the geode module associated with the specified module.
- *
+ *
* @param moduleName The module name (i.e. tomcat, appserver, etc.) of the module that should be
* extract. Used as a search parameter to find the module archive.
* @return The path to the non-archive (extracted) version of the module files
- * @throws IOException
*/
- protected static String findAndExtractModule(String moduleName) throws IOException {
+ protected static String findAndExtractModule(String geodeModuleLocation, String moduleName)
+ throws IOException {
File modulePath = null;
- File modulesDir = new File(DEFAULT_MODULE_LOCATION);
+ File modulesDir = new File(geodeModuleLocation);
boolean archive = false;
logger.info("Trying to access build dir " + modulesDir);
@@ -318,21 +317,28 @@ public abstract class ContainerInstall {
modulePath = file;
archive = !file.isDirectory();
- if (!archive)
+ if (!archive) {
break;
+ }
}
}
+ String extractedModulePath =
+ modulePath.getName().substring(0, modulePath.getName().length() - 4);
+ // Get the name of the new module folder within the extraction directory
+ File newModuleFolder = new File(DEFAULT_MODULE_EXTRACTION_DIR + extractedModulePath);
+ // Remove any previous module folders extracted here
+ if (newModuleFolder.exists()) {
+ logger.info("Deleting previous modules directory " + newModuleFolder.getAbsolutePath());
+ FileUtils.deleteDirectory(newModuleFolder);
+ }
+
// Unzip if it is a zip file
if (archive) {
if (!FilenameUtils.getExtension(modulePath.getAbsolutePath()).equals("zip")) {
throw new IOException("Bad module archive " + modulePath);
}
- // Get the name of the new module folder within the extraction directory
- File newModuleFolder = new File(DEFAULT_MODULE_EXTRACTION_DIR
- + modulePath.getName().substring(0, modulePath.getName().length() - 4));
-
// Extract folder to location if not already there
if (!newModuleFolder.exists()) {
ZipUtils.unzip(modulePath.getAbsolutePath(), newModuleFolder.getAbsolutePath());
@@ -342,14 +348,15 @@ public abstract class ContainerInstall {
}
// No module found within directory throw IOException
- if (modulePath == null)
+ if (modulePath == null) {
throw new IOException("No module found in " + modulesDir);
+ }
return modulePath.getAbsolutePath();
}
/**
* Edits the specified property within the given property file
- *
+ *
* @param filePath path to the property file
* @param propertyName property name to edit
* @param propertyValue new property value
@@ -364,10 +371,11 @@ public abstract class ContainerInstall {
properties.load(input);
String val;
- if (append)
+ if (append) {
val = properties.getProperty(propertyName) + propertyValue;
- else
+ } else {
val = propertyValue;
+ }
properties.setProperty(propertyName, val);
properties.store(new FileOutputStream(filePath), null);
@@ -397,7 +405,7 @@ public abstract class ContainerInstall {
* {@link #rewriteNodeAttributes(Node, HashMap)},
* {@link #nodeHasExactAttributes(Node, HashMap, boolean)} to edit the required parts of the XML
* file.
- *
+ *
* @param XMLPath The path to the xml file to edit
* @param tagId The id of tag to edit. If null, then this method will add a new xml element,
* unless writeOnSimilarAttributeNames is set to true.
@@ -441,11 +449,13 @@ public abstract class ContainerInstall {
} else {
Element e = doc.createElement(tagName);
// Set id attribute
- if (tagId != null)
+ if (tagId != null) {
e.setAttribute("id", tagId);
+ }
// Set other attributes
- for (String key : attributes.keySet())
+ for (String key : attributes.keySet()) {
e.setAttribute(key, attributes.get(key));
+ }
// Add it as a child of the tag for the file
doc.getElementsByTagName(parentTagName).item(0).appendChild(e);
@@ -466,7 +476,7 @@ public abstract class ContainerInstall {
/**
* Finds the node in the given document with the given name and attribute
- *
+ *
* @param doc XML document to search for the node
* @param nodeName The name of the node to search for
* @param name The name of the attribute that the node should contain
@@ -476,15 +486,17 @@ public abstract class ContainerInstall {
private static Node findNodeWithAttribute(Document doc, String nodeName, String name,
String value) {
NodeList nodes = doc.getElementsByTagName(nodeName);
- if (nodes == null)
+ if (nodes == null) {
return null;
+ }
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
Node nodeAttr = node.getAttributes().getNamedItem(name);
- if (nodeAttr != null && nodeAttr.getTextContent().equals(value))
+ if (nodeAttr != null && nodeAttr.getTextContent().equals(value)) {
return node;
+ }
}
return null;
@@ -492,7 +504,7 @@ public abstract class ContainerInstall {
/**
* Replaces the node's attributes with the attributes in the given hashmap
- *
+ *
* @param node XML node that should be edited
* @param attributes HashMap of strings representing the attributes of a node (key = value)
* @return The given node with ONLY the given attributes
@@ -501,12 +513,14 @@ public abstract class ContainerInstall {
NamedNodeMap nodeAttrs = node.getAttributes();
// Remove all previous attributes
- while (nodeAttrs.getLength() > 0)
+ while (nodeAttrs.getLength() > 0) {
nodeAttrs.removeNamedItem(nodeAttrs.item(0).getNodeName());
+ }
// Set to new attributes
- for (String key : attributes.keySet())
+ for (String key : attributes.keySet()) {
((Element) node).setAttribute(key, attributes.get(key));
+ }
return node;
}
@@ -514,7 +528,7 @@ public abstract class ContainerInstall {
/**
* Checks to see whether the given XML node has the exact attributes given in the attributes
* hashmap
- *
+ *
* @param checkSimilarValues If true, will also check to make sure that the given node's
* attributes also have the exact same values as the ones given in the attributes HashMap.
* @return True if the node has only the attributes the are given by the HashMap (no more and no
http://git-wip-us.apache.org/repos/asf/geode/blob/f38dff9d/geode-assembly/src/test/java/org/apache/geode/session/tests/TomcatInstall.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/org/apache/geode/session/tests/TomcatInstall.java b/geode-assembly/src/test/java/org/apache/geode/session/tests/TomcatInstall.java
index ba5f6bc..57dc519 100644
--- a/geode-assembly/src/test/java/org/apache/geode/session/tests/TomcatInstall.java
+++ b/geode-assembly/src/test/java/org/apache/geode/session/tests/TomcatInstall.java
@@ -32,6 +32,8 @@ import java.util.regex.Pattern;
*/
public class TomcatInstall extends ContainerInstall {
+ public static final String GEODE_BUILD_HOME_LIB = GEODE_BUILD_HOME + "/lib/";
+
/**
* Version of tomcat that this class will install
*
@@ -43,6 +45,10 @@ public class TomcatInstall extends ContainerInstall {
"http://archive.apache.org/dist/tomcat/tomcat-6/v6.0.37/bin/apache-tomcat-6.0.37.zip"),
TOMCAT7(7,
"http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.73/bin/apache-tomcat-7.0.73.zip"),
+ TOMCAT755(7,
+ "http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.55/bin/apache-tomcat-7.0.55.zip"),
+ TOMCAT779(7,
+ "http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.79/bin/apache-tomcat-7.0.79.zip"),
TOMCAT8(8,
"http://archive.apache.org/dist/tomcat/tomcat-8/v8.5.15/bin/apache-tomcat-8.5.15.zip"),
TOMCAT9(9,
@@ -72,7 +78,7 @@ public class TomcatInstall extends ContainerInstall {
case TOMCAT9:
return 8;
default:
- throw new IllegalArgumentException("Illegal tomcat version option");
+ return getVersion();
}
}
@@ -93,6 +99,8 @@ public class TomcatInstall extends ContainerInstall {
case TOMCAT6:
return null;
case TOMCAT7:
+ case TOMCAT755:
+ case TOMCAT779:
return "tomcat.util.scan.DefaultJarScanner.jarsToSkip";
case TOMCAT8:
case TOMCAT9:
@@ -104,42 +112,40 @@ public class TomcatInstall extends ContainerInstall {
}
private static final String[] tomcatRequiredJars =
- {"antlr", "commons-lang", "fastutil", "geode-core", "geode-modules", "geode-modules-tomcat7",
- "geode-modules-tomcat8", "javax.transaction-api", "jgroups", "log4j-api", "log4j-core",
- "log4j-jul", "shiro-core", "slf4j-api", "slf4j-jdk14", "commons-validator"};
+ {"antlr", "commons-lang", "fastutil", "geode-core", "javax.transaction-api", "jgroups",
+ "log4j-api", "log4j-core", "log4j-jul", "shiro-core", "commons-validator"};
private final TomcatVersion version;
- public TomcatInstall(TomcatVersion version) throws Exception {
- this(version, ConnectionType.PEER_TO_PEER, DEFAULT_INSTALL_DIR);
- }
-
public TomcatInstall(TomcatVersion version, String installDir) throws Exception {
- this(version, ConnectionType.PEER_TO_PEER, installDir);
+ this(version, ConnectionType.PEER_TO_PEER, installDir, DEFAULT_MODULE_LOCATION,
+ GEODE_BUILD_HOME_LIB);
}
- public TomcatInstall(TomcatVersion version, ConnectionType connType) throws Exception {
- this(version, connType, DEFAULT_INSTALL_DIR);
+ public TomcatInstall(TomcatVersion version, ConnectionType connType, String installDir)
+ throws Exception {
+ this(version, connType, installDir, DEFAULT_MODULE_LOCATION, GEODE_BUILD_HOME_LIB);
}
/**
* Download and setup an installation tomcat using the {@link ContainerInstall} constructor and
* some extra functions this class provides
*
- * Specifically, this function uses {@link #copyTomcatGeodeReqFiles(String)} to install geode
- * session into Tomcat, {@link #setupDefaultSettings()} to modify the context and server XML files
- * within the installation's 'conf' folder, and {@link #updateProperties()} to set the jar
+ * Specifically, this function uses {@link #copyTomcatGeodeReqFiles(String, String)} to install
+ * geode session into Tomcat, {@link #setupDefaultSettings()} to modify the context and server XML
+ * files within the installation's 'conf' folder, and {@link #updateProperties()} to set the jar
* skipping properties needed to speedup container startup.
*/
- public TomcatInstall(TomcatVersion version, ConnectionType connType, String installDir)
- throws Exception {
+ public TomcatInstall(TomcatVersion version, ConnectionType connType, String installDir,
+ String modulesJarLocation, String extraJarsPath) throws Exception {
// Does download and install from URL
- super(installDir, version.getDownloadURL(), connType, "tomcat");
+ super(installDir, version.getDownloadURL(), connType, "tomcat", modulesJarLocation);
this.version = version;
+ modulesJarLocation = getModulePath() + "/lib/";
// Install geode sessions into tomcat install
- copyTomcatGeodeReqFiles(GEODE_BUILD_HOME + "/lib/");
+ copyTomcatGeodeReqFiles(modulesJarLocation, extraJarsPath);
// Set some default XML attributes in server and cache XMLs
setupDefaultSettings();
@@ -255,39 +261,26 @@ public class TomcatInstall extends ContainerInstall {
* @throws IOException if the {@link #getModulePath()}, installation lib directory, or extra
* directory passed in contain no files.
*/
- private void copyTomcatGeodeReqFiles(String extraJarsPath) throws IOException {
+ private void copyTomcatGeodeReqFiles(String moduleJarDir, String extraJarsPath)
+ throws IOException {
ArrayList<File> requiredFiles = new ArrayList<>();
// The library path for the current tomcat installation
String tomcatLibPath = getHome() + "/lib/";
// List of required jars and form version regexps from them
- String versionRegex = "-[0-9]+.*\\.jar";
+ String versionRegex = "-?[0-9]*.*\\.jar";
ArrayList<Pattern> patterns = new ArrayList<>(tomcatRequiredJars.length);
for (String jar : tomcatRequiredJars)
patterns.add(Pattern.compile(jar + versionRegex));
// Don't need to copy any jars already in the tomcat install
File tomcatLib = new File(tomcatLibPath);
- if (tomcatLib.exists()) {
- try {
- for (File file : tomcatLib.listFiles())
- patterns.removeIf(pattern -> pattern.matcher(file.getName()).find());
- } catch (NullPointerException e) {
- throw new IOException("No files found in tomcat lib directory " + tomcatLibPath);
- }
- } else {
- tomcatLib.mkdir();
- }
// Find all the required jars in the tomcatModulePath
try {
- for (File file : (new File(getModulePath() + "/lib/")).listFiles()) {
- for (Pattern pattern : patterns) {
- if (pattern.matcher(file.getName()).find()) {
- requiredFiles.add(file);
- patterns.remove(pattern);
- break;
- }
+ for (File file : (new File(moduleJarDir)).listFiles()) {
+ if (file.isFile() && file.getName().endsWith(".jar")) {
+ requiredFiles.add(file);
}
}
} catch (NullPointerException e) {
@@ -301,7 +294,6 @@ public class TomcatInstall extends ContainerInstall {
for (Pattern pattern : patterns) {
if (pattern.matcher(file.getName()).find()) {
requiredFiles.add(file);
- patterns.remove(pattern);
break;
}
}
http://git-wip-us.apache.org/repos/asf/geode/blob/f38dff9d/geode-assembly/src/test/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTest.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTest.java b/geode-assembly/src/test/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTest.java
new file mode 100644
index 0000000..7b23380
--- /dev/null
+++ b/geode-assembly/src/test/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTest.java
@@ -0,0 +1,244 @@
+/*
+ * 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.session.tests;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import org.apache.geode.internal.AvailablePortHelper;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
+import org.apache.geode.test.dunit.rules.GfshShellConnectionRule;
+import org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
+import org.apache.geode.test.dunit.standalone.VersionManager;
+import org.apache.geode.test.junit.categories.BackwardCompatibilityTest;
+import org.apache.geode.test.junit.categories.DistributedTest;
+import org.apache.geode.test.junit.runners.CategoryWithParameterizedRunnerFactory;
+
+/**
+ * This test iterates through the versions of Geode and executes session client compatibility with
+ * the current version of Geode.
+ */
+@Category({DistributedTest.class, BackwardCompatibilityTest.class})
+@RunWith(Parameterized.class)
+@Parameterized.UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class)
+public class TomcatSessionBackwardsCompatibilityTest {
+
+ @Parameterized.Parameters
+ public static Collection<String> data() {
+ List<String> result = VersionManager.getInstance().getVersionsWithoutCurrent();
+ result.removeIf(s -> Integer.parseInt(s) < 120);
+ if (result.size() < 1) {
+ throw new RuntimeException("No older versions of Geode were found to test against");
+ }
+ return result;
+ }
+
+ @Rule
+ public transient GfshShellConnectionRule gfsh = new GfshShellConnectionRule();
+
+ @Rule
+ public transient LocatorServerStartupRule locatorStartup = new LocatorServerStartupRule();
+
+ @Rule
+ public transient TestName testName = new TestName();
+
+ public transient Client client;
+ public transient ContainerManager manager;
+
+ File oldBuild;
+ File oldModules;
+
+ TomcatInstall tomcat7079AndOldModules;
+ TomcatInstall tomcat7079AndCurrentModules;
+ TomcatInstall tomcat8AndOldModules;
+ TomcatInstall tomcat8AndCurrentModules;
+
+ int locatorPort;
+ String classPathTomcat7079;
+ String classPathTomcat8;
+
+ public TomcatSessionBackwardsCompatibilityTest(String version) {
+ VersionManager versionManager = VersionManager.getInstance();
+ String installLocation = versionManager.getInstall(version);
+ oldBuild = new File(installLocation);
+ oldModules = new File(installLocation + "/tools/Modules/");
+ }
+
+ protected void startServer(String name, String classPath, int locatorPort) throws Exception {
+ CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_SERVER);
+ command.addOption(CliStrings.START_SERVER__NAME, name);
+ command.addOption(CliStrings.START_SERVER__SERVER_PORT, "0");
+ command.addOption(CliStrings.START_SERVER__CLASSPATH, classPath);
+ command.addOption(CliStrings.START_SERVER__LOCATORS, "localhost[" + locatorPort + "]");
+ gfsh.executeAndVerifyCommand(command.toString());
+ }
+
+ protected void startLocator(String name, String classPath, int port) throws Exception {
+ CommandStringBuilder locStarter = new CommandStringBuilder(CliStrings.START_LOCATOR);
+ locStarter.addOption(CliStrings.START_LOCATOR__MEMBER_NAME, name);
+ locStarter.addOption(CliStrings.START_LOCATOR__CLASSPATH, classPath);
+ locStarter.addOption(CliStrings.START_LOCATOR__PORT, Integer.toString(port));
+ gfsh.executeAndVerifyCommand(locStarter.toString());
+
+ }
+
+ @Before
+ public void setup() throws Exception {
+ tomcat7079AndOldModules = new TomcatInstall(TomcatInstall.TomcatVersion.TOMCAT779,
+ ContainerInstall.ConnectionType.CLIENT_SERVER,
+ ContainerInstall.DEFAULT_INSTALL_DIR + "Tomcat7079AndOldModules",
+ oldModules.getAbsolutePath(), oldBuild.getAbsolutePath() + "/lib");
+
+ tomcat7079AndCurrentModules = new TomcatInstall(TomcatInstall.TomcatVersion.TOMCAT779,
+ ContainerInstall.ConnectionType.CLIENT_SERVER,
+ ContainerInstall.DEFAULT_INSTALL_DIR + "Tomcat7079AndCurrentModules");
+
+ tomcat8AndOldModules = new TomcatInstall(TomcatInstall.TomcatVersion.TOMCAT8,
+ ContainerInstall.ConnectionType.CLIENT_SERVER,
+ ContainerInstall.DEFAULT_INSTALL_DIR + "Tomcat8AndOldModules", oldModules.getAbsolutePath(),
+ oldBuild.getAbsolutePath() + "/lib");
+
+ tomcat8AndCurrentModules = new TomcatInstall(TomcatInstall.TomcatVersion.TOMCAT8,
+ ContainerInstall.ConnectionType.CLIENT_SERVER,
+ ContainerInstall.DEFAULT_INSTALL_DIR + "Tomcat8AndCurrentModules");
+
+ classPathTomcat7079 = tomcat7079AndCurrentModules.getHome() + "/lib/*" + File.pathSeparator
+ + tomcat7079AndCurrentModules.getHome() + "/bin/*";
+ classPathTomcat8 = tomcat8AndCurrentModules.getHome() + "/lib/*" + File.pathSeparator
+ + tomcat8AndCurrentModules.getHome() + "/bin/*";
+
+ // Get available port for the locator
+ locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
+
+ tomcat7079AndOldModules.setDefaultLocator("localhost", locatorPort);
+ tomcat7079AndCurrentModules.setDefaultLocator("localhost", locatorPort);
+
+ tomcat8AndOldModules.setDefaultLocator("localhost", locatorPort);
+ tomcat8AndCurrentModules.setDefaultLocator("localhost", locatorPort);
+
+ client = new Client();
+ manager = new ContainerManager();
+ // Due to parameterization of the test name, the URI would be malformed. Instead, it strips off
+ // the [] symbols
+ manager.setTestName(testName.getMethodName().replace("[", "").replace("]", ""));
+ }
+
+ private void startClusterWithTomcat(String tomcatClassPath) throws Exception {
+ startLocator("loc", tomcatClassPath, locatorPort);
+ startServer("server", tomcatClassPath, locatorPort);
+ }
+
+ /**
+ * Stops all containers that were previously started and cleans up their configurations
+ */
+ @After
+ public void stop() throws Exception {
+ manager.stopAllActiveContainers();
+ manager.cleanUp();
+
+ CommandStringBuilder locStop = new CommandStringBuilder(CliStrings.STOP_LOCATOR);
+ locStop.addOption(CliStrings.STOP_LOCATOR__DIR, "loc");
+ gfsh.executeAndVerifyCommand(locStop.toString());
+
+ CommandStringBuilder command = new CommandStringBuilder(CliStrings.STOP_SERVER);
+ command.addOption(CliStrings.STOP_SERVER__DIR, "server");
+ gfsh.executeAndVerifyCommand(command.toString());
+ }
+
+ private void doPutAndGetSessionOnAllClients() throws IOException, URISyntaxException {
+ // This has to happen at the start of every test
+ manager.startAllInactiveContainers();
+
+ String key = "value_testSessionPersists";
+ String value = "Foo";
+
+ client.setPort(Integer.parseInt(manager.getContainerPort(0)));
+ Client.Response resp = client.set(key, value);
+ String cookie = resp.getSessionCookie();
+
+ for (int i = 0; i < manager.numContainers(); i++) {
+ System.out.println("Checking get for container:" + i);
+ client.setPort(Integer.parseInt(manager.getContainerPort(i)));
+ resp = client.get(key);
+
+ assertEquals("Sessions are not replicating properly", cookie, resp.getSessionCookie());
+ assertEquals("Session data is not replicating properly", value, resp.getResponse());
+ }
+ }
+
+ @Test
+ public void tomcat7079WithOldModuleCanDoPuts() throws Exception {
+ startClusterWithTomcat(classPathTomcat7079);
+ manager.addContainer(tomcat7079AndOldModules);
+ manager.addContainer(tomcat7079AndOldModules);
+ doPutAndGetSessionOnAllClients();
+ }
+
+ @Test
+ public void tomcat7079WithOldModulesMixedWithCurrentCanDoPutFromOldModule() throws Exception {
+ startClusterWithTomcat(classPathTomcat7079);
+ manager.addContainer(tomcat7079AndOldModules);
+ manager.addContainer(tomcat7079AndCurrentModules);
+ doPutAndGetSessionOnAllClients();
+ }
+
+ @Test
+ public void tomcat7079WithOldModulesMixedWithCurrentCanDoPutFromCurrentModule() throws Exception {
+ startClusterWithTomcat(classPathTomcat7079);
+ manager.addContainer(tomcat7079AndCurrentModules);
+ manager.addContainer(tomcat7079AndOldModules);
+ doPutAndGetSessionOnAllClients();
+ }
+
+ @Test
+ public void tomcat8WithOldModuleCanDoPuts() throws Exception {
+ startClusterWithTomcat(classPathTomcat8);
+ manager.addContainer(tomcat8AndOldModules);
+ manager.addContainer(tomcat8AndOldModules);
+ doPutAndGetSessionOnAllClients();
+ }
+
+ @Test
+ public void tomcat8WithOldModulesMixedWithCurrentCanDoPutFromOldModule() throws Exception {
+ startClusterWithTomcat(classPathTomcat8);
+ manager.addContainer(tomcat8AndOldModules);
+ manager.addContainer(tomcat8AndCurrentModules);
+ doPutAndGetSessionOnAllClients();
+ }
+
+ @Test
+ public void tomcat8WithOldModulesMixedWithCurrentCanDoPutFromCurrentModule() throws Exception {
+ startClusterWithTomcat(classPathTomcat8);
+ manager.addContainer(tomcat8AndCurrentModules);
+ manager.addContainer(tomcat8AndOldModules);
+ doPutAndGetSessionOnAllClients();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/f38dff9d/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManager.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManager.java b/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManager.java
index 8eefa01..9f4c357 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManager.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManager.java
@@ -24,7 +24,9 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Properties;
+import java.util.function.BiConsumer;
/**
* VersionManager loads the class-paths for all of the releases of Geode configured for
@@ -44,7 +46,11 @@ public class VersionManager {
protected static void init() {
instance = new VersionManager();
final String fileName = "geodeOldVersionClasspaths.txt";
+ final String installLocations = "geodeOldVersionInstalls.txt";
instance.findVersions(fileName);
+ instance.findInstalls(installLocations);
+ System.out
+ .println("VersionManager has loaded the following classpaths:\n" + instance.classPaths);
}
public static VersionManager getInstance() {
@@ -58,7 +64,7 @@ public class VersionManager {
* for unit testing, this creates a VersionManager with paths loaded from the given file, which
* may or may not exist. The instance is not retained
*/
- protected static VersionManager getInstance(String classpathsFileName) {
+ protected static VersionManager getInstance(String classpathsFileName, String installFileName) {
VersionManager result = new VersionManager();
result.findVersions(classpathsFileName);
return result;
@@ -71,6 +77,8 @@ public class VersionManager {
private List<String> testVersions = new ArrayList<String>(10);
+ private Map<String, String> installs = new HashMap();
+
/**
* Test to see if a version string is known to VersionManager. Versions are either CURRENT_VERSION
* or one of the versions returned by VersionManager#getVersions()
@@ -94,6 +102,11 @@ public class VersionManager {
return classPaths.get(version);
}
+
+ public String getInstall(String version) {
+ return installs.get(version);
+ }
+
/**
* Returns a list of older versions available for testing
*/
@@ -118,30 +131,57 @@ public class VersionManager {
private void findVersions(String fileName) {
// this file is created by the gradle task createClasspathsPropertiesFile
+ readVersionsFile(fileName, (version, path) -> {
+ Optional<String> parsedVersion = parseVersion(version);
+ if (parsedVersion.isPresent()) {
+ classPaths.put(parsedVersion.get(), path);
+ testVersions.add(parsedVersion.get());
+ }
+ });
+ }
+
+ private void findInstalls(String fileName) {
+ readVersionsFile(fileName, (version, install) -> {
+ Optional<String> parsedVersion = parseVersion(version);
+ if (parsedVersion.isPresent()) {
+ installs.put(parsedVersion.get(), install);
+ }
+ });
+ }
+
+ private Optional<String> parseVersion(String version) {
+ String parsedVersion = null;
+ if (version.startsWith("test") && version.length() >= "test".length()) {
+ if (version.equals("test")) {
+ parsedVersion = CURRENT_VERSION;
+ } else {
+ parsedVersion = version.substring("test".length());
+ }
+ }
+ return Optional.ofNullable(parsedVersion);
+ }
+
+ private void readVersionsFile(String fileName, BiConsumer<String, String> consumer) {
+ Properties props = readPropertiesFile(fileName);
+ props.forEach((k, v) -> {
+ consumer.accept(k.toString(), v.toString());
+ });
+ }
+
+ public Properties readPropertiesFile(String fileName) {
+ // this file is created by the gradle task createClasspathsPropertiesFile
Properties props = new Properties();
URL url = VersionManager.class.getResource("/" + fileName);
if (url == null) {
loadFailure = "VersionManager: unable to locate " + fileName + " in class-path";
- return;
+ return props;
}
try (InputStream in = VersionManager.class.getResource("/" + fileName).openStream()) {
props.load(in);
} catch (IOException e) {
loadFailure = "VersionManager: unable to read resource " + fileName;
- return;
- }
-
- for (Map.Entry<Object, Object> entry : props.entrySet()) {
- String version = (String) entry.getKey();
- if (version.startsWith("test") && version.length() >= "test".length()) {
- if (version.equals("test")) {
- version = CURRENT_VERSION;
- } else {
- version = version.substring("test".length());
- }
- classPaths.put(version, (String) entry.getValue());
- testVersions.add(version);
- }
+ return props;
}
+ return props;
}
}
http://git-wip-us.apache.org/repos/asf/geode/blob/f38dff9d/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManagerJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManagerJUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManagerJUnitTest.java
index af1fa58..7e89dfc 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManagerJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManagerJUnitTest.java
@@ -27,13 +27,15 @@ public class VersionManagerJUnitTest {
@Test
public void exceptionIsNotThrownInInitialization() throws Exception {
- VersionManager instance = VersionManager.getInstance("--nonexistant-file?--");
+ VersionManager instance =
+ VersionManager.getInstance("--nonexistant-file?--", "--nonexistant-install-file--");
Assert.assertNotEquals("", instance.loadFailure);
}
@Test
public void exceptionIsThrownOnUse() throws Exception {
- VersionManager instance = VersionManager.getInstance("--nonexistant-file?--");
+ VersionManager instance =
+ VersionManager.getInstance("--nonexistant-file?--", "--nonexistant-install-file--");
Assert.assertNotEquals("", instance.loadFailure);
assertThatThrownBy(() -> instance.getVersionsWithoutCurrent()).hasMessage(instance.loadFailure);
assertThatThrownBy(() -> instance.getVersions()).hasMessage(instance.loadFailure);
http://git-wip-us.apache.org/repos/asf/geode/blob/f38dff9d/geode-old-versions/build.gradle
----------------------------------------------------------------------
diff --git a/geode-old-versions/build.gradle b/geode-old-versions/build.gradle
index 1a39ea0..2e9257c 100644
--- a/geode-old-versions/build.gradle
+++ b/geode-old-versions/build.gradle
@@ -15,11 +15,16 @@
* limitations under the License.
*/
+plugins {
+ id "de.undercouch.download" version "3.2.0"
+}
+import de.undercouch.gradle.tasks.download.Download
disableMavenPublishing()
-def addTestSource(def source, def geodeVersion) {
-// def sourceSet =
+project.ext.installs = new Properties();
+
+def addOldVersion(def source, def geodeVersion, def downloadInstall) {
sourceSets.create(source, {
compileClasspath += configurations.provided
runtimeClasspath += configurations.provided
@@ -33,14 +38,36 @@ def addTestSource(def source, def geodeVersion) {
dependencies.add "${source}Compile", "org.apache.geode:geode-cq:$geodeVersion"
dependencies.add "${source}Compile", "org.apache.geode:geode-rebalancer:$geodeVersion"
-}
+ project.ext.installs.setProperty(source, "$buildDir/apache-geode-${geodeVersion}")
-// Add sourceSets for backwards compatibility, rolling upgrade, and
-// pdx testing.
-addTestSource('test100', '1.0.0-incubating')
-addTestSource('test110', '1.1.0')
-addTestSource('test111', '1.1.1')
-addTestSource('test120', '1.2.0')
+ task "downloadZipFile${source}" (type: Download) {
+ src "https://www.apache.org/dyn/closer.cgi?action=download&filename=geode/$geodeVersion/apache-geode-${geodeVersion}.tar.gz"
+ dest new File(buildDir, "apache-geode-${geodeVersion}.tar.gz")
+ }
+
+ task "downloadSHA${source}" (type: Download) {
+ src "https://www.apache.org/dist/geode/${geodeVersion}/apache-geode-${geodeVersion}.tar.gz.sha256"
+ dest new File(buildDir, "apache-geode-${geodeVersion}.tar.gz.sha256")
+ }
+
+
+ task "verifyGeode${source}" (type: de.undercouch.gradle.tasks.download.Verify, dependsOn: [tasks["downloadSHA${source}"], tasks["downloadZipFile${source}"]]) {
+ src tasks["downloadZipFile${source}"].dest
+ algorithm "SHA-256"
+ doFirst {
+ checksum new File(buildDir, "apache-geode-${geodeVersion}.tar.gz.sha256").text.split(' ')[0]
+ }
+ }
+
+ task "downloadAndUnzipFile${source}" (dependsOn: "verifyGeode${source}", type: Copy) {
+ from tarTree(tasks["downloadZipFile${source}"].dest)
+ into buildDir
+ }
+
+ if (downloadInstall) {
+ createGeodeClasspathsFile.dependsOn tasks["downloadAndUnzipFile${source}"]
+ }
+}
def generatedResources = "$buildDir/generated-resources/main"
@@ -52,7 +79,9 @@ sourceSets {
task createGeodeClasspathsFile {
File classpathsFile = file("$generatedResources/geodeOldVersionClasspaths.txt")
- outputs.file(classpathsFile);
+ File installsFile = file("$generatedResources/geodeOldVersionInstalls.txt")
+ outputs.file(classpathsFile)
+ outputs.file(installsFile)
doLast {
Properties versions = new Properties();
@@ -65,6 +94,21 @@ task createGeodeClasspathsFile {
new FileOutputStream(classpathsFile).withStream { fos ->
versions.store(fos, '')
}
+
+ installsFile.getParentFile().mkdirs();
+
+ new FileOutputStream(installsFile).withStream { fos ->
+ project.ext.installs.store(fos, '')
+ }
}
+
+ // Add sourceSets for backwards compatibility, rolling upgrade, and
+ // pdx testing.
+ addOldVersion('test100', '1.0.0-incubating', false)
+ addOldVersion('test110', '1.1.0', false)
+ addOldVersion('test111', '1.1.1', false)
+ addOldVersion('test120', '1.2.0', true)
+
}
+