aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2021-03-27 16:01:37 -0700
committerTrumeet <yuuta@yuuta.moe>2021-03-27 16:01:37 -0700
commit6166ddaf522f01ccc2e7c65ec98f7e48fa061c9b (patch)
treeef2edac5eff0088f6080bc9f87482270905c801d
parent2ee583fb60ae79a7d1a0ab971cc0eafa488bd079 (diff)
downloaddn42peering-6166ddaf522f01ccc2e7c65ec98f7e48fa061c9b.tar
dn42peering-6166ddaf522f01ccc2e7c65ec98f7e48fa061c9b.tar.gz
dn42peering-6166ddaf522f01ccc2e7c65ec98f7e48fa061c9b.tar.bz2
dn42peering-6166ddaf522f01ccc2e7c65ec98f7e48fa061c9b.zip
feat(central): move gRPC logic into a separate verticle and fix shutdown issuesv1.7
-rw-r--r--.idea/compiler.xml8
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/Main.java2
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/manage/ManageHandler.java107
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/node/Node.java23
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/peer/Peer.java41
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/provision/BGPRequestCommon.java127
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/provision/IProvisionRemoteService.java56
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/provision/NodeCommon.java112
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/provision/ProvisionRemoteServiceImpl.java107
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/provision/ProvisionVerticle.java41
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/provision/WGRequestCommon.java155
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/provision/package-info.java4
12 files changed, 708 insertions, 75 deletions
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 6620e8f..7480914 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -48,6 +48,14 @@
</processorPath>
<module name="dn42peering.central.main" />
</profile>
+ <profile name="Gradle Imported" enabled="true">
+ <outputRelativeToContentRoot value="true" />
+ <processorPath useClasspath="false">
+ <entry name="$USER_HOME$/.local/share/gradle/caches/modules-2/files-2.1/io.vertx/vertx-codegen/4.0.3/416429ea05c4c43afcf4104ab488bda10f43ba87/vertx-codegen-4.0.3-processor.jar" />
+ <entry name="$USER_HOME$/.local/share/gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-core/2.11.3/c2351800432bdbdd8284c3f5a7f0782a352aa84a/jackson-core-2.11.3.jar" />
+ </processorPath>
+ <module name="dn42peering.rpc-common.main" />
+ </profile>
</annotationProcessing>
<bytecodeTargetLevel target="1.8" />
</component>
diff --git a/central/src/main/java/moe/yuuta/dn42peering/Main.java b/central/src/main/java/moe/yuuta/dn42peering/Main.java
index 595cb30..5fa6690 100644
--- a/central/src/main/java/moe/yuuta/dn42peering/Main.java
+++ b/central/src/main/java/moe/yuuta/dn42peering/Main.java
@@ -8,6 +8,7 @@ import moe.yuuta.dn42peering.asn.ASNVerticle;
import moe.yuuta.dn42peering.node.NodeVerticle;
import moe.yuuta.dn42peering.peer.PeerVerticle;
import moe.yuuta.dn42peering.portal.HTTPPortalVerticle;
+import moe.yuuta.dn42peering.provision.ProvisionVerticle;
import moe.yuuta.dn42peering.whois.WhoisVerticle;
import javax.annotation.Nonnull;
@@ -40,6 +41,7 @@ public class Main {
Future.<String>future(f -> vertx.deployVerticle(WhoisVerticle.class.getName(), options, f)),
Future.<String>future(f -> vertx.deployVerticle(ASNVerticle.class.getName(), options, f)),
Future.<String>future(f -> vertx.deployVerticle(NodeVerticle.class.getName(), options, f)),
+ Future.<String>future(f -> vertx.deployVerticle(ProvisionVerticle.class.getName(), options, f)),
Future.<String>future(f -> vertx.deployVerticle(HTTPPortalVerticle.class.getName(), options, f))
).onComplete(res -> {
if (res.succeeded()) {
diff --git a/central/src/main/java/moe/yuuta/dn42peering/manage/ManageHandler.java b/central/src/main/java/moe/yuuta/dn42peering/manage/ManageHandler.java
index d2d66a3..5127df0 100644
--- a/central/src/main/java/moe/yuuta/dn42peering/manage/ManageHandler.java
+++ b/central/src/main/java/moe/yuuta/dn42peering/manage/ManageHandler.java
@@ -27,9 +27,8 @@ import io.vertx.json.schema.SchemaParser;
import io.vertx.json.schema.SchemaRouter;
import io.vertx.json.schema.SchemaRouterOptions;
import io.vertx.json.schema.common.dsl.ObjectSchemaBuilder;
-import moe.yuuta.dn42peering.agent.proto.BGPRequest;
-import moe.yuuta.dn42peering.agent.proto.VertxAgentGrpc;
-import moe.yuuta.dn42peering.agent.proto.WGRequest;
+import moe.yuuta.dn42peering.provision.BGPRequestCommon;
+import moe.yuuta.dn42peering.provision.WGRequestCommon;
import moe.yuuta.dn42peering.asn.IASNService;
import moe.yuuta.dn42peering.jaba.Pair;
import moe.yuuta.dn42peering.node.INodeService;
@@ -40,6 +39,7 @@ import moe.yuuta.dn42peering.peer.ProvisionStatus;
import moe.yuuta.dn42peering.portal.FormException;
import moe.yuuta.dn42peering.portal.HTTPException;
import moe.yuuta.dn42peering.portal.ISubRouter;
+import moe.yuuta.dn42peering.provision.IProvisionRemoteService;
import moe.yuuta.dn42peering.whois.IWhoisService;
import moe.yuuta.dn42peering.whois.WhoisObject;
import org.apache.commons.validator.routines.InetAddressValidator;
@@ -64,6 +64,7 @@ public class ManageHandler implements ISubRouter {
final IWhoisService whoisService = IWhoisService.createProxy(vertx, IWhoisService.ADDRESS);
final IPeerService peerService = IPeerService.createProxy(vertx);
final INodeService nodeService = INodeService.createProxy(vertx);
+ final IProvisionRemoteService provisionService = IProvisionRemoteService.create(vertx);
final TemplateEngine engine = FreeMarkerTemplateEngine.create(vertx, "ftlh");
final Router router = Router.router(vertx);
@@ -209,7 +210,7 @@ public class ManageHandler implements ISubRouter {
.setStatusCode(303)
.putHeader("Location", "/manage")
.end();
- provisionPeer(vertx, nodeService, peer).onComplete(ar ->
+ provisionPeer(nodeService, provisionService, peer).onComplete(ar ->
this.handleProvisionResult(peerService, peer, ar));
})
.onFailure(err -> {
@@ -382,7 +383,7 @@ public class ManageHandler implements ISubRouter {
.end();
final Peer existingPeer = pair.a;
final Peer inPeer = pair.b;
- reloadPeer(vertx, nodeService, existingPeer, inPeer).onComplete(ar ->
+ reloadPeer(nodeService, provisionService, existingPeer, inPeer).onComplete(ar ->
this.handleProvisionResult(peerService, inPeer, ar));
})
.onFailure(err -> {
@@ -435,7 +436,7 @@ public class ManageHandler implements ISubRouter {
}
return Future.succeededFuture(peer);
})
- .compose(peer -> unprovisionPeer(vertx, nodeService, peer))
+ .compose(peer -> unprovisionPeer(nodeService, provisionService, peer))
.compose(_v -> Future.<Void>future(f -> peerService.deletePeer(asn, id, f)))
.onSuccess(_id -> ctx.response()
.setStatusCode(303)
@@ -961,8 +962,8 @@ public class ManageHandler implements ISubRouter {
}
@Nonnull
- private Future<Void> reloadPeer(@Nonnull Vertx vertx,
- @Nonnull INodeService nodeService,
+ private Future<Void> reloadPeer(@Nonnull INodeService nodeService,
+ @Nonnull IProvisionRemoteService provisionService,
@Nonnull Peer existingPeer, @Nonnull Peer inPeer) {
// Check if we can reload on the fly.
// Otherwise, we can only deprovision and provision.
@@ -1004,33 +1005,37 @@ public class ManageHandler implements ISubRouter {
return Future.succeededFuture(node);
})
.compose(node -> {
- final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(node.toChannel(vertx));
switch (existingPeer.getType()) {
case WIREGUARD:
- return stub.reloadWG(
- inPeer.toWGRequest().setNode(node.toRPCNode()).build()
- ).compose(wgReply -> Future.succeededFuture(new Pair<>(node, wgReply.getDevice())));
+ final WGRequestCommon wgReq = inPeer.toWGRequest();
+ wgReq.setNode(node.toRPCNode());
+ return Future.<String>future(f -> provisionService.reloadWG(
+ node.toRPCNode(),
+ wgReq,
+ f)
+ ).compose(device -> Future.succeededFuture(new Pair<>(node, device)));
default:
throw new UnsupportedOperationException("Bug: Unknown type.");
}
})
.compose(pair -> {
- final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(pair.a.toChannel(vertx));
- return stub.reloadBGP(inPeer.toBGPRequest()
- .setNode(pair.a.toRPCNode())
- .setDevice(pair.b)
- .build())
- .compose(reply -> Future.succeededFuture(null));
+ final BGPRequestCommon bgpReq = inPeer.toBGPRequest();
+ bgpReq.setNode(pair.a.toRPCNode());
+ bgpReq.setDevice(pair.b);
+ return Future.future(f -> provisionService.reloadBGP(
+ pair.a.toRPCNode(),
+ bgpReq,
+ f));
});
} else {
- future = unprovisionPeer(vertx, nodeService, existingPeer)
- .compose(f -> provisionPeer(vertx, nodeService, inPeer));
+ future = unprovisionPeer(nodeService, provisionService, existingPeer)
+ .compose(f -> provisionPeer(nodeService, provisionService, inPeer));
}
return future;
}
- private Future<Void> unprovisionPeer(@Nonnull Vertx vertx,
- @Nonnull INodeService nodeService,
+ private Future<Void> unprovisionPeer(@Nonnull INodeService nodeService,
+ @Nonnull IProvisionRemoteService provisionService,
@Nonnull Peer existingPeer) {
return Future.<Node>future(f -> nodeService.getNode(existingPeer.getNode(), f))
.compose(node -> {
@@ -1040,27 +1045,43 @@ public class ManageHandler implements ISubRouter {
return Future.succeededFuture(node);
})
.compose(node -> {
- final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(node.toChannel(vertx));
switch (existingPeer.getType()) {
case WIREGUARD:
- return stub.deleteWG(WGRequest.newBuilder().setId(existingPeer.getId()).build())
- .compose(wgReply -> Future.succeededFuture(node));
+ return Future.<Void>future(f -> provisionService.deleteWG(
+ node.toRPCNode(),
+ new WGRequestCommon(null,
+ (long)existingPeer.getId(),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null),
+ f))
+ .compose(res -> Future.succeededFuture(node));
default:
throw new UnsupportedOperationException("Bug: Unknown type.");
}
})
.compose(node -> {
- final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(node.toChannel(vertx));
- return stub.deleteBGP(BGPRequest.newBuilder().setId(existingPeer.getId())
- .build())
- .compose(reply -> Future.succeededFuture(null));
+ return Future.future(f -> provisionService.deleteBGP(
+ node.toRPCNode(),
+ new BGPRequestCommon(null,
+ (long)existingPeer.getId(),
+ null,
+ null,
+ null,
+ null,
+ null),
+ f));
})
;
}
@Nonnull
- private Future<Void> provisionPeer(@Nonnull Vertx vertx,
- @Nonnull INodeService nodeService,
+ private Future<Void> provisionPeer(@Nonnull INodeService nodeService,
+ @Nonnull IProvisionRemoteService provisionService,
@Nonnull Peer inPeer) {
return Future.<Node>future(f -> nodeService.getNode(inPeer.getNode(), f))
.compose(node -> {
@@ -1070,23 +1091,27 @@ public class ManageHandler implements ISubRouter {
return Future.succeededFuture(node);
})
.compose(node -> {
- final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(node.toChannel(vertx));
switch (inPeer.getType()) {
case WIREGUARD:
- return stub.provisionWG(
- inPeer.toWGRequest().setNode(node.toRPCNode()).build()
- ).compose(wgReply -> Future.succeededFuture(new Pair<>(node, wgReply.getDevice())));
+ final WGRequestCommon wgReq = inPeer.toWGRequest();
+ wgReq.setNode(node.toRPCNode());
+ return Future.<String>future(f -> provisionService.provisionWG(
+ node.toRPCNode(),
+ wgReq,
+ f)
+ ).compose(device -> Future.succeededFuture(new Pair<>(node, device)));
default:
throw new UnsupportedOperationException("Bug: Unknown type.");
}
})
.compose(pair -> {
- final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(pair.a.toChannel(vertx));
- return stub.provisionBGP(inPeer.toBGPRequest()
- .setNode(pair.a.toRPCNode())
- .setDevice(pair.b)
- .build())
- .compose(reply -> Future.succeededFuture(null));
+ final BGPRequestCommon bgpReq = inPeer.toBGPRequest();
+ bgpReq.setNode(pair.a.toRPCNode());
+ bgpReq.setDevice(pair.b);
+ return Future.future(f -> provisionService.provisionBGP(
+ pair.a.toRPCNode(),
+ bgpReq,
+ f));
});
}
diff --git a/central/src/main/java/moe/yuuta/dn42peering/node/Node.java b/central/src/main/java/moe/yuuta/dn42peering/node/Node.java
index 5135947..250930f 100644
--- a/central/src/main/java/moe/yuuta/dn42peering/node/Node.java
+++ b/central/src/main/java/moe/yuuta/dn42peering/node/Node.java
@@ -11,6 +11,7 @@ import io.vertx.sqlclient.templates.annotations.Column;
import io.vertx.sqlclient.templates.annotations.ParametersMapped;
import io.vertx.sqlclient.templates.annotations.RowMapped;
import io.vertx.sqlclient.templates.annotations.TemplateParameter;
+import moe.yuuta.dn42peering.provision.NodeCommon;
import moe.yuuta.dn42peering.peer.Peer;
import javax.annotation.Nonnull;
@@ -107,21 +108,13 @@ public class Node {
@GenIgnore
@Nonnull
- public moe.yuuta.dn42peering.agent.proto.Node toRPCNode() {
- return moe.yuuta.dn42peering.agent.proto.Node.newBuilder()
- .setId(id)
- .setIpv4(dn42Ip4)
- .setIpv6(dn42Ip6)
- .setIpv6NonLL(dn42Ip6NonLL)
- .build();
- }
-
- @GenIgnore
- @Nonnull
- public ManagedChannel toChannel(@Nonnull Vertx vertx) {
- return VertxChannelBuilder.forAddress(vertx, internalIp, internalPort)
- .usePlaintext()
- .build();
+ public NodeCommon toRPCNode() {
+ return new NodeCommon(id,
+ dn42Ip4,
+ dn42Ip6,
+ dn42Ip6NonLL,
+ internalIp,
+ internalPort);
}
// BEGIN GETTER / SETTER
diff --git a/central/src/main/java/moe/yuuta/dn42peering/peer/Peer.java b/central/src/main/java/moe/yuuta/dn42peering/peer/Peer.java
index e7f31fa..b54f4e0 100644
--- a/central/src/main/java/moe/yuuta/dn42peering/peer/Peer.java
+++ b/central/src/main/java/moe/yuuta/dn42peering/peer/Peer.java
@@ -10,8 +10,8 @@ import io.vertx.sqlclient.templates.annotations.Column;
import io.vertx.sqlclient.templates.annotations.ParametersMapped;
import io.vertx.sqlclient.templates.annotations.RowMapped;
import io.vertx.sqlclient.templates.annotations.TemplateParameter;
-import moe.yuuta.dn42peering.agent.proto.BGPRequest;
-import moe.yuuta.dn42peering.agent.proto.WGRequest;
+import moe.yuuta.dn42peering.provision.BGPRequestCommon;
+import moe.yuuta.dn42peering.provision.WGRequestCommon;
import javax.annotation.Nonnull;
import java.io.IOException;
@@ -193,26 +193,29 @@ public class Peer {
}
@GenIgnore
- public WGRequest.Builder toWGRequest() {
- return WGRequest.newBuilder()
- .setId(getId())
- .setListenPort(Integer.parseInt(calcWireGuardPort()))
- .setEndpoint(getWgEndpoint() == null && getWgEndpointPort() == null ? "" : String.format("%s:%d", getWgEndpoint(), getWgEndpointPort()))
- .setPeerPubKey(getWgPeerPubkey())
- .setSelfPrivKey(getWgSelfPrivKey())
- .setSelfPresharedSecret(getWgPresharedSecret())
- .setPeerIPv4(getIpv4())
- .setPeerIPv6(getIpv6() == null ? "" : getIpv6());
+ public WGRequestCommon toWGRequest() {
+ return new WGRequestCommon(
+ null,
+ (long)id,
+ Integer.parseInt(calcWireGuardPort()),
+ wgEndpoint == null && wgEndpointPort == null ? "" :
+ String.format("%s:%d", getWgEndpoint(), getWgEndpointPort()),
+ wgPeerPubkey,
+ wgSelfPrivKey,
+ wgPresharedSecret,
+ ipv4,
+ ipv6 == null ? "" : ipv6);
}
@GenIgnore
- public BGPRequest.Builder toBGPRequest() {
- return BGPRequest.newBuilder()
- .setId(getId())
- .setAsn(getAsn())
- .setIpv4(getIpv4())
- .setIpv6(getIpv6() == null ? "" : getIpv6())
- .setMpbgp(isMpbgp());
+ public BGPRequestCommon toBGPRequest() {
+ return new BGPRequestCommon(null,
+ (long)id,
+ asn,
+ mpbgp,
+ ipv4,
+ ipv6 == null ? "" : ipv6,
+ null);
}
// START GETTERS / SETTERS
diff --git a/central/src/main/java/moe/yuuta/dn42peering/provision/BGPRequestCommon.java b/central/src/main/java/moe/yuuta/dn42peering/provision/BGPRequestCommon.java
new file mode 100644
index 0000000..8ca9ea2
--- /dev/null
+++ b/central/src/main/java/moe/yuuta/dn42peering/provision/BGPRequestCommon.java
@@ -0,0 +1,127 @@
+package moe.yuuta.dn42peering.provision;
+
+import io.vertx.codegen.annotations.DataObject;
+import io.vertx.core.json.JsonObject;
+import moe.yuuta.dn42peering.agent.proto.BGPRequest;
+
+import javax.annotation.Nonnull;
+
+@DataObject
+public class BGPRequestCommon {
+ private NodeCommon node;
+ private Long id;
+ private String asn;
+ private Boolean mpbgp;
+ private String ipv4;
+ private String ipv6;
+ private String device;
+
+ public BGPRequestCommon(NodeCommon node,
+ Long id,
+ String asn,
+ Boolean mpbgp,
+ String ipv4,
+ String ipv6,
+ String device) {
+ this.node = node;
+ this.id = id;
+ this.asn = asn;
+ this.mpbgp = mpbgp;
+ this.ipv4 = ipv4;
+ this.ipv6 = ipv6;
+ this.device = device;
+ }
+
+ public BGPRequestCommon(@Nonnull JsonObject json) {
+ if(json.getValue("node") != null) this.node = new NodeCommon(json.getJsonObject("node"));
+ if(json.getValue("id") != null) this.id = json.getLong("id");
+ this.asn = json.getString("asn");
+ if(json.getValue("mpbgp") != null) this.mpbgp = json.getBoolean("mpbgp");
+ this.ipv4 = json.getString("ipv4");
+ this.ipv6 = json.getString("ipv6");
+ this.device = json.getString("device");
+ }
+
+ @Nonnull
+ public JsonObject toJson() {
+ return new JsonObject()
+ .put("node", node == null ? null : node.toJson())
+ .put("id", id)
+ .put("asn", asn)
+ .put("mpbgp", mpbgp)
+ .put("ipv4", ipv4)
+ .put("ipv6", ipv6)
+ .put("device", device);
+ }
+
+ @Nonnull
+ public BGPRequest toGRPC() {
+ final BGPRequest.Builder builder = BGPRequest.newBuilder();
+ if(node != null) builder.setNode(node.toGRPC());
+ if(id != null) builder.setId(id);
+ if(asn != null) builder.setAsn(asn);
+ if(mpbgp != null) builder.setMpbgp(mpbgp);
+ if(ipv4 != null) builder.setIpv4(ipv4);
+ if(ipv6 != null) builder.setIpv6(ipv6);
+ if(device != null) builder.setDevice(device);
+ return builder.build();
+ }
+
+ // Getters & Setters
+
+ public NodeCommon getNode() {
+ return node;
+ }
+
+ public void setNode(NodeCommon node) {
+ this.node = node;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getAsn() {
+ return asn;
+ }
+
+ public void setAsn(String asn) {
+ this.asn = asn;
+ }
+
+ public Boolean getMpbgp() {
+ return mpbgp;
+ }
+
+ public void setMpbgp(Boolean mpbgp) {
+ this.mpbgp = mpbgp;
+ }
+
+ public String getIpv4() {
+ return ipv4;
+ }
+
+ public void setIpv4(String ipv4) {
+ this.ipv4 = ipv4;
+ }
+
+ public String getIpv6() {
+ return ipv6;
+ }
+
+ public void setIpv6(String ipv6) {
+ this.ipv6 = ipv6;
+ }
+
+ public String getDevice() {
+ return device;
+ }
+
+ public void setDevice(String device) {
+ this.device = device;
+ }
+}
diff --git a/central/src/main/java/moe/yuuta/dn42peering/provision/IProvisionRemoteService.java b/central/src/main/java/moe/yuuta/dn42peering/provision/IProvisionRemoteService.java
new file mode 100644
index 0000000..ace1c54
--- /dev/null
+++ b/central/src/main/java/moe/yuuta/dn42peering/provision/IProvisionRemoteService.java
@@ -0,0 +1,56 @@
+package moe.yuuta.dn42peering.provision;
+
+import io.vertx.codegen.annotations.Fluent;
+import io.vertx.codegen.annotations.ProxyGen;
+import io.vertx.core.AsyncResult;
+import io.vertx.core.Handler;
+import io.vertx.core.Vertx;
+import moe.yuuta.dn42peering.node.Node;
+
+import javax.annotation.Nonnull;
+
+@ProxyGen
+public interface IProvisionRemoteService {
+ String ADDRESS = IProvisionRemoteService.class.getName();
+
+ @Nonnull
+ static IProvisionRemoteService create(@Nonnull Vertx vertx) {
+ return new IProvisionRemoteServiceVertxEBProxy(vertx, ADDRESS);
+ }
+
+ @Fluent
+ @Nonnull
+ IProvisionRemoteService provisionBGP(@Nonnull NodeCommon node,
+ @Nonnull BGPRequestCommon request,
+ @Nonnull Handler<AsyncResult<Void>> handler);
+
+ @Fluent
+ @Nonnull
+ IProvisionRemoteService reloadBGP(@Nonnull NodeCommon node,
+ @Nonnull BGPRequestCommon request,
+ @Nonnull Handler<AsyncResult<Void>> handler);
+
+ @Fluent
+ @Nonnull
+ IProvisionRemoteService deleteBGP(@Nonnull NodeCommon node,
+ @Nonnull BGPRequestCommon request,
+ @Nonnull Handler<AsyncResult<Void>> handler);
+
+ @Fluent
+ @Nonnull
+ IProvisionRemoteService provisionWG(@Nonnull NodeCommon node,
+ @Nonnull WGRequestCommon request,
+ @Nonnull Handler<AsyncResult<String>> handler);
+
+ @Fluent
+ @Nonnull
+ IProvisionRemoteService reloadWG(@Nonnull NodeCommon node,
+ @Nonnull WGRequestCommon request,
+ @Nonnull Handler<AsyncResult<String>> handler);
+
+ @Fluent
+ @Nonnull
+ IProvisionRemoteService deleteWG(@Nonnull NodeCommon node,
+ @Nonnull WGRequestCommon request,
+ @Nonnull Handler<AsyncResult<Void>> handler);
+}
diff --git a/central/src/main/java/moe/yuuta/dn42peering/provision/NodeCommon.java b/central/src/main/java/moe/yuuta/dn42peering/provision/NodeCommon.java
new file mode 100644
index 0000000..316965c
--- /dev/null
+++ b/central/src/main/java/moe/yuuta/dn42peering/provision/NodeCommon.java
@@ -0,0 +1,112 @@
+package moe.yuuta.dn42peering.provision;
+
+import io.vertx.codegen.annotations.DataObject;
+import io.vertx.core.json.JsonObject;
+import moe.yuuta.dn42peering.agent.proto.Node;
+
+import javax.annotation.Nonnull;
+
+@DataObject
+public class NodeCommon {
+ private Long id;
+ private String ipv4;
+ private String ipv6;
+ private String ipv6NonLL;
+ private String internalIp;
+ private int internalPort;
+
+ public NodeCommon(long id,
+ @Nonnull String ipv4,
+ @Nonnull String ipv6,
+ @Nonnull String ipv6NonLL,
+ @Nonnull String internalIp,
+ @Nonnull Integer internalPort) {
+ this.id = id;
+ this.ipv4 = ipv4;
+ this.ipv6 = ipv6;
+ this.ipv6NonLL = ipv6NonLL;
+ this.internalIp = internalIp;
+ this.internalPort = internalPort;
+ }
+
+ public NodeCommon(@Nonnull JsonObject json) {
+ if(json.getValue("id") != null) this.id = json.getLong("id");
+ else this.id = null;
+ this.ipv4 = json.getString("ipv4");
+ this.ipv6 = json.getString("ipv6");
+ this.ipv6NonLL = json.getString("ipv6_non_ll");
+ this.internalIp = json.getString("internal_ip");
+ if(json.getValue("internal_port") != null) this.internalPort = json.getInteger("internal_port");
+ }
+
+ @Nonnull
+ public JsonObject toJson() {
+ return new JsonObject()
+ .put("id", id)
+ .put("ipv4", ipv4)
+ .put("ipv6", ipv6)
+ .put("ipv6_non_ll", ipv6NonLL)
+ .put("internal_ip", internalIp)
+ .put("internal_port", internalPort);
+ }
+
+ @Nonnull
+ public Node toGRPC() {
+ final Node.Builder builder = Node.newBuilder()
+ .setIpv4(ipv4)
+ .setIpv6(ipv6)
+ .setIpv6NonLL(ipv6NonLL);
+ if(id != null) builder.setId(id);
+ return builder.build();
+ }
+
+ // Getters & Getters
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getIpv4() {
+ return ipv4;
+ }
+
+ public String getIpv6() {
+ return ipv6;
+ }
+
+ public String getIpv6NonLL() {
+ return ipv6NonLL;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public void setIpv4(String ipv4) {
+ this.ipv4 = ipv4;
+ }
+
+ public void setIpv6(String ipv6) {
+ this.ipv6 = ipv6;
+ }
+
+ public void setIpv6NonLL(String ipv6NonLL) {
+ this.ipv6NonLL = ipv6NonLL;
+ }
+
+ String getInternalIp() {
+ return internalIp;
+ }
+
+ void setInternalIp(String internalIp) {
+ this.internalIp = internalIp;
+ }
+
+ int getInternalPort() {
+ return internalPort;
+ }
+
+ void setInternalPort(int internalPort) {
+ this.internalPort = internalPort;
+ }
+}
diff --git a/central/src/main/java/moe/yuuta/dn42peering/provision/ProvisionRemoteServiceImpl.java b/central/src/main/java/moe/yuuta/dn42peering/provision/ProvisionRemoteServiceImpl.java
new file mode 100644
index 0000000..a642326
--- /dev/null
+++ b/central/src/main/java/moe/yuuta/dn42peering/provision/ProvisionRemoteServiceImpl.java
@@ -0,0 +1,107 @@
+package moe.yuuta.dn42peering.provision;
+
+import io.grpc.ManagedChannel;
+import io.vertx.core.*;
+import io.vertx.grpc.VertxChannelBuilder;
+import moe.yuuta.dn42peering.agent.proto.VertxAgentGrpc;
+import moe.yuuta.dn42peering.node.Node;
+
+import javax.annotation.Nonnull;
+
+class ProvisionRemoteServiceImpl implements IProvisionRemoteService {
+ private final Vertx vertx;
+
+ ProvisionRemoteServiceImpl(@Nonnull Vertx vertx) {
+ this.vertx = vertx;
+ }
+
+ private @Nonnull ManagedChannel toChannel(@Nonnull NodeCommon node) {
+ return VertxChannelBuilder.forAddress(vertx, node.getInternalIp(), node.getInternalPort())
+ .usePlaintext()
+ .build();
+ }
+
+ @Nonnull
+ @Override
+ public IProvisionRemoteService provisionBGP(@Nonnull NodeCommon node,
+ @Nonnull BGPRequestCommon request,
+ @Nonnull Handler<AsyncResult<Void>> handler) {
+ final ManagedChannel channel = toChannel(node);
+ final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(channel);
+ stub.provisionBGP(request.toGRPC())
+ .<Void>compose(reply -> Future.succeededFuture(null))
+ .onComplete(res -> channel.shutdown())
+ .onComplete(handler);
+ return this;
+ }
+
+ @Nonnull
+ @Override
+ public IProvisionRemoteService reloadBGP(@Nonnull NodeCommon node,
+ @Nonnull BGPRequestCommon request,
+ @Nonnull Handler<AsyncResult<Void>> handler) {
+ final ManagedChannel channel = toChannel(node);
+ final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(channel);
+ stub.reloadBGP(request.toGRPC())
+ .<Void>compose(reply -> Future.succeededFuture(null))
+ .onComplete(res -> channel.shutdown())
+ .onComplete(handler);
+ return this;
+ }
+
+ @Nonnull
+ @Override
+ public IProvisionRemoteService deleteBGP(@Nonnull NodeCommon node,
+ @Nonnull BGPRequestCommon request,
+ @Nonnull Handler<AsyncResult<Void>> handler) {
+ final ManagedChannel channel = toChannel(node);
+ final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(channel);
+ stub.deleteBGP(request.toGRPC())
+ .<Void>compose(reply -> Future.succeededFuture(null))
+ .onComplete(res -> channel.shutdown())
+ .onComplete(handler);
+ return this;
+ }
+
+ @Nonnull
+ @Override
+ public IProvisionRemoteService provisionWG(@Nonnull NodeCommon node,
+ @Nonnull WGRequestCommon request,
+ @Nonnull Handler<AsyncResult<String>> handler) {
+ final ManagedChannel channel = toChannel(node);
+ final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(channel);
+ stub.provisionWG(request.toGRPC())
+ .compose(wgReply -> Future.succeededFuture(wgReply.getDevice()))
+ .onComplete(res -> channel.shutdown())
+ .onComplete(handler);
+ return this;
+ }
+
+ @Nonnull
+ @Override
+ public IProvisionRemoteService reloadWG(@Nonnull NodeCommon node,
+ @Nonnull WGRequestCommon request,
+ @Nonnull Handler<AsyncResult<String>> handler) {
+ final ManagedChannel channel = toChannel(node);
+ final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(channel);
+ stub.reloadWG(request.toGRPC())
+ .compose(wgReply -> Future.succeededFuture(wgReply.getDevice()))
+ .onComplete(res -> channel.shutdown())
+ .onComplete(handler);
+ return this;
+ }
+
+ @Nonnull
+ @Override
+ public IProvisionRemoteService deleteWG(@Nonnull NodeCommon node,
+ @Nonnull WGRequestCommon request,
+ @Nonnull Handler<AsyncResult<Void>> handler) {
+ final ManagedChannel channel = toChannel(node);
+ final VertxAgentGrpc.AgentVertxStub stub = VertxAgentGrpc.newVertxStub(channel);
+ stub.deleteWG(request.toGRPC())
+ .<Void>compose(wgReply -> Future.succeededFuture(null))
+ .onComplete(res -> channel.shutdown())
+ .onComplete(handler);
+ return this;
+ }
+}
diff --git a/central/src/main/java/moe/yuuta/dn42peering/provision/ProvisionVerticle.java b/central/src/main/java/moe/yuuta/dn42peering/provision/ProvisionVerticle.java
new file mode 100644
index 0000000..7d2772f
--- /dev/null
+++ b/central/src/main/java/moe/yuuta/dn42peering/provision/ProvisionVerticle.java
@@ -0,0 +1,41 @@
+package moe.yuuta.dn42peering.provision;
+
+import io.vertx.core.AbstractVerticle;
+import io.vertx.core.Future;
+import io.vertx.core.Promise;
+import io.vertx.core.eventbus.MessageConsumer;
+import io.vertx.core.impl.logging.Logger;
+import io.vertx.core.impl.logging.LoggerFactory;
+import io.vertx.core.json.JsonObject;
+import io.vertx.serviceproxy.ServiceBinder;
+
+public class ProvisionVerticle extends AbstractVerticle {
+ private final Logger logger = LoggerFactory.getLogger(getClass().getSimpleName());
+
+ private MessageConsumer<JsonObject> consumer;
+
+ @Override
+ public void start(Promise<Void> startPromise) throws Exception {
+ consumer = new ServiceBinder(vertx)
+ .setAddress(IProvisionRemoteService.ADDRESS)
+ .register(IProvisionRemoteService.class, new ProvisionRemoteServiceImpl(vertx));
+ consumer.completionHandler(ar -> {
+ if(ar.succeeded()) {
+ startPromise.complete();
+ } else {
+ startPromise.fail(ar.cause());
+ }
+ });
+ }
+
+ @Override
+ public void stop(Promise<Void> stopPromise) throws Exception {
+ Future.future(f -> consumer.unregister(ar -> {
+ if(ar.succeeded()) f.complete();
+ else f.fail(ar.cause());
+ })).onComplete(ar -> {
+ if(ar.succeeded()) stopPromise.complete();
+ else stopPromise.fail(ar.cause());
+ });
+ }
+}
diff --git a/central/src/main/java/moe/yuuta/dn42peering/provision/WGRequestCommon.java b/central/src/main/java/moe/yuuta/dn42peering/provision/WGRequestCommon.java
new file mode 100644
index 0000000..d4694b6
--- /dev/null
+++ b/central/src/main/java/moe/yuuta/dn42peering/provision/WGRequestCommon.java
@@ -0,0 +1,155 @@
+package moe.yuuta.dn42peering.provision;
+
+import io.vertx.codegen.annotations.DataObject;
+import io.vertx.core.json.JsonObject;
+import moe.yuuta.dn42peering.agent.proto.WGRequest;
+
+import javax.annotation.Nonnull;
+
+@DataObject
+public class WGRequestCommon {
+ private NodeCommon node;
+ private Long id;
+ private Integer listenPort;
+ private String endpoint;
+ private String peerPubKey;
+ private String selfPrivKey;
+ private String selfPresharedSecret;
+ private String peerIPv4;
+ private String peerIPv6;
+
+ public WGRequestCommon(NodeCommon node,
+ Long id,
+ Integer listenPort,
+ String endpoint,
+ String peerPubKey,
+ String selfPrivKey,
+ String selfPresharedSecret,
+ String peerIPv4,
+ String peerIPv6) {
+ this.node = node;
+ this.id = id;
+ this.listenPort = listenPort;
+ this.endpoint = endpoint;
+ this.peerPubKey = peerPubKey;
+ this.selfPrivKey = selfPrivKey;
+ this.selfPresharedSecret = selfPresharedSecret;
+ this.peerIPv4 = peerIPv4;
+ this.peerIPv6 = peerIPv6;
+ }
+
+ public WGRequestCommon(@Nonnull JsonObject json) {
+ if(json.getValue("node") != null) this.node = new NodeCommon(json.getJsonObject("node"));
+ if(json.getValue("id") != null) this.id = json.getLong("id");
+ if(json.getValue("listen_port") != null) this.listenPort = json.getInteger("listen_port");
+ this.endpoint = json.getString("endpoint");
+ this.peerPubKey = json.getString("peer_public_key");
+ this.selfPrivKey = json.getString("self_private_key");
+ this.selfPresharedSecret = json.getString("self_preshared_secret");
+ this.peerIPv4 = json.getString("peer_ipv4");
+ this.peerIPv6 = json.getString("peer_ipv6");
+ }
+
+ @Nonnull
+ public JsonObject toJson() {
+ return new JsonObject()
+ .put("node", node == null ? null : node.toJson())
+ .put("id", id)
+ .put("listen_port", listenPort)
+ .put("endpoint", endpoint)
+ .put("peer_public_key", peerPubKey)
+ .put("self_private_key", selfPrivKey)
+ .put("self_preshared_secret", selfPresharedSecret)
+ .put("peer_ipv4", peerIPv4)
+ .put("peer_ipv6", peerIPv6);
+ }
+
+ @Nonnull
+ public WGRequest toGRPC() {
+ final WGRequest.Builder builder = WGRequest.newBuilder();
+ if(node != null) builder.setNode(node.toGRPC());
+ if(id != null) builder.setId(id);
+ if(listenPort != null) builder.setListenPort(listenPort);
+ if(endpoint != null) builder.setEndpoint(endpoint);
+ if(peerPubKey != null) builder.setPeerPubKey(peerPubKey);
+ if(selfPrivKey != null) builder.setSelfPrivKey(selfPrivKey);
+ if(selfPresharedSecret != null) builder.setSelfPresharedSecret(selfPresharedSecret);
+ if(peerIPv4 != null) builder.setPeerIPv4(peerIPv4);
+ if(peerIPv6 != null) builder.setPeerIPv6(peerIPv6);
+ return builder.build();
+ }
+
+ // Getters & Setters
+
+ public NodeCommon getNode() {
+ return node;
+ }
+
+ public void setNode(NodeCommon node) {
+ this.node = node;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Integer getListenPort() {
+ return listenPort;
+ }
+
+ public void setListenPort(Integer listenPort) {
+ this.listenPort = listenPort;
+ }
+
+ public String getEndpoint() {
+ return endpoint;
+ }
+
+ public void setEndpoint(String endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ public String getPeerPubKey() {
+ return peerPubKey;
+ }
+
+ public void setPeerPubKey(String peerPubKey) {
+ this.peerPubKey = peerPubKey;
+ }
+
+ public String getSelfPrivKey() {
+ return selfPrivKey;
+ }
+
+ public void setSelfPrivKey(String selfPrivKey) {
+ this.selfPrivKey = selfPrivKey;
+ }
+
+ public String getSelfPresharedSecret() {
+ return selfPresharedSecret;
+ }
+
+ public void setSelfPresharedSecret(String selfPresharedSecret) {
+ this.selfPresharedSecret = selfPresharedSecret;
+ }
+
+ public String getPeerIPv4() {
+ return peerIPv4;
+ }
+
+ public void setPeerIPv4(String peerIPv4) {
+ this.peerIPv4 = peerIPv4;
+ }
+
+ public String getPeerIPv6() {
+ return peerIPv6;
+ }
+
+ public void setPeerIPv6(String peerIPv6) {
+ this.peerIPv6 = peerIPv6;
+ }
+}
diff --git a/central/src/main/java/moe/yuuta/dn42peering/provision/package-info.java b/central/src/main/java/moe/yuuta/dn42peering/provision/package-info.java
new file mode 100644
index 0000000..22b72c9
--- /dev/null
+++ b/central/src/main/java/moe/yuuta/dn42peering/provision/package-info.java
@@ -0,0 +1,4 @@
+@ModuleGen(groupPackage = "moe.yuuta.dn42peering.provision", name = "provision")
+package moe.yuuta.dn42peering.provision;
+
+import io.vertx.codegen.annotations.ModuleGen; \ No newline at end of file