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

org.yamcs.commanding.CommandQueue Maven / Gradle / Ivy

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

import static org.yamcs.parameter.SystemParametersService.getPV;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.regex.Pattern;

import org.yamcs.Processor;
import org.yamcs.YamcsServer;
import org.yamcs.parameter.ParameterValue;
import org.yamcs.parameter.SystemParametersService;
import org.yamcs.protobuf.Commanding.CommandId;
import org.yamcs.protobuf.Commanding.QueueState;
import org.yamcs.protobuf.Yamcs.Value.Type;
import org.yamcs.security.Directory;
import org.yamcs.security.Group;
import org.yamcs.security.User;
import org.yamcs.xtce.EnumeratedParameterType;
import org.yamcs.xtce.MetaCommand;
import org.yamcs.xtce.Significance.Levels;
import org.yamcs.xtce.SystemParameter;

public class CommandQueue {

    private String name;
    private Set users = new HashSet<>();
    private Set groups = new HashSet<>();
    private Set tcPatterns = new HashSet<>();
    private Levels minLevel = Levels.NONE;

    private ConcurrentLinkedQueue commands = new ConcurrentLinkedQueue<>();
    QueueState defaultState;
    QueueState state;
    Processor processor;

    int nbSentCommands = 0;
    int nbRejectedCommands = 0;

    SystemParameter spQueueState, spNumSentCommands, spNumRejectedCommands, spNumCommands;

    CommandQueue(Processor channel, String name, QueueState state) {
        this.processor = channel;
        this.name = name;
        this.state = state;
        this.defaultState = state;
    }

    void setupSysParameters() {
        SystemParametersService sps = SystemParametersService.getInstance(processor.getInstance());
        spQueueState = sps.createEnumeratedSystemParameter("cmdQueue/" + name + "/state", QueueState.class,
                "The current state of this commanding queue");
        EnumeratedParameterType spQueueStateType = (EnumeratedParameterType) spQueueState.getParameterType();
        spQueueStateType.enumValue(QueueState.BLOCKED.name())
                .setDescription("Commands are held in the queue until manually released or the queue is unblocked");
        spQueueStateType.enumValue(QueueState.DISABLED.name())
                .setDescription("Commands are rejected immediately");
        spQueueStateType.enumValue(QueueState.ENABLED.name())
                .setDescription("Commands pass through the queue immediately (subject to transmission constraints)");

        spNumCommands = sps.createSystemParameter("cmdQueue/" + name + "/numCommands", Type.SINT32,
                "Number of queued commands");
        spNumSentCommands = sps.createSystemParameter("cmdQueue/" + name + "/numSentCommands", Type.UINT32,
                "The total number of commands that have been sent through this queue since Yamcs has started execution");
        spNumRejectedCommands = sps.createSystemParameter("cmdQueue/" + name + "/numRejectedCommands", Type.UINT32,
                "The total number of commands that have been rejected by this queue since Yamcs has started execution");
    }

    public String getName() {
        return name;
    }

    public Set getUsers() {
        return users;
    }

    public Set getGroups() {
        return groups;
    }

    public Set getTcPatterns() {
        return tcPatterns;
    }

    public Levels getMinLevel() {
        return minLevel;
    }

    public void setMinLevel(Levels minLevel) {
        this.minLevel = minLevel;
    }

    public void addUsers(Collection users) {
        this.users.addAll(users);
    }

    public void addGroups(Collection groups) {
        this.groups.addAll(groups);
    }

    public void addTcPatterns(Collection tcPatterns) {
        this.tcPatterns.addAll(tcPatterns);
    }

    public boolean matches(User user, MetaCommand metaCmd) {
        if (!isUserMatched(user)) {
            return false;
        }

        Levels level = Levels.NONE;

        if (metaCmd.getEffectiveDefaultSignificance() != null) {
            level = metaCmd.getEffectiveDefaultSignificance().getConsequenceLevel();
        }
        if (!isLevelMatched(level)) {
            return false;
        }
        if (!isCommandNameMatched(metaCmd.getQualifiedName())) {
            return false;
        }

        return true;
    }

    private boolean isUserMatched(User user) {
        if (users.isEmpty() && groups.isEmpty()) {
            return true;
        }

        if (users.contains(user.getName())) {
            return true;
        }

        Directory directory = YamcsServer.getServer().getSecurityStore().getDirectory();
        for (Group group : directory.getGroups(user)) {
            if (groups.contains(group.getName())) {
                return true;
            }
        }

        return false;
    }

    private boolean isLevelMatched(Levels level) {
        return minLevel == level || level.isMoreSevere(minLevel);
    }

    private boolean isCommandNameMatched(String qname) {
        if (tcPatterns.isEmpty()) {
            return true; // No filter
        }
        for (var tcPattern : tcPatterns) {
            if (tcPattern.matcher(qname).matches()) {
                return true;
            }
        }
        return false;
    }

    public QueueState getState() {
        return state;
    }

    public Processor getProcessor() {
        return processor;
    }

    public PreparedCommand[] getCommandArray() {
        return commands.toArray(new PreparedCommand[0]);
    }

    public int getCommandCount() {
        return commands.size();
    }

    public void add(ActiveCommand pc) {
        commands.add(pc);
    }

    /**
     * remove the command from the queue and return true if it has been removed
     * 
     * @param pc
     * @param isSent:
     *            true if the command has been sent, false if the command has been rejected
     * @return
     */
    public boolean remove(ActiveCommand pc, boolean isSent) {
        boolean removed = commands.remove(pc);
        if (removed) {
            if (isSent) {
                nbSentCommands++;
            } else {
                nbRejectedCommands++;
            }
        }
        return removed;
    }

    public void clear(boolean areSent) {
        int nbCommands = commands.size();
        commands.clear();
        if (areSent) {
            nbSentCommands += nbCommands;
        } else {
            nbRejectedCommands += nbCommands;
        }
    }

    public int getNbRejectedCommands() {
        return nbRejectedCommands;
    }

    public int getNbSentCommands() {
        return nbSentCommands;
    }

    void fillInSystemParameters(List params, long time) {
        params.add(getPV(spQueueState, time, state));
        params.add(getPV(spNumCommands, time, commands.size()));
        params.add(getPV(spNumSentCommands, time, nbSentCommands));
        params.add(getPV(spNumRejectedCommands, time, nbRejectedCommands));
    }

    public ActiveCommand getcommand(CommandId commandId) {
        for (ActiveCommand c : commands) {
            if (c.getCommandId().equals(commandId)) {
                return c;
            }
        }
        return null;
    }

    public ActiveCommand getcommand(String id) {
        for (ActiveCommand c : commands) {
            if (c.preparedCommand.getId().equals(id)) {
                return c;
            }
        }
        return null;
    }

    public ConcurrentLinkedQueue getCommands() {
        return commands;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy