use of org.yamcs.api.HttpRoute in project yamcs by yamcs.
the class ClientStreamingObserver method next.
@Override
public synchronized void next(Message message) {
// Synchronize so that sender is available after the first request
if (sender == null) {
HttpRoute route = method.getOptions().getExtension(AnnotationsProto.route);
// Holder for extracting route and query params
Message.Builder partial = message.toBuilder();
HttpMethod httpMethod = HttpMethodHandler.getMethod(route);
String uriTemplate = HttpMethodHandler.getPattern(route);
QueryStringEncoder uri = HttpMethodHandler.resolveUri(uriTemplate, message, method.getInputType(), partial);
message = partial.buildPartial();
try {
sender = baseClient.doBulkSendRequest(uri.toString(), httpMethod).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
cancel(e.getCause());
}
} else {
// First message is always the initial request setup (no payload)
if (bodyField != null) {
message = (Message) message.getField(bodyField);
}
try {
sender.sendData(delimit(message));
} catch (ClientException e) {
cancel(e);
}
}
}
use of org.yamcs.api.HttpRoute in project yamcs by yamcs.
the class HttpServer method addApi.
public void addApi(Api<Context> api) {
apis.add(api);
for (MethodDescriptor method : api.getDescriptorForType().getMethods()) {
RpcDescriptor descriptor = protobufRegistry.getRpc(method.getFullName());
if (descriptor == null) {
throw new UnsupportedOperationException("Unable to find rpc definition: " + method.getFullName());
}
if (WEBSOCKET_ROUTE.equals(descriptor.getHttpRoute())) {
topics.add(new Topic(api, descriptor.getWebSocketTopic(), descriptor));
for (WebSocketTopic topic : descriptor.getAdditionalWebSocketTopics()) {
topics.add(new Topic(api, topic, descriptor));
}
} else {
routes.add(new Route(api, descriptor.getHttpRoute(), descriptor, metricRegistry));
for (HttpRoute route : descriptor.getAdditionalHttpRoutes()) {
routes.add(new Route(api, route, descriptor, metricRegistry));
}
}
}
// Regenerate JSON converters with type support (needed for the "Any" type)
TypeRegistry.Builder typeRegistryb = TypeRegistry.newBuilder();
typeRegistryb.add(CancelOptions.getDescriptor());
typeRegistryb.add(Reply.getDescriptor());
apis.forEach(a -> typeRegistryb.add(a.getDescriptorForType().getFile().getMessageTypes()));
TypeRegistry typeRegistry = typeRegistryb.build();
jsonParser = JsonFormat.parser().usingTypeRegistry(typeRegistry);
jsonPrinter = JsonFormat.printer().usingTypeRegistry(typeRegistry);
// Sort in a way that increases chances of a good URI match
Collections.sort(routes);
}
use of org.yamcs.api.HttpRoute in project yamcs by yamcs.
the class ProtobufRegistry method importDefinitions.
public void importDefinitions(InputStream in) throws IOException {
if (in == null) {
throw new NullPointerException("input stream cannot be null");
}
FileDescriptorSet proto = FileDescriptorSet.parseFrom(in, extensionRegistry);
// Index all messages by fully-qualified protobuf name
for (FileDescriptorProto file : proto.getFileList()) {
scanComments(file);
String javaPackage = file.getOptions().getJavaPackage();
javaPackages.put(file.getName(), javaPackage);
for (DescriptorProto messageType : file.getMessageTypeList()) {
String qname = file.getPackage() + "." + messageType.getName();
messageTypes.put(qname, messageType);
}
}
// Index RPCs
for (FileDescriptorProto file : proto.getFileList()) {
for (ServiceDescriptorProto service : file.getServiceList()) {
for (MethodDescriptorProto method : service.getMethodList()) {
MethodOptions options = method.getOptions();
String serviceName = service.getName();
String methodName = method.getName();
DescriptorProto inputType = messageTypes.get(method.getInputType().substring(1));
DescriptorProto outputType = messageTypes.get(method.getOutputType().substring(1));
if (options.hasExtension(AnnotationsProto.route)) {
HttpRoute route = options.getExtension(AnnotationsProto.route);
RpcDescriptor descriptor = new RpcDescriptor(serviceName, methodName, inputType, outputType, route);
String qname = String.join(".", file.getPackage(), serviceName, methodName);
rpcs.put(qname, descriptor);
} else if (options.hasExtension(AnnotationsProto.websocket)) {
WebSocketTopic topic = options.getExtension(AnnotationsProto.websocket);
RpcDescriptor descriptor = new RpcDescriptor(serviceName, methodName, inputType, outputType, topic);
String qname = String.join(".", file.getPackage(), serviceName, methodName);
rpcs.put(qname, descriptor);
}
}
}
}
}
use of org.yamcs.api.HttpRoute in project yamcs by yamcs.
the class HttpMethodHandler method call.
@Override
@SuppressWarnings("unchecked")
public void call(MethodDescriptor method, Message request, Message responsePrototype, Observer<? extends Message> observer) {
HttpRoute route = method.getOptions().getExtension(AnnotationsProto.route);
// Holder for extracting route and query params
Message.Builder partial = request.toBuilder();
String template = getPattern(route);
QueryStringEncoder uri = resolveUri(template, request, method.getInputType(), partial);
Message body = null;
if (route.hasBody()) {
if ("*".equals(route.getBody())) {
body = partial.buildPartial();
} else {
FieldDescriptor bodyField = method.getInputType().findFieldByName(route.getBody());
if (!request.hasField(bodyField)) {
throw new IllegalArgumentException("Request message must have the field '" + route.getBody() + "' set");
}
body = (Message) request.getField(bodyField);
partial.clearField(bodyField);
}
}
HttpMethod httpMethod = getMethod(route);
if (method.toProto().getServerStreaming()) {
BulkRestDataReceiver receiver = data -> {
try {
Message serverMessage = responsePrototype.toBuilder().mergeFrom(data).build();
((Observer<Message>) observer).next(serverMessage);
} catch (InvalidProtocolBufferException e) {
throw new IllegalArgumentException(e);
}
};
CompletableFuture<Void> future;
if (body == null) {
future = baseClient.doBulkRequest(httpMethod, uri.toString(), receiver);
} else if (body instanceof HttpBody) {
byte[] data = ((HttpBody) body).getData().toByteArray();
future = baseClient.doBulkRequest(httpMethod, uri.toString(), data, receiver);
} else {
future = baseClient.doBulkRequest(httpMethod, uri.toString(), body.toByteArray(), receiver);
}
future.whenComplete((v, err) -> {
if (err == null) {
observer.complete();
} else {
observer.completeExceptionally(err);
}
});
} else {
CompletableFuture<byte[]> requestFuture;
if (body == null) {
appendQueryString(uri, partial.build(), method.getInputType());
requestFuture = baseClient.doRequest(uri.toString(), httpMethod);
} else if (body instanceof HttpBody) {
byte[] data = ((HttpBody) body).getData().toByteArray();
requestFuture = baseClient.doRequest(uri.toString(), httpMethod, data);
} else {
requestFuture = baseClient.doRequest(uri.toString(), httpMethod, body);
}
requestFuture.whenComplete((data, err) -> {
if (err == null) {
if (responsePrototype instanceof HttpBody) {
Message serverMessage = HttpBody.newBuilder().setData(ByteString.copyFrom(data)).build();
((Observer<Message>) observer).complete(serverMessage);
} else {
try {
Message serverMessage = responsePrototype.toBuilder().mergeFrom(data).build();
((Observer<Message>) observer).complete(serverMessage);
} catch (Exception e) {
observer.completeExceptionally(e);
}
}
} else {
observer.completeExceptionally(err);
}
});
}
}
Aggregations