Index: ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/webapp/WEB-INF/web.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/webapp/WEB-INF/web.xml (revision 0608f90f4a50f3b12bc142f8094c42e666f6596d) +++ ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/webapp/WEB-INF/web.xml (revision ) @@ -29,6 +29,10 @@ IgniteWebSessionsFilter org.apache.ignite.cache.websession.WebSessionFilter + + IgniteWebSessionsKeepBinary + true + @@ -36,6 +40,16 @@ IgniteWebSessionsFilter /* + + + testSvl + org.apache.ignite.internal.websession.WebSessionTestSvl + + + + testSvl + /test/* + Index: ../incubator-ignite/modules/web/src/test/resources/default-server-config.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../incubator-ignite/modules/web/src/test/resources/default-server-config.xml (revision ) +++ ../incubator-ignite/modules/web/src/test/resources/default-server-config.xml (revision ) @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + Index: ../incubator-ignite/modules/core/src/main/java/org/apache/ignite/internal/websession/TestObject.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../incubator-ignite/modules/core/src/main/java/org/apache/ignite/internal/websession/TestObject.java (revision ) +++ ../incubator-ignite/modules/core/src/main/java/org/apache/ignite/internal/websession/TestObject.java (revision ) @@ -0,0 +1,120 @@ +/* + * 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.ignite.internal.websession; + +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +/** + * + */ +public class TestObject implements Externalizable { + /** */ + private static final long serialVersionUID = 0L; + + /** */ + private String name; + + /** */ + private int num; + + /** + * + */ + public TestObject() { + } + + /** + * @param name Name. + * @param num Num. + */ + public TestObject(final String name, final int num) { + this.name = name; + this.num = num; + } + + /** + * @return Name. + */ + public String getName() { + return name; + } + + /** + * @param name Name. + */ + public void setName(final String name) { + this.name = name; + } + + /** + * @return Num. + */ + public int getNum() { + return num; + } + + /** + * @param num Num. + */ + public void setNum(final int num) { + this.num = num; + } + + /** {@inheritDoc} */ + @Override public void writeExternal(final ObjectOutput out) throws IOException { + System.out.println("================ MARSHAL COMMON =================="); + + U.writeString(out, name); + out.writeInt(num); + } + + /** {@inheritDoc} */ + @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { + System.out.println("================ UNMARSHAL COMMON =================="); + name = U.readString(in); + num = in.readInt(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(TestObject.class, this); + } + + /** {@inheritDoc} */ + @Override public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final TestObject that = (TestObject) o; + + if (num != that.num) return false; + return name != null ? name.equals(that.name) : that.name == null; + + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + int res = name != null ? name.hashCode() : 0; + res = 31 * res + num; + return res; + } +} Index: ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/java/org/apache/ignite/internal/websession/WebSessionTestSvl.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/java/org/apache/ignite/internal/websession/WebSessionTestSvl.java (revision ) +++ ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/java/org/apache/ignite/internal/websession/WebSessionTestSvl.java (revision ) @@ -0,0 +1,293 @@ +/* + * 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.ignite.internal.websession; + +import org.apache.ignite.IgniteCache; +import org.apache.ignite.Ignition; +import org.apache.ignite.internal.util.typedef.C1; +import org.jetbrains.annotations.Nullable; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Simple test servlet. + */ +public class WebSessionTestSvl extends HttpServlet { + /** */ + private static final long serialVersionUID = 0L; + + /** */ + public static final String ATTR_NAME = "user"; + + /** */ + private static final C1 WL_SES_TRANSFORMER = new C1() { + @Override public String apply(String s) { + // Find first exclamation mark. + int idx = s.indexOf('!'); + + // Return original string if not found. + if (idx < 0 || idx == s.length() - 1) + return s; + + // Find second exclamation mark. + idx = s.indexOf('!', idx + 1); + + // Return original string if not found. + if (idx < 0) + return s; + + // Return the session ID without timestamp. + return s.substring(0, idx); + } + }; + + /** {@inheritDoc} */ + @Override protected void doGet(final HttpServletRequest req, + final HttpServletResponse resp) throws ServletException, IOException { + final String op = req.getParameter("operation"); + final String val = req.getParameter("val"); + + final HttpSession ses = req.getSession(true); + + assert op != null; + + String res = ""; + + switch (op) { + case "create": + res = createTestObject(ses); + + break; + + case "get": + res = getTestObject(ses); + + break; + + case "remove": + res = removeTestObject(ses); + + break; + + case "cached": + res = cached(ses); + + break; + + case "invalidate": + res = invalidate(ses); + + break; + + case "interval": + res = setInterval(ses, Integer.parseInt(val)); + + break; + + case "createStr": + res = createStr(ses, val); + + break; + + case "getStr": + res = getStr(ses); + + break; + + case "createCommon": + res = createCommon(ses); + + break; + + case "getCommon": + res = getCommon(ses); + + break; + } + + resp.getWriter().append("
").append(res).append("
"); + } + + /** + * @param ses Session. + * @return String representation of saved object. + */ + private String createTestObject(final HttpSession ses) { + final UserTestObj obj = new UserTestObj(ATTR_NAME, ThreadLocalRandom.current().nextInt()); + + ses.setAttribute(obj.getName(), obj); + + return "Created: " + obj.toString() + sessionParams(ses); + } + + /** + * @param ses Session. + * @return String representation of cached object. + */ + private String getTestObject(final HttpSession ses) { + final UserTestObj obj = (UserTestObj) ses.getAttribute(ATTR_NAME); + + return "Got: " + String.valueOf(obj) + sessionParams(ses); + } + + /** + * @param ses Session. + * @return "Removed" string. + */ + private String removeTestObject(final HttpSession ses) { + ses.removeAttribute(ATTR_NAME); + + return "Removed" + sessionParams(ses); + } + + /** + * @param ses Session. + * @return String representation of cached session and attribute. + */ + private String cached(final HttpSession ses) { + try { + final String sesid = WL_SES_TRANSFORMER.apply(ses.getId()); + + final IgniteCache cache = Ignition.ignite().cache("atomic"); + + final Object obj = cache.get(sesid); + + if (obj != null) { + if (obj instanceof HttpSession) { + final HttpSession session = (HttpSession) obj; + + final Object attr = session.getAttribute(ATTR_NAME); + + return "Cached object: [class name=" + session.getClass().getName() + + ", attribute value=" + String.valueOf(attr) + "]," + + sessionParams(session); + } + else if (obj instanceof WebSessionEntity) { + final WebSessionEntity entity = (WebSessionEntity) obj; + + return "Cached object: [class name=" + entity.getClass().getName() + + ", attribute names=" + entity.attributes().keySet().toString() + + ", access time=" + entity.accessTime() + + ", max valid interval=" + entity.maxInactiveInterval() + "]"; + } + } + + return "null"; + } + catch (Exception e) { + return e.toString(); + } + + } + + /** + * Invalidate session. + * + * @param ses Session. + * @return Result of operation. + */ + private String invalidate(final HttpSession ses) { + try { + ses.invalidate(); + } + catch (Exception e) { + return e.toString(); + } + + return "Invalidated [class name=" + ses.getClass().getName() + ", hash code=" + ses.hashCode() + "]"; + } + + /** + * Change max inactive interval. + * + * @param ses Session. + * @param interval Interval to set. + * @return Operation result. + */ + private String setInterval(final HttpSession ses, final int interval) { + ses.setMaxInactiveInterval(interval); + + return "Max inactive interval set to: " + interval + sessionParams(ses); + } + + /** + * Put a string in session attribute. + * + * @param ses Session. + * @return Result of operation. + */ + private String createStr(final HttpSession ses, final @Nullable String val) { + final String str = val == null ? "test value" : val; + + ses.setAttribute(ATTR_NAME, str); + + return "Created attribute [" + ATTR_NAME + "=" + str + "]" + sessionParams(ses); + } + + /** + * Get string representation of the attribute. + * + * @param ses Session. + * @return String representation of the attribute. + */ + private String getStr(final HttpSession ses) { + return String.valueOf(ses.getAttribute(ATTR_NAME)); + } + + /** + * Create common object for server and client into session attribute. + * + * @param ses Session. + * @return Operation result. + */ + private String createCommon(final HttpSession ses) { + final TestObject obj = new TestObject(ATTR_NAME, ThreadLocalRandom.current().nextInt()); + + ses.setAttribute(obj.getName(), obj); + + return obj.toString() + sessionParams(ses); + } + + /** + * Get string representation of common object. + * + * @param ses Session. + * @return Operation result. + */ + private String getCommon(final HttpSession ses) { + final TestObject obj = (TestObject) ses.getAttribute(ATTR_NAME); + + return String.valueOf(obj) + sessionParams(ses); + } + + /** + * @param ses Session. + * @return Access time, max valid interval, creation time. + */ + private String sessionParams(final HttpSession ses) { + return " Session: [access time= " + ses.getLastAccessedTime() + + ", max valid interval= " + ses.getMaxInactiveInterval() + + ", creation time=" + ses.getCreationTime() + + "]"; + } + +} Index: ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/webapp/META-INF/config/default-config.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/webapp/META-INF/config/default-config.xml (revision 0608f90f4a50f3b12bc142f8094c42e666f6596d) +++ ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/webapp/META-INF/config/default-config.xml (revision ) @@ -22,6 +22,12 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> + + + + + + Index: ../incubator-ignite/modules/web/src/test/java/org/apache/ignite/internal/websession/StartNode.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../incubator-ignite/modules/web/src/test/java/org/apache/ignite/internal/websession/StartNode.java (revision ) +++ ../incubator-ignite/modules/web/src/test/java/org/apache/ignite/internal/websession/StartNode.java (revision ) @@ -0,0 +1,30 @@ +/* + * 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.ignite.internal.websession; + +import org.apache.ignite.Ignition; + +/** + * Simple start class. + */ +public class StartNode { + /** + * @param args Srgs. + */ + public static void main(String[] args) { + Ignition.start("default-server-config.xml"); + } +} Index: ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/java/org/apache/ignite/internal/websession/UserTestObj.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/java/org/apache/ignite/internal/websession/UserTestObj.java (revision ) +++ ../incubator-ignite/modules/web/ignite-weblogic-test/src/main/java/org/apache/ignite/internal/websession/UserTestObj.java (revision ) @@ -0,0 +1,121 @@ +/* + * 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.ignite.internal.websession; + +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +/** + * Test object (doesn't exist in server classpath). + */ +public class UserTestObj implements Externalizable { + /** */ + private static final long serialVersionUID = 0L; + + /** */ + private String name; + + /** */ + private int num; + + /** + * Constructor for marshaller. + */ + public UserTestObj() { + } + + /** + * @param name Name. + * @param num Num. + */ + public UserTestObj(final String name, final int num) { + this.name = name; + this.num = num; + } + + /** + * @return Name. + */ + public String getName() { + return name; + } + + /** + * @param name Name. + */ + public void setName(final String name) { + this.name = name; + } + + /** + * @return Num. + */ + public int getNum() { + return num; + } + + /** + * @param num Num. + */ + public void setNum(final int num) { + this.num = num; + } + + /** {@inheritDoc} */ + @Override public void writeExternal(final ObjectOutput out) throws IOException { + System.out.println("================ MARSHAL " + getClass().getName() + " =================="); + + U.writeString(out, name); + out.writeInt(num); + } + + /** {@inheritDoc} */ + @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { + System.out.println("================ UNMARSHAL " + getClass().getName() + " =================="); + + name = U.readString(in); + num = in.readInt(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(UserTestObj.class, this); + } + + /** {@inheritDoc} */ + @Override public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final UserTestObj that = (UserTestObj) o; + + if (num != that.num) return false; + return name != null ? name.equals(that.name) : that.name == null; + + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + int res = name != null ? name.hashCode() : 0; + res = 31 * res + num; + return res; + } +}