All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yamcs.actions.ActionHelper Maven / Gradle / Ivy

There is a newer version: 5.10.9
Show newest version
package org.yamcs.actions;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

import org.yamcs.ValidationException;
import org.yamcs.actions.Action.ActionStyle;
import org.yamcs.api.Observer;
import org.yamcs.http.BadRequestException;
import org.yamcs.http.HttpException;
import org.yamcs.http.InternalServerErrorException;
import org.yamcs.http.api.ConfigApi;
import org.yamcs.protobuf.actions.ActionInfo;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Struct;
import com.google.protobuf.util.JsonFormat;

public class ActionHelper {

    private static final Type HASHMAP_TYPE = new TypeToken>() {
    }.getType();

    public static ActionInfo toActionInfo(Action action) {
        return toActionInfo(action, true);
    }

    public static ActionInfo toActionInfo(Action action, boolean addSpec) {
        var b = ActionInfo.newBuilder()
                .setId(action.getId())
                .setLabel(action.getLabel())
                .setStyle(action.getStyle().name())
                .setEnabled(action.isEnabled());
        if (action.getStyle() == ActionStyle.CHECK_BOX) {
            b.setChecked(action.isChecked());
        }
        var spec = action.getSpec();
        if (spec != null && !spec.getOptions().isEmpty()) {
            b.setSpec(ConfigApi.toSpecInfo(spec));
        }
        return b.build();
    }

    /**
     * Run an action on a target.
     */
    public static  void runAction(T target, Action action, Struct options,
            Observer responseObserver) throws HttpException {
        var gson = new Gson();
        JsonObject actionMessage = null;
        Map actionOptions = null;
        try {
            String json = JsonFormat.printer().print(options);
            actionMessage = gson.fromJson(json, JsonElement.class).getAsJsonObject();

            actionOptions = gson.fromJson(actionMessage, HASHMAP_TYPE);
        } catch (InvalidProtocolBufferException e) {
            // Should not happen, it's already been converted from JSON through transcoding
            throw new InternalServerErrorException(e);
        }

        if (!action.isEnabled()) {
            throw new BadRequestException("Action '" + action.getId() + "' is not enabled");
        }

        var spec = action.getSpec();
        if (spec != null) {
            try {
                // Validate, and apply defaults
                actionOptions = spec.validate(actionOptions);
                actionMessage = gson.toJsonTree(actionOptions, HASHMAP_TYPE).getAsJsonObject();
            } catch (ValidationException e) {
                throw new BadRequestException(e.getMessage());
            }
        }

        var actionResult = new ActionResult();
        action.execute(target, actionMessage, actionResult);
        actionResult.future().whenComplete((response, t) -> {
            if (t != null) {
                responseObserver.completeExceptionally(t);
            } else {
                if (response == null) {
                    responseObserver.next(Struct.getDefaultInstance());
                } else {
                    var json = response.toString();
                    var responseb = Struct.newBuilder();
                    try {
                        JsonFormat.parser().merge(json, responseb);
                    } catch (InvalidProtocolBufferException e) {
                        throw new InternalServerErrorException(e);
                    }
                    responseObserver.next(responseb.build());
                }
            }
        });
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy