Skip to content
This repository was archived by the owner on Aug 20, 2025. It is now read-only.

Commit c899eca

Browse files
committed
Refactored ZkConfigurationManager. The previous implementation followed what already existed. Some of that was not needed
1 parent 5151f23 commit c899eca

File tree

4 files changed

+27
-96
lines changed

4 files changed

+27
-96
lines changed

metron-analytics/metron-profiler-client/src/main/java/org/apache/metron/profiler/client/HBaseProfilerClient.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,15 @@
2424
import org.apache.hadoop.hbase.client.HTableInterface;
2525
import org.apache.hadoop.hbase.client.Result;
2626
import org.apache.hadoop.hbase.util.Bytes;
27+
import org.apache.metron.common.utils.SerDeUtils;
2728
import org.apache.metron.profiler.ProfilePeriod;
2829
import org.apache.metron.profiler.hbase.ColumnBuilder;
2930
import org.apache.metron.profiler.hbase.RowKeyBuilder;
30-
import org.apache.metron.common.utils.SerDeUtils;
3131

3232
import java.io.IOException;
3333
import java.util.ArrayList;
3434
import java.util.Arrays;
3535
import java.util.List;
36-
import java.util.concurrent.TimeUnit;
3736
import java.util.stream.Collectors;
3837

3938
/**

metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/manager/ZkConfigurationManager.java

Lines changed: 19 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,16 @@
2121
package org.apache.metron.common.configuration.manager;
2222

2323
import org.apache.curator.framework.CuratorFramework;
24-
import org.apache.curator.framework.recipes.cache.TreeCache;
24+
import org.apache.curator.framework.recipes.cache.NodeCache;
2525
import org.apache.curator.utils.CloseableUtils;
26-
import org.apache.metron.common.Constants;
2726
import org.apache.metron.common.utils.JSONUtils;
2827

2928
import java.io.ByteArrayInputStream;
3029
import java.io.IOException;
31-
import java.util.ArrayList;
32-
import java.util.List;
30+
import java.util.Collections;
31+
import java.util.HashMap;
3332
import java.util.Map;
3433
import java.util.Optional;
35-
import java.util.concurrent.ConcurrentHashMap;
3634

3735
import static org.apache.commons.lang.ArrayUtils.isNotEmpty;
3836

@@ -48,44 +46,18 @@ public class ZkConfigurationManager implements ConfigurationManager {
4846
private CuratorFramework zookeeperClient;
4947

5048
/**
51-
* A cache of the values stored in Zookeeper.
49+
* The configuration values under management. Maps the path to the configuration values
50+
* in Zookeeper to the cache of its values.
5251
*/
53-
private TreeCache zookeeperCache;
54-
55-
/**
56-
* The configuration values under management
57-
*/
58-
private Map<String, byte[]> values;
59-
60-
/**
61-
* The paths within Zookeeper that we care about.
62-
*/
63-
private List<String> paths;
64-
65-
/**
66-
* All configuration values must live under this root path.
67-
*/
68-
private String rootPath;
52+
private Map<String, NodeCache> valuesCache;
6953

7054
/**
7155
* @param zookeeperClient The client used to communicate with Zookeeper. The client is not
7256
* closed. It must be managed externally.
7357
*/
7458
public ZkConfigurationManager(CuratorFramework zookeeperClient) {
75-
this(zookeeperClient, Constants.ZOOKEEPER_TOPOLOGY_ROOT);
76-
}
77-
78-
/**
79-
* @param zookeeperClient The client used to communicate with Zookeeper. The client is not
80-
* closed. It must be managed externally.
81-
* @param rootPath The root of all configuration paths in Zookeeper that should be
82-
* monitored for configuration values.
83-
*/
84-
public ZkConfigurationManager(CuratorFramework zookeeperClient, String rootPath) {
8559
this.zookeeperClient = zookeeperClient;
86-
this.paths = new ArrayList<>();
87-
this.values = new ConcurrentHashMap<>();
88-
this.rootPath = rootPath;
60+
this.valuesCache = Collections.synchronizedMap(new HashMap<>());
8961
}
9062

9163
/**
@@ -94,15 +66,16 @@ public ZkConfigurationManager(CuratorFramework zookeeperClient, String rootPath)
9466
*/
9567
@Override
9668
public ZkConfigurationManager with(String zookeeperPath) {
97-
paths.add(zookeeperPath);
69+
NodeCache cache = new NodeCache(zookeeperClient, zookeeperPath);
70+
valuesCache.put(zookeeperPath, cache);
9871
return this;
9972
}
10073

10174
/**
10275
* Open a connection to Zookeeper and retrieve the initial configuration value.
10376
*/
10477
@Override
105-
public ZkConfigurationManager open() throws IOException {
78+
public synchronized ZkConfigurationManager open() throws IOException {
10679
try {
10780
doOpen();
10881
} catch(Exception e) {
@@ -113,51 +86,21 @@ public ZkConfigurationManager open() throws IOException {
11386
}
11487

11588
private void doOpen() throws Exception {
116-
117-
// the cache which will remain synced with zookeeper
118-
zookeeperCache = new TreeCache(zookeeperClient, rootPath);
119-
zookeeperCache.getListenable().addListener((client, event) -> {
120-
121-
// is there data that was added or changed?
122-
if(event != null && event.getData() != null) {
123-
String pathAffected = event.getData().getPath();
124-
125-
switch(event.getType()) {
126-
case NODE_ADDED:
127-
case NODE_UPDATED:
128-
paths.stream()
129-
.filter(path -> path.equals(pathAffected))
130-
.forEach(path -> values.put(path, event.getData().getData()));
131-
break;
132-
133-
case NODE_REMOVED:
134-
paths.stream()
135-
.filter(path -> path.equals(pathAffected))
136-
.forEach(path -> values.remove(path));
137-
break;
138-
}
139-
}
140-
});
141-
142-
// initialize the values
143-
for (String path : paths) {
144-
fetch(path).ifPresent(val -> values.put(path, val));
89+
for (NodeCache cache : valuesCache.values()) {
90+
cache.start(true);
14591
}
146-
147-
// start the cache
148-
zookeeperCache.start();
14992
}
15093

15194
/**
15295
* Retrieve the configuration object.
15396
*/
15497
@Override
155-
public <T> Optional<T> get(String key, Class<T> clazz) throws IOException {
98+
public synchronized <T> Optional<T> get(String key, Class<T> clazz) throws IOException {
15699
T result = null;
157100

158-
byte[] val = values.get(key);
159-
if(isNotEmpty(val)) {
160-
result = deserialize(val, clazz);
101+
NodeCache cache = valuesCache.get(key);
102+
if(cache != null && cache.getCurrentData() != null && isNotEmpty(cache.getCurrentData().getData())) {
103+
result = deserialize(cache.getCurrentData().getData(), clazz);
161104
}
162105

163106
return Optional.ofNullable(result);
@@ -169,22 +112,10 @@ public <T> Optional<T> get(String key, Class<T> clazz) throws IOException {
169112
* Does not close the zookeeperClient that was passed in to the constructor.
170113
*/
171114
@Override
172-
public void close() {
173-
CloseableUtils.closeQuietly(zookeeperCache);
174-
}
175-
176-
/**
177-
* Retrieves the initial configuration value from Zookeeper
178-
* @param zookeeperPath The path in Zookeeper where the value is stored.
179-
*/
180-
private Optional<byte[]> fetch(String zookeeperPath) throws Exception {
181-
byte[] result = null;
182-
183-
if(zookeeperClient.checkExists().forPath(zookeeperPath) != null) {
184-
result = zookeeperClient.getData().forPath(zookeeperPath);
115+
public synchronized void close() {
116+
for (NodeCache cache : valuesCache.values()) {
117+
CloseableUtils.closeQuietly(cache);
185118
}
186-
187-
return Optional.ofNullable(result);
188119
}
189120

190121
/**

metron-platform/metron-common/src/test/java/org/apache/metron/common/configuration/ZkConfigurationManagerTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ public void testUpdate() throws Exception {
168168
}
169169
}
170170

171-
172171
/**
173172
* If the path is deleted from Zookeeper, the configuration value should be removed.
174173
*/
@@ -196,11 +195,12 @@ public void testDelete() throws Exception {
196195

197196
// wait until the 'delete' takes
198197
waitOrTimeout(() -> {
199-
boolean result = false;
198+
boolean result;
200199
try {
201200
result = !manager.get(GLOBAL.getZookeeperRoot(), Map.class).isPresent();
202201
} catch(Exception e) {
203-
throw new RuntimeException(e);
202+
System.out.println("unexpected exception: " + e);
203+
result = false;
204204
}
205205
return result;
206206
}, timeout(seconds(90)));

metron-platform/metron-common/src/test/java/org/apache/metron/common/utils/StellarProcessorUtils.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818

1919
package org.apache.metron.common.utils;
2020

21-
import org.apache.metron.common.dsl.*;
21+
import org.apache.metron.common.dsl.Context;
22+
import org.apache.metron.common.dsl.MapVariableResolver;
23+
import org.apache.metron.common.dsl.StellarFunctions;
24+
import org.apache.metron.common.dsl.VariableResolver;
2225
import org.apache.metron.common.stellar.StellarPredicateProcessor;
23-
import org.apache.metron.common.stellar.StellarProcessor;
2426
import org.junit.Assert;
25-
import org.junit.Test;
2627

2728
import java.util.Map;
2829

0 commit comments

Comments
 (0)