package de.rwth.idsg.bikeman.web.rest; import com.google.common.base.Optional; import de.rwth.idsg.bikeman.ixsi.store.WebSocketSessionStore; import de.rwth.idsg.bikeman.ixsi.store.AvailabilityStore; import de.rwth.idsg.bikeman.ixsi.store.BookingAlertStore; import de.rwth.idsg.bikeman.ixsi.store.ConsumptionStore; import de.rwth.idsg.bikeman.ixsi.store.ExternalBookingStore; import de.rwth.idsg.bikeman.ixsi.store.PlaceAvailabilityStore; import de.rwth.idsg.bikeman.web.rest.dto.monitor.EndpointDTO; import de.rwth.idsg.bikeman.web.rest.dto.monitor.StoreDTO; import de.rwth.idsg.bikeman.web.rest.dto.monitor.StoreItem; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.WebSocketSession; import xjc.schema.ixsi.BookingTargetIDType; import xjc.schema.ixsi.UserInfoType; import java.io.IOException; import java.util.ArrayList; import java.util.Deque; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** * Created by max on 15/07/15. */ @RestController @RequestMapping(value = "api/", produces = MediaType.APPLICATION_JSON_VALUE) @Slf4j public class MonitorResource { @Autowired private WebSocketSessionStore webSocketSessionStore; @Autowired private AvailabilityStore availabilityStore; @Autowired private ConsumptionStore consumptionStore; @Autowired private ExternalBookingStore externalBookingStore; @Autowired private PlaceAvailabilityStore placeAvailabilityStore; @Autowired private BookingAlertStore bookingAlertStore; private static final String BASE_PATH = "monitor/"; private static final String IXSI_SESSION_STATUS = "monitor/session-status"; private static final String IXSI_SESSION_KILL = "monitor/session/{systemId}/{sessionId}"; private static final String IXSI_STORE_LIST = "monitor/store-list"; private static final String IXSI_STORE_AVAIL = "monitor/store/avail"; private static final String IXSI_STORE_PLACE_AVAIL = "monitor/store/place-avail"; private static final String IXSI_STORE_CONSUMPTION = "monitor/store/consumption"; private static final String IXSI_STORE_EX_BOOK = "monitor/store/external-book"; private static final String IXSI_STORE_BOOKING_ALERT = "monitor/store/booking-alert"; private static final String AVAILABILITY_STORE = "Availability Store"; private static final String PLACE_AVAILABILITY_STORE = "Place Availability Store"; private static final String CONSUMPTION_STORE = "Consumption Store"; private static final String EXTERNAL_BOOKING_STORE = "External Booking Store"; private static final String BOOKING_ALERT_STORE = "Booking Alert Store"; private static final String PLACE_AVAILABILITY_DESCR = "Place Id"; private static final String CONSUMPTION_DESCR = "Booking Id"; private static final String BOOKING_ALERT_DESCR = "Booking Id"; @RequestMapping(value = IXSI_SESSION_STATUS, method = RequestMethod.GET) public List<EndpointDTO> getSessionStatus() { log.debug("REST request for {} data", IXSI_SESSION_STATUS); List<EndpointDTO> endPoints = new ArrayList<>(); Map<String, Deque<WebSocketSession>> sessionMap = webSocketSessionStore.getLookupTable(); for (Map.Entry<String, Deque<WebSocketSession>> entry : sessionMap.entrySet()) { for (WebSocketSession sess : entry.getValue()) { EndpointDTO endPoint = new EndpointDTO(); endPoint.setSystemId(entry.getKey()); endPoint.setSessionId(sess.getId()); endPoint.setOpen(sess.isOpen()); endPoints.add(endPoint); } } return endPoints; } @RequestMapping(value = IXSI_STORE_LIST, method = RequestMethod.GET) public List<StoreDTO> getStoreList() { List<StoreDTO> stores = new ArrayList<>(); StoreDTO avail = new StoreDTO(); avail.setName(AVAILABILITY_STORE); avail.setLinkName(IXSI_STORE_AVAIL.substring(IXSI_STORE_AVAIL.lastIndexOf('/')+1)); stores.add(avail); StoreDTO place = new StoreDTO(); place.setName(PLACE_AVAILABILITY_STORE); place.setLinkName(IXSI_STORE_PLACE_AVAIL.substring(IXSI_STORE_PLACE_AVAIL.lastIndexOf('/')+1)); stores.add(place); StoreDTO cons = new StoreDTO(); cons.setName(CONSUMPTION_STORE); cons.setLinkName(IXSI_STORE_CONSUMPTION.substring(IXSI_STORE_CONSUMPTION.lastIndexOf('/')+1)); stores.add(cons); StoreDTO ext = new StoreDTO(); ext.setName(EXTERNAL_BOOKING_STORE); ext.setLinkName(IXSI_STORE_EX_BOOK.substring(IXSI_STORE_EX_BOOK.lastIndexOf('/')+1)); stores.add(ext); StoreDTO balert = new StoreDTO(); balert.setName(BOOKING_ALERT_STORE); balert.setLinkName(IXSI_STORE_BOOKING_ALERT.substring(IXSI_STORE_BOOKING_ALERT.lastIndexOf('/')+1)); stores.add(balert); return stores; } @RequestMapping(value = IXSI_STORE_AVAIL, method = RequestMethod.GET) public StoreDTO<BookingTargetIDType> getAvailabilityStore() { log.debug("REST request for {} data", IXSI_STORE_AVAIL); StoreDTO<BookingTargetIDType> avail = new StoreDTO<>(); avail.setName(AVAILABILITY_STORE); avail.setItemDescription(BookingTargetIDType.class.getSimpleName()); avail.setItems(itemMapToList(availabilityStore.getLookupTable())); avail.setSize(avail.getItems().size()); return avail; } @RequestMapping(value = IXSI_STORE_PLACE_AVAIL, method = RequestMethod.GET) public StoreDTO<String> getPlaceAvailabilityStore() { log.debug("REST request for {} data", IXSI_STORE_PLACE_AVAIL); StoreDTO<String> pAvail = new StoreDTO<>(); pAvail.setName(PLACE_AVAILABILITY_STORE); pAvail.setItemDescription(PLACE_AVAILABILITY_DESCR); pAvail.setItems(itemMapToList(placeAvailabilityStore.getLookupTable())); pAvail.setSize(pAvail.getItems().size()); return pAvail; } @RequestMapping(value = IXSI_STORE_CONSUMPTION, method = RequestMethod.GET) public StoreDTO<String> getConsumptionStore() { log.debug("REST request for {} data", IXSI_STORE_CONSUMPTION); StoreDTO<String> cons = new StoreDTO<>(); cons.setName(CONSUMPTION_STORE); cons.setItemDescription(CONSUMPTION_DESCR); cons.setItems(itemMapToList(consumptionStore.getLookupTable())); cons.setSize(cons.getItems().size()); return cons; } @RequestMapping(value = IXSI_STORE_EX_BOOK, method = RequestMethod.GET) public StoreDTO<UserInfoType> getExternalBookingStore() { log.debug("REST request for {} data", IXSI_STORE_EX_BOOK); StoreDTO<UserInfoType> exBook = new StoreDTO<>(); exBook.setName(EXTERNAL_BOOKING_STORE); exBook.setItemDescription(UserInfoType.class.getSimpleName()); exBook.setItems(itemMapToList(externalBookingStore.getLookupTable())); exBook.setSize(exBook.getItems().size()); return exBook; } @RequestMapping(value = IXSI_STORE_BOOKING_ALERT, method = RequestMethod.GET) public StoreDTO<String> getBookingAlertStore() { log.debug("REST request for {} data", IXSI_STORE_BOOKING_ALERT); StoreDTO<String> alertStore = new StoreDTO<>(); alertStore.setName(BOOKING_ALERT_STORE); alertStore.setItemDescription(BOOKING_ALERT_DESCR); alertStore.setItems(itemMapToList(bookingAlertStore.getLookupTable())); alertStore.setSize(alertStore.getItems().size()); return alertStore; } @RequestMapping(value = IXSI_SESSION_KILL, method = RequestMethod.PUT) public void killSession(@PathVariable String systemId, @PathVariable String sessionId) { Optional<WebSocketSession> optional = webSocketSessionStore.get(systemId, sessionId); if (optional.isPresent()) { WebSocketSession session = optional.get(); if (session.isOpen()) { try { session.close(new CloseStatus(1000, "User requested disconnection")); } catch (IOException e) { throw new RuntimeException("Failed to close the session", e); } } } } private <T> List<StoreItem<T>> itemMapToList(Map<T, Set<String>> map) { List<StoreItem<T>> items = new ArrayList<>(); for (Map.Entry<T, Set<String>> entry : map.entrySet()) { items.addAll(entry.getValue() .stream() .map(system -> new StoreItem<>(system, entry.getKey())) .collect(Collectors.toList())); } return items; } }