Skip to content

Commit 20c880c

Browse files
committed
WIP
1 parent c00f2a8 commit 20c880c

File tree

9 files changed

+342
-79
lines changed

9 files changed

+342
-79
lines changed

docs/modules/druid/pages/usage-guide/overrides.adoc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,3 @@ Read the xref:concepts:overrides.adoc#pod-overrides[Pod overrides documentation]
129129

130130
Stackable operators automatically determine the set of needed JVM arguments, such as memory settings or trust- and keystores.
131131
Using JVM argument overrides you can configure the JVM arguments xref:concepts:overrides.adoc#jvm-argument-overrides[according to the concepts page].
132-
133-
TODO more docs specific to Druid.

rust/operator-binary/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ indoc.workspace = true
2222
openssl.workspace = true
2323
pin-project.workspace = true
2424
semver.workspace = true
25-
serde.workspace = true
2625
serde_json.workspace = true
26+
serde.workspace = true
2727
snafu.workspace = true
2828
strum.workspace = true
2929
tokio.workspace = true

rust/operator-binary/src/config.rs

Lines changed: 0 additions & 61 deletions
This file was deleted.
Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
use snafu::{ResultExt, Snafu};
2+
use stackable_operator::role_utils::{
3+
GenericRoleConfig, JavaCommonConfig, JvmArgumentOverrides, Role,
4+
};
5+
use stackable_operator::{memory::MemoryQuantity, role_utils};
6+
7+
use crate::crd::DruidRole;
8+
use crate::crd::{
9+
JVM_SECURITY_PROPERTIES_FILE, LOG4J2_CONFIG, RW_CONFIG_DIRECTORY, STACKABLE_TRUST_STORE,
10+
STACKABLE_TRUST_STORE_PASSWORD,
11+
};
12+
13+
#[derive(Snafu, Debug)]
14+
pub enum Error {
15+
#[snafu(display("failed to format memory quantity {value:?} for Java"))]
16+
FormatMemoryStringForJava {
17+
value: MemoryQuantity,
18+
source: stackable_operator::memory::Error,
19+
},
20+
21+
#[snafu(display("failed to merge jvm argument overrides"))]
22+
MergeJvmArgumentOverrides { source: role_utils::Error },
23+
}
24+
25+
/// Please note that this function is slightly different than all other operators, because memory
26+
/// management is far more advanced in this operator.
27+
pub fn construct_jvm_args<T>(
28+
druid_role: &DruidRole,
29+
role: &Role<T, GenericRoleConfig, JavaCommonConfig>,
30+
role_group: &str,
31+
heap: MemoryQuantity,
32+
direct_memory: Option<MemoryQuantity>,
33+
) -> Result<String, Error> {
34+
let heap_str = heap
35+
.format_for_java()
36+
.with_context(|_| FormatMemoryStringForJavaSnafu { value: heap })?;
37+
let direct_memory_str = if let Some(m) = direct_memory {
38+
Some(
39+
m.format_for_java()
40+
.with_context(|_| FormatMemoryStringForJavaSnafu { value: m })?,
41+
)
42+
} else {
43+
None
44+
};
45+
46+
let mut jvm_args = vec![
47+
"-server".to_owned(),
48+
format!("-Xmx{heap_str}"),
49+
format!("-Xms{heap_str}"),
50+
];
51+
if let Some(direct_memory) = direct_memory_str {
52+
jvm_args.push(format!("-XX:MaxDirectMemorySize={direct_memory}"));
53+
}
54+
jvm_args.extend([
55+
"-XX:+ExitOnOutOfMemoryError".to_owned(),
56+
"-XX:+UseG1GC".to_owned(),
57+
format!("-Djava.security.properties={RW_CONFIG_DIRECTORY}/{JVM_SECURITY_PROPERTIES_FILE}"),
58+
"-Duser.timezone=UTC".to_owned(),
59+
"-Dfile.encoding=UTF-8".to_owned(),
60+
"-Djava.io.tmpdir=/tmp".to_owned(),
61+
"-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager".to_owned(),
62+
format!("-Dlog4j.configurationFile={RW_CONFIG_DIRECTORY}/{LOG4J2_CONFIG}"),
63+
format!("-Djavax.net.ssl.trustStore={STACKABLE_TRUST_STORE}"),
64+
format!("-Djavax.net.ssl.trustStorePassword={STACKABLE_TRUST_STORE_PASSWORD}"),
65+
"-Djavax.net.ssl.trustStoreType=pkcs12".to_owned(),
66+
]);
67+
if druid_role == &DruidRole::Coordinator {
68+
jvm_args.push("-Dderby.stream.error.file=/stackable/var/druid/derby.log".to_owned());
69+
}
70+
71+
let operator_generated = JvmArgumentOverrides::new_with_only_additions(jvm_args);
72+
let merged_jvm_argument_overrides = role
73+
.get_merged_jvm_argument_overrides(role_group, &operator_generated)
74+
.context(MergeJvmArgumentOverridesSnafu)?;
75+
76+
Ok(merged_jvm_argument_overrides
77+
.effective_jvm_config_after_merging()
78+
.join("\n"))
79+
}
80+
81+
#[cfg(test)]
82+
mod tests {
83+
use indoc::indoc;
84+
85+
use crate::crd::v1alpha1::DruidCluster;
86+
87+
use super::*;
88+
89+
#[test]
90+
fn test_construct_jvm_arguments_defaults() {
91+
let input = r#"
92+
apiVersion: druid.stackable.tech/v1alpha1
93+
kind: DruidCluster
94+
metadata:
95+
name: simple-druid
96+
spec:
97+
image:
98+
productVersion: 30.0.0
99+
clusterConfig:
100+
deepStorage:
101+
hdfs:
102+
configMapName: simple-hdfs
103+
directory: /druid
104+
metadataStorageDatabase:
105+
dbType: postgresql
106+
connString: jdbc:postgresql://druid-postgresql/druid
107+
host: druid-postgresql
108+
port: 5432
109+
credentialsSecret: mySecret
110+
zookeeperConfigMapName: simple-druid-znode
111+
brokers:
112+
roleGroups:
113+
default:
114+
replicas: 1
115+
coordinators:
116+
roleGroups:
117+
default:
118+
replicas: 1
119+
historicals:
120+
roleGroups:
121+
default:
122+
replicas: 1
123+
middleManagers:
124+
roleGroups:
125+
default:
126+
replicas: 1
127+
routers:
128+
roleGroups:
129+
default:
130+
replicas: 1
131+
"#;
132+
133+
let coordinator_jvm_config = construct_jvm_config_for_test(input, &DruidRole::Coordinator);
134+
let historical_jvm_config = construct_jvm_config_for_test(input, &DruidRole::Historical);
135+
136+
assert_eq!(
137+
coordinator_jvm_config,
138+
indoc! {"
139+
-server
140+
-Xmx212m
141+
-Xms212m
142+
-XX:+ExitOnOutOfMemoryError
143+
-XX:+UseG1GC
144+
-Djava.security.properties=/stackable/rwconfig/security.properties
145+
-Duser.timezone=UTC
146+
-Dfile.encoding=UTF-8
147+
-Djava.io.tmpdir=/tmp
148+
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
149+
-Dlog4j.configurationFile=/stackable/rwconfig/log4j2.properties
150+
-Djavax.net.ssl.trustStore=/stackable/truststore.p12
151+
-Djavax.net.ssl.trustStorePassword=changeit
152+
-Djavax.net.ssl.trustStoreType=pkcs12
153+
-Dderby.stream.error.file=/stackable/var/druid/derby.log"}
154+
);
155+
assert_eq!(
156+
historical_jvm_config,
157+
indoc! {"
158+
-server
159+
-Xmx900m
160+
-Xms900m
161+
-XX:MaxDirectMemorySize=300m
162+
-XX:+ExitOnOutOfMemoryError
163+
-XX:+UseG1GC
164+
-Djava.security.properties=/stackable/rwconfig/security.properties
165+
-Duser.timezone=UTC
166+
-Dfile.encoding=UTF-8
167+
-Djava.io.tmpdir=/tmp
168+
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
169+
-Dlog4j.configurationFile=/stackable/rwconfig/log4j2.properties
170+
-Djavax.net.ssl.trustStore=/stackable/truststore.p12
171+
-Djavax.net.ssl.trustStorePassword=changeit
172+
-Djavax.net.ssl.trustStoreType=pkcs12"}
173+
);
174+
}
175+
176+
#[test]
177+
fn test_construct_jvm_argument_overrides() {
178+
let input = r#"
179+
apiVersion: druid.stackable.tech/v1alpha1
180+
kind: DruidCluster
181+
metadata:
182+
name: simple-druid
183+
spec:
184+
image:
185+
productVersion: 30.0.0
186+
clusterConfig:
187+
deepStorage:
188+
hdfs:
189+
configMapName: simple-hdfs
190+
directory: /druid
191+
metadataStorageDatabase:
192+
dbType: postgresql
193+
connString: jdbc:postgresql://druid-postgresql/druid
194+
host: druid-postgresql
195+
port: 5432
196+
credentialsSecret: mySecret
197+
zookeeperConfigMapName: simple-druid-znode
198+
brokers:
199+
roleGroups:
200+
default:
201+
replicas: 1
202+
coordinators:
203+
config:
204+
resources:
205+
memory:
206+
limit: 42Gi
207+
jvmArgumentOverrides:
208+
add:
209+
- -Dhttps.proxyHost=proxy.my.corp
210+
- -Dhttps.proxyPort=8080
211+
- -Djava.net.preferIPv4Stack=true
212+
roleGroups:
213+
default:
214+
replicas: 1
215+
jvmArgumentOverrides:
216+
# We need more memory!
217+
removeRegex:
218+
- -Xmx.*
219+
- -Dhttps.proxyPort=.*
220+
add:
221+
- -Xmx40000m
222+
- -Dhttps.proxyPort=1234
223+
historicals:
224+
config:
225+
resources:
226+
memory:
227+
limit: 13Gi
228+
jvmArgumentOverrides:
229+
add:
230+
- -Dfoo=bar
231+
roleGroups:
232+
default:
233+
replicas: 1
234+
middleManagers:
235+
roleGroups:
236+
default:
237+
replicas: 1
238+
routers:
239+
roleGroups:
240+
default:
241+
replicas: 1
242+
"#;
243+
244+
let coordinator_jvm_config = construct_jvm_config_for_test(input, &DruidRole::Coordinator);
245+
let historical_jvm_config = construct_jvm_config_for_test(input, &DruidRole::Historical);
246+
247+
assert_eq!(
248+
coordinator_jvm_config,
249+
indoc! {"
250+
-server
251+
-Xms42708m
252+
-XX:+ExitOnOutOfMemoryError
253+
-XX:+UseG1GC
254+
-Djava.security.properties=/stackable/rwconfig/security.properties
255+
-Duser.timezone=UTC
256+
-Dfile.encoding=UTF-8
257+
-Djava.io.tmpdir=/tmp
258+
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
259+
-Dlog4j.configurationFile=/stackable/rwconfig/log4j2.properties
260+
-Djavax.net.ssl.trustStore=/stackable/truststore.p12
261+
-Djavax.net.ssl.trustStorePassword=changeit
262+
-Djavax.net.ssl.trustStoreType=pkcs12
263+
-Dderby.stream.error.file=/stackable/var/druid/derby.log
264+
-Dhttps.proxyHost=proxy.my.corp
265+
-Djava.net.preferIPv4Stack=true
266+
-Xmx40000m
267+
-Dhttps.proxyPort=1234"}
268+
);
269+
assert_eq!(
270+
historical_jvm_config,
271+
indoc! {"
272+
-server
273+
-Xmx9759m
274+
-Xms9759m
275+
-XX:MaxDirectMemorySize=3253m
276+
-XX:+ExitOnOutOfMemoryError
277+
-XX:+UseG1GC
278+
-Djava.security.properties=/stackable/rwconfig/security.properties
279+
-Duser.timezone=UTC
280+
-Dfile.encoding=UTF-8
281+
-Djava.io.tmpdir=/tmp
282+
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
283+
-Dlog4j.configurationFile=/stackable/rwconfig/log4j2.properties
284+
-Djavax.net.ssl.trustStore=/stackable/truststore.p12
285+
-Djavax.net.ssl.trustStorePassword=changeit
286+
-Djavax.net.ssl.trustStoreType=pkcs12
287+
-Dfoo=bar"}
288+
);
289+
}
290+
291+
fn construct_jvm_config_for_test(druid_cluster: &str, druid_role: &DruidRole) -> String {
292+
let deserializer = serde_yaml::Deserializer::from_str(druid_cluster);
293+
let druid: DruidCluster =
294+
serde_yaml::with::singleton_map_recursive::deserialize(deserializer).unwrap();
295+
296+
let role = druid.get_role(druid_role);
297+
let merged_config = druid.merged_config().unwrap();
298+
let (heap, direct) = merged_config
299+
.common_config(druid_role, "default")
300+
.unwrap()
301+
.resources
302+
.get_memory_sizes(druid_role)
303+
.unwrap();
304+
305+
construct_jvm_args(druid_role, &role, "default", heap, direct).unwrap()
306+
}
307+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod jvm;

rust/operator-binary/src/crd/affinity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ mod tests {
146146
let merged_config = druid
147147
.merged_config()
148148
.unwrap()
149-
.common_config(role.clone(), "default")
149+
.common_config(&role, "default")
150150
.unwrap();
151151

152152
let mut expected_affinities = vec![];

0 commit comments

Comments
 (0)