Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat (cli): Introduce --server (still un-tested & un-documented) #300

Merged
merged 2 commits into from
Sep 30, 2023
Merged
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
41 changes: 31 additions & 10 deletions cli/src/main/java/dev/enola/cli/CommandWithModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@

import dev.enola.common.io.resource.ResourceProviders;
import dev.enola.core.EnolaServiceProvider;
import dev.enola.core.grpc.EnolaGrpcClientProvider;
import dev.enola.core.grpc.EnolaGrpcInProcess;
import dev.enola.core.meta.EntityKindRepository;
import dev.enola.core.proto.EnolaServiceGrpc.EnolaServiceBlockingStub;

import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
import picocli.CommandLine.Spec;
Expand All @@ -36,24 +38,28 @@ public abstract class CommandWithModel implements CheckedRunnable {
protected EnolaServiceProvider esp;
@Spec CommandSpec spec;

@Option(
names = {"--model"},
required = true,
description = "URI to EntityKinds (e.g. file:model.yaml)")
private URI model;
@ArgGroup(multiplicity = "1")
ModelOrServer group;

private EnolaServiceBlockingStub service;

@Override
public final void run() throws Exception {
out = spec.commandLine().getOut();

// TODO Fix design; as-is, this may stay null if --server instead of --model is used
EntityKindRepository ekr = null;

// TODO Move elsewhere for continuous ("shell") mode, as this is "expensive".
var modelResource = new ResourceProviders().getReadableResource(model);
var ekr = new EntityKindRepository();
ekr.load(modelResource);
esp = new EnolaServiceProvider();
service = new EnolaGrpcInProcess(esp.get(ekr)).getClient();
if (group.model != null) {
var modelResource = new ResourceProviders().getReadableResource(group.model);
ekr = new EntityKindRepository();
ekr.load(modelResource);
esp = new EnolaServiceProvider();
service = new EnolaGrpcInProcess(esp.get(ekr)).get();
} else if (group.server != null) {
service = new EnolaGrpcClientProvider(group.server).get();
}

run(ekr, service);
}
Expand All @@ -62,4 +68,19 @@ public final void run() throws Exception {
// here
protected abstract void run(EntityKindRepository ekr, EnolaServiceBlockingStub service)
throws Exception;

static class ModelOrServer {

@Option(
names = {"--model"},
required = true,
description = "URI to EntityKinds (e.g. file:model.yaml)")
private URI model;

@Option(
names = {"--server"},
required = true,
description = "Target of an Enola gRPC Server (e.g. localhost:7070)")
private String server;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2023 The Enola <https://enola.dev> Authors
*
* 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
*
* https://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 dev.enola.core.grpc;

import static java.util.concurrent.TimeUnit.SECONDS;

import dev.enola.core.proto.EnolaServiceGrpc;

import io.grpc.Grpc;
import io.grpc.InsecureChannelCredentials;
import io.grpc.ManagedChannel;

public class EnolaGrpcClientProvider
implements AutoCloseable { // javax.inject.Provider<EnolaServiceGrpc.EnolaServiceBlockingStub>

private final EnolaServiceGrpc.EnolaServiceBlockingStub client;
private final ManagedChannel channel;

public EnolaGrpcClientProvider(String endpoint) {
var credz = InsecureChannelCredentials.create();
channel = Grpc.newChannelBuilder(endpoint, credz).build();
client = EnolaServiceGrpc.newBlockingStub(channel).withDeadlineAfter(3, SECONDS);
}

public EnolaServiceGrpc.EnolaServiceBlockingStub get() {
return client;
}

public void close() throws Exception {
channel.shutdownNow().awaitTermination(3, SECONDS);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class EnolaGrpcInProcess implements AutoCloseable {
public class EnolaGrpcInProcess
implements AutoCloseable { // javax.inject.Provider<EnolaServiceGrpc.EnolaServiceBlockingStub>

private final EnolaService service;
private final Server server;
Expand All @@ -46,10 +47,11 @@ public EnolaGrpcInProcess(EnolaService service) throws IOException {
channelBuilder.directExecutor(); // as above
channel = channelBuilder.build();

// .withDeadlineAfter(13, SECONDS) doesn't seem to work will with InProcessChannelBuilder?!
client = EnolaServiceGrpc.newBlockingStub(channel);
}

public EnolaServiceGrpc.EnolaServiceBlockingStub getClient() {
public EnolaServiceGrpc.EnolaServiceBlockingStub get() {
return client;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.grpc.ServerBuilder;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class EnolaGrpcServer implements AutoCloseable {

Expand All @@ -46,7 +47,7 @@ public int getPort() {
}

@Override
public void close() throws Exception {
server.shutdown().awaitTermination();
public void close() throws InterruptedException {
server.shutdown().awaitTermination(7, TimeUnit.SECONDS);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

import static com.google.common.truth.Truth.assertThat;

import static java.util.concurrent.TimeUnit.SECONDS;

import dev.enola.common.io.resource.ClasspathResource;
import dev.enola.core.EnolaService;
import dev.enola.core.EnolaServiceProvider;
Expand All @@ -29,10 +27,6 @@
import dev.enola.core.proto.GetEntityRequest;
import dev.enola.core.proto.ID;

import io.grpc.Grpc;
import io.grpc.InsecureChannelCredentials;
import io.grpc.ManagedChannel;

import org.junit.Test;

public class EnolaGrpcServerTest {
Expand All @@ -43,17 +37,16 @@ public void remoting() throws Exception {
// similarly in dev.enola.demo.ServerTest
var port = enolaServer.getPort();
var endpoint = "localhost:" + port;
var credz = InsecureChannelCredentials.create();
ManagedChannel channel = Grpc.newChannelBuilder(endpoint, credz).build();
check(EnolaServiceGrpc.newBlockingStub(channel).withDeadlineAfter(3, SECONDS));
channel.shutdownNow().awaitTermination(3, SECONDS);
try (var enolaClient = new EnolaGrpcClientProvider(endpoint)) {
check(enolaClient.get());
}
}
}

@Test
public void inProcess() throws Exception {
try (var enolaServer = new EnolaGrpcInProcess(service())) {
check(enolaServer.getClient());
check(enolaServer.get());
}
}

Expand Down
2 changes: 1 addition & 1 deletion web/rest/src/test/java/dev/enola/web/rest/RestTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void getAndList() throws IOException {
var addr = new InetSocketAddress(0);
try (var server = new SunServer(addr)) {
// Setup
var testGrpcService = new EnolaGrpcInProcess(new TestService()).getClient();
var testGrpcService = new EnolaGrpcInProcess(new TestService()).get();
new RestAPI(testGrpcService).register(server);
server.start();
var rp = new ResourceProviders();
Expand Down
2 changes: 1 addition & 1 deletion web/ui-soy/src/test/java/dev/enola/web/ui/UiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class UiTest {
public void testUi() throws IOException {
var addr = new InetSocketAddress(0);
try (var server = new SunServer(addr)) {
var testGrpcService = new EnolaGrpcInProcess(new TestService()).getClient();
var testGrpcService = new EnolaGrpcInProcess(new TestService()).get();
new UI(testGrpcService).register(server);
server.start();
var rp = new ResourceProviders();
Expand Down