001package jmri.server.json.throttle;
002
003import static jmri.server.json.JSON.NAME;
004import static jmri.server.json.throttle.JsonThrottle.THROTTLE;
005
006import com.fasterxml.jackson.databind.JsonNode;
007import com.fasterxml.jackson.databind.node.ObjectNode;
008import java.io.IOException;
009import java.util.HashMap;
010import java.util.HashSet;
011import javax.servlet.http.HttpServletResponse;
012import jmri.JmriException;
013import jmri.server.json.JsonConnection;
014import jmri.server.json.JsonException;
015import jmri.server.json.JsonRequest;
016import jmri.server.json.JsonSocketService;
017import org.slf4j.Logger;
018import org.slf4j.LoggerFactory;
019
020/**
021 *
022 * @author Randall Wood
023 */
024public class JsonThrottleSocketService extends JsonSocketService<JsonThrottleHttpService> {
025
026    private final HashMap<String, JsonThrottle> throttles = new HashMap<>();
027    private final HashMap<JsonThrottle, String> throttleIds = new HashMap<>();
028    private static final Logger log = LoggerFactory.getLogger(JsonThrottleSocketService.class);
029
030    public JsonThrottleSocketService(JsonConnection connection) {
031        super(connection, new JsonThrottleHttpService(connection.getObjectMapper()));
032    }
033
034    @Override
035    public void onMessage(String type, JsonNode data, JsonRequest request) throws IOException, JmriException, JsonException {
036        log.debug("Processing {}", data);
037        String name = data.path(NAME).asText();
038        if (name.isEmpty()) {
039            name = data.path(THROTTLE).asText();
040            log.warn("JSON throttle \"{}\" requested using \"throttle\" instead of \"name\"", name);
041        }
042        if (name.isEmpty()) {
043            throw new JsonException(HttpServletResponse.SC_BAD_REQUEST, Bundle.getMessage(request.locale, "ErrorThrottleId"), request.id); // NOI18N
044        }
045        JsonThrottle throttle = throttles.get(name);
046        if (!throttles.containsKey(name)) {
047            throttle = JsonThrottle.getThrottle(name, data, this, request.id);
048            throttles.put(name, throttle);
049            throttleIds.put(throttle, name);
050            throttle.sendStatus(this);
051        }
052        throttle.onMessage(request.locale, data, this);
053    }
054
055    @Override
056    public void onList(String type, JsonNode data, JsonRequest request) throws JsonException {
057        throw new JsonException(HttpServletResponse.SC_BAD_REQUEST, Bundle.getMessage(request.locale, "UnlistableService", type), request.id);
058    }
059
060    @Override
061    public void onClose() {
062        new HashSet<>(throttles.keySet()).stream().forEach(throttleId -> {
063            throttles.get(throttleId).close(this, false);
064            throttles.remove(throttleId);
065        });
066        throttleIds.clear();
067    }
068
069    void release(JsonThrottle throttle) {
070        throttle.release(this, true);
071        throttles.remove(throttleIds.get(throttle));
072        throttleIds.remove(throttle);
073    }
074
075    public void sendMessage(JsonThrottle throttle, ObjectNode data) throws IOException {
076        String id = throttleIds.get(throttle);
077        if (id != null) {
078            data.put(NAME, id);
079            data.put(THROTTLE, id);
080            connection.sendMessage(service.message(THROTTLE, data, 0), 0);
081        }
082    }
083
084}