New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CentralDogma backed EndpointGroup #105
Conversation
there's no unit test yet, or you will add it later? |
/** | ||
* A CentralDogma based {@link EndpointGroup} implementation. This {@link EndpointGroup} retrieves the list of | ||
* {@link Endpoint}s from a route file served by CentralDogma, and update the list when upstream data changes. | ||
* Route file could be json file or normal text file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/json/JSON/g
* {@link Endpoint}s from a route file served by CentralDogma, and update the list when upstream data changes. | ||
* Route file could be json file or normal text file. | ||
* <p> | ||
* <p>In below example, json file with below content will be served as route file: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, the following JSON file will be served as a route file:
* "host3:port3" | ||
* ] | ||
* } | ||
* </pre> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
}</pre>
(no newline between }
and </pre>
)
* A CentralDogma based {@link EndpointGroup} implementation. This {@link EndpointGroup} retrieves the list of | ||
* {@link Endpoint}s from a route file served by CentralDogma, and update the list when upstream data changes. | ||
* Route file could be json file or normal text file. | ||
* <p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An empty <p>
is redundant. Please just use an empty line.
* } | ||
* </pre> | ||
* <p> | ||
* <p>The route file could be retrieve as {@link EndpointGroup} using below code: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- retrieve -> retrieved
- as -> as an
- below code -> the following code
|
||
import com.linecorp.armeria.client.Endpoint; | ||
|
||
public final class DefaultCentralDogmaJsonCodec implements EndpointListCodec<JsonNode> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- How about making it package-local?
JsonEndpointListDecoder
?
|
||
import com.linecorp.armeria.client.Endpoint; | ||
|
||
public final class DefaultCentralDogmaTextCodec implements EndpointListCodec<String> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- How about making it package-local?
TextEndpointListDecoder
?
* | ||
* @param <T> Type of CentralDomgma file (could be JsonNode or String) | ||
*/ | ||
public interface EndpointListCodec<T> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EndpointListDecoder
?
public interface EndpointListCodec<T> { | ||
|
||
/** | ||
* Default {@link EndpointListCodec} implementation for JsonNode object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{@link JsonNode}
public List<Endpoint> decode(String object) { | ||
final List<String> endpoints; | ||
try { | ||
endpoints = OBJECT_MAPPER.readValue(object, new TypeReference<List<String>>() {}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If an entry being watched is a JSON, decoding would be done by DefaultCentralDogmaJsonCodec
. How about making this class decode a text file? e.g. a text file each line contains an endpoint:
foo.com:8080
bar.com:8443
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
* </ul> | ||
* Note that the port number must be specified when you want to specify the weight. | ||
*/ | ||
EndpointListCodec<JsonNode> DEFAULT_JSON_CODEC = new DefaultCentralDogmaJsonCodec(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JSON
?
* </ul> | ||
* Note that the port number must be specified when you want to specify the weight. | ||
*/ | ||
EndpointListCodec<String> DEFAULT_STRING_CODEC = new DefaultCentralDogmaTextCodec(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TEXT
?
import com.linecorp.armeria.client.Endpoint; | ||
|
||
final class EndpointListCodecUtils { | ||
static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().disable(FAIL_ON_UNKNOWN_PROPERTIES); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
objectMapper
, because it's not really a constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see a checkstyle failure:
[ERROR] C:\projects\centraldogma\client\java\src\main\java\com\linecorp\centraldogma\client\armeria\JsonEndpointListDecoder.java:19: Wrong order for 'com.linecorp.centraldogma.client.armeria.EndpointListCodecUtils.convertToEndpointList' import. [ImportOrder]
import com.linecorp.armeria.client.Endpoint; | ||
|
||
final class TextEndpointListDecoder implements EndpointListDecoder<String> { | ||
private static final Splitter NEWLINE_SPLITTER = Splitter.on(System.getProperty("line.separator", "\n")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we make the splitter split on both \r\n
and \n
rather than only on one?
* <pre>{@code | ||
* CentralDogmaEndpointGroup<JsonNode> endpointGroup = CentralDogmaEndpointGroup.ofJsonFile( | ||
* centralDogma, "myProject", "myRepo", | ||
* CentralDogmaCodec.DEFAULT_JSON_CODEC, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example needs update.
@imasahiro Thanks for an update! Shall I review now or wait for another update? |
Maybe not ready yet. Let me update my internal usage to confirm the changes at first. |
Note: Special thanks to @huydx who is the initial author of CentralDogmaEndpointGroup(line/armeria#828)
Codecov Report
@@ Coverage Diff @@
## master #105 +/- ##
=========================================
+ Coverage 64.47% 64.58% +0.1%
=========================================
Files 271 276 +5
Lines 9695 9741 +46
Branches 1098 1099 +1
=========================================
+ Hits 6251 6291 +40
- Misses 2812 2818 +6
Partials 632 632
Continue to review full report at Codecov.
|
@trustin Now ready for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly nits. Great job!
import com.linecorp.armeria.client.Endpoint; | ||
|
||
/** | ||
* Decode and encode between CentralDogma upstream file content and list of {@link Endpoint}s. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Decodes the content of a file in Central Dogma into a list of {@link Endpoint}s.
?
/** | ||
* Decode and encode between CentralDogma upstream file content and list of {@link Endpoint}s. | ||
* | ||
* @param <T> Type of CentralDogma file (could be {@link JsonNode} or {@link String}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the type of the file in Central Dogma?
public interface EndpointListDecoder<T> { | ||
|
||
/** | ||
* Default {@link EndpointListDecoder} implementation for JsonNode object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{@link JsonNode}
- OK to remove 'object'?
|
||
/** | ||
* Default {@link EndpointListDecoder} implementation for JsonNode object. | ||
* Retrive object must be a json array (which has format as "[ \"segment1\", \"segment2\" ]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Retrieve -> Retrieved
- json -> JSON
(
has no matching)
.
EndpointListDecoder<JsonNode> JSON = new JsonEndpointListDecoder(); | ||
|
||
/** | ||
* Default {@link EndpointListDecoder} implementation for String object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String object -> {@link String}
?
* ] | ||
* }</pre> | ||
* | ||
* <p>The route file could be retrieved as an {@link EndpointGroup} using the following code: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The JSON array file could be..
* | ||
* <p>The route file could be retrieved as an {@link EndpointGroup} using the following code: | ||
* <pre>{@code | ||
* CentralDogmaEndpointGroup<JsonNode> endpointGroup = CentralDogmaEndpointGroup.of( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be indented one less column?
* endpointGroup.endpoints(); | ||
* }</pre> | ||
* | ||
* @param <T> Type of CentralDomgma file (could be {@link JsonNode} or {@link String}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the type of the file in Central Dogma?
@Test(timeout = 10000) | ||
public void text() throws Exception { | ||
Watcher<String> watcher = dogma.client().fileWatcher("directory", "my-service", | ||
Query.ofText("/endpoint.txt")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
endpoints.txt
?
@Test | ||
public void json() { | ||
Watcher<JsonNode> watcher = dogma.client().fileWatcher("directory", "my-service", | ||
Query.ofJson("/endpoint.json")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/endpoints.json
?
@@ -0,0 +1,69 @@ | |||
/* | |||
* Copyright 2017 LINE Corporation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2018?
|
||
/** | ||
* Default {@link EndpointListDecoder} implementation for {@link String}. | ||
* Retrieved object must be a string which is a list of segments separated by by a newline character. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by by?
/** | ||
* Decodes an object into a set of {@link Endpoint}s. | ||
* | ||
* @param object an object retrieve from Central Dogma. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
retrieved?
* centralDogma, "myProject", "myRepo", | ||
* Query.ofJson("/endpoints.json"), | ||
* EndpointListDecoder.JSON | ||
* ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
)
-> );
You can append it after EndpointListDecoder.JSON
without the newline. :)
private static final long WATCH_INITIALIZATION_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(10); | ||
|
||
private final Watcher<T> instanceListWatcher; | ||
private final EndpointListDecoder<T> endpointCodec; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if we need a different name for this. Codec means encoder and decoder, but this seems like only decoding now.
Is there any chance to use this as encoder later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some nits. Great job!
.join(); | ||
|
||
await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> assertThat(latch.getCount()).isZero()); | ||
assertThat(endpointGroup.endpoints()).isEqualTo(ImmutableList.of(Endpoint.of("foo.bar", 1234))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Could use containsExactly()
?
dogma.client().push("directory", "my-service", | ||
Revision.HEAD, "commit", | ||
Change.ofTextUpsert("/endpoints.txt", | ||
"foo.bar:1234")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Could be merged into a single line
|
||
@Test(timeout = 10000) | ||
public void text() throws Exception { | ||
Watcher<String> watcher = dogma.client().fileWatcher("directory", "my-service", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use try-resources
?
|
||
@Test | ||
public void json() throws Exception { | ||
Watcher<JsonNode> watcher = dogma.client().fileWatcher("directory", "my-service", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use try-resources
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @imasahiro and @huydx!
@hyangtack Comments? |
Thanks, @imasahiro, @huydx and reviewers :-) |
Note: Special thanks to @huydx who is the initial author of
CentralDogmaEndpointGroup(line/armeria#828)