diff --git a/grpc/src/main/proto/leyden.proto b/grpc/src/main/proto/leyden.proto index 50f12dcdc..129cf9cbb 100644 --- a/grpc/src/main/proto/leyden.proto +++ b/grpc/src/main/proto/leyden.proto @@ -16,7 +16,7 @@ package leyden; service Binder { rpc bind(Binding) returns(google.protobuf.Empty) {} - rpc unbind(stereotomy.Ident) returns(google.protobuf.Empty) {} + rpc unbind(Key_) returns(google.protobuf.Empty) {} } service Reconciliation { @@ -46,8 +46,12 @@ message Interval { crypto.Digeste end = 2; } -message Bound { +message Key_ { bytes key = 1; +} + +message Bound { + Key_ key = 1; bytes value = 2; } diff --git a/leyden/src/main/java/com/salesforce/apollo/leyden/LeydenJar.java b/leyden/src/main/java/com/salesforce/apollo/leyden/LeydenJar.java index 916636226..702d1b2ea 100644 --- a/leyden/src/main/java/com/salesforce/apollo/leyden/LeydenJar.java +++ b/leyden/src/main/java/com/salesforce/apollo/leyden/LeydenJar.java @@ -1,15 +1,18 @@ package com.salesforce.apollo.leyden; -import com.salesforce.apollo.thoth.proto.Intervals; -import com.salesforce.apollo.thoth.proto.Update; -import com.salesforce.apollo.thoth.proto.Updating; import com.salesforce.apollo.archipelago.Router; import com.salesforce.apollo.archipelago.RouterImpl; import com.salesforce.apollo.cryptography.Digest; -import com.salesforce.apollo.leyden.comm.*; +import com.salesforce.apollo.leyden.comm.binding.*; +import com.salesforce.apollo.leyden.comm.reconcile.*; +import com.salesforce.apollo.leyden.proto.Binding; +import com.salesforce.apollo.leyden.proto.Key_; import com.salesforce.apollo.membership.Context; import com.salesforce.apollo.membership.Member; import com.salesforce.apollo.membership.SigningMember; +import com.salesforce.apollo.thoth.proto.Intervals; +import com.salesforce.apollo.thoth.proto.Update; +import com.salesforce.apollo.thoth.proto.Updating; /** * @author hal.hildebrand @@ -17,18 +20,27 @@ public class LeydenJar { private final Context context; - private final RouterImpl.CommonCommunications comms; + private final RouterImpl.CommonCommunications reconComms; + private final RouterImpl.CommonCommunications binderComms; private final double fpr; + private final SigningMember member; public LeydenJar(SigningMember member, Context context, Router communications, double fpr, - ReconciliationMetrics metrics) { + ReconciliationMetrics metrics, BinderMetrics binderMetrics) { this.context = context; - ReconciliationService service = new Reconciled(); + this.member = member; + var recon = new Reconciled(); + reconComms = communications.create(member, context.getId(), recon, + ReconciliationService.class.getCanonicalName(), + r -> new ReconciliationServer(r, communications.getClientIdentityProvider(), + metrics), c -> Reckoning.getCreate(c, metrics), + Reckoning.getLocalLoopback(recon, member)); - comms = communications.create(member, context.getId(), service, service.getClass().getCanonicalName(), - r -> new ReconciliationServer(r, communications.getClientIdentityProvider(), - metrics), c -> Reckoning.getCreate(c, metrics), - Reckoning.getLocalLoopback(service, member)); + var borders = new Borders(); + binderComms = communications.create(member, context.getId(), borders, BinderService.class.getCanonicalName(), + r -> new BinderServer(r, communications.getClientIdentityProvider(), + binderMetrics), c -> Bind.getCreate(c, binderMetrics), + Bind.getLocalLoopback(borders, member)); this.fpr = fpr; } @@ -44,4 +56,17 @@ public void update(Updating request, Digest from) { } } + + private class Borders implements BinderService { + + @Override + public void bind(Binding request, Digest from) { + + } + + @Override + public void unbind(Key_ request, Digest from) { + + } + } } diff --git a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/Bind.java b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/Bind.java new file mode 100644 index 000000000..248ed65e7 --- /dev/null +++ b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/Bind.java @@ -0,0 +1,73 @@ +package com.salesforce.apollo.leyden.comm.binding; + +import com.salesforce.apollo.archipelago.ManagedServerChannel; +import com.salesforce.apollo.leyden.proto.BinderGrpc; +import com.salesforce.apollo.leyden.proto.Binding; +import com.salesforce.apollo.leyden.proto.Key_; +import com.salesforce.apollo.membership.Member; +import com.salesforce.apollo.membership.SigningMember; + +import java.io.IOException; + +/** + * @author hal.hildebrand + **/ +public class Bind implements BinderClient { + private final ManagedServerChannel channel; + private final BinderMetrics metrics; + private final BinderGrpc.BinderBlockingStub client; + + public Bind(ManagedServerChannel channel, BinderMetrics metrics) { + this.channel = channel; + this.metrics = metrics; + this.client = BinderGrpc.newBlockingStub(channel); + } + + public static BinderClient getCreate(ManagedServerChannel c, BinderMetrics binderMetrics) { + return new Bind(c, binderMetrics); + } + + public static BinderClient getLocalLoopback(BinderService service, SigningMember member) { + return new BinderClient() { + @Override + public void bind(Binding binding) { + service.bind(binding, member.getId()); + } + + @Override + public void close() throws IOException { + // no op + } + + @Override + public Member getMember() { + return member; + } + + @Override + public void unbind(Key_ key) { + service.unbind(key, member.getId()); + } + }; + } + + @Override + public void bind(Binding binding) { + client.bind(binding); + } + + @Override + public void close() throws IOException { + channel.shutdown(); + } + + @Override + public Member getMember() { + return channel.getMember(); + } + + @Override + public void unbind(Key_ key) { + client.unbind(key); + } +} diff --git a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderClient.java b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderClient.java new file mode 100644 index 000000000..ee65784d0 --- /dev/null +++ b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderClient.java @@ -0,0 +1,15 @@ +package com.salesforce.apollo.leyden.comm.binding; + +import com.salesforce.apollo.archipelago.Link; +import com.salesforce.apollo.leyden.proto.Binding; +import com.salesforce.apollo.leyden.proto.Key_; + +/** + * @author hal.hildebrand + **/ +public interface BinderClient extends Link { + + void bind(Binding binding); + + void unbind(Key_ key); +} diff --git a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderMetrics.java b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderMetrics.java new file mode 100644 index 000000000..56d30c2f1 --- /dev/null +++ b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderMetrics.java @@ -0,0 +1,18 @@ +package com.salesforce.apollo.leyden.comm.binding; + +import com.codahale.metrics.Histogram; +import com.codahale.metrics.Timer; +import com.salesforce.apollo.protocols.EndpointMetrics; + +/** + * @author hal.hildebrand + **/ +public interface BinderMetrics extends EndpointMetrics { + Histogram inboundBind(); + + Timer inboundBindTimer(); + + Histogram inboundUnbind(); + + Timer inboundUnbindTimer(); +} diff --git a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderServer.java b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderServer.java new file mode 100644 index 000000000..4d734333b --- /dev/null +++ b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderServer.java @@ -0,0 +1,80 @@ +package com.salesforce.apollo.leyden.comm.binding; + +import com.codahale.metrics.Timer; +import com.google.protobuf.Empty; +import com.salesforce.apollo.archipelago.RoutableService; +import com.salesforce.apollo.cryptography.Digest; +import com.salesforce.apollo.leyden.proto.BinderGrpc; +import com.salesforce.apollo.leyden.proto.Binding; +import com.salesforce.apollo.leyden.proto.Key_; +import com.salesforce.apollo.protocols.ClientIdentity; +import io.grpc.stub.StreamObserver; + +/** + * @author hal.hildebrand + **/ +public class BinderServer extends BinderGrpc.BinderImplBase { + + private final RoutableService routing; + private final ClientIdentity identity; + private final BinderMetrics metrics; + + public BinderServer(RoutableService r, ClientIdentity clientIdentityProvider, + BinderMetrics binderMetrics) { + routing = r; + this.identity = clientIdentityProvider; + this.metrics = binderMetrics; + } + + @Override + public void bind(Binding request, StreamObserver responseObserver) { + Timer.Context timer = metrics == null ? null : metrics.inboundBindTimer().time(); + if (metrics != null) { + var serializedSize = request.getSerializedSize(); + metrics.inboundBandwidth().mark(serializedSize); + metrics.inboundBind().update(serializedSize); + } + Digest from = identity.getFrom(); + if (from == null) { + responseObserver.onError(new IllegalStateException("Member has been removed")); + return; + } + routing.evaluate(responseObserver, s -> { + try { + s.bind(request, from); + responseObserver.onNext(Empty.getDefaultInstance()); + responseObserver.onCompleted(); + } finally { + if (timer != null) { + timer.stop(); + } + } + }); + } + + @Override + public void unbind(Key_ request, StreamObserver responseObserver) { + Timer.Context timer = metrics == null ? null : metrics.inboundUnbindTimer().time(); + if (metrics != null) { + var serializedSize = request.getSerializedSize(); + metrics.inboundBandwidth().mark(serializedSize); + metrics.inboundUnbind().update(serializedSize); + } + Digest from = identity.getFrom(); + if (from == null) { + responseObserver.onError(new IllegalStateException("Member has been removed")); + return; + } + routing.evaluate(responseObserver, s -> { + try { + s.unbind(request, from); + responseObserver.onNext(Empty.getDefaultInstance()); + responseObserver.onCompleted(); + } finally { + if (timer != null) { + timer.stop(); + } + } + }); + } +} diff --git a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderService.java b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderService.java new file mode 100644 index 000000000..b4ff4b893 --- /dev/null +++ b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/binding/BinderService.java @@ -0,0 +1,14 @@ +package com.salesforce.apollo.leyden.comm.binding; + +import com.salesforce.apollo.cryptography.Digest; +import com.salesforce.apollo.leyden.proto.Binding; +import com.salesforce.apollo.leyden.proto.Key_; + +/** + * @author hal.hildebrand + **/ +public interface BinderService { + void bind(Binding request, Digest from); + + void unbind(Key_ request, Digest from); +} diff --git a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/Reckoning.java b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/Reckoning.java similarity index 94% rename from leyden/src/main/java/com/salesforce/apollo/leyden/comm/Reckoning.java rename to leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/Reckoning.java index fab6e5119..ad06a7e87 100644 --- a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/Reckoning.java +++ b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/Reckoning.java @@ -1,10 +1,10 @@ -package com.salesforce.apollo.leyden.comm; +package com.salesforce.apollo.leyden.comm.reconcile; +import com.salesforce.apollo.archipelago.ManagedServerChannel; import com.salesforce.apollo.leyden.proto.Intervals; import com.salesforce.apollo.leyden.proto.ReconciliationGrpc; import com.salesforce.apollo.leyden.proto.Update; import com.salesforce.apollo.leyden.proto.Updating; -import com.salesforce.apollo.archipelago.ManagedServerChannel; import com.salesforce.apollo.membership.Member; import com.salesforce.apollo.membership.SigningMember; @@ -25,7 +25,7 @@ public Reckoning(ManagedServerChannel channel, Member member, ReconciliationMetr } public static ReconciliationClient getCreate(ManagedServerChannel channel, ReconciliationMetrics metrics) { - return null; + return new Reckoning(channel, channel.getMember(), metrics); } public static ReconciliationClient getLocalLoopback(ReconciliationService service, SigningMember member) { diff --git a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationClient.java b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationClient.java similarity index 87% rename from leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationClient.java rename to leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationClient.java index 86c609b66..b375f4a42 100644 --- a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationClient.java +++ b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationClient.java @@ -1,9 +1,9 @@ -package com.salesforce.apollo.leyden.comm; +package com.salesforce.apollo.leyden.comm.reconcile; +import com.salesforce.apollo.archipelago.Link; import com.salesforce.apollo.leyden.proto.Intervals; import com.salesforce.apollo.leyden.proto.Update; import com.salesforce.apollo.leyden.proto.Updating; -import com.salesforce.apollo.archipelago.Link; /** * @author hal.hildebrand diff --git a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationMetrics.java b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationMetrics.java similarity index 86% rename from leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationMetrics.java rename to leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationMetrics.java index 08de988fe..63baf8dff 100644 --- a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationMetrics.java +++ b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationMetrics.java @@ -1,4 +1,4 @@ -package com.salesforce.apollo.leyden.comm; +package com.salesforce.apollo.leyden.comm.reconcile; import com.codahale.metrics.Histogram; import com.codahale.metrics.Timer; diff --git a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationServer.java b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationServer.java similarity index 98% rename from leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationServer.java rename to leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationServer.java index 2d97b2951..e6fafd48f 100644 --- a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationServer.java +++ b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationServer.java @@ -1,14 +1,14 @@ -package com.salesforce.apollo.leyden.comm; +package com.salesforce.apollo.leyden.comm.reconcile; import com.codahale.metrics.Timer; import com.google.protobuf.Empty; +import com.salesforce.apollo.archipelago.RoutableService; +import com.salesforce.apollo.cryptography.Digest; +import com.salesforce.apollo.protocols.ClientIdentity; import com.salesforce.apollo.thoth.proto.Intervals; import com.salesforce.apollo.thoth.proto.ReconciliationGrpc; import com.salesforce.apollo.thoth.proto.Update; import com.salesforce.apollo.thoth.proto.Updating; -import com.salesforce.apollo.archipelago.RoutableService; -import com.salesforce.apollo.cryptography.Digest; -import com.salesforce.apollo.protocols.ClientIdentity; import io.grpc.stub.StreamObserver; /** diff --git a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationService.java b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationService.java similarity index 87% rename from leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationService.java rename to leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationService.java index acf0a3071..5c5a147c6 100644 --- a/leyden/src/main/java/com/salesforce/apollo/leyden/comm/ReconciliationService.java +++ b/leyden/src/main/java/com/salesforce/apollo/leyden/comm/reconcile/ReconciliationService.java @@ -1,9 +1,9 @@ -package com.salesforce.apollo.leyden.comm; +package com.salesforce.apollo.leyden.comm.reconcile; +import com.salesforce.apollo.cryptography.Digest; import com.salesforce.apollo.thoth.proto.Intervals; import com.salesforce.apollo.thoth.proto.Update; import com.salesforce.apollo.thoth.proto.Updating; -import com.salesforce.apollo.cryptography.Digest; /** * @author hal.hildebrand