Search in sources :

Example 1 with HttpRoute

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);
        }
    }
}
Also used : HttpRoute(org.yamcs.api.HttpRoute) Message(com.google.protobuf.Message) ClientException(org.yamcs.client.ClientException) ExecutionException(java.util.concurrent.ExecutionException) HttpMethod(io.netty.handler.codec.http.HttpMethod) QueryStringEncoder(io.netty.handler.codec.http.QueryStringEncoder)

Example 2 with HttpRoute

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);
}
Also used : HttpRoute(org.yamcs.api.HttpRoute) WebSocketTopic(org.yamcs.api.WebSocketTopic) WebSocketTopic(org.yamcs.api.WebSocketTopic) MethodDescriptor(com.google.protobuf.Descriptors.MethodDescriptor) TypeRegistry(com.google.protobuf.util.JsonFormat.TypeRegistry) HttpRoute(org.yamcs.api.HttpRoute)

Example 3 with HttpRoute

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);
                }
            }
        }
    }
}
Also used : HttpRoute(org.yamcs.api.HttpRoute) FileDescriptorSet(com.google.protobuf.DescriptorProtos.FileDescriptorSet) ServiceDescriptorProto(com.google.protobuf.DescriptorProtos.ServiceDescriptorProto) WebSocketTopic(org.yamcs.api.WebSocketTopic) ServiceDescriptorProto(com.google.protobuf.DescriptorProtos.ServiceDescriptorProto) MethodDescriptorProto(com.google.protobuf.DescriptorProtos.MethodDescriptorProto) FileDescriptorProto(com.google.protobuf.DescriptorProtos.FileDescriptorProto) DescriptorProto(com.google.protobuf.DescriptorProtos.DescriptorProto) MethodOptions(com.google.protobuf.DescriptorProtos.MethodOptions) FileDescriptorProto(com.google.protobuf.DescriptorProtos.FileDescriptorProto) MethodDescriptorProto(com.google.protobuf.DescriptorProtos.MethodDescriptorProto)

Example 4 with HttpRoute

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);
            }
        });
    }
}
Also used : InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) AnnotationsProto(org.yamcs.api.AnnotationsProto) QueryStringEncoder(io.netty.handler.codec.http.QueryStringEncoder) Descriptor(com.google.protobuf.Descriptors.Descriptor) MethodHandler(org.yamcs.api.MethodHandler) HttpMethod(io.netty.handler.codec.http.HttpMethod) CompletableFuture(java.util.concurrent.CompletableFuture) FieldDescriptor(com.google.protobuf.Descriptors.FieldDescriptor) Instant(java.time.Instant) YamcsClient(org.yamcs.client.YamcsClient) Timestamp(com.google.protobuf.Timestamp) ByteString(com.google.protobuf.ByteString) URLEncoder(java.net.URLEncoder) List(java.util.List) Duration(com.google.protobuf.Duration) Matcher(java.util.regex.Matcher) HttpBody(org.yamcs.api.HttpBody) Entry(java.util.Map.Entry) HttpRoute(org.yamcs.api.HttpRoute) Message(com.google.protobuf.Message) MethodDescriptor(com.google.protobuf.Descriptors.MethodDescriptor) Pattern(java.util.regex.Pattern) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Observer(org.yamcs.api.Observer) Message(com.google.protobuf.Message) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) HttpBody(org.yamcs.api.HttpBody) ByteString(com.google.protobuf.ByteString) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) FieldDescriptor(com.google.protobuf.Descriptors.FieldDescriptor) HttpRoute(org.yamcs.api.HttpRoute) Observer(org.yamcs.api.Observer) QueryStringEncoder(io.netty.handler.codec.http.QueryStringEncoder) HttpMethod(io.netty.handler.codec.http.HttpMethod)

Aggregations

HttpRoute (org.yamcs.api.HttpRoute)4 MethodDescriptor (com.google.protobuf.Descriptors.MethodDescriptor)2 Message (com.google.protobuf.Message)2 HttpMethod (io.netty.handler.codec.http.HttpMethod)2 QueryStringEncoder (io.netty.handler.codec.http.QueryStringEncoder)2 WebSocketTopic (org.yamcs.api.WebSocketTopic)2 ByteString (com.google.protobuf.ByteString)1 DescriptorProto (com.google.protobuf.DescriptorProtos.DescriptorProto)1 FileDescriptorProto (com.google.protobuf.DescriptorProtos.FileDescriptorProto)1 FileDescriptorSet (com.google.protobuf.DescriptorProtos.FileDescriptorSet)1 MethodDescriptorProto (com.google.protobuf.DescriptorProtos.MethodDescriptorProto)1 MethodOptions (com.google.protobuf.DescriptorProtos.MethodOptions)1 ServiceDescriptorProto (com.google.protobuf.DescriptorProtos.ServiceDescriptorProto)1 Descriptor (com.google.protobuf.Descriptors.Descriptor)1 FieldDescriptor (com.google.protobuf.Descriptors.FieldDescriptor)1 Duration (com.google.protobuf.Duration)1 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)1 Timestamp (com.google.protobuf.Timestamp)1 TypeRegistry (com.google.protobuf.util.JsonFormat.TypeRegistry)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1