Add Galaxy repository API and clients
This commit is contained in:
+194
@@ -1,5 +1,7 @@
|
||||
package com.dohertylan.mxgateway.cli;
|
||||
|
||||
import com.dohertylan.mxgateway.client.DeployEventStream;
|
||||
import com.dohertylan.mxgateway.client.GalaxyRepositoryClient;
|
||||
import com.dohertylan.mxgateway.client.MxEventStream;
|
||||
import com.dohertylan.mxgateway.client.MxGatewayClient;
|
||||
import com.dohertylan.mxgateway.client.MxGatewayClientOptions;
|
||||
@@ -7,15 +9,21 @@ import com.dohertylan.mxgateway.client.MxGatewayClientVersion;
|
||||
import com.dohertylan.mxgateway.client.MxGatewaySecrets;
|
||||
import com.dohertylan.mxgateway.client.MxGatewaySession;
|
||||
import com.dohertylan.mxgateway.client.MxValues;
|
||||
import galaxy_repository.v1.GalaxyRepositoryOuterClass.DeployEvent;
|
||||
import galaxy_repository.v1.GalaxyRepositoryOuterClass.GalaxyAttribute;
|
||||
import galaxy_repository.v1.GalaxyRepositoryOuterClass.GalaxyObject;
|
||||
import com.google.protobuf.Message;
|
||||
import com.google.protobuf.util.JsonFormat;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import mxaccess_gateway.v1.MxaccessGateway.CloseSessionRequest;
|
||||
import mxaccess_gateway.v1.MxaccessGateway.MxCommandReply;
|
||||
@@ -83,9 +91,195 @@ public final class MxGatewayCli implements Callable<Integer> {
|
||||
commandLine.addSubcommand("write", new WriteCommand(clientFactory));
|
||||
commandLine.addSubcommand("stream-events", new StreamEventsCommand(clientFactory));
|
||||
commandLine.addSubcommand("smoke", new SmokeCommand(clientFactory));
|
||||
commandLine.addSubcommand("galaxy-test", new GalaxyTestConnectionCommand());
|
||||
commandLine.addSubcommand("galaxy-deploy-time", new GalaxyDeployTimeCommand());
|
||||
commandLine.addSubcommand("galaxy-discover", new GalaxyDiscoverCommand());
|
||||
commandLine.addSubcommand("galaxy-watch", new GalaxyWatchCommand());
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
abstract static class GalaxyCommand implements Callable<Integer> {
|
||||
@Mixin
|
||||
CommonOptions common = new CommonOptions();
|
||||
|
||||
@Option(names = "--json", description = "Write JSON output.")
|
||||
boolean json;
|
||||
|
||||
GalaxyRepositoryClient connect() {
|
||||
return GalaxyRepositoryClient.connect(common.resolved().toClientOptions());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(name = "galaxy-test", description = "Calls GalaxyRepository.TestConnection.")
|
||||
static final class GalaxyTestConnectionCommand extends GalaxyCommand {
|
||||
@Override
|
||||
public Integer call() {
|
||||
try (GalaxyRepositoryClient client = connect()) {
|
||||
boolean ok = client.testConnection();
|
||||
PrintWriter out = common.spec.commandLine().getOut();
|
||||
if (json) {
|
||||
Map<String, Object> output = new LinkedHashMap<>();
|
||||
output.put("command", "galaxy-test");
|
||||
output.put("options", common.redactedJsonMap());
|
||||
output.put("ok", ok);
|
||||
out.println(jsonObject(output));
|
||||
} else {
|
||||
out.println(ok);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Command(name = "galaxy-deploy-time", description = "Calls GalaxyRepository.GetLastDeployTime.")
|
||||
static final class GalaxyDeployTimeCommand extends GalaxyCommand {
|
||||
@Override
|
||||
public Integer call() {
|
||||
try (GalaxyRepositoryClient client = connect()) {
|
||||
Optional<Instant> result = client.getLastDeployTime();
|
||||
PrintWriter out = common.spec.commandLine().getOut();
|
||||
if (json) {
|
||||
Map<String, Object> output = new LinkedHashMap<>();
|
||||
output.put("command", "galaxy-deploy-time");
|
||||
output.put("options", common.redactedJsonMap());
|
||||
output.put("present", result.isPresent());
|
||||
output.put("timeOfLastDeploy", result.map(Instant::toString).orElse(""));
|
||||
out.println(jsonObject(output));
|
||||
} else if (result.isPresent()) {
|
||||
out.println(result.get());
|
||||
} else {
|
||||
out.println("(none)");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Command(name = "galaxy-discover", description = "Calls GalaxyRepository.DiscoverHierarchy.")
|
||||
static final class GalaxyDiscoverCommand extends GalaxyCommand {
|
||||
@Override
|
||||
public Integer call() {
|
||||
try (GalaxyRepositoryClient client = connect()) {
|
||||
List<GalaxyObject> objects = client.discoverHierarchy();
|
||||
PrintWriter out = common.spec.commandLine().getOut();
|
||||
if (json) {
|
||||
Map<String, Object> output = new LinkedHashMap<>();
|
||||
output.put("command", "galaxy-discover");
|
||||
output.put("options", common.redactedJsonMap());
|
||||
output.put("objects", objects.stream().map(MxGatewayCli::galaxyObjectMap).toList());
|
||||
out.println(jsonObject(output));
|
||||
} else {
|
||||
out.printf("count=%d%n", objects.size());
|
||||
for (GalaxyObject obj : objects) {
|
||||
out.printf(" %s [%s] attrs=%d%n",
|
||||
obj.getTagName(), obj.getBrowseName(), obj.getAttributesCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "galaxy-watch",
|
||||
description = "Streams GalaxyRepository.WatchDeployEvents until cancelled.")
|
||||
static final class GalaxyWatchCommand extends GalaxyCommand {
|
||||
@Option(
|
||||
names = "--last-seen-deploy-time",
|
||||
description =
|
||||
"Optional ISO-8601 instant. When supplied, the bootstrap event is suppressed if the cached"
|
||||
+ " deploy time matches.")
|
||||
String lastSeenDeployTime;
|
||||
|
||||
@Option(names = "--limit", defaultValue = "0", description = "Maximum events to print before exiting.")
|
||||
int limit;
|
||||
|
||||
@Override
|
||||
public Integer call() {
|
||||
Instant after = parseInstant(lastSeenDeployTime);
|
||||
try (GalaxyRepositoryClient client = connect();
|
||||
DeployEventStream events = client.watchDeployEvents(after)) {
|
||||
PrintWriter out = common.spec.commandLine().getOut();
|
||||
Thread shutdownHook = new Thread(events::close, "galaxy-watch-shutdown");
|
||||
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
||||
try {
|
||||
int count = 0;
|
||||
while (events.hasNext()) {
|
||||
DeployEvent event = events.next();
|
||||
if (json) {
|
||||
out.println(protoJson(event));
|
||||
} else {
|
||||
out.printf(
|
||||
"seq=%d observed=%s deployTime=%s objects=%d attributes=%d%n",
|
||||
event.getSequence(),
|
||||
formatTimestamp(event.getObservedAt()),
|
||||
event.getTimeOfLastDeployPresent()
|
||||
? formatTimestamp(event.getTimeOfLastDeploy())
|
||||
: "(none)",
|
||||
event.getObjectCount(),
|
||||
event.getAttributeCount());
|
||||
}
|
||||
out.flush();
|
||||
count++;
|
||||
if (limit > 0 && count >= limit) {
|
||||
events.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
Runtime.getRuntime().removeShutdownHook(shutdownHook);
|
||||
} catch (IllegalStateException ignored) {
|
||||
// JVM is already shutting down.
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static Instant parseInstant(String value) {
|
||||
if (value == null || value.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
return Instant.parse(value);
|
||||
}
|
||||
|
||||
private static String formatTimestamp(com.google.protobuf.Timestamp ts) {
|
||||
return Instant.ofEpochSecond(ts.getSeconds(), ts.getNanos()).toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, Object> galaxyObjectMap(GalaxyObject obj) {
|
||||
Map<String, Object> values = new LinkedHashMap<>();
|
||||
values.put("gobjectId", obj.getGobjectId());
|
||||
values.put("tagName", obj.getTagName());
|
||||
values.put("containedName", obj.getContainedName());
|
||||
values.put("browseName", obj.getBrowseName());
|
||||
values.put("parentGobjectId", obj.getParentGobjectId());
|
||||
values.put("isArea", obj.getIsArea());
|
||||
values.put("categoryId", obj.getCategoryId());
|
||||
values.put("hostedByGobjectId", obj.getHostedByGobjectId());
|
||||
values.put("templateChain", new ArrayList<>(obj.getTemplateChainList()));
|
||||
List<Map<String, Object>> attrs = new ArrayList<>();
|
||||
for (GalaxyAttribute attr : obj.getAttributesList()) {
|
||||
Map<String, Object> attrMap = new LinkedHashMap<>();
|
||||
attrMap.put("attributeName", attr.getAttributeName());
|
||||
attrMap.put("fullTagReference", attr.getFullTagReference());
|
||||
attrMap.put("mxDataType", attr.getMxDataType());
|
||||
attrMap.put("dataTypeName", attr.getDataTypeName());
|
||||
attrMap.put("isArray", attr.getIsArray());
|
||||
attrMap.put("arrayDimension", attr.getArrayDimension());
|
||||
attrMap.put("arrayDimensionPresent", attr.getArrayDimensionPresent());
|
||||
attrMap.put("mxAttributeCategory", attr.getMxAttributeCategory());
|
||||
attrMap.put("securityClassification", attr.getSecurityClassification());
|
||||
attrMap.put("isHistorized", attr.getIsHistorized());
|
||||
attrMap.put("isAlarm", attr.getIsAlarm());
|
||||
attrs.add(attrMap);
|
||||
}
|
||||
values.put("attributes", attrs);
|
||||
return values;
|
||||
}
|
||||
|
||||
@Command(name = "version", description = "Prints the Java client version.")
|
||||
public static final class VersionCommand implements Callable<Integer> {
|
||||
@Spec
|
||||
|
||||
Reference in New Issue
Block a user