Skip to content

Commit 91c3bc1

Browse files
authored
Change node naming (#4)
* Fix node descriptor class * Remove unused config options * Add more clear node names behaviour * Fix tick-tock handler * Fix config bug * Expand docs
1 parent e69fa02 commit 91c3bc1

File tree

33 files changed

+672
-263
lines changed

33 files changed

+672
-263
lines changed

.codestyle/pmd.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ limitations under the License.
3838
<exclude name="LongVariable" />
3939
<exclude name="MethodArgumentCouldBeFinal" />
4040
<exclude name="OnlyOneReturn" />
41+
<exclude name="PrematureDeclaration" />
4142
<exclude name="ShortClassName" />
4243
<exclude name="ShortMethodName" />
4344
<exclude name="ShortVariable" />

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1717
- Rething caches in terms and modules.
1818
- Add lazy deserialization for terms.
1919

20+
## [1.3.0](https://github.com/appulse-projects/encon-java/releases/tag/1.3.0) - 2018-06-28
21+
22+
Add correct node naming.
23+
24+
### Changed
25+
26+
- Configs from `encon-config` are now cloneable via constructor.
27+
- `NodeDescriptor` works as in Erlang's docs said.
28+
- Several minor fixes.
29+
2030
## [1.2.0](https://github.com/appulse-projects/encon-java/releases/tag/1.2.0) - 2018-06-25
2131

2232
Refactoring and cleaning.

encon-common/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ limitations under the License.
2525
<parent>
2626
<groupId>io.appulse.encon</groupId>
2727
<artifactId>encon-parent</artifactId>
28-
<version>1.2.0</version>
28+
<version>1.3.0</version>
2929
</parent>
3030

3131
<artifactId>encon-common</artifactId>

encon-common/src/main/java/io/appulse/encon/common/NodeDescriptor.java

Lines changed: 173 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
import java.net.UnknownHostException;
2525
import java.util.Map;
2626
import java.util.concurrent.ConcurrentHashMap;
27-
import java.util.function.Function;
2827

28+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
2929
import lombok.AllArgsConstructor;
3030
import lombok.EqualsAndHashCode;
3131
import lombok.NonNull;
@@ -50,72 +50,214 @@
5050
@Value
5151
@EqualsAndHashCode(of = "fullName")
5252
@AllArgsConstructor(access = PRIVATE)
53+
@SuppressWarnings({
54+
"PMD.AvoidThrowingRawExceptionTypes",
55+
"PMD.AvoidLiteralsInIfCondition"
56+
})
57+
@SuppressFBWarnings("RV_RETURN_VALUE_OF_PUTIFABSENT_IGNORED")
5358
public class NodeDescriptor implements Serializable {
5459

5560
private static final long serialVersionUID = 7324588959922091097L;
5661

5762
private static final Map<String, NodeDescriptor> NODE_DESCRIPTOR_CACHE;
5863

59-
private static final Function<String, NodeDescriptor> COMPUTE_NODE_DESCRIPTOR;
64+
private static final InetAddress LOCALHOST;
65+
66+
private static final InetAddress LOOPBACK;
67+
68+
private static final String HOST_NAME;
6069

6170
static {
62-
val loopback = InetAddress.getLoopbackAddress();
71+
try {
72+
LOCALHOST = InetAddress.getLocalHost();
73+
} catch (UnknownHostException ex) {
74+
throw new RuntimeException(ex);
75+
}
76+
LOOPBACK = InetAddress.getLoopbackAddress();
77+
HOST_NAME = LOCALHOST.getHostName();
6378
NODE_DESCRIPTOR_CACHE = new ConcurrentHashMap<>();
64-
COMPUTE_NODE_DESCRIPTOR = str -> {
65-
val tokens = str.split("@", 2);
66-
val shortName = tokens[0];
67-
val fullName = tokens.length == 2
68-
? str
69-
: shortName + '@' + loopback.getHostName();
70-
71-
val address = tokens.length == 2
72-
? getByName(tokens[1])
73-
: loopback;
74-
75-
return new NodeDescriptor(shortName, fullName, address);
76-
};
7779
}
7880

7981
/**
8082
* Parses node descriptor from string.
8183
* <p>
82-
* A string could be short like <b>popa_node</b> and full, like <b>[email protected]</b>.
84+
* A string could be short like <b>popa_node</b> and long, like <b>[email protected]</b>.
8385
* <p>
8486
* Node descriptors are caching.
8587
*
8688
* @param node node name
8789
*
8890
* @return parsed {@link NodeDescriptor} instance
8991
*/
90-
@SneakyThrows
9192
public static NodeDescriptor from (@NonNull String node) {
9293
val cached = NODE_DESCRIPTOR_CACHE.get(node);
9394
if (cached != null) {
9495
return cached;
9596
}
96-
return of(node)
97+
val descriptor = getFromCacheOrCreateNew(node);
98+
NODE_DESCRIPTOR_CACHE.putIfAbsent(node, descriptor);
99+
NODE_DESCRIPTOR_CACHE.putIfAbsent(descriptor.getFullName(), descriptor);
100+
NODE_DESCRIPTOR_CACHE.putIfAbsent(descriptor.getNodeName(), descriptor);
101+
return descriptor;
102+
}
103+
104+
/**
105+
* Parses node descriptor from string.
106+
* <p>
107+
* A string could be short like <b>popa_node</b> and long, like <b>[email protected]</b>.
108+
* <p>
109+
* Node descriptors are caching.
110+
*
111+
* @param node node name
112+
*
113+
* @param isShortName indicates is this node name short or long
114+
*
115+
* @return parsed {@link NodeDescriptor} instance
116+
*/
117+
118+
public static NodeDescriptor from (@NonNull String node, boolean isShortName) {
119+
val cached = NODE_DESCRIPTOR_CACHE.get(node);
120+
if (cached != null) {
121+
return cached;
122+
}
123+
val descriptor = getFromCacheOrCreateNew(node, isShortName);
124+
NODE_DESCRIPTOR_CACHE.putIfAbsent(node, descriptor);
125+
NODE_DESCRIPTOR_CACHE.putIfAbsent(descriptor.getFullName(), descriptor);
126+
NODE_DESCRIPTOR_CACHE.putIfAbsent(descriptor.getNodeName(), descriptor);
127+
return descriptor;
128+
}
129+
130+
/**
131+
* Checks, if this node cached or not.
132+
*
133+
* @param node node name
134+
*
135+
* @return {@code true}, if node descriptor was cached, or
136+
* {@code false} if there was no such node
137+
*/
138+
public static boolean wasCached (@NonNull String node) {
139+
val descriptor = getFromCacheOrCreateNew(node);
140+
return wasCached(descriptor);
141+
}
142+
143+
/**
144+
* Checks, if this node cached or not.
145+
*
146+
* @param descriptor node descriptor
147+
*
148+
* @return {@code true}, if node descriptor was cached, or
149+
* {@code false} if there was no such node
150+
*/
151+
public static boolean wasCached (@NonNull NodeDescriptor descriptor) {
152+
return NODE_DESCRIPTOR_CACHE.containsKey(descriptor.getNodeName()) ||
153+
NODE_DESCRIPTOR_CACHE.containsKey(descriptor.getFullName());
154+
}
155+
156+
/**
157+
* Removes a node from cached values.
158+
*
159+
* @param node node name
160+
*
161+
* @return {@code true}, if node descriptor was removed, or
162+
* {@code false} if there was no such node
163+
*/
164+
public static boolean removeFromCache (@NonNull String node) {
165+
val descriptor = getFromCacheOrCreateNew(node);
166+
return removeFromCache(descriptor);
167+
}
168+
169+
/**
170+
* Removes a node from cached values.
171+
*
172+
* @param descriptor node descriptor
173+
*
174+
* @return {@code true}, if node descriptor was removed, or
175+
* {@code false} if there was no such node
176+
*/
177+
public static boolean removeFromCache (@NonNull NodeDescriptor descriptor) {
178+
val wasRemoved = NODE_DESCRIPTOR_CACHE.remove(descriptor.getNodeName()) != null;
179+
return NODE_DESCRIPTOR_CACHE.remove(descriptor.getFullName()) != null || wasRemoved;
180+
}
181+
182+
private static NodeDescriptor getFromCacheOrCreateNew (@NonNull String node) {
183+
val atIndex = node.indexOf('@');
184+
val isShortName = atIndex < 0 || node.indexOf('.', atIndex) < 0;
185+
return getFromCacheOrCreateNew(node, isShortName);
186+
}
187+
188+
private static NodeDescriptor getFromCacheOrCreateNew (@NonNull String node, boolean isShortName) {
189+
String trimmedNode = of(node)
97190
.map(String::trim)
98191
.filter(it -> !it.isEmpty())
99-
.map(it -> NODE_DESCRIPTOR_CACHE.computeIfAbsent(it, COMPUTE_NODE_DESCRIPTOR))
100-
.orElseThrow(() -> new IllegalArgumentException("Invalid node descriptor string"));
192+
.orElseThrow(() -> new IllegalArgumentException("Invalid node descriptor string '" + node + "'"));
193+
194+
val cached = NODE_DESCRIPTOR_CACHE.get(trimmedNode);
195+
return cached == null
196+
? parse(trimmedNode, isShortName)
197+
: cached;
101198
}
102199

103-
@SuppressWarnings("PMD.PreserveStackTrace")
104-
private static InetAddress getByName (@NonNull String hostname) {
105-
try {
106-
return InetAddress.getByName(hostname);
107-
} catch (UnknownHostException ex) {
108-
try {
109-
return InetAddress.getByName(hostname + ".local");
110-
} catch (UnknownHostException ex1) {
111-
throw new IllegalArgumentException("Wrapped", ex);
200+
@SneakyThrows
201+
private static NodeDescriptor parse (@NonNull String node, boolean isShortName) {
202+
val tokens = node.split("@", 2);
203+
204+
val nodeName = tokens[0];
205+
if (nodeName.isEmpty()) {
206+
throw new IllegalArgumentException();
207+
}
208+
209+
String hostName;
210+
InetAddress address;
211+
if (tokens.length == 2) {
212+
hostName = tokens[1];
213+
if (isShortName && hostName.contains(".")) {
214+
val message = String.format("Using host name '%s' in short node name is illegal, " +
215+
"because it contains dots ('.') and suits only for long name nodes",
216+
hostName);
217+
throw new IllegalArgumentException(message);
112218
}
219+
address = InetAddress.getByName(hostName);
220+
} else if (isShortName) {
221+
val dotIndex = HOST_NAME.indexOf('.');
222+
hostName = dotIndex > 0
223+
? HOST_NAME.substring(dotIndex)
224+
: HOST_NAME;
225+
226+
address = LOOPBACK;
227+
} else {
228+
hostName = HOST_NAME;
229+
address = LOCALHOST;
113230
}
231+
232+
val fullName = nodeName + '@' + hostName;
233+
return new NodeDescriptor(nodeName, hostName, fullName, address, isShortName);
114234
}
115235

116-
String shortName;
236+
String nodeName;
237+
238+
String hostName;
117239

118240
String fullName;
119241

120242
InetAddress address;
243+
244+
boolean shortName;
245+
246+
/**
247+
* Tells is this {@link NodeDescriptor} instance for short-named node or not.
248+
*
249+
* @return {@code true} if node name is short, {@code false} otherwise
250+
*/
251+
public boolean isShortName () {
252+
return shortName;
253+
}
254+
255+
/**
256+
* Tells is this {@link NodeDescriptor} instance for long-named node or not.
257+
*
258+
* @return {@code true} if node name is long, {@code false} otherwise
259+
*/
260+
public boolean isLongName () {
261+
return !shortName;
262+
}
121263
}

0 commit comments

Comments
 (0)