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}