Skip to content

Commit

Permalink
Service proxy JPMS example
Browse files Browse the repository at this point in the history
  • Loading branch information
vietj committed Dec 12, 2024
1 parent 983dd88 commit bf797bb
Show file tree
Hide file tree
Showing 11 changed files with 442 additions and 0 deletions.
4 changes: 4 additions & 0 deletions jpms-examples/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,7 @@ Or launch a JVM with `--add-modules io.netty.tcnative.classes.openssl,io.netty.i
A simple link:src/main/java/io/vertx/example/jpms/sqlclient/Client.java[client] accessing the PostgreSQL database.

Since it requires a database, you can run it from a link:src/test/java/io/vertx/example/jpms/tests/SqlClientTest.java[JUnit5 test]

== Service Proxy

A simple link:src/main/java/io/vertx/example/jpms/serviceproxy/UserService.java[service proxy] example.
21 changes: 21 additions & 0 deletions jpms-examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@
<artifactId>vertx-core</artifactId>
</dependency>

<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-service-proxy</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-codegen-api</artifactId>
</dependency>

<dependency>
<groupId>com.aayushatharva.brotli4j</groupId>
<artifactId>brotli4j</artifactId>
Expand Down Expand Up @@ -228,6 +237,18 @@
<version>3.13.0</version>
<configuration>
<release>11</release>
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>io.vertx</groupId>
<artifactId>vertx-codegen-processor</artifactId>
<classifier>processor</classifier>
<version>${project.version}</version>
</annotationProcessorPath>
<annotationProcessorPath>
<groupId>io.vertx</groupId>
<artifactId>vertx-service-proxy</artifactId>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.vertx.example.jpms.serviceproxy;

import io.vertx.core.json.JsonObject;
import io.vertx.core.json.JsonArray;
import java.time.Instant;
import java.time.format.DateTimeFormatter;

/**
* Converter and mapper for {@link io.vertx.example.jpms.serviceproxy.User}.
* NOTE: This class has been automatically generated from the {@link io.vertx.example.jpms.serviceproxy.User} original class using Vert.x codegen.
*/
public class UserConverter {

static void fromJson(Iterable<java.util.Map.Entry<String, Object>> json, User obj) {
for (java.util.Map.Entry<String, Object> member : json) {
switch (member.getKey()) {
case "firstName":
if (member.getValue() instanceof String) {
obj.setFirstName((String)member.getValue());
}
break;
case "lastName":
if (member.getValue() instanceof String) {
obj.setLastName((String)member.getValue());
}
break;
}
}
}

static void toJson(User obj, JsonObject json) {
toJson(obj, json.getMap());
}

static void toJson(User obj, java.util.Map<String, Object> json) {
if (obj.getFirstName() != null) {
json.put("firstName", obj.getFirstName());
}
if (obj.getLastName() != null) {
json.put("lastName", obj.getLastName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2014 Red Hat, Inc.
*
* Red Hat licenses this file to you 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.vertx.example.jpms.serviceproxy;

import io.vertx.core.eventbus.DeliveryOptions;
import io.vertx.core.Vertx;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import io.vertx.core.json.JsonArray;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.function.Function;
import io.vertx.serviceproxy.ServiceException;
import io.vertx.serviceproxy.ServiceExceptionMessageCodec;
import io.vertx.serviceproxy.ProxyUtils;

import io.vertx.example.jpms.serviceproxy.User;
import io.vertx.example.jpms.serviceproxy.UserService;
import io.vertx.core.Vertx;
import io.vertx.core.Future;
/*
Generated Proxy code - DO NOT EDIT
@author Roger the Robot
*/

@SuppressWarnings({"unchecked", "rawtypes"})
public class UserServiceVertxEBProxy implements UserService {
private Vertx _vertx;
private String _address;
private DeliveryOptions _options;
private boolean closed;

public UserServiceVertxEBProxy(Vertx vertx, String address) {
this(vertx, address, null);
}

public UserServiceVertxEBProxy(Vertx vertx, String address, DeliveryOptions options) {
this._vertx = vertx;
this._address = address;
this._options = options;
try {
this._vertx.eventBus().registerDefaultCodec(ServiceException.class, new ServiceExceptionMessageCodec());
} catch (IllegalStateException ex) {
}
}

@Override
public Future<User> getUser(String userID){
if (closed) return io.vertx.core.Future.failedFuture("Proxy is closed");
JsonObject _json = new JsonObject();
_json.put("userID", userID);

DeliveryOptions _deliveryOptions = (_options != null) ? new DeliveryOptions(_options) : new DeliveryOptions();
_deliveryOptions.addHeader("action", "getUser");
_deliveryOptions.getHeaders().set("action", "getUser");
return _vertx.eventBus().<JsonObject>request(_address, _json, _deliveryOptions).map(msg -> {
return msg.body() != null ? new io.vertx.example.jpms.serviceproxy.User((JsonObject)msg.body()) : null;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright 2014 Red Hat, Inc.
*
* Red Hat licenses this file to you 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.vertx.example.jpms.serviceproxy;

import io.vertx.example.jpms.serviceproxy.UserService;
import io.vertx.core.Vertx;
import io.vertx.core.Handler;
import io.vertx.core.AsyncResult;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.eventbus.Message;
import io.vertx.core.eventbus.MessageConsumer;
import io.vertx.core.eventbus.DeliveryOptions;
import io.vertx.core.eventbus.ReplyException;
import io.vertx.core.json.JsonObject;
import io.vertx.core.json.JsonArray;
import java.util.Collection;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import io.vertx.serviceproxy.ProxyHandler;
import io.vertx.serviceproxy.ServiceException;
import io.vertx.serviceproxy.ServiceExceptionMessageCodec;
import io.vertx.serviceproxy.HelperUtils;
import io.vertx.serviceproxy.ServiceBinder;

import io.vertx.example.jpms.serviceproxy.User;
import io.vertx.example.jpms.serviceproxy.UserService;
import io.vertx.core.Vertx;
import io.vertx.core.Future;
/*
Generated Proxy code - DO NOT EDIT
@author Roger the Robot
*/

@SuppressWarnings({"unchecked", "rawtypes"})
public class UserServiceVertxProxyHandler extends ProxyHandler {

public static final long DEFAULT_CONNECTION_TIMEOUT = 5 * 60; // 5 minutes
private final Vertx vertx;
private final UserService service;
private final long timerID;
private long lastAccessed;
private final long timeoutSeconds;
private final boolean includeDebugInfo;

public UserServiceVertxProxyHandler(Vertx vertx, UserService service){
this(vertx, service, DEFAULT_CONNECTION_TIMEOUT);
}

public UserServiceVertxProxyHandler(Vertx vertx, UserService service, long timeoutInSecond){
this(vertx, service, true, timeoutInSecond);
}

public UserServiceVertxProxyHandler(Vertx vertx, UserService service, boolean topLevel, long timeoutInSecond){
this(vertx, service, true, timeoutInSecond, false);
}

public UserServiceVertxProxyHandler(Vertx vertx, UserService service, boolean topLevel, long timeoutSeconds, boolean includeDebugInfo) {
this.vertx = vertx;
this.service = service;
this.includeDebugInfo = includeDebugInfo;
this.timeoutSeconds = timeoutSeconds;
try {
this.vertx.eventBus().registerDefaultCodec(ServiceException.class,
new ServiceExceptionMessageCodec());
} catch (IllegalStateException ex) {}
if (timeoutSeconds != -1 && !topLevel) {
long period = timeoutSeconds * 1000 / 2;
if (period > 10000) {
period = 10000;
}
this.timerID = vertx.setPeriodic(period, this::checkTimedOut);
} else {
this.timerID = -1;
}
accessed();
}


private void checkTimedOut(long id) {
long now = System.nanoTime();
if (now - lastAccessed > timeoutSeconds * 1000000000) {
close();
}
}

@Override
public void close() {
if (timerID != -1) {
vertx.cancelTimer(timerID);
}
super.close();
}

private void accessed() {
this.lastAccessed = System.nanoTime();
}

public void handle(Message<JsonObject> msg) {
try{
JsonObject json = msg.body();
String action = msg.headers().get("action");
if (action == null) throw new IllegalStateException("action not specified");
accessed();
switch (action) {
case "getUser": {
service.getUser((java.lang.String)json.getValue("userID")).onComplete(res -> {
if (res.failed()) {
HelperUtils.manageFailure(msg, res.cause(), includeDebugInfo);
} else {
msg.reply(res.result() != null ? res.result().toJson() : null);
}
});
break;
}
default: throw new IllegalStateException("Invalid action: " + action);
}
} catch (Throwable t) {
if (includeDebugInfo) msg.reply(new ServiceException(500, t.getMessage(), HelperUtils.generateDebugInfo(t)));
else msg.reply(new ServiceException(500, t.getMessage()));
throw t;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.vertx.example.jpms.serviceproxy;

import io.vertx.codegen.annotations.DataObject;
import io.vertx.codegen.json.annotations.JsonGen;
import io.vertx.core.json.JsonObject;

@JsonGen(publicConverter = false)
@DataObject
public class User {

private String firstName;
private String lastName;

public User(JsonObject json) {
UserConverter.fromJson(json, this);
}

public User() {
}

public String getFirstName() {
return firstName;
}

public User setFirstName(String firstName) {
this.firstName = firstName;
return this;
}

public String getLastName() {
return lastName;
}

public User setLastName(String lastName) {
this.lastName = lastName;
return this;
}

public JsonObject toJson() {
JsonObject json = new JsonObject();
UserConverter.toJson(this, json);
return json;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.vertx.example.jpms.serviceproxy;

import io.vertx.codegen.annotations.ProxyGen;
import io.vertx.codegen.annotations.VertxGen;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.example.jpms.serviceproxy.impl.SimpleUserService;
import io.vertx.serviceproxy.ServiceProxyBuilder;

/**
* The service interface.
*/
@ProxyGen
@VertxGen
public interface UserService {

static void createService(Vertx vertx) {
vertx
.eventBus()
.consumer("user-service", new UserServiceVertxProxyHandler(vertx, new SimpleUserService(vertx)));
}

static UserService createProxy(Vertx vertx) {
return new ServiceProxyBuilder(vertx)
.setAddress("user-service")
.build(UserService.class);
}

// The service methods
Future<User> getUser(String userID);

}
Loading

0 comments on commit bf797bb

Please sign in to comment.