Repository: iluwatar/java-design-patterns
Issue: Client Session State pattern
Labels: epic: pattern
type: feature

https://dzone.com/articles/practical-php-patterns/practical-php-patterns-client

Issue comments:
I would like to work on this issue. Could you assign me this?
Yes, please go ahead @nakul251197 
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@nakul251197, the PR build is failing and we need your effort to investigate it

Pull request review comments:
See the YAML frontmatter requirements in https://github.com/iluwatar/java-design-patterns/wiki/01.-How-to-contribute

Please pick the category and the tags from the existing list, if applicable. See https://github.com/iluwatar/java-design-patterns/wiki/07.-Categories-and-Tags
Please add at least the programmatic example here
Add maven-assembly-plugin so that the example can be executed from the command line e.g. java -jar client-session.jar
Here, above the App, please explain the pattern briefly and describe how the code example implements it
You need to add comments to describe what is going on. This is studying material for people.

You can use `var` for local variables.
Use Lombok to get rid of boilerplate code. Check this throughout the code.
I'm not sure we need the archetype. I propose we remove this file.
Is this file needed somewhere?
I would remove this file
I think you are using an old version of JUnit here. Please upgrade to the latest version.
Fixed.
Added example.
Added.
Added comments.
Fixed.
Fixed
Removed.
Removed.
Removed.
Fixed.
We need a bit more verbosity and description. Show the code for the used classes, describe their purposes and relations. The reader should be able to understand the design pattern by only reading this document.
I have added additional description as requested. Please let me know if they are adequate.

Patch that resolved the issue:
diff --git a/client-session/README.md b/client-session/README.md
new file mode 100644
index 000000000000..82204eb3495d
--- /dev/null
+++ b/client-session/README.md
@@ -0,0 +1,114 @@
+---
+title: Client Session Pattern
+category: Architectural
+language: en
+tags:
+- Decoupling
+---
+
+## Name
+
+[Client Session pattern](https://dzone.com/articles/practical-php-patterns/practical-php-patterns-client)
+
+## Intent
+
+- Create stateless servers that removes the problem of clustering, as users can switch between servers seamlessly.
+- Makes data more resilient in case of server fail-over.
+- Works well with smaller data sizes.
+
+## Explanation
+
+Real-World Example
+
+> You're looking to create a data management app allowing users to send requests to the server to 
+> modify and make changes to data stored on their devices. These requests are small in size and the 
+> data is individual to each user, negating the need for a large scale database implementation. 
+> Using the client session pattern, you are able to handle multiple concurrent requests, load 
+> balancing clients across different servers with ease due to servers remaining stateless. You also 
+> remove the need to store session IDs on the server side due to clients providing all the 
+> information that a server needs to perform their process.
+
+In Plain words
+
+> Instead of storing information about the current client and the information being accessed on the 
+> server, it is maintained client side only. Client has to send session data with each request to 
+> the server and has to send an updated state back to the client, which is stored on the clients 
+> machine. The server doesn't have to store the client information.
+> ([ref](https://dzone.com/articles/practical-php-patterns/practical-php-patterns-client))
+
+**Programmatic Example**
+
+Here is the sample code to describe the client-session pattern. In the below code we are first 
+creating an instance of the Server. This server instance will then be used to get Session objects 
+for two clients. As you can see from the code below the Session object can be used to store any 
+relevant information that are required by the server to process the client request. These session 
+objects will then be passed on with every Request to the server. The Request will have the Session 
+object that stores the relevant client details along with the required data for processing the 
+request. The session information in every request helps the server identify the client and process 
+the request accordingly. 
+
+```java
+public class App {
+
+  public static void main(String[] args) {
+    var server = new Server("localhost", 8080);
+    var session1 = server.getSession("Session1");
+    var session2 = server.getSession("Session2");
+    var request1 = new Request("Data1", session1);
+    var request2 = new Request("Data2", session2);
+    server.process(request1);
+    server.process(request2);
+  }
+}
+
+@Data
+@AllArgsConstructor
+public class Session {
+
+  /**
+   * Session id.
+   */
+  private String id;
+
+  /**
+   * Client name.
+   */
+  private String clientName;
+
+}
+
+@Data
+@AllArgsConstructor
+public class Request {
+
+  private String data;
+
+  private Session session;
+
+}
+```
+
+## Architecture Diagram
+
+![alt text](./etc/session_state_pattern.png "Session State Pattern")
+
+## Applicability
+
+Use the client state pattern when:
+
+- Processing smaller amounts of data to prevent larger requests and response sizes.
+- Remove the need for servers to save client states. Doing so also removes the need to store session IDs.
+- Clustering is an issue and needs to be avoided. Stateless servers allow clients to be easily distributed across servers.
+- Creates resilience from data losses due to server fails.
+
+## Consequences
+
+- The server is stateless. Any compute API will not store any data.
+- Struggles to deal with large amounts of data. Creates longer send and receive times due to larger amounts of session data to manage.
+- Security. All data is stored on the client's machine. This means that any vulnerabilities on the clients side can expose all data being sent and received by the server.
+
+
+## Credits
+
+- [Dzone - Practical PHP patterns](https://dzone.com/articles/practical-php-patterns/practical-php-patterns-client)
+- [Client Session State Design Pattern - Ram N Java](https://www.youtube.com/watch?v=ycOSj9g41pc)
diff --git a/client-session/pom.xml b/client-session/pom.xml
new file mode 100644
index 000000000000..b7ff08637091
--- /dev/null
+++ b/client-session/pom.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+
+    The MIT License
+    Copyright © 2014-2022 Ilkka Seppälä
+
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.iluwatar</groupId>
+        <artifactId>java-design-patterns</artifactId>
+        <version>1.26.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>client-session</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <configuration>
+                            <archive>
+                                <manifest>
+                                    <mainClass>com.iluwatar.client.session.App</mainClass>
+                                </manifest>
+                            </archive>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/client-session/src/main/java/com/iluwatar/client/session/App.java b/client-session/src/main/java/com/iluwatar/client/session/App.java
new file mode 100644
index 000000000000..282d8a7f3b28
--- /dev/null
+++ b/client-session/src/main/java/com/iluwatar/client/session/App.java
@@ -0,0 +1,55 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.client.session;
+
+/**
+ * The Client-Session pattern allows the session data to be stored on the client side and send this
+ * data to the server with each request.
+ *
+ * <p> In this example, The {@link Server} class represents the server that would process the
+ * incoming {@link Request} and also assign {@link Session} to a client. Here one instance of Server
+ * is created. The we create two sessions for two different clients. These sessions are then passed
+ * on to the server in the request along with the data. The server is then able to interpret the
+ * client based on the session associated with it.
+ * </p>
+ */
+public class App {
+
+  /**
+   * Program entry point.
+   *
+   * @param args Command line args
+   */
+  public static void main(String[] args) {
+    var server = new Server("localhost", 8080);
+    var session1 = server.getSession("Session1");
+    var session2 = server.getSession("Session2");
+    var request1 = new Request("Data1", session1);
+    var request2 = new Request("Data2", session2);
+    server.process(request1);
+    server.process(request2);
+  }
+}
diff --git a/client-session/src/main/java/com/iluwatar/client/session/Request.java b/client-session/src/main/java/com/iluwatar/client/session/Request.java
new file mode 100644
index 000000000000..008011f180f7
--- /dev/null
+++ b/client-session/src/main/java/com/iluwatar/client/session/Request.java
@@ -0,0 +1,42 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.client.session;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * The Request class which contains the Session details and data.
+ */
+@Data
+@AllArgsConstructor
+public class Request {
+
+  private String data;
+
+  private Session session;
+
+}
diff --git a/client-session/src/main/java/com/iluwatar/client/session/Server.java b/client-session/src/main/java/com/iluwatar/client/session/Server.java
new file mode 100644
index 000000000000..6d9dc3dbc80a
--- /dev/null
+++ b/client-session/src/main/java/com/iluwatar/client/session/Server.java
@@ -0,0 +1,65 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.client.session;
+
+import java.util.UUID;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * The Server class. The client communicates with the server and request processing and getting a new session.
+ */
+@Slf4j
+@Data
+@AllArgsConstructor
+public class Server {
+  private String host;
+
+  private int port;
+
+
+  /**
+   * Creates a new session.
+   *
+   * @param name name of the client
+   *
+   * @return Session Object
+   */
+  public Session getSession(String name) {
+    return new Session(UUID.randomUUID().toString(), name);
+  }
+
+  /**
+   * Processes a request based on the session.
+   *
+   * @param request Request object with data and Session
+   */
+  public void process(Request request) {
+    LOGGER.info("Processing Request with client: " + request.getSession().getClientName() + " data: " + request.getData());
+  }
+
+}
diff --git a/client-session/src/main/java/com/iluwatar/client/session/Session.java b/client-session/src/main/java/com/iluwatar/client/session/Session.java
new file mode 100644
index 000000000000..bb9f7246cb4e
--- /dev/null
+++ b/client-session/src/main/java/com/iluwatar/client/session/Session.java
@@ -0,0 +1,48 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.client.session;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * The Session class. Each client get assigned a Session which is then used for further communications.
+ */
+@Data
+@AllArgsConstructor
+public class Session {
+
+  /**
+   * Session id.
+   */
+  private String id;
+
+  /**
+   * Client name.
+   */
+  private String clientName;
+
+}
diff --git a/pom.xml b/pom.xml
index 09e4dea4fb70..90c4b29410bb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -198,6 +198,7 @@
     <module>composite-view</module>
     <module>metadata-mapping</module>
     <module>service-to-worker</module>
+    <module>client-session</module>
     <module>embedded-value</module>
     <module>currying</module>
     <module>serialized-entity</module>


Test patch:
diff --git a/client-session/src/test/java/com/iluwatar/client/session/AppTest.java b/client-session/src/test/java/com/iluwatar/client/session/AppTest.java
new file mode 100644
index 000000000000..0e33f74f460b
--- /dev/null
+++ b/client-session/src/test/java/com/iluwatar/client/session/AppTest.java
@@ -0,0 +1,38 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.client.session;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.Test;
+
+class AppTest {
+
+  @Test
+  void appStartsWithoutException() {
+    assertDoesNotThrow(() -> App.main(new String[]{}));
+  }
+}
diff --git a/client-session/src/test/java/com/iluwatar/client/session/ServerTest.java b/client-session/src/test/java/com/iluwatar/client/session/ServerTest.java
new file mode 100644
index 000000000000..dc09441f0a6a
--- /dev/null
+++ b/client-session/src/test/java/com/iluwatar/client/session/ServerTest.java
@@ -0,0 +1,14 @@
+package com.iluwatar.client.session;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class ServerTest {
+
+  @Test
+  void checkGetSession() {
+    Server server = new Server("localhost", 8080);
+    Session session = server.getSession("Session");
+    assertEquals("Session", session.getClientName());
+  }
+}