Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.concurrent.CompletableFuture;

import org.springframework.util.StringUtils;

Expand Down Expand Up @@ -89,6 +90,11 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl

Response response = InvokerUtils.innerSyncInvoke(invocation);
Copy link
Member

Choose a reason for hiding this comment

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

Here is the sync invocation, I think this part change is only for supporting the return type signature.

Copy link
Author

Choose a reason for hiding this comment

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

是的,这次修改的代码重点关注在了服务端,consumer侧只是为了能够兼容服务端的接口做了下适配。
这次提交主要是用来讨论下方案,如果方案可以,我可以重新修改代码,实现完应用层服务端和客户端的异步能力。

if (response.isSuccessed()) {
if (consumerOperation.getConsumerMethod().getReturnType().equals(CompletableFuture.class)) {
CompletableFuture future = new CompletableFuture();
future.complete(consumerOperation.getResponseMapper().mapResponse(response));
return future;
}
return consumerOperation.getResponseMapper().mapResponse(response);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2017 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.servicecomb.samples.common.schema;


import java.util.concurrent.CompletableFuture;

import io.servicecomb.samples.common.schema.models.Person;

public interface HelloAsync {

CompletableFuture<Person> sayHi(String name);

CompletableFuture<String> sayHello(Person person);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.servicecomb.foundation.common.utils.Log4jUtils;
import io.servicecomb.provider.pojo.RpcReference;
import io.servicecomb.samples.common.schema.Hello;
import io.servicecomb.samples.common.schema.HelloAsync;
import io.servicecomb.samples.common.schema.models.Person;
import io.servicecomb.samples.pojo.Compute;

Expand All @@ -33,6 +34,9 @@ public class PojoConsumerMain {
@RpcReference(microserviceName = "hello", schemaId = "codeFirstCompute")
public static Compute compute;

@RpcReference(microserviceName = "hello", schemaId = "helloasync")
public static HelloAsync helloAsync;

public static void main(String[] args)
throws Exception {
init();
Expand All @@ -41,6 +45,11 @@ public static void main(String[] args)
person.setName("ServiceComb/Java Chassis");
System.out.println(hello.sayHello(person));
System.out.println("a=1, b=2, result=" + compute.add(1, 2));



System.out.println(helloAsync.sayHi("Java Chassis").get().getName());
System.out.println(helloAsync.sayHello(person).get());
}

public static void init()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
swagger: '2.0'
info:
title: hello
version: 1.0.0
x-java-interface: io.servicecomb.samples.springmvc.HelloAsync
basePath: /pojo/rest/hello
produces:
- application/json

paths:
/sayhi:
post:
operationId: sayHi
parameters:
- name: name
in: body
required: true
schema:
type: string
responses:
200:
description: 正确返回
schema:
$ref: "#/definitions/Person"
default:
description: 默认返回
schema:
type: string
/sayhello:
post:
operationId: sayHello
parameters:
- name: person
in: body
required: true
schema:
$ref: "#/definitions/Person"
responses:
200:
description: 正确返回
schema:
type: string
default:
description: 默认返回
schema:
type: string
definitions:
Person:
type: "object"
properties:
name:
type: "string"
description: "person name"
xml:
name: "Person"
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.servicecomb.samples.pojo.provider;


import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import io.servicecomb.provider.pojo.RpcSchema;
import io.servicecomb.samples.common.schema.HelloAsync;
import io.servicecomb.samples.common.schema.models.Person;

@RpcSchema(schemaId = "helloasync")
public class HelloAsyncImpl implements HelloAsync {

private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(8);

@Override
public CompletableFuture<Person> sayHi(String name) {
Person person = new Person();
CompletableFuture<Person> result = new CompletableFuture<Person>();
person.setName("Hello" + name);
executorService.schedule(() -> result.complete(person), 2000, TimeUnit.MILLISECONDS);
return result;
}

@Override
public CompletableFuture<String> sayHello(Person person) {
CompletableFuture<String> result = new CompletableFuture<String>();
executorService.schedule(() -> result.complete("Hello person " + person.getName()), 2000, TimeUnit.MILLISECONDS);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
swagger: '2.0'
info:
title: hello
version: 1.0.0
x-java-interface: io.servicecomb.samples.springmvc.HelloAsync
basePath: /pojo/rest/hello
produces:
- application/json

paths:
/sayhi:
post:
operationId: sayHi
parameters:
- name: name
in: body
required: true
schema:
type: string
responses:
200:
description: 正确返回
schema:
$ref: "#/definitions/Person"
default:
description: 默认返回
schema:
type: string
/sayhello:
post:
operationId: sayHello
parameters:
- name: person
in: body
required: true
schema:
$ref: "#/definitions/Person"
responses:
200:
description: 正确返回
schema:
type: string
default:
description: 默认返回
schema:
type: string
definitions:
Person:
type: "object"
properties:
name:
type: "string"
description: "person name"
xml:
name: "Person"
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.servicecomb.provider.pojo.RpcReference;
import io.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
import io.servicecomb.samples.common.schema.Hello;
import io.servicecomb.samples.common.schema.HelloAsync;
import io.servicecomb.samples.common.schema.models.Person;

@Component
Expand All @@ -33,6 +34,9 @@ public class SpringmvcConsumerMain {
@RpcReference(microserviceName = "springmvc", schemaId = "springmvcHello")
private static Hello hello;

@RpcReference(microserviceName = "springmvc", schemaId = "springmvcHelloAsync")
private static HelloAsync helloasync;

public static void main(String[] args) throws Exception {
init();
Person person = new Person();
Expand All @@ -50,6 +54,21 @@ public static void main(String[] args) throws Exception {
// POJO Consumer
System.out.println("POJO consumer sayhi services: " + hello.sayHi("Java Chassis"));
System.out.println("POJO consumer sayhi services: " + hello.sayHello(person));



// RestTemplate Consumer or POJO Consumer. You can choose whatever you like
// RestTemplate Consumer
Person sayHiResultAsync =
restTemplate.postForObject("cse://springmvc/springmvchelloasync/sayhi?name=Java Chassis", null, Person.class);
String sayHelloResultAsync = restTemplate.postForObject("cse://springmvc/springmvchelloasync/sayhello", person, String.class);
System.out.println("RestTemplate Consumer or POJO Consumer. You can choose whatever you like.");
System.out.println("RestTemplate consumer sayhi services: " + sayHiResultAsync.getName());
System.out.println("RestTemplate consumer sayhello services: " + sayHelloResultAsync);

// POJO Consumer
System.out.println("POJO consumer sayhi services: " + helloasync.sayHi("Java Chassis").get().getName());
System.out.println("POJO consumer sayhi services: " + helloasync.sayHello(person).get());
}

public static void init() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
swagger: '2.0'
info:
title: hello
version: 1.0.0
x-java-interface: io.servicecomb.samples.springmvc.HelloAsync
basePath: /pojo/rest/hello
produces:
- application/json

paths:
/sayhi:
post:
operationId: sayHi
parameters:
- name: name
in: body
required: true
schema:
type: string
responses:
200:
description: 正确返回
schema:
$ref: "#/definitions/Person"
default:
description: 默认返回
schema:
type: string
/sayhello:
post:
operationId: sayHello
parameters:
- name: person
in: body
required: true
schema:
$ref: "#/definitions/Person"
responses:
200:
description: 正确返回
schema:
type: string
default:
description: 默认返回
schema:
type: string
definitions:
Person:
type: "object"
properties:
name:
type: "string"
description: "person name"
xml:
name: "Person"
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2017 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.servicecomb.samples.springmvc.provider;


import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.ws.rs.core.MediaType;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import io.netty.util.concurrent.CompleteFuture;
import io.servicecomb.provider.rest.common.RestSchema;
import io.servicecomb.samples.common.schema.Hello;
import io.servicecomb.samples.common.schema.HelloAsync;
import io.servicecomb.samples.common.schema.models.Person;

@RestSchema(schemaId = "springmvcHelloAsync")
@RequestMapping(path = "/springmvchelloasync", produces = MediaType.APPLICATION_JSON)
public class SpringmvcHelloAsyncImpl implements HelloAsync {

private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(8);


@Override
@RequestMapping(path = "/sayhi", method = RequestMethod.POST)
public CompletableFuture<Person> sayHi(@RequestParam(name = "name") String name) {
Person person = new Person();
CompletableFuture<Person> result = new CompletableFuture<Person>();
person.setName("Hello" + name);
executorService.schedule(() -> result.complete(person), 2000, TimeUnit.MILLISECONDS);
return result;
}

@Override
@RequestMapping(path = "/sayhello", method = RequestMethod.POST)
public CompletableFuture<String> sayHello(@RequestBody Person person) {
CompletableFuture<String> result = new CompletableFuture<String>();
executorService.schedule(() -> result.complete("Hello person " + person.getName()), 2000, TimeUnit.MILLISECONDS);
return result;
}
}
Loading