You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sh...@apache.org on 2016/03/07 02:58:07 UTC

ignite git commit: IGNITE-2710: Proper invalidation of session within a request. - Fixes #530.

Repository: ignite
Updated Branches:
  refs/heads/master a9a995e0d -> 79ae76cef


IGNITE-2710: Proper invalidation of session within a request. - Fixes #530.

Signed-off-by: shtykh_roman <rs...@yahoo.com>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/79ae76ce
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/79ae76ce
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/79ae76ce

Branch: refs/heads/master
Commit: 79ae76cef10e32bc3336cd2e1d00b3348e5f7655
Parents: a9a995e
Author: shtykh_roman <rs...@yahoo.com>
Authored: Mon Mar 7 10:50:01 2016 +0900
Committer: shtykh_roman <rs...@yahoo.com>
Committed: Mon Mar 7 10:50:01 2016 +0900

----------------------------------------------------------------------
 .../ignite/cache/websession/WebSession.java     |  52 +++++++-
 .../cache/websession/WebSessionFilter.java      |  21 +++-
 .../IgniteWebSessionSelfTestSuite.java          |   5 +
 .../internal/websession/WebSessionSelfTest.java | 124 ++++++++++++++++++-
 4 files changed, 194 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/79ae76ce/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSession.java
----------------------------------------------------------------------
diff --git a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSession.java b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSession.java
index 496600a..7441a1a 100644
--- a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSession.java
+++ b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSession.java
@@ -45,6 +45,9 @@ class WebSession implements HttpSession, Externalizable {
     /** */
     private static final long serialVersionUID = 0L;
 
+    /** Flag indicating if the session is valid. */
+    private volatile transient boolean isValid = true;
+
     /** Empty session context. */
     private static final HttpSessionContext EMPTY_SES_CTX = new HttpSessionContext() {
         @Nullable @Override public HttpSession getSession(String id) {
@@ -86,6 +89,9 @@ class WebSession implements HttpSession, Externalizable {
     /** Updates list. */
     private transient Collection<T2<String, Object>> updates;
 
+    /** Genuine http session. */
+    private transient HttpSession genuineSession;
+
     /**
      * Required by {@link Externalizable}.
      */
@@ -114,6 +120,8 @@ class WebSession implements HttpSession, Externalizable {
 
             attrs.put(name, ses.getAttribute(name));
         }
+
+        genuineSession = ses;
     }
 
     /**
@@ -152,6 +160,15 @@ class WebSession implements HttpSession, Externalizable {
     }
 
     /**
+     * Checks if the session is valid.
+     *
+     * @return True is valid, otherwise false.
+     */
+    protected boolean isValid() {
+        return this.isValid;
+    }
+
+    /**
      * Resets updates list.
      */
     public void resetUpdates() {
@@ -181,11 +198,17 @@ class WebSession implements HttpSession, Externalizable {
 
     /** {@inheritDoc} */
     @Override public long getCreationTime() {
+        if (!isValid)
+            throw new IllegalStateException("Call on invalidated session!");
+
         return createTime;
     }
 
     /** {@inheritDoc} */
     @Override public long getLastAccessedTime() {
+        if (!isValid)
+            throw new IllegalStateException("Call on invalidated session!");
+
         return accessTime;
     }
 
@@ -201,26 +224,38 @@ class WebSession implements HttpSession, Externalizable {
 
     /** {@inheritDoc} */
     @Override public Object getAttribute(String name) {
+        if (!isValid)
+            throw new IllegalStateException("Call on invalidated session!");
+
         return attrs.get(name);
     }
 
     /** {@inheritDoc} */
     @Override public Object getValue(String name) {
-        return attrs.get(name);
+        return getAttribute(name);
     }
 
     /** {@inheritDoc} */
     @Override public Enumeration<String> getAttributeNames() {
+        if (!isValid)
+            throw new IllegalStateException("Call on invalidated session!");
+
         return Collections.enumeration(attrs.keySet());
     }
 
     /** {@inheritDoc} */
     @Override public String[] getValueNames() {
+        if (!isValid)
+            throw new IllegalStateException("Call on invalidated session!");
+
         return attrs.keySet().toArray(new String[attrs.size()]);
     }
 
     /** {@inheritDoc} */
     @Override public void setAttribute(String name, Object val) {
+        if (!isValid)
+            throw new IllegalStateException("Call on invalidated session!");
+
         attrs.put(name, val);
 
         if (updates != null)
@@ -234,6 +269,9 @@ class WebSession implements HttpSession, Externalizable {
 
     /** {@inheritDoc} */
     @Override public void removeAttribute(String name) {
+        if (!isValid)
+            throw new IllegalStateException("Call on invalidated session!");
+
         attrs.remove(name);
 
         if (updates != null)
@@ -247,11 +285,18 @@ class WebSession implements HttpSession, Externalizable {
 
     /** {@inheritDoc} */
     @Override public void invalidate() {
+        if (!isValid)
+            throw new IllegalStateException("Call on invalidated session!");
+
         attrs.clear();
 
         updates = null;
 
         lsnr.destroySession(id);
+
+        genuineSession.invalidate();
+
+        isValid = false;
     }
 
     /**
@@ -263,6 +308,9 @@ class WebSession implements HttpSession, Externalizable {
 
     /** {@inheritDoc} */
     @Override public boolean isNew() {
+        if (!isValid)
+            throw new IllegalStateException("Call on invalidated session!");
+
         return isNew;
     }
 
@@ -293,4 +341,4 @@ class WebSession implements HttpSession, Externalizable {
     @Override public String toString() {
         return S.toString(WebSession.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/79ae76ce/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
----------------------------------------------------------------------
diff --git a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
index 4a84931..6e6be33 100644
--- a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
+++ b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
@@ -328,7 +328,7 @@ public class WebSessionFilter implements Filter {
      * @param chain Filter chain.
      * @return Session ID.
      * @throws IOException In case of I/O error.
-     * @throws ServletException In case oif servlet error.
+     * @throws ServletException In case of servlet error.
      * @throws CacheException In case of other error.
      */
     private String doFilter0(HttpServletRequest httpReq, ServletResponse res, FilterChain chain) throws IOException,
@@ -476,9 +476,9 @@ public class WebSessionFilter implements Filter {
     /**
      * Request wrapper.
      */
-    private static class RequestWrapper extends HttpServletRequestWrapper {
+    private class RequestWrapper extends HttpServletRequestWrapper {
         /** Session. */
-        private final WebSession ses;
+        private volatile WebSession ses;
 
         /**
          * @param req Request.
@@ -494,12 +494,23 @@ public class WebSessionFilter implements Filter {
 
         /** {@inheritDoc} */
         @Override public HttpSession getSession(boolean create) {
+            if (!ses.isValid()) {
+                if (create) {
+                    this.ses = createSession((HttpServletRequest)getRequest());
+                    this.ses.servletContext(ctx);
+                    this.ses.listener(lsnr);
+                    this.ses.resetUpdates();
+                }
+                else
+                    return null;
+            }
+
             return ses;
         }
 
         /** {@inheritDoc} */
         @Override public HttpSession getSession() {
-            return ses;
+            return getSession(true);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/79ae76ce/modules/web/src/test/java/org/apache/ignite/internal/websession/IgniteWebSessionSelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/web/src/test/java/org/apache/ignite/internal/websession/IgniteWebSessionSelfTestSuite.java b/modules/web/src/test/java/org/apache/ignite/internal/websession/IgniteWebSessionSelfTestSuite.java
index 5c4d736..c69b019 100644
--- a/modules/web/src/test/java/org/apache/ignite/internal/websession/IgniteWebSessionSelfTestSuite.java
+++ b/modules/web/src/test/java/org/apache/ignite/internal/websession/IgniteWebSessionSelfTestSuite.java
@@ -57,6 +57,11 @@ public class IgniteWebSessionSelfTestSuite extends TestSuite {
         @Override public void testRestarts() throws Exception {
             fail("https://issues.apache.org/jira/browse/IGNITE-810");
         }
+
+        /** {@inheritDoc} */
+        @Override public void testInvalidatedSession() throws Exception {
+            fail("https://issues.apache.org/jira/browse/IGNITE-810");
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/79ae76ce/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java b/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java
index 7a321d6..e2fda37 100644
--- a/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java
+++ b/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java
@@ -24,6 +24,8 @@ import java.net.URL;
 import java.net.URLConnection;
 import java.util.Random;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.atomic.AtomicReferenceArray;
@@ -32,11 +34,14 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
+import org.apache.ignite.events.Event;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.util.typedef.G;
 import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.eclipse.jetty.server.Server;
@@ -44,6 +49,8 @@ import org.eclipse.jetty.servlet.ServletHolder;
 import org.eclipse.jetty.webapp.WebAppContext;
 import org.jetbrains.annotations.Nullable;
 
+import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT;
+
 /**
  * Tests the correctness of web sessions caching functionality.
  */
@@ -110,6 +117,91 @@ public class WebSessionSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Tests invalidated sessions.
+     *
+     * @throws Exception Exception If failed.
+     */
+    public void testInvalidatedSession() throws Exception {
+        String invalidatedSesId;
+        Server srv = null;
+
+        try {
+            srv = startServer(TEST_JETTY_PORT, "/modules/core/src/test/config/websession/example-cache.xml",
+                null, new InvalidatedSessionServlet());
+
+            Ignite ignite = G.ignite();
+
+            URLConnection conn = new URL("http://localhost:" + TEST_JETTY_PORT + "/ignitetest/invalidated").openConnection();
+
+            conn.connect();
+
+            try (BufferedReader rdr = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
+
+                // checks if the old session object is invalidated.
+                invalidatedSesId = rdr.readLine();
+
+                assertNotNull(invalidatedSesId);
+
+                IgniteCache<String, HttpSession> cache = ignite.cache(getCacheName());
+
+                assertNotNull(cache);
+
+                HttpSession invalidatedSes = cache.get(invalidatedSesId);
+
+                assertNull(invalidatedSes);
+
+                // requests to subsequent getSession() returns null.
+                String ses = rdr.readLine();
+
+                assertEquals("null", ses);
+            }
+
+            // put and update.
+            final CountDownLatch latch = new CountDownLatch(2);
+
+            final IgnitePredicate<Event> putLsnr = new IgnitePredicate<Event>() {
+                @Override public boolean apply(Event evt) {
+                    assert evt != null;
+
+                    latch.countDown();
+
+                    return true;
+                }
+            };
+
+            ignite.events().localListen(putLsnr, EVT_CACHE_OBJECT_PUT);
+
+            // new request that creates a new session.
+            conn = new URL("http://localhost:" + TEST_JETTY_PORT + "/ignitetest/valid").openConnection();
+
+            conn.addRequestProperty("Cookie", "JSESSIONID=" + invalidatedSesId);
+
+            conn.connect();
+
+            try (BufferedReader rdr = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
+                String sesId = rdr.readLine();
+
+                assertFalse(sesId.equals("null"));
+
+                assertTrue(latch.await(10, TimeUnit.SECONDS));
+
+                IgniteCache<String, HttpSession> cache = ignite.cache(getCacheName());
+
+                assertNotNull(cache);
+
+                HttpSession ses = cache.get(sesId);
+
+                assertNotNull(ses);
+
+                assertEquals("val10", ses.getAttribute("key10"));
+            }
+        }
+        finally {
+            stopServer(srv);
+        }
+    }
+
+    /**
      * @throws Exception If failed.
      */
     public void testRestarts() throws Exception {
@@ -296,6 +388,36 @@ public class WebSessionSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Test for invalidated sessions.
+     */
+    private static class InvalidatedSessionServlet extends HttpServlet {
+        /** {@inheritDoc} */
+        @Override protected void doGet(HttpServletRequest req, HttpServletResponse res)
+            throws ServletException, IOException {
+            HttpSession ses = req.getSession();
+
+            assert ses != null;
+
+            if (req.getPathInfo().equals("/invalidated")) {
+                X.println(">>>", "Session to invalidate with id: " + ses.getId(), ">>>");
+
+                ses.invalidate();
+
+                res.getWriter().println(ses.getId());
+            }
+            else if (req.getPathInfo().equals("/valid")) {
+                X.println(">>>", "Created session: " + ses.getId(), ">>>");
+
+                ses.setAttribute("key10", "val10");
+            }
+
+            res.getWriter().println((req.getSession(false) == null) ? "null" : ses.getId());
+
+            res.getWriter().flush();
+        }
+    }
+
+    /**
      * Servlet for restarts test.
      */
     private static class RestartsTestServlet extends HttpServlet {
@@ -330,4 +452,4 @@ public class WebSessionSelfTest extends GridCommonAbstractTest {
             res.getWriter().flush();
         }
     }
-}
\ No newline at end of file
+}