Repository: geode Updated Branches: refs/heads/feature/GEODE-3434 [created] e9ed8a12f
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 Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/e9ed8a12 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/e9ed8a12 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/e9ed8a12 Branch: refs/heads/feature/GEODE-3434 Commit: e9ed8a12f6f8cb9dfeedcec5922069bce2e7b7e3 Parents: 645a32d Author: Jason Huynh <huyn...@gmail.com> Authored: Mon Aug 14 09:02:11 2017 -0700 Committer: Jason Huynh <huyn...@gmail.com> Committed: Mon Aug 14 10:20:18 2017 -0700 ---------------------------------------------------------------------- .../modules/session/catalina/DeltaSession7.java | 529 +----------------- .../modules/session/catalina/DeltaSession8.java | 534 +------------------ .../modules/session/catalina/DeltaSession.java | 50 +- geode-assembly/build.gradle | 3 + .../geode/session/tests/ContainerInstall.java | 65 ++- .../geode/session/tests/ServerContainer.java | 1 + .../geode/session/tests/TomcatInstall.java | 92 +++- ...TomcatSessionBackwardsCompatibilityTest.java | 254 +++++++++ .../test/dunit/standalone/VersionManager.java | 70 ++- .../standalone/VersionManagerJUnitTest.java | 6 +- .../lucene/internal/LuceneEventListener.java | 1 + geode-old-versions/build.gradle | 118 +++- 12 files changed, 598 insertions(+), 1125 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/e9ed8a12/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..2f9319b 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 @@ -18,6 +18,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; @@ -54,35 +55,8 @@ import org.apache.geode.modules.session.catalina.internal.DeltaSessionDestroyAtt import org.apache.geode.modules.session.catalina.internal.DeltaSessionUpdateAttributeEvent; @SuppressWarnings("serial") -public class DeltaSession7 extends StandardSession - implements DataSerializable, Delta, GatewayDelta, Sizeable, DeltaSessionInterface { +public class DeltaSession7 extends DeltaSession { - 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. @@ -95,7 +69,7 @@ public class DeltaSession7 extends StandardSession * <code>Manager</code> will be assigned later using {@link #setOwner(Object)}. */ public DeltaSession7() { - super(null); + super(); } /** @@ -105,503 +79,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/e9ed8a12/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..bbd7736 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 @@ -18,6 +18,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; @@ -55,42 +56,13 @@ import org.apache.geode.modules.session.catalina.internal.DeltaSessionUpdateAttr @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 +72,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/e9ed8a12/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..2b1cf3d 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; @@ -50,6 +51,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; @SuppressWarnings("serial") public class DeltaSession extends StandardSession @@ -531,7 +533,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 +555,30 @@ 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 { + Map map = DataSerializer.readObject(in); + ConcurrentMap newMap = new ConcurrentHashMap(); + newMap.putAll(map); + try { + Field field = getAttributesFieldObject(); + field.setAccessible(true); + field.set(this, newMap); + } catch (NoSuchFieldException e) { + logError(e); + } catch (IllegalAccessException e) { + logError(e); + } + } + + protected Field getAttributesFieldObject() throws NoSuchFieldException { + return StandardSession.class.getDeclaredField("attributes"); + } + + protected void logError(Exception e) { + if (getManager() != null) { + DeltaSessionManager mgr = (DeltaSessionManager) getManager(); + mgr.getLogger().error(e); + } } @Override @@ -573,11 +597,11 @@ public class DeltaSession extends StandardSession } @SuppressWarnings({"unchecked", "rawtypes"}) - protected Map<String, byte[]> getSerializedAttributes() { + 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. - Map<String, byte[]> serializedAttributes = new ConcurrentHashMap<String, byte[]>(); - for (Iterator i = this.attributes.entrySet().iterator(); i.hasNext();) { + ConcurrentMap<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 +610,20 @@ public class DeltaSession extends StandardSession return serializedAttributes; } + protected ConcurrentMap getAttributes() { + try { + Field field = getAttributesFieldObject(); + field.setAccessible(true); + Map oldMap = (Map) field.get(this); + ConcurrentMap newMap = new ConcurrentHashMap(); + newMap.putAll(oldMap); + return newMap; + } catch (Exception e) { + logError(e); + } + return null; + } + protected byte[] serialize(Object obj) { byte[] serializedValue = null; try { http://git-wip-us.apache.org/repos/asf/geode/blob/e9ed8a12/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/e9ed8a12/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..46779c4 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, null); + } + /** * Base class for handling downloading and configuring J2EE installations * @@ -103,19 +108,16 @@ 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(); - logger.info("Installing container from URL " + downloadURL); // Optional step to install the container from a URL pointing to its distribution @@ -125,7 +127,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(); @@ -256,7 +258,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 +300,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,8 +320,9 @@ public abstract class ContainerInstall { modulePath = file; archive = !file.isDirectory(); - if (!archive) + if (!archive) { break; + } } } @@ -342,14 +345,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 +368,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 +402,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 +446,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 +473,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 +483,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 +501,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 +510,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 +525,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/e9ed8a12/geode-assembly/src/test/java/org/apache/geode/session/tests/ServerContainer.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/session/tests/ServerContainer.java b/geode-assembly/src/test/java/org/apache/geode/session/tests/ServerContainer.java index dbd438a..c50a1f2 100644 --- a/geode-assembly/src/test/java/org/apache/geode/session/tests/ServerContainer.java +++ b/geode-assembly/src/test/java/org/apache/geode/session/tests/ServerContainer.java @@ -134,6 +134,7 @@ public abstract class ServerContainer { // Set cacheXML file File installXMLFile = install.getCacheXMLFile(); + String path = logDir.getAbsolutePath() + "/" + installXMLFile.getName(); setCacheXMLFile(new File(logDir.getAbsolutePath() + "/" + installXMLFile.getName())); // Copy the cacheXML file to a new, unique location for this container FileUtils.copyFile(installXMLFile, cacheXMLFile); http://git-wip-us.apache.org/repos/asf/geode/blob/e9ed8a12/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..08d75fa 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 @@ -43,6 +43,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 +76,7 @@ public class TomcatInstall extends ContainerInstall { case TOMCAT9: return 8; default: - throw new IllegalArgumentException("Illegal tomcat version option"); + return getVersion(); } } @@ -93,6 +97,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: @@ -111,15 +117,20 @@ public class TomcatInstall extends ContainerInstall { private final TomcatVersion version; public TomcatInstall(TomcatVersion version) throws Exception { - this(version, ConnectionType.PEER_TO_PEER, DEFAULT_INSTALL_DIR); + this(version, ConnectionType.PEER_TO_PEER, DEFAULT_INSTALL_DIR, null, null); } public TomcatInstall(TomcatVersion version, String installDir) throws Exception { - this(version, ConnectionType.PEER_TO_PEER, installDir); + this(version, ConnectionType.PEER_TO_PEER, installDir, null, null); } public TomcatInstall(TomcatVersion version, ConnectionType connType) throws Exception { - this(version, connType, DEFAULT_INSTALL_DIR); + this(version, connType, DEFAULT_INSTALL_DIR, null, null); + } + + public TomcatInstall(TomcatVersion version, ConnectionType connType, String installDir) + throws Exception { + this(version, connType, installDir, null, null); } /** @@ -131,15 +142,20 @@ public class TomcatInstall extends ContainerInstall { * 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 == null ? DEFAULT_MODULE_LOCATION : modulesJarLocation); this.version = version; + // if (modulesJarLocation == null || modulesJarLocation.endsWith("zip")) + modulesJarLocation = getModulePath() + "/lib/"; + if (extraJarsPath == null) + extraJarsPath = GEODE_BUILD_HOME + "/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(); @@ -150,6 +166,66 @@ public class TomcatInstall extends ContainerInstall { } /** + * Copies jars specified by {@link #tomcatRequiredJars} from the {@link #getModulePath()} and the + * specified other directory passed to the function + * + * @throws IOException if the {@link #getModulePath()}, installation lib directory, or extra + * directory passed in contain no files. + */ + 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"; + 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); + + // Find all the required jars in the tomcatModulePath + try { + for (File file : (new File(moduleJarDir)).listFiles()) { + if (file.isFile() && file.getName().endsWith(".jar")) { + requiredFiles.add(file); + } + } + } catch (NullPointerException e) { + throw new IOException( + "No files found in tomcat module directory " + getModulePath() + "/lib/"); + } + + // Find all the required jars in the extraJarsPath + try { + for (File file : (new File(extraJarsPath)).listFiles()) { + for (Pattern pattern : patterns) { + if (pattern.matcher(file.getName()).find()) { + requiredFiles.add(file); + // patterns.remove(pattern); + break; + } + } + } + } catch (NullPointerException e) { + throw new IOException("No files found in extra jars directory " + extraJarsPath); + } + + // Copy the required jars to the given tomcat lib folder + for (File file : requiredFiles) { + Files.copy(file.toPath(), tomcatLib.toPath().resolve(file.toPath().getFileName()), + StandardCopyOption.REPLACE_EXISTING); + logger.debug("Copied required jar from " + file.toPath() + " to " + + (new File(tomcatLibPath)).toPath().resolve(file.toPath().getFileName())); + } + + logger.info("Copied required jars into the Tomcat installation"); + } + + /** * Modifies the context and server XML files in the installation's 'conf' directory so that they * contain the session manager class ({@link #getContextSessionManagerClass()}) and life cycle * listener class ({@link #getServerLifeCycleListenerClass()}) respectively http://git-wip-us.apache.org/repos/asf/geode/blob/e9ed8a12/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..6a9de92 --- /dev/null +++ b/geode-assembly/src/test/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTest.java @@ -0,0 +1,254 @@ +/* + * 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.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +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, "loc"); + 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(); + + tomcat8AndCurrentModules.clearPreviousRuns(); + tomcat8AndOldModules.clearPreviousRuns(); + tomcat7079AndCurrentModules.clearPreviousRuns(); + tomcat7079AndOldModules.clearPreviousRuns(); + + 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/e9ed8a12/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 739b690..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,9 @@ 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); } @@ -60,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; @@ -73,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() @@ -96,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 */ @@ -120,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/e9ed8a12/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/e9ed8a12/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java index ac5c971..db53184 100644 --- a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java @@ -34,6 +34,7 @@ import org.apache.geode.cache.lucene.internal.repository.IndexRepository; import org.apache.geode.cache.query.internal.DefaultQuery; import org.apache.geode.internal.cache.BucketNotFoundException; import org.apache.geode.internal.cache.PrimaryBucketException; +import org.apache.geode.internal.cache.tier.sockets.command.Default; import org.apache.geode.internal.logging.LogService; import org.apache.lucene.store.AlreadyClosedException; http://git-wip-us.apache.org/repos/asf/geode/blob/e9ed8a12/geode-old-versions/build.gradle ---------------------------------------------------------------------- diff --git a/geode-old-versions/build.gradle b/geode-old-versions/build.gradle index 1a39ea0..a5c729f 100644 --- a/geode-old-versions/build.gradle +++ b/geode-old-versions/build.gradle @@ -15,10 +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) { +project.ext.installs = new Properties(); + +def addOldVersion(def source, def geodeVersion) { // def sourceSet = sourceSets.create(source, { compileClasspath += configurations.provided @@ -33,14 +39,41 @@ 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 "http://apache.mirrors.ionfish.org/geode/${geodeVersion}/apache-geode-${geodeVersion}.zip" +// dest new File(buildDir, "apache-geode-${geodeVersion}.zip") +// } + + 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: "downloadZipFile${source}", type: Copy) { + task "downloadAndUnzipFile${source}" (dependsOn: "verifyGeode${source}", type: Copy) { + from tarTree(tasks["downloadZipFile${source}"].dest) + into buildDir + } + + createGeodeClasspathsFile.dependsOn tasks["downloadAndUnzipFile${source}"] + //build.dependsOn tasks["downloadAndUnzipFile${source}"]; +} def generatedResources = "$buildDir/generated-resources/main" @@ -52,7 +85,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 +100,71 @@ 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') + addOldVersion('test110', '1.1.0') + addOldVersion('test111', '1.1.1') + addOldVersion('test120', '1.2.0') + + + +// +// def downloadUrl = (geodeReleaseUrl != "") ? geodeReleaseUrl : +// "https://www.apache.org/dyn/closer.cgi?action=download&filename=geode/$geodeVersion" +// def verificationUrl = (geodeReleaseUrl != "") ? geodeReleaseUrl : +// "https://www.apache.org/dist/geode/$geodeVersion" +// +// def downloadFile = "apache-geode-${geodeVersion}.tar.gz" +// def installFile = "$buildDir/$downloadFile" +// def installDir = "$buildDir/apache-geode-${geodeVersion}" +// +// + + + +// task "downloadZipFile${source}" (type: Download) { +// src ([ +// "https://www.apache.org/dyn/closer.cgi?action=download&filename=geode/$geodeVersion/apache-geode-${geodeVersion}.tar.gz", +// "https://www.apache.org/dist/geode/$geodeVersion/apache-geode-${geodeVersion}.tar.gz.sha256" +// ]) +// +// dest new File(buildDir, "apache-geode-${geodeVersion}.zip") +// } +// +// task downloadGeode { +// inputs.property 'geodeVersion', geodeVersion +// outputs.file installFile +// outputs.file "${installFile}.sha256" +// +// doLast { +// download { +// src([ +// "$downloadUrl/$downloadFile", +// "$verificationUrl/${downloadFile}.sha256" +// ]) +// dest buildDir +// } +// } +// } +// + +// +// task installGeode(type: Copy, dependsOn: verifyGeode) { +// inputs.file installFile +// outputs.dir installDir +// +// from tarTree(resources.gzip(installFile)) +// into buildDir +// } } +