Skip to content

Commit 0dbd8ef

Browse files
author
innokenty
committed
calculate open sessions separately for each user
1 parent baeda85 commit 0dbd8ef

File tree

14 files changed

+278
-131
lines changed

14 files changed

+278
-131
lines changed

proxy/src/main/java/ru/qatools/gridrouter/JsonWireUtils.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ public static String getSessionHash(String uri) {
4141
return uri.substring(WD_HUB_SESSION.length(), getUriPrefixLength());
4242
}
4343

44+
public static String getFullSessionId(String uri) {
45+
String tail = uri.substring(WD_HUB_SESSION.length());
46+
int end = tail.indexOf('/');
47+
if (end < 0) {
48+
return tail;
49+
}
50+
return tail.substring(0, end);
51+
}
52+
4453
public static int getUriPrefixLength() {
4554
return WD_HUB_SESSION.length() + SESSION_HASH_LENGTH;
4655
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package ru.qatools.gridrouter;
2+
3+
import java.time.Duration;
4+
import java.time.temporal.Temporal;
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.Optional;
9+
10+
import static java.time.ZonedDateTime.now;
11+
import static java.util.stream.Collectors.toList;
12+
13+
/**
14+
* @author Innokenty Shuvalov [email protected]
15+
*/
16+
public class MemorySessionStorage implements SessionStorage {
17+
18+
private final Map<String, Temporal> session2instant = new HashMap<>();
19+
private final Map<String, Integer> user2count = new HashMap<>();
20+
private final Map<String, String> session2user = new HashMap<>();
21+
22+
@Override
23+
public synchronized void put(String sessionId, String user) {
24+
if (session2instant.put(sessionId, now()) == null) {
25+
user2count.compute(user, (k, count) -> Optional.ofNullable(count).orElse(0) + 1);
26+
session2user.put(sessionId, user);
27+
}
28+
}
29+
30+
@Override
31+
public void update(String sessionId) {
32+
session2instant.replace(sessionId, now());
33+
}
34+
35+
@Override
36+
public synchronized void remove(String sessionId) {
37+
if (session2instant.remove(sessionId) != null) {
38+
String user = session2user.remove(sessionId);
39+
user2count.compute(user, (k, count) -> count - 1);
40+
}
41+
}
42+
43+
@Override
44+
public synchronized List<String> expireSessionsOlderThan(Duration duration) {
45+
List<String> sessions2delete = session2instant.entrySet().stream()
46+
.filter(e -> duration.compareTo(Duration.between(e.getValue(), now())) < 0)
47+
.map(Map.Entry::getKey)
48+
.collect(toList());
49+
sessions2delete.stream().forEach(this::remove);
50+
return sessions2delete;
51+
}
52+
53+
@Override
54+
public synchronized int getCountFor(String user) {
55+
return user2count.getOrDefault(user, 0);
56+
}
57+
}

proxy/src/main/java/ru/qatools/gridrouter/ProxyServlet.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import org.slf4j.Logger;
77
import org.slf4j.LoggerFactory;
88
import org.springframework.beans.factory.annotation.Autowired;
9-
import ru.qatools.gridrouter.json.GridStats;
109
import ru.qatools.gridrouter.json.JsonMessage;
1110
import ru.qatools.gridrouter.json.JsonMessageFactory;
1211

@@ -45,7 +44,7 @@ public class ProxyServlet extends org.eclipse.jetty.proxy.ProxyServlet {
4544
private ConfigRepository config;
4645

4746
@Autowired
48-
private GridStats stats;
47+
private SessionStorage sessionStorage;
4948

5049
@Override
5150
public void init(ServletConfig config) throws ServletException {
@@ -87,7 +86,9 @@ protected String rewriteTarget(HttpServletRequest request) {
8786

8887
if (isSessionDeleteRequest(request, command)) {
8988
LOGGER.info("[SESSION_DELETED] [{}] [{}] [{}]", remoteHost, route, command);
90-
stats.stopSession();
89+
sessionStorage.remove(getFullSessionId(uri));
90+
} else {
91+
sessionStorage.update(getFullSessionId(uri));
9192
}
9293

9394
try {

proxy/src/main/java/ru/qatools/gridrouter/RouteServlet.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import ru.qatools.gridrouter.config.HostSelectionStrategy;
1818
import ru.qatools.gridrouter.config.Region;
1919
import ru.qatools.gridrouter.config.Version;
20-
import ru.qatools.gridrouter.json.GridStats;
2120
import ru.qatools.gridrouter.json.JsonCapabilities;
2221
import ru.qatools.gridrouter.json.JsonMessage;
2322
import ru.qatools.gridrouter.json.JsonMessageFactory;
@@ -64,7 +63,7 @@ public class RouteServlet extends HttpServlet {
6463
private HostSelectionStrategy hostSelectionStrategy;
6564

6665
@Autowired
67-
private GridStats stats;
66+
private SessionStorage sessionStorage;
6867

6968
@Autowired
7069
private CapabilityProcessorFactory capabilityProcessorFactory;
@@ -124,7 +123,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
124123
replyWithOk(hubMessage, response);
125124
LOGGER.info("[SESSION_CREATED] [{}] [{}] [{}] [{}] [{}] [{}]",
126125
user, remoteHost, browser, route, sessionId, attempt);
127-
stats.startSession();
126+
sessionStorage.put(hubMessage.getSessionId(), user);
128127
return;
129128
}
130129
LOGGER.warn("[SESSION_FAILED] [{}] [{}] [{}] [{}] - {}",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package ru.qatools.gridrouter;
2+
3+
import java.time.Duration;
4+
import java.util.List;
5+
6+
/**
7+
* @author Innokenty Shuvalov [email protected]
8+
*/
9+
public interface SessionStorage {
10+
11+
void put(String sessionId, String user);
12+
13+
void update(String sessionId);
14+
15+
void remove(String sessionId);
16+
17+
List<String> expireSessionsOlderThan(Duration duration);
18+
19+
int getCountFor(String user);
20+
}

proxy/src/main/java/ru/qatools/gridrouter/StatsServlet.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
import org.apache.commons.io.IOUtils;
44
import org.springframework.beans.factory.annotation.Autowired;
5-
import ru.qatools.gridrouter.json.GridStats;
65

76
import javax.servlet.ServletConfig;
87
import javax.servlet.ServletException;
8+
import javax.servlet.annotation.HttpConstraint;
9+
import javax.servlet.annotation.ServletSecurity;
910
import javax.servlet.annotation.WebServlet;
1011
import javax.servlet.http.HttpServlet;
1112
import javax.servlet.http.HttpServletRequest;
@@ -15,17 +16,18 @@
1516

1617
import static java.nio.charset.StandardCharsets.UTF_8;
1718
import static javax.servlet.http.HttpServletResponse.SC_OK;
18-
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
19+
import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
1920
import static org.springframework.web.context.support.SpringBeanAutowiringSupport.processInjectionBasedOnServletContext;
2021

2122
/**
2223
* @author Dmitry Baev [email protected]
2324
*/
2425
@WebServlet(urlPatterns = {"/stats"}, asyncSupported = true)
26+
@ServletSecurity(value = @HttpConstraint(rolesAllowed = {"user"}))
2527
public class StatsServlet extends HttpServlet {
2628

2729
@Autowired
28-
private GridStats stats;
30+
private SessionStorage sessionStorage;
2931

3032
@Override
3133
public void init(ServletConfig config) throws ServletException {
@@ -34,11 +36,13 @@ public void init(ServletConfig config) throws ServletException {
3436
}
3537

3638
@Override
37-
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
38-
resp.setStatus(SC_OK);
39-
resp.setContentType(APPLICATION_JSON_VALUE);
40-
try (OutputStream output = resp.getOutputStream()) {
41-
IOUtils.write(stats.toJson(), output, UTF_8);
39+
protected void doGet(HttpServletRequest request, HttpServletResponse response)
40+
throws ServletException, IOException {
41+
response.setStatus(SC_OK);
42+
response.setContentType(TEXT_PLAIN_VALUE);
43+
try (OutputStream output = response.getOutputStream()) {
44+
int count = sessionStorage.getCountFor(request.getRemoteUser());
45+
IOUtils.write(String.valueOf(count), output, UTF_8);
4246
}
4347
}
4448
}

proxy/src/main/java/ru/qatools/gridrouter/json/WithOpenSessions.java

Lines changed: 0 additions & 24 deletions
This file was deleted.

proxy/src/main/resources/META-INF/spring/application-context.xml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
44
xmlns:context="http://www.springframework.org/schema/context"
55
xsi:schemaLocation="
6-
http://www.springframework.org/schema/beans
7-
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
8-
http://www.springframework.org/schema/context
9-
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
6+
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
7+
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
108

119
<context:component-scan base-package="ru.qatools.gridrouter"/>
1210

@@ -21,6 +19,6 @@
2119

2220
<bean id="hostSelectionStrategy" class="ru.qatools.gridrouter.config.RandomHostSelectionStrategy"/>
2321

24-
<bean id="stats" class="ru.qatools.gridrouter.json.GridStats"/>
22+
<bean class="ru.qatools.gridrouter.MemorySessionStorage"/>
2523

2624
</beans>

proxy/src/main/resources/xsd/stats.xjb

Lines changed: 0 additions & 16 deletions
This file was deleted.

proxy/src/main/resources/xsd/stats.xsd

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)