Skip to content

Commit 0cfda31

Browse files
authored
Merge pull request #6 from cloudquery/mnorbury-adding-cli-skeleton
Adding initial CLI structure
2 parents 4931cec + d2f202e commit 0cfda31

File tree

18 files changed

+312
-86
lines changed

18 files changed

+312
-86
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ replay_pid*
2828
.DS_Store
2929
# Ignore Gradle build output directory
3030
build
31+
32+
# Intellij
33+
.idea

lib/build.gradle

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
plugins {
22
id 'java-library'
3+
id "io.freefair.lombok" version "8.1.0"
34
}
45

56
repositories {
@@ -19,9 +20,12 @@ dependencies {
1920

2021
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
2122
implementation 'com.google.guava:guava:31.1-jre'
23+
implementation 'info.picocli:picocli:4.7.4'
24+
implementation 'com.google.guava:guava:31.1-jre'
2225
implementation "io.grpc:grpc-protobuf:1.57.0"
2326
implementation "io.grpc:grpc-stub:1.57.0"
2427
implementation "io.grpc:grpc-services:1.57.0"
28+
implementation "io.grpc:grpc-testing:1.15.1"
2529
implementation 'com.cloudquery:plugin-pb-java:0.0.2'
2630
}
2731

@@ -38,6 +42,6 @@ testing {
3842
// Apply a specific Java toolchain to ease working on different environments.
3943
java {
4044
toolchain {
41-
languageVersion = JavaLanguageVersion.of(18)
45+
languageVersion = JavaLanguageVersion.of(20)
4246
}
4347
}

lib/src/main/java/cloudquery/plugin/sdk/DiscoveryServer.java

-29
This file was deleted.

lib/src/main/java/cloudquery/plugin/sdk/PluginServer.java

-29
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.cloudquery.internal.servers.discovery.v1;
2+
3+
import cloudquery.discovery.v1.DiscoveryGrpc.DiscoveryImplBase;
4+
import cloudquery.discovery.v1.DiscoveryOuterClass.GetVersions.Request;
5+
import cloudquery.discovery.v1.DiscoveryOuterClass.GetVersions.Response;
6+
import io.grpc.stub.StreamObserver;
7+
8+
import java.util.List;
9+
10+
public class DiscoverServer extends DiscoveryImplBase {
11+
private final List<Integer> versions;
12+
13+
public DiscoverServer(List<Integer> versions) {
14+
this.versions = versions;
15+
}
16+
17+
@Override
18+
public void getVersions(Request request, StreamObserver<Response> responseObserver) {
19+
responseObserver.onNext(Response.newBuilder().addAllVersions(versions).build());
20+
responseObserver.onCompleted();
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.cloudquery.internal.servers.plugin.v3;
2+
3+
import cloudquery.plugin.v3.PluginGrpc.PluginImplBase;
4+
import io.cloudquery.plugin.Plugin;
5+
6+
public class PluginServer extends PluginImplBase {
7+
private final Plugin plugin;
8+
9+
public PluginServer(Plugin plugin) {
10+
this.plugin = plugin;
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.cloudquery.plugin;
2+
3+
import lombok.Builder;
4+
import lombok.Getter;
5+
import lombok.NonNull;
6+
7+
@Builder(builderMethodName = "innerBuilder")
8+
@Getter
9+
public class Plugin {
10+
public static PluginBuilder builder(String name, String version) {
11+
return innerBuilder().name(name).verion(version);
12+
}
13+
14+
@NonNull
15+
private final String name;
16+
@NonNull
17+
private final String verion;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.cloudquery.server;
2+
3+
import picocli.CommandLine.ITypeConverter;
4+
5+
public class AddressConverter implements ITypeConverter<AddressConverter.Address> {
6+
public static class AddressParseException extends RuntimeException {
7+
8+
}
9+
public record Address(String host, int port) {
10+
}
11+
12+
@Override
13+
public Address convert(String rawAddress) throws Exception {
14+
String[] components = rawAddress.split(":");
15+
if (components.length != 2) {
16+
throw new AddressParseException();
17+
}
18+
return new Address(components[0], Integer.parseInt(components[1]));
19+
}
20+
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.cloudquery.server;
2+
3+
import picocli.CommandLine;
4+
5+
@CommandLine.Command
6+
public class DocCommand {
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.cloudquery.server;
2+
3+
import io.cloudquery.plugin.Plugin;
4+
import lombok.AccessLevel;
5+
import lombok.Builder;
6+
import lombok.NonNull;
7+
import picocli.CommandLine;
8+
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
12+
@Builder(access = AccessLevel.PUBLIC)
13+
public class PluginServe {
14+
@NonNull
15+
private final Plugin plugin;
16+
@Builder.Default
17+
private List<String> args = new ArrayList<>();
18+
private boolean destinationV0V1Server;
19+
private String sentryDSN;
20+
private boolean testListener;
21+
//TODO: Allow a test listener to be passed in
22+
// testListenerConn *bufconn.Listener
23+
24+
public void Serve() throws ServerException {
25+
int exitStatus = new CommandLine(new RootCommand()).
26+
addSubcommand("serve", new ServeCommand(plugin)).
27+
addSubcommand("doc", new DocCommand()).
28+
execute(args.toArray(new String[]{}));
29+
if (exitStatus != 0) {
30+
throw new ServerException("error processing command line exit status = "+exitStatus);
31+
}
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.cloudquery.server;
2+
3+
import picocli.CommandLine;
4+
5+
@CommandLine.Command
6+
public class RootCommand {
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package io.cloudquery.server;
2+
3+
import io.cloudquery.internal.servers.discovery.v1.DiscoverServer;
4+
import io.cloudquery.internal.servers.plugin.v3.PluginServer;
5+
import io.cloudquery.plugin.Plugin;
6+
import io.cloudquery.server.AddressConverter.Address;
7+
import io.grpc.Grpc;
8+
import io.grpc.InsecureServerCredentials;
9+
import io.grpc.Server;
10+
import io.grpc.protobuf.services.ProtoReflectionService;
11+
import lombok.ToString;
12+
13+
import java.util.List;
14+
import java.util.concurrent.Callable;
15+
import java.util.concurrent.Executors;
16+
import java.util.logging.Level;
17+
import java.util.logging.Logger;
18+
19+
import static picocli.CommandLine.Command;
20+
import static picocli.CommandLine.Option;
21+
22+
@Command
23+
@ToString
24+
public class ServeCommand implements Callable<Integer> {
25+
private static final Logger logger = Logger.getLogger(ServeCommand.class.getName());
26+
public static final List<Integer> DISCOVERY_VERSIONS = List.of(3);
27+
28+
@Option(names = "--address", converter = AddressConverter.class, description = "address to serve on. can be tcp: localhost:7777 or unix socket: `/tmp/plugin.rpc.sock` (default \"${DEFAULT-VALUE}\")")
29+
private Address address = new Address("localhost", 7777);
30+
31+
@Option(names = "--log-format", description = "log format. one of: text,json (default \"${DEFAULT-VALUE}\")")
32+
private String logFormat = "text";
33+
34+
@Option(names = "--log-level", description = "log level. one of: trace,debug,info,warn,error (default \"${DEFAULT-VALUE}\")")
35+
private String logLevel = "info";
36+
37+
@Option(names = "--network", description = "the network must be \"tcp\", \"tcp4\", \"tcp6\", \"unix\" or \"unixpacket\" (default \"${DEFAULT-VALUE}\")")
38+
private String network = "tcp";
39+
40+
@Option(names = "--disable-sentry", description = "disable sentry")
41+
private Boolean disableSentry = false;
42+
43+
@Option(names = "--otel-endpoint", description = "Open Telemetry HTTP collector endpoint")
44+
private String otelEndpoint = "";
45+
46+
@Option(names = "--otel-endpoint-insecure", description = "use Open Telemetry HTTP endpoint (for development only)")
47+
private Boolean otelEndpointInsecure = false;
48+
49+
private final Plugin plugin;
50+
51+
public ServeCommand(Plugin plugin) {
52+
this.plugin = plugin;
53+
}
54+
55+
@Override
56+
public Integer call() throws Exception {
57+
// Initialize a logger
58+
59+
// Configure open telemetry
60+
61+
// Configure test listener
62+
63+
// Configure gRPC server
64+
Server server = Grpc.newServerBuilderForPort(address.port(), InsecureServerCredentials.create()).
65+
addService(new DiscoverServer(DISCOVERY_VERSIONS)).
66+
addService(new PluginServer(plugin)).
67+
addService(ProtoReflectionService.newInstance()).
68+
executor(Executors.newFixedThreadPool(10)).
69+
build();
70+
71+
// Configure sentry
72+
73+
// Log we are listening on address and port
74+
75+
// Run gRPC server and block
76+
server.start();
77+
logger.log(Level.INFO, "Started server on {0}", address);
78+
server.awaitTermination();
79+
return 0;
80+
}
81+
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.cloudquery.server;
2+
3+
public class ServerException extends Exception {
4+
public ServerException(String message) {
5+
super(message);
6+
}
7+
}

lib/src/test/java/cloudquery/plugin/sdk/DiscoveryServerTest.java

-13
This file was deleted.

lib/src/test/java/cloudquery/plugin/sdk/PluginServerTest.java

-13
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package io.cloudquery.server;
2+
3+
import io.cloudquery.server.AddressConverter.Address;
4+
import org.junit.Assert;
5+
import org.junit.Before;
6+
import org.junit.Test;
7+
8+
import static org.junit.Assert.assertEquals;
9+
10+
public class AddressTest {
11+
12+
private AddressConverter addressConverter;
13+
14+
@Before
15+
public void setUp() {
16+
addressConverter = new AddressConverter();
17+
}
18+
19+
@Test
20+
public void shouldParseAddressFromString() throws Exception {
21+
String rawAddress = "127.0.0.1:12345";
22+
23+
Address address = addressConverter.convert(rawAddress);
24+
25+
assertEquals(new Address("127.0.0.1", 12345), address);
26+
}
27+
28+
@Test
29+
public void shouldThrowExceptionIfAddressNotFormattedCorrectly() {
30+
String rawAddress = "bad address";
31+
32+
AddressConverter addressConverter = new AddressConverter();
33+
34+
Assert.assertThrows(AddressConverter.AddressParseException.class, () -> addressConverter.convert(rawAddress));
35+
}
36+
}

0 commit comments

Comments
 (0)