Skip to content

Commit 72c12c3

Browse files
authored
Merge pull request #2810 from ClickHouse/03/26/26/set_session
[client-v2] Session API with reusable Session objects
2 parents d351710 + 7ae5f16 commit 72c12c3

15 files changed

Lines changed: 959 additions & 20 deletions

File tree

client-v2/src/main/java/com/clickhouse/client/api/Client.java

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ public class Client implements AutoCloseable {
115115

116116
private final List<Endpoint> endpoints;
117117
private final Map<String, Object> configuration;
118+
private final Session session;
118119

119120
private final Map<String, String> readOnlyConfig;
120121

@@ -143,7 +144,9 @@ public class Client implements AutoCloseable {
143144
private Client(Collection<Endpoint> endpoints, Map<String,String> configuration,
144145
ExecutorService sharedOperationExecutor, ColumnToMethodMatchingStrategy columnToMethodMatchingStrategy,
145146
Object metricsRegistry, Supplier<String> queryIdGenerator) {
146-
this.configuration = ClientConfigProperties.parseConfigMap(configuration);
147+
Map<String, Object> parsedConfiguration = ClientConfigProperties.parseConfigMap(configuration);
148+
this.session = Session.extractFrom(parsedConfiguration);
149+
this.configuration = new ConcurrentHashMap<>(parsedConfiguration);
147150
this.readOnlyConfig = Collections.unmodifiableMap(configuration);
148151
this.metricsRegistry = metricsRegistry;
149152
this.queryIdGenerator = queryIdGenerator;
@@ -931,6 +934,54 @@ public Builder serverSetting(String name, Collection<String> values) {
931934
return this;
932935
}
933936

937+
/**
938+
* Sets ClickHouse session id to be sent with each request.
939+
*/
940+
public Builder setSessionId(String sessionId) {
941+
ValidationUtils.checkNonBlank(sessionId, ClickHouseHttpProto.QPARAM_SESSION_ID);
942+
return serverSetting(ClickHouseHttpProto.QPARAM_SESSION_ID, sessionId);
943+
}
944+
945+
/**
946+
* Sets ClickHouse session check flag to be sent with each request.
947+
*/
948+
public Builder setSessionCheck(boolean sessionCheck) {
949+
return serverSetting(ClickHouseHttpProto.QPARAM_SESSION_CHECK, sessionCheck ? "1" : "0");
950+
}
951+
952+
/**
953+
* Sets ClickHouse session timeout in seconds to be sent with each request.
954+
*/
955+
public Builder setSessionTimeout(int timeoutInSeconds) {
956+
ValidationUtils.checkPositive(timeoutInSeconds, ClickHouseHttpProto.QPARAM_SESSION_TIMEOUT);
957+
return serverSetting(ClickHouseHttpProto.QPARAM_SESSION_TIMEOUT, String.valueOf(timeoutInSeconds));
958+
}
959+
960+
/**
961+
* Sets ClickHouse session timezone to be sent with each request.
962+
*/
963+
public Builder setSessionTimezone(String timezone) {
964+
ValidationUtils.checkNonBlank(timezone, ClickHouseHttpProto.QPARAM_SESSION_TIMEZONE);
965+
return serverSetting(ClickHouseHttpProto.QPARAM_SESSION_TIMEZONE, timezone);
966+
}
967+
968+
public Builder use(Session session) {
969+
ValidationUtils.checkNotNull(session, "session");
970+
if (session.getSessionId() != null) {
971+
setSessionId(session.getSessionId());
972+
}
973+
if (session.getSessionCheck() != null) {
974+
setSessionCheck(session.getSessionCheck());
975+
}
976+
if (session.getSessionTimeout() != null) {
977+
setSessionTimeout(session.getSessionTimeout());
978+
}
979+
if (session.getSessionTimezone() != null) {
980+
setSessionTimezone(session.getSessionTimezone());
981+
}
982+
return this;
983+
}
984+
934985
/**
935986
* Sets column to method matching strategy. It is used while registering POJO serializers and deserializers.
936987
* Default is {@link DefaultColumnToMethodMatchingStrategy}.
@@ -2114,6 +2165,14 @@ public void updateClientName(String name) {
21142165
this.configuration.put(ClientConfigProperties.CLIENT_NAME.getKey(), name);
21152166
}
21162167

2168+
/**
2169+
* Updates ClickHouse session id for all subsequent requests created by this client.
2170+
*/
2171+
public void updateSessionId(String sessionId) {
2172+
ValidationUtils.checkNonBlank(sessionId, ClickHouseHttpProto.QPARAM_SESSION_ID);
2173+
this.session.updateSessionId(sessionId);
2174+
}
2175+
21172176
public static final String clientVersion =
21182177
ClickHouseClientOption.readVersionFromResource("client-v2-version.properties");
21192178
public static final String CLIENT_USER_AGENT = "clickhouse-java-v2/";
@@ -2146,8 +2205,8 @@ private Endpoint getNextAliveNode() {
21462205
* @return request settings - merged client and operation settings
21472206
*/
21482207
private Map<String, Object> buildRequestSettings(Map<String, Object> opSettings) {
2149-
Map<String, Object> requestSettings = new HashMap<>();
2150-
requestSettings.putAll(configuration);
2208+
Map<String, Object> requestSettings = new HashMap<>(configuration);
2209+
session.applyTo(requestSettings);
21512210
requestSettings.putAll(opSettings);
21522211
return requestSettings;
21532212
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package com.clickhouse.client.api;
2+
3+
import com.clickhouse.client.api.http.ClickHouseHttpProto;
4+
import com.clickhouse.client.api.internal.ValidationUtils;
5+
6+
import java.util.Map;
7+
8+
/**
9+
* Reusable ClickHouse session configuration that can be applied to clients or operation settings.
10+
*/
11+
public class Session {
12+
private String sessionId;
13+
private Boolean sessionCheck;
14+
private Integer sessionTimeout;
15+
private String sessionTimezone;
16+
17+
static Session extractFrom(Map<String, Object> configuration) {
18+
Session session = new Session();
19+
20+
String sessionId = (String) configuration.get(ClientConfigProperties.serverSetting(ClickHouseHttpProto.QPARAM_SESSION_ID));
21+
if (sessionId != null) {
22+
session.setSessionId(sessionId);
23+
}
24+
25+
String sessionCheck = (String) configuration.get(ClientConfigProperties.serverSetting(ClickHouseHttpProto.QPARAM_SESSION_CHECK));
26+
if (sessionCheck != null) {
27+
session.setSessionCheck("1".equals(sessionCheck) || Boolean.parseBoolean(sessionCheck));
28+
}
29+
30+
String sessionTimeout = (String) configuration.get(ClientConfigProperties.serverSetting(ClickHouseHttpProto.QPARAM_SESSION_TIMEOUT));
31+
if (sessionTimeout != null) {
32+
session.setSessionTimeout(Integer.parseInt(sessionTimeout));
33+
}
34+
35+
String sessionTimezone = (String) configuration.get(ClientConfigProperties.serverSetting(ClickHouseHttpProto.QPARAM_SESSION_TIMEZONE));
36+
if (sessionTimezone != null) {
37+
session.setSessionTimezone(sessionTimezone);
38+
}
39+
40+
return session;
41+
}
42+
43+
public synchronized Session setSessionId(String sessionId) {
44+
ValidationUtils.checkNonBlank(sessionId, ClickHouseHttpProto.QPARAM_SESSION_ID);
45+
this.sessionId = sessionId;
46+
return this;
47+
}
48+
49+
public synchronized String getSessionId() {
50+
return sessionId;
51+
}
52+
53+
public synchronized Session setSessionCheck(boolean sessionCheck) {
54+
this.sessionCheck = sessionCheck;
55+
return this;
56+
}
57+
58+
public synchronized Boolean getSessionCheck() {
59+
return sessionCheck;
60+
}
61+
62+
public synchronized Session setSessionTimeout(int timeoutInSeconds) {
63+
ValidationUtils.checkPositive(timeoutInSeconds, ClickHouseHttpProto.QPARAM_SESSION_TIMEOUT);
64+
this.sessionTimeout = timeoutInSeconds;
65+
return this;
66+
}
67+
68+
public synchronized Integer getSessionTimeout() {
69+
return sessionTimeout;
70+
}
71+
72+
public synchronized Session setSessionTimezone(String timezone) {
73+
ValidationUtils.checkNonBlank(timezone, ClickHouseHttpProto.QPARAM_SESSION_TIMEZONE);
74+
this.sessionTimezone = timezone;
75+
return this;
76+
}
77+
78+
public synchronized String getSessionTimezone() {
79+
return sessionTimezone;
80+
}
81+
82+
public synchronized void updateSessionId(String sessionId) {
83+
setSessionId(sessionId);
84+
}
85+
86+
public synchronized void applyTo(Map<String, Object> requestSettings) {
87+
putIfSet(requestSettings, ClickHouseHttpProto.QPARAM_SESSION_ID, sessionId);
88+
putIfSet(requestSettings, ClickHouseHttpProto.QPARAM_SESSION_CHECK,
89+
sessionCheck == null ? null : (sessionCheck ? "1" : "0"));
90+
putIfSet(requestSettings, ClickHouseHttpProto.QPARAM_SESSION_TIMEOUT,
91+
sessionTimeout == null ? null : String.valueOf(sessionTimeout));
92+
putIfSet(requestSettings, ClickHouseHttpProto.QPARAM_SESSION_TIMEZONE, sessionTimezone);
93+
}
94+
95+
private static void putIfSet(Map<String, Object> settings, String key, String value) {
96+
if (value != null) {
97+
settings.put(ClientConfigProperties.serverSetting(key), value);
98+
}
99+
}
100+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,36 @@
11
package com.clickhouse.client.api.command;
22

3+
import com.clickhouse.client.api.Session;
34
import com.clickhouse.client.api.query.QuerySettings;
45

56
public class CommandSettings extends QuerySettings {
7+
@Override
8+
public CommandSettings setSessionId(String sessionId) {
9+
super.setSessionId(sessionId);
10+
return this;
11+
}
12+
13+
@Override
14+
public CommandSettings setSessionCheck(boolean sessionCheck) {
15+
super.setSessionCheck(sessionCheck);
16+
return this;
17+
}
18+
19+
@Override
20+
public CommandSettings setSessionTimeout(int timeoutInSeconds) {
21+
super.setSessionTimeout(timeoutInSeconds);
22+
return this;
23+
}
24+
25+
@Override
26+
public CommandSettings setSessionTimezone(String timezone) {
27+
super.setSessionTimezone(timezone);
28+
return this;
29+
}
30+
31+
@Override
32+
public CommandSettings use(Session session) {
33+
super.use(session);
34+
return this;
35+
}
636
}

client-v2/src/main/java/com/clickhouse/client/api/http/ClickHouseHttpProto.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,26 @@ public class ClickHouseHttpProto {
5757
*/
5858
public static final String QPARAM_QUERY_ID = "query_id";
5959

60+
/**
61+
* Query parameter to specify a session id.
62+
*/
63+
public static final String QPARAM_SESSION_ID = "session_id";
64+
65+
/**
66+
* Query parameter to check session status (1/0).
67+
*/
68+
public static final String QPARAM_SESSION_CHECK = "session_check";
69+
70+
/**
71+
* Query parameter to specify session timeout in seconds.
72+
*/
73+
public static final String QPARAM_SESSION_TIMEOUT = "session_timeout";
74+
75+
/**
76+
* Query parameter to specify session timezone.
77+
*/
78+
public static final String QPARAM_SESSION_TIMEZONE = "session_timezone";
79+
6080
public static final String QPARAM_ROLE = "role";
6181

6282
/**

client-v2/src/main/java/com/clickhouse/client/api/insert/InsertSettings.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.clickhouse.client.api.Client;
44
import com.clickhouse.client.api.ClientConfigProperties;
5+
import com.clickhouse.client.api.Session;
56
import com.clickhouse.client.api.internal.CommonSettings;
67
import org.apache.hc.core5.http.HttpHeaders;
78

@@ -91,6 +92,59 @@ public InsertSettings setQueryId(String queryId) {
9192
return this;
9293
}
9394

95+
/**
96+
* Sets ClickHouse session id for this operation.
97+
*/
98+
public InsertSettings setSessionId(String sessionId) {
99+
settings.setSessionId(sessionId);
100+
return this;
101+
}
102+
103+
public String getSessionId() {
104+
return settings.getSessionId();
105+
}
106+
107+
/**
108+
* Sets ClickHouse session check flag for this operation.
109+
*/
110+
public InsertSettings setSessionCheck(boolean sessionCheck) {
111+
settings.setSessionCheck(sessionCheck);
112+
return this;
113+
}
114+
115+
public Boolean getSessionCheck() {
116+
return settings.getSessionCheck();
117+
}
118+
119+
/**
120+
* Sets ClickHouse session timeout (seconds) for this operation.
121+
*/
122+
public InsertSettings setSessionTimeout(int timeoutInSeconds) {
123+
settings.setSessionTimeout(timeoutInSeconds);
124+
return this;
125+
}
126+
127+
public Integer getSessionTimeout() {
128+
return settings.getSessionTimeout();
129+
}
130+
131+
/**
132+
* Sets ClickHouse session timezone for this operation.
133+
*/
134+
public InsertSettings setSessionTimezone(String timezone) {
135+
settings.setSessionTimezone(timezone);
136+
return this;
137+
}
138+
139+
public String getSessionTimezone() {
140+
return settings.getSessionTimezone();
141+
}
142+
143+
public InsertSettings use(Session session) {
144+
settings.use(session);
145+
return this;
146+
}
147+
94148
public int getInputStreamCopyBufferSize() {
95149
return this.inputStreamCopyBufferSize;
96150
}

client-v2/src/main/java/com/clickhouse/client/api/internal/CommonSettings.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.clickhouse.client.api.Client;
44
import com.clickhouse.client.api.ClientConfigProperties;
5+
import com.clickhouse.client.api.Session;
6+
import com.clickhouse.client.api.http.ClickHouseHttpProto;
57

68
import java.time.Duration;
79
import java.time.temporal.ChronoUnit;
@@ -90,6 +92,53 @@ public CommonSettings setQueryId(String queryId) {
9092
return this;
9193
}
9294

95+
public CommonSettings setSessionId(String sessionId) {
96+
ValidationUtils.checkNonBlank(sessionId, ClickHouseHttpProto.QPARAM_SESSION_ID);
97+
serverSetting(ClickHouseHttpProto.QPARAM_SESSION_ID, sessionId);
98+
return this;
99+
}
100+
101+
public String getSessionId() {
102+
return (String) settings.get(ClientConfigProperties.serverSetting(ClickHouseHttpProto.QPARAM_SESSION_ID));
103+
}
104+
105+
public CommonSettings setSessionCheck(boolean sessionCheck) {
106+
serverSetting(ClickHouseHttpProto.QPARAM_SESSION_CHECK, sessionCheck ? "1" : "0");
107+
return this;
108+
}
109+
110+
public Boolean getSessionCheck() {
111+
String value = (String) settings.get(ClientConfigProperties.serverSetting(ClickHouseHttpProto.QPARAM_SESSION_CHECK));
112+
return value == null ? null : ("1".equals(value) || Boolean.parseBoolean(value));
113+
}
114+
115+
public CommonSettings setSessionTimeout(int timeoutInSeconds) {
116+
ValidationUtils.checkPositive(timeoutInSeconds, ClickHouseHttpProto.QPARAM_SESSION_TIMEOUT);
117+
serverSetting(ClickHouseHttpProto.QPARAM_SESSION_TIMEOUT, String.valueOf(timeoutInSeconds));
118+
return this;
119+
}
120+
121+
public Integer getSessionTimeout() {
122+
String value = (String) settings.get(ClientConfigProperties.serverSetting(ClickHouseHttpProto.QPARAM_SESSION_TIMEOUT));
123+
return value == null ? null : Integer.valueOf(value);
124+
}
125+
126+
public CommonSettings setSessionTimezone(String timezone) {
127+
ValidationUtils.checkNonBlank(timezone, ClickHouseHttpProto.QPARAM_SESSION_TIMEZONE);
128+
serverSetting(ClickHouseHttpProto.QPARAM_SESSION_TIMEZONE, timezone);
129+
return this;
130+
}
131+
132+
public String getSessionTimezone() {
133+
return (String) settings.get(ClientConfigProperties.serverSetting(ClickHouseHttpProto.QPARAM_SESSION_TIMEZONE));
134+
}
135+
136+
public CommonSettings use(Session session) {
137+
ValidationUtils.checkNotNull(session, "session");
138+
session.applyTo(settings);
139+
return this;
140+
}
141+
93142
/**
94143
* Operation id. Used internally to register new operation.
95144
* Should not be called directly.

0 commit comments

Comments
 (0)