Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
5e792b1
Generate updated javadocs for 1.3.1 (#643)
artursouza Oct 18, 2021
09d2bc5
Migrated out of JCenter as a Maven repository manager (#648)
mthmulders Oct 29, 2021
0171346
initial commit: modified ./dapr/client/DaprClientHttpTest.java unit test
willtsai Nov 1, 2021
d6c18c0
refactored hardcoded 127.0.0.1 localhost IP to use Dapr sidecar IP
willtsai Nov 3, 2021
4aa8aba
refactored hardcoded 127.0.0.1 localhost IP to use Dapr sidecar IP
willtsai Nov 4, 2021
95f3728
cleaned up unused imports
willtsai Nov 4, 2021
cdb5ba8
fixed tabbing and imports
willtsai Nov 4, 2021
943596e
added utils for getting local host and test utils for ipv6 addresses
willtsai Dec 6, 2021
b4874d4
Add auto-assign dapr_bot workflow (#654)
Nov 12, 2021
d23894d
Bump actions/setup-java from 2.3.1 to 2.4.0 (#663)
dependabot[bot] Dec 7, 2021
be5b2a9
added HTTP client tests for IPv6 addresses
willtsai Dec 8, 2021
f4363d6
fixed tests by returning SIDECAR_IP to IPv4 address
willtsai Dec 8, 2021
ff7c074
changes to address PMD code validation violations
willtsai Dec 8, 2021
aed37ac
changing back to loopback address for DEFAULT_SIDECAR_IP fallback
willtsai Jan 26, 2022
3ffc34d
Fix vault example + Upgrade Dapr CLI and runtime. (#666)
artursouza Dec 9, 2021
5ff9e1d
Update LICENSE to Apache 2.0 (#657)
greenie-msft Dec 9, 2021
d2ba277
Bump actions/github-script from 1 to 5 (#655)
dependabot[bot] Dec 17, 2021
0504596
Add DCO requirements and updated code of conduct (#669)
willtsai Dec 30, 2021
5990bb8
Bump actions/setup-java from 2.4.0 to 2.5.0 (#668)
dependabot[bot] Jan 10, 2022
6c09c69
Config api support (#670)
pravinpushkar Jan 13, 2022
fea50e6
Update for next release: 1.5.0 snapshot (#672)
artursouza Jan 18, 2022
5f75481
Update proto RC. (#674)
artursouza Jan 21, 2022
667efd3
Java SDK - Documentation for configuration API methods (#676)
pravinpushkar Jan 24, 2022
ab3f874
Generate updated javadocs for 1.4.0 (#677)
artursouza Jan 25, 2022
78da63f
Merge branch 'master' into loopback-auto-detect-218
willtsai Jan 26, 2022
ade335f
address package dependency issue on integration test
willtsai Jan 26, 2022
a0a353b
Merge branch 'loopback-auto-detect-218' of https://github.com/willtsa…
willtsai Jan 26, 2022
d10b3d0
Merge branch 'master' into loopback-auto-detect-218
Jan 27, 2022
77f56f4
added comment to include spec for ipv6 represention in url
willtsai Jan 27, 2022
a5b9e4e
Merge branch 'loopback-auto-detect-218' of https://github.com/willtsa…
willtsai Jan 27, 2022
3917e70
corrected comment in NetworkUtils.getHostLoopbackAddress()
willtsai Jan 27, 2022
08ab9dd
added comment to include spec for ipv6 represention in url
willtsai Jan 27, 2022
8fce9bd
Merge branch 'master' into loopback-auto-detect-218
willtsai Jan 27, 2022
29bf6a6
updated dependency scope to test
willtsai Jan 28, 2022
59dca39
Merge branch 'master' into loopback-auto-detect-218
willtsai Jul 12, 2022
52821d8
Merge branch 'master' into loopback-auto-detect-218
willtsai Aug 15, 2023
e391e95
Merge branch 'master' into loopback-auto-detect-218
willtsai Jan 2, 2024
424e70a
fix NetworkUtils.java
willtsai Jan 2, 2024
3797e31
checkstyle fix in NetworkUtils.java
willtsai Jan 2, 2024
e8ddb5c
fix imports
willtsai Jan 2, 2024
cbc11cb
fix ipv6 formatting issues
willtsai Jan 4, 2024
904387b
fix ipv6 formatting issues
willtsai Jan 4, 2024
3b39e86
fix code style nits
willtsai Jan 4, 2024
9c82edb
refactor formatIpAddress method in actors utls
willtsai Jan 5, 2024
447edb1
Merge branch 'master' into loopback-auto-detect-218
cicoyle Jan 5, 2024
cbf4f47
Merge branch 'master' into loopback-auto-detect-218
cicoyle Jan 5, 2024
9543fcd
Merge branch 'master' into loopback-auto-detect-218
artursouza Feb 19, 2024
d9fd2c0
Merge branch 'master' into loopback-auto-detect-218
cicoyle Feb 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
.run/
.vs/
.vscode/
.devcontainer/

# Output folders
**/target/
Expand Down
6 changes: 6 additions & 0 deletions sdk-actors/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
<version>${grpc.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
Comment thread
willtsai marked this conversation as resolved.
<artifactId>commons-validator</artifactId>
<version>1.7</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
11 changes: 10 additions & 1 deletion sdk-actors/src/test/java/io/dapr/actors/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.dapr.exceptions.DaprException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.function.Executable;
import org.apache.commons.validator.routines.InetAddressValidator;

public final class TestUtils {

Expand Down Expand Up @@ -54,4 +55,12 @@ public static <T extends Throwable> void assertThrowsDaprException(
Assertions.assertEquals(expectedErrorCode, daprException.getErrorCode());
Assertions.assertEquals(expectedErrorMessage, daprException.getMessage());
}
}

public static String formatIpAddress(final String ipAddress) {
String formattedIpAddress = ipAddress;
if(InetAddressValidator.getInstance().isValidInet6Address(ipAddress)) {
formattedIpAddress = "[" + ipAddress + "]"; // per URL spec https://url.spec.whatwg.org/#host-writing
}
return formattedIpAddress;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;

import static io.dapr.actors.TestUtils.formatIpAddress;
import static io.dapr.actors.TestUtils.assertThrowsDaprException;
import static org.junit.jupiter.api.Assertions.assertEquals;

Expand All @@ -36,21 +37,40 @@ public class DaprHttpClientTest {

private MockInterceptor mockInterceptor;

private String sidecarIp;

private final String EXPECTED_RESULT = "{\"data\":\"ewoJCSJwcm9wZXJ0eUEiOiAidmFsdWVBIiwKCQkicHJvcGVydHlCIjogInZhbHVlQiIKCX0=\"}";

@BeforeEach
public void setUp() {
sidecarIp = formatIpAddress(Properties.SIDECAR_IP.get());
mockInterceptor = new MockInterceptor(Behavior.UNORDERED);
okHttpClient = new OkHttpClient.Builder().addInterceptor(mockInterceptor).build();
}

@Test
public void invokeActorMethod() {
mockInterceptor.addRule()
.post("http://127.0.0.1:3000/v1.0/actors/DemoActor/1/method/Payment")
.post("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/method/Payment")
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<byte[]> mono =
DaprHttpClient.invoke("DemoActor", "1", "Payment", "".getBytes());
assertEquals(new String(mono.block()), EXPECTED_RESULT);
}

@Test
public void invokeActorMethodIPv6() {
String prevSidecarIp = sidecarIp;
System.setProperty(Properties.SIDECAR_IP.getName(), "2001:db8:3333:4444:5555:6666:7777:8888");
sidecarIp = formatIpAddress(Properties.SIDECAR_IP.get());
mockInterceptor.addRule()
.post("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/method/Payment")
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
System.setProperty(Properties.SIDECAR_IP.getName(), prevSidecarIp);
Mono<byte[]> mono =
DaprHttpClient.invoke("DemoActor", "1", "Payment", "".getBytes());
assertEquals(new String(mono.block()), EXPECTED_RESULT);
Expand All @@ -59,12 +79,12 @@ public void invokeActorMethod() {
@Test
public void invokeActorMethodError() {
mockInterceptor.addRule()
.post("http://127.0.0.1:3000/v1.0/actors/DemoActor/1/method/Payment")
.post("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/method/Payment")
.respond(404,
ResponseBody.create("" +
"{\"errorCode\":\"ERR_SOMETHING\"," +
"\"message\":\"error message\"}", MediaTypes.MEDIATYPE_JSON));
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<byte[]> mono =
DaprHttpClient.invoke("DemoActor", "1", "Payment", "".getBytes());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.fail;
import static io.dapr.actors.TestUtils.formatIpAddress;

public class DaprHttpClientTest {

Expand All @@ -46,33 +47,50 @@ public class DaprHttpClientTest {
private OkHttpClient okHttpClient;

private MockInterceptor mockInterceptor;

private String sidecarIp;

private final String EXPECTED_RESULT = "{\"data\":\"ewoJCSJwcm9wZXJ0eUEiOiAidmFsdWVBIiwKCQkicHJvcGVydHlCIjogInZhbHVlQiIKCX0=\"}";

@BeforeEach
public void setUp() throws Exception {
sidecarIp = formatIpAddress(Properties.SIDECAR_IP.get());
mockInterceptor = new MockInterceptor(Behavior.UNORDERED);
okHttpClient = new OkHttpClient.Builder().addInterceptor(mockInterceptor).build();
}

@Test
public void getActorState() {
mockInterceptor.addRule()
.get("http://127.0.0.1:3000/v1.0/actors/DemoActor/1/state/order")
.get("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/state/order")
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<byte[]> mono = DaprHttpClient.getState("DemoActor", "1", "order");
assertEquals(new String(mono.block()), EXPECTED_RESULT);
}

@Test
public void getActorStateIPv6() {
String prevSidecarIp = sidecarIp;
System.setProperty(Properties.SIDECAR_IP.getName(), "2001:db8:3333:4444:5555:6666:7777:8888");
sidecarIp = formatIpAddress(Properties.SIDECAR_IP.get());
mockInterceptor.addRule()
.get("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/state/order")
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
System.setProperty(Properties.SIDECAR_IP.getName(), prevSidecarIp);
Mono<byte[]> mono = DaprHttpClient.getState("DemoActor", "1", "order");
assertEquals(new String(mono.block()), EXPECTED_RESULT);
}

@Test
public void saveActorStateTransactionally() {
mockInterceptor.addRule()
.put("http://127.0.0.1:3000/v1.0/actors/DemoActor/1/state")
.put("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/state")
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
List<ActorStateOperation> ops = Collections.singletonList(new ActorStateOperation("UPSERT", "key", "value"));
Mono<Void> mono = DaprHttpClient.saveStateTransactionally("DemoActor", "1", ops);
Expand All @@ -82,9 +100,9 @@ public void saveActorStateTransactionally() {
@Test
public void registerActorReminder() {
mockInterceptor.addRule()
.put("http://127.0.0.1:3000/v1.0/actors/DemoActor/1/reminders/reminder")
.put("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/reminders/reminder")
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<Void> mono =
DaprHttpClient.registerReminder(
Expand All @@ -98,9 +116,9 @@ public void registerActorReminder() {
@Test
public void unregisterActorReminder() {
mockInterceptor.addRule()
.delete("http://127.0.0.1:3000/v1.0/actors/DemoActor/1/reminders/reminder")
.delete("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/reminders/reminder")
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<Void> mono = DaprHttpClient.unregisterReminder("DemoActor", "1", "reminder");
assertNull(mono.block());
Expand All @@ -110,7 +128,7 @@ public void unregisterActorReminder() {
public void registerActorTimer() {
String data = "hello world";
mockInterceptor.addRule()
.put("http://127.0.0.1:3000/v1.0/actors/DemoActor/1/timers/timer")
.put("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/timers/timer")
.answer(new RuleAnswer() {
@Override
public Response.Builder respond(Request request) {
Expand All @@ -132,7 +150,7 @@ public Response.Builder respond(Request request) {
.body(ResponseBody.create("{}", MediaType.get("application/json")));
}
});
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<Void> mono =
DaprHttpClient.registerTimer(
Expand All @@ -150,9 +168,9 @@ public Response.Builder respond(Request request) {
@Test
public void unregisterActorTimer() {
mockInterceptor.addRule()
.delete("http://127.0.0.1:3000/v1.0/actors/DemoActor/1/timers/timer")
.delete("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/timers/timer")
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<Void> mono = DaprHttpClient.unregisterTimer("DemoActor", "1", "timer");
assertNull(mono.block());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import io.dapr.it.BaseIT;
import io.dapr.it.DaprRun;
import io.dapr.config.Properties;
import io.dapr.v1.DaprGrpc;
import io.dapr.v1.DaprProtos;
import io.grpc.ManagedChannel;
Expand All @@ -34,7 +35,7 @@ public void testHelloWorldState() throws Exception {
2000
);
ManagedChannel channel =
ManagedChannelBuilder.forAddress("127.0.0.1", daprRun.getGrpcPort()).usePlaintext().build();
ManagedChannelBuilder.forAddress(Properties.SIDECAR_IP.get(), daprRun.getGrpcPort()).usePlaintext().build();
DaprGrpc.DaprBlockingStub client = DaprGrpc.newBlockingStub(channel);

String key = "mykey";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package io.dapr.it.state;

import com.google.protobuf.ByteString;
import io.dapr.config.Properties;
import io.dapr.v1.CommonProtos.StateItem;
import io.dapr.v1.DaprGrpc;
import io.dapr.v1.DaprGrpc.DaprBlockingStub;
Expand All @@ -37,7 +38,7 @@ public static void main(String[] args) {

// If port string is not valid, it will throw an exception.
int grpcPortInt = Integer.parseInt(grpcPort);
ManagedChannel channel = ManagedChannelBuilder.forAddress("127.0.0.1", grpcPortInt).usePlaintext().build();
ManagedChannel channel = ManagedChannelBuilder.forAddress(Properties.SIDECAR_IP.get(), grpcPortInt).usePlaintext().build();
DaprBlockingStub client = DaprGrpc.newBlockingStub(channel);

String key = "mykey";
Expand Down
6 changes: 6 additions & 0 deletions sdk/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@
<artifactId>junit-jupiter-migrationsupport</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
Comment thread
willtsai marked this conversation as resolved.
<version>1.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
Expand Down
3 changes: 2 additions & 1 deletion sdk/src/main/java/io/dapr/config/Properties.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package io.dapr.config;

import io.dapr.client.DaprApiProtocol;
import io.dapr.utils.NetworkUtils;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
Expand All @@ -27,7 +28,7 @@ public class Properties {
/**
* Dapr's default IP for HTTP and gRPC communication.
*/
private static final String DEFAULT_SIDECAR_IP = "127.0.0.1";
private static final String DEFAULT_SIDECAR_IP = NetworkUtils.getHostLoopbackAddress();

/**
* Dapr's default HTTP port.
Expand Down
12 changes: 11 additions & 1 deletion sdk/src/main/java/io/dapr/utils/NetworkUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
import io.grpc.ManagedChannelBuilder;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URI;
import java.net.UnknownHostException;

/**
* Utility methods for network, internal to Dapr SDK.
Expand Down Expand Up @@ -112,4 +114,12 @@ private static void callWithRetry(Runnable function, long retryTimeoutMillisecon
Thread.sleep(Math.min(remaining, RETRY_WAIT_MILLISECONDS));
}
}
}

/**
* Retrieve loopback address for the host.
* @return The loopback address String
*/
public static String getHostLoopbackAddress() {
return InetAddress.getLoopbackAddress().getHostAddress();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this method automatically return the Ipv6 between "[]"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@artursouza Sorry for the delay, finally had some time to look into this. I changed some unit tests locally to validate IPv6 sidecar IP constants contained within "[]" and it seems like your suggestion is viable - for both URL endpoint invocation formats and Dapr client instantiation. Great recommendation!

However, before I proceed, I need to validate an implementation detail with you. To test for whether an address is IPv6, it would be convenient to leverage the Apache Commons Validator, though you have recommended against bringing in 3P libraries beyond the test scope. Is it possible to get an exception for this case, or do I have to write a custom IPv6 validator within NetworkUtils?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@willtsai Is it complex to write a validator for IPv6 ? both standard pattern and hex compressed pattern along with IPv4 validation?
I am wary of adding a new dependency specifically for one validation ....

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood - should not be too complex but I wanted to see if the work (and subsequent unit tests) could be avoided. Seems like adding a new dependency is not worth it here, so I'll work on the custom validator.

@willtsai willtsai Jul 12, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started the implementation for this and have a working validator, but then realized that this would introduce inconsistencies into the Property<String> SIDECAR_IP config object since the result would be that the special IPv6 formatting would only get applied when DEFAULT_SIDECAR_IP is used in fallback scenarios, so the IPv6 address would not get "[]" applied to them when they are sourced from the system property name or env variable.

Thus, I think there are two options:

  1. Leave the implementation of adding "[]" to the http address to the client and thus just modifying our test clients accordingly, i.e. code in this PR remain as is.
  2. Make modifications to the Property and/or Properties objects to introduce a new object class IpProperty.java or equivalent that would apply the required IPv6 formatting to the IP address it returns.

@artursouza @mukundansundar - what are your thoughts here? which option would you prefer? (I personally think option 1 introduces less surprises to the client who may not be expecting IPv6 address to be pre-formatted for http URLs)

}
}
Loading