diff --git a/.gitignore b/.gitignore
index 323dad2409..474c650f34 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,3 +41,5 @@ hs_err_pid*
# Some other generated folders/files
**/components/redis.yaml
**/components/redis_messagebus.yaml
+/proto/dapr
+/proto/daprclient
diff --git a/pom.xml b/pom.xml
index fba7e3506b..eeae23bf6b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,6 +17,8 @@
1.25.0
3.11.0
3.10.0
+ https://raw.githubusercontent.com/dapr/dapr/master/pkg/proto/dapr/dapr.proto
+ https://raw.githubusercontent.com/dapr/dapr/master/pkg/proto/daprclient/daprclient.proto
1.6.2
3.1.1
1.8
diff --git a/proto/dapr/dapr.proto b/proto/dapr/dapr.proto
deleted file mode 100644
index b87d0f4fc9..0000000000
--- a/proto/dapr/dapr.proto
+++ /dev/null
@@ -1,106 +0,0 @@
-syntax = "proto3";
-
-package dapr;
-
-import "google/protobuf/any.proto";
-import "google/protobuf/empty.proto";
-import "google/protobuf/duration.proto";
-
-option java_outer_classname = "DaprProtos";
-option java_package = "io.dapr";
-
-option csharp_namespace = "Dapr.Client.Grpc";
-
-
-// Dapr definitions
-service Dapr {
- rpc PublishEvent(PublishEventEnvelope) returns (google.protobuf.Empty) {}
- rpc InvokeService(InvokeServiceEnvelope) returns (InvokeServiceResponseEnvelope) {}
- rpc InvokeBinding(InvokeBindingEnvelope) returns (google.protobuf.Empty) {}
- rpc GetState(GetStateEnvelope) returns (GetStateResponseEnvelope) {}
- rpc SaveState(SaveStateEnvelope) returns (google.protobuf.Empty) {}
- rpc DeleteState(DeleteStateEnvelope) returns (google.protobuf.Empty) {}
-}
-
-message InvokeServiceResponseEnvelope {
- google.protobuf.Any data = 1;
- map metadata = 2;
-}
-
-message DeleteStateEnvelope {
- string key = 1;
- string etag = 2;
- StateOptions options = 3;
-}
-
-message SaveStateEnvelope {
- repeated StateRequest requests = 1;
-}
-
-message GetStateEnvelope {
- string key = 1;
- string consistency = 2;
-}
-
-message GetStateResponseEnvelope {
- google.protobuf.Any data = 1;
- string etag = 2;
-}
-
-message InvokeBindingEnvelope {
- string name = 1;
- google.protobuf.Any data = 2;
- map metadata = 3;
-}
-
-message InvokeServiceEnvelope {
- string id = 1;
- string method = 2;
- google.protobuf.Any data = 3;
- map metadata = 4;
-}
-
-message PublishEventEnvelope {
- string topic = 1;
- google.protobuf.Any data = 2;
-}
-
-message State {
- string key = 1;
- google.protobuf.Any value = 2;
- string etag = 3;
- map metadata = 4;
- StateOptions options = 5;
-}
-
-message StateOptions {
- string concurrency = 1;
- string consistency = 2;
- RetryPolicy retryPolicy = 3;
-}
-
-message RetryPolicy {
- int32 threshold = 1;
- string pattern = 2;
- google.protobuf.Duration interval = 3;
-}
-
-message StateRequest {
- string key = 1;
- google.protobuf.Any value = 2;
- string etag = 3;
- map metadata = 4;
- StateRequestOptions options = 5;
-}
-
-message StateRequestOptions {
- string concurrency = 1;
- string consistency = 2;
- StateRetryPolicy retryPolicy = 3;
-}
-
-message StateRetryPolicy {
- int32 threshold = 1;
- string pattern = 2;
- google.protobuf.Duration interval = 3;
-}
diff --git a/proto/daprclient/daprclient.proto b/proto/daprclient/daprclient.proto
deleted file mode 100644
index a383ba16c5..0000000000
--- a/proto/daprclient/daprclient.proto
+++ /dev/null
@@ -1,76 +0,0 @@
-syntax = "proto3";
-
-package daprclient;
-
-import "google/protobuf/any.proto";
-import "google/protobuf/empty.proto";
-import "google/protobuf/duration.proto";
-
-option java_outer_classname = "DaprClientProtos";
-option java_package = "io.dapr";
-
-// User Code definitions
-service DaprClient {
- rpc OnInvoke (InvokeEnvelope) returns (google.protobuf.Any) {}
- rpc GetTopicSubscriptions(google.protobuf.Empty) returns (GetTopicSubscriptionsEnvelope) {}
- rpc GetBindingsSubscriptions(google.protobuf.Empty) returns (GetBindingsSubscriptionsEnvelope) {}
- rpc OnBindingEvent(BindingEventEnvelope) returns (BindingResponseEnvelope) {}
- rpc OnTopicEvent(CloudEventEnvelope) returns (google.protobuf.Empty) {}
-}
-
-message CloudEventEnvelope {
- string id = 1;
- string source = 2;
- string type = 3;
- string specVersion = 4;
- string dataContentType = 5;
- string topic = 6;
- google.protobuf.Any data = 7;
-}
-
-message BindingEventEnvelope {
- string name = 1;
- google.protobuf.Any data = 2;
- map metadata = 3;
-}
-
-message BindingResponseEnvelope {
- google.protobuf.Any data = 1;
- repeated string to = 2;
- repeated State state = 3;
- string concurrency = 4;
-}
-
-message InvokeEnvelope {
- string method = 1;
- google.protobuf.Any data = 2;
- map metadata = 3;
-}
-
-message GetTopicSubscriptionsEnvelope {
- repeated string topics = 1;
-}
-
-message GetBindingsSubscriptionsEnvelope {
- repeated string bindings = 1;
-}
-
-message State {
- string key = 1;
- google.protobuf.Any value = 2;
- string etag = 3;
- map metadata = 4;
- StateOptions options = 5;
-}
-
-message StateOptions {
- string concurrency = 1;
- string consistency = 2;
- RetryPolicy retryPolicy = 3;
-}
-
-message RetryPolicy {
- int32 threshold = 1;
- string pattern = 2;
- google.protobuf.Duration interval = 3;
-}
diff --git a/sdk-autogen/pom.xml b/sdk-autogen/pom.xml
index 6d9bfe4355..56fbf91f2a 100644
--- a/sdk-autogen/pom.xml
+++ b/sdk-autogen/pom.xml
@@ -56,6 +56,41 @@
+
+ com.googlecode.maven-download-plugin
+ download-maven-plugin
+ 1.3.0
+
+
+ getDaprProto
+
+ initialize
+
+ wget
+
+
+ ${dapr.proto.url}
+ dapr.proto
+
+ ${protobuf.input.directory}/dapr
+
+
+
+ getDaprClientProto
+
+ initialize
+
+ wget
+
+
+ ${dapr.client.proto.url}
+ daprclient.proto
+
+ ${protobuf.input.directory}/daprclient
+
+
+
+
com.github.os72
protoc-jar-maven-plugin
diff --git a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeController.java b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeController.java
new file mode 100644
index 0000000000..8f1a676ee5
--- /dev/null
+++ b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeController.java
@@ -0,0 +1,72 @@
+package io.dapr.it.methodinvoke.http;
+
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+/**
+ * SpringBoot Controller to handle input binding.
+ */
+@RestController
+public class MethodInvokeController {
+
+ private static final Map messagesReceived = new HashMap<>();
+ private static final List persons= new ArrayList<>();
+
+ @PostMapping("/messages")
+ public void postMessages(@RequestBody String message){
+ System.out.println("Controller got message: " + message);
+ final Optional maxKey = messagesReceived.keySet().stream().max(Integer::compareTo);
+ final Integer key = maxKey.orElse(-1)+1;
+ messagesReceived.put(key,message);
+ System.out.println("Controller save the message: " + message);
+ }
+
+ @PutMapping(path = "/messages/{messageId}")
+ public void putMessages(@PathVariable Integer messageId, @RequestBody String message){
+ messagesReceived.put(messageId,message);
+ }
+
+ @DeleteMapping(path = "/messages/{messageId}")
+ public void deleteMessages(@PathVariable Integer messageId){
+ messagesReceived.remove(messageId);
+ }
+
+ @GetMapping(path = "/messages")
+ public Map getMessages() {
+ return messagesReceived;
+ }
+
+ @PostMapping("/persons")
+ public void postPerson(@RequestBody Person person){
+ System.out.println("Controller get person: " + person);
+ final Optional max = persons.stream().map(person1 -> person1.getId()).max(Integer::compareTo);
+ final Integer key = max.orElse(-1)+1;
+ person.setId(key);
+ persons.add(person);
+ System.out.println("Controller save the person: " + person);
+ }
+
+ @PutMapping(path = "/persons/{personId}")
+ public void putPerson(@PathVariable Integer personId, @RequestBody Person person){
+ final Optional auxPerson = persons.stream().filter(person1 -> person1.getId() == personId).findFirst();
+ if(auxPerson.isPresent()){
+ auxPerson.get().setName(person.getName());
+ auxPerson.get().setLastName(person.getLastName());
+ auxPerson.get().setBirthDate(person.getBirthDate());
+ }
+ }
+
+ @DeleteMapping(path = "/persons/{personId}")
+ public void deletePerson(@PathVariable Integer personId){
+ final Optional auxPerson = persons.stream().filter(person1 -> person1.getId() == personId).findFirst();
+ if(auxPerson.isPresent()) {
+ persons.remove(auxPerson.get());
+ }
+ }
+
+ @GetMapping(path = "/persons")
+ public List getPersons() {
+ return persons;
+ }
+}
diff --git a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeIT.java b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeIT.java
new file mode 100644
index 0000000000..67ab3d16ca
--- /dev/null
+++ b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeIT.java
@@ -0,0 +1,94 @@
+package io.dapr.it.methodinvoke.http;
+
+import io.dapr.client.DaprClient;
+import io.dapr.client.DaprClientBuilder;
+import io.dapr.client.domain.Verb;
+import io.dapr.it.BaseIT;
+import io.dapr.it.DaprRun;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.*;
+
+import static org.junit.Assert.assertEquals;
+
+public class MethodInvokeIT extends BaseIT {
+
+ //Number of messages to be sent: 10
+ private static final int NUM_MESSAGES = 10;
+ private static DaprRun daprRun=null;
+
+ @BeforeClass
+ public static void init() throws Exception {
+ System.out.println("Working Directory = " + System.getProperty("user.dir"));
+
+ daprRun = startDaprApp(
+ MethodInvokeIT.class.getSimpleName(),
+ MethodInvokeService.SUCCESS_MESSAGE,
+ MethodInvokeService.class,
+ true,
+ 60000);
+ }
+
+ @Test
+ public void testInvoke() {
+
+ // At this point, it is guaranteed that the service above is running and all ports being listened to.
+
+ DaprClient client = new DaprClientBuilder().build();
+ for (int i = 0; i < NUM_MESSAGES; i++) {
+ String message = String.format("This is message #%d", i);
+ //Publishing messages
+ client.invokeService(Verb.POST, daprRun.getAppName(), "messages", message).block();
+ System.out.println("Invoke method messages : " + message);
+ }
+
+ Map messages = client.invokeService(Verb.GET, daprRun.getAppName(), "messages", null, Map.class).block();
+ assertEquals(10, messages.size());
+
+ client.invokeService(Verb.DELETE,daprRun.getAppName(),"messages/1",null).block();
+
+ messages = client.invokeService(Verb.GET, daprRun.getAppName(), "messages", null, Map.class).block();
+ assertEquals(9, messages.size());
+
+ client.invokeService(Verb.PUT, daprRun.getAppName(), "messages/2", "updated message").block();
+ messages = client.invokeService(Verb.GET, daprRun.getAppName(), "messages", null, Map.class).block();
+ assertEquals("updated message", messages.get("2"));
+
+ }
+
+ @Test
+ public void testInvokeWithObjects() {
+ DaprClient client = new DaprClientBuilder().build();
+
+ for (int i = 0; i < NUM_MESSAGES; i++) {
+ Person person= new Person();
+ person.setName(String.format("Name %d", i));
+ person.setLastName(String.format("Last Name %d", i));
+ person.setBirthDate(new Date());
+ //Publishing messages
+ client.invokeService(Verb.POST, daprRun.getAppName(), "persons", person).block();
+ System.out.println("Invoke method persons with parameter : " + person);
+ }
+
+ List persons = Arrays.asList(client.invokeService(Verb.GET, daprRun.getAppName(), "persons", null, Person[].class).block());
+ assertEquals(10, persons.size());
+
+ client.invokeService(Verb.DELETE,daprRun.getAppName(),"persons/1",null).block();
+
+ persons = Arrays.asList(client.invokeService(Verb.GET, daprRun.getAppName(), "persons", null, Person[].class).block());
+ assertEquals(9, persons.size());
+
+ Person person= new Person();
+ person.setName("John");
+ person.setLastName("Smith");
+ person.setBirthDate(Calendar.getInstance().getTime());
+
+ client.invokeService(Verb.PUT, daprRun.getAppName(), "persons/2", person).block();
+
+ persons = Arrays.asList(client.invokeService(Verb.GET, daprRun.getAppName(), "persons", null, Person[].class).block());
+ Person resultPerson= persons.get(1);
+ assertEquals("John", resultPerson.getName());
+ assertEquals("Smith", resultPerson.getLastName());
+ }
+}
diff --git a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeService.java b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeService.java
new file mode 100644
index 0000000000..f2dd6f6df4
--- /dev/null
+++ b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeService.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ */
+
+package io.dapr.it.methodinvoke.http;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+
+/**
+ * Service for subscriber.
+ */
+@SpringBootApplication(scanBasePackages = {"io.dapr.it.methodinvoke.http"})
+public class MethodInvokeService {
+
+ public static final String SUCCESS_MESSAGE = "dapr initialized. Status: Running. Init Elapsed";
+
+ public static void main(String[] args) {
+ int port = Integer.parseInt(args[0]);
+
+ System.out.printf("Service starting on port %d ...\n", port);
+
+ // Start Dapr's callback endpoint.
+ start(port);
+ }
+
+ /**
+ * Starts Dapr's callback in a given port.
+ *
+ * @param port Port to listen to.
+ */
+ private static void start(int port) {
+ SpringApplication app = new SpringApplication(MethodInvokeService.class);
+ app.run(String.format("--server.port=%d", port));
+ }
+
+}
\ No newline at end of file
diff --git a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/Person.java b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/Person.java
new file mode 100644
index 0000000000..4e9eec69d7
--- /dev/null
+++ b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/Person.java
@@ -0,0 +1,53 @@
+package io.dapr.it.methodinvoke.http;
+
+import java.util.Date;
+
+public class Person {
+
+ private int id;
+ private String name;
+ private String lastName;
+ private Date birthDate;
+
+ @Override
+ public String toString() {
+ return "Person{" +
+ "id=" + id +
+ ", name='" + name + '\'' +
+ ", lastName='" + lastName + '\'' +
+ ", birthDate=" + birthDate +
+ '}';
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public Date getBirthDate() {
+ return birthDate;
+ }
+
+ public void setBirthDate(Date birthDate) {
+ this.birthDate = birthDate;
+ }
+}