@Override
  @SuppressWarnings("unchecked")
  public void handleWebSocketReceive(String connectionId, Object data) {
    Map<String, Object> message = (Map<String, Object>) data;

    String command = (String) message.get(MasterApiMessage.MASTER_API_MESSAGE_ENVELOPE_TYPE);
    Map<String, Object> commandArgs =
        (Map<String, Object>) message.get(MasterApiMessage.MASTER_API_MESSAGE_ENVELOPE_DATA);

    String requestId =
        (String) message.get(MasterApiMessage.MASTER_API_MESSAGE_ENVELOPE_REQUEST_ID);

    try {
      if (command.startsWith(MasterApiMessage.MASTER_API_COMMAND_EXTENSION_PREFIX)) {
        String extensionName =
            command.substring(MasterApiMessage.MASTER_API_COMMAND_EXTENSION_PREFIX.length());
        Map<String, Object> responseMessage =
            extensionManager.evaluateApiExtension(extensionName, commandArgs);
        responseMessage.put("command", command);
        responseMessage.put(
            MasterApiMessage.MASTER_API_MESSAGE_ENVELOPE_TYPE,
            MasterApiMessage.MASTER_API_MESSAGE_TYPE_COMMAND_RESPONSE);
        potentiallyAddRequestId(responseMessage, requestId);

        webSocketFactory.sendJson(connectionId, responseMessage);
      } else {
        MasterApiWebSocketCommandHandler handler = commandHandlers.get(command);
        if (handler != null) {
          Map<String, Object> responseMessage = handler.execute(commandArgs);
          responseMessage.put(
              MasterApiMessage.MASTER_API_MESSAGE_ENVELOPE_TYPE,
              MasterApiMessage.MASTER_API_MESSAGE_TYPE_COMMAND_RESPONSE);
          potentiallyAddRequestId(responseMessage, requestId);
          webSocketFactory.sendJson(connectionId, responseMessage);
        } else {
          spaceEnvironment
              .getLog()
              .error(
                  String.format("Master API websocket connection got unknown command %s", command));
        }
      }
    } catch (Exception e) {
      spaceEnvironment
          .getLog()
          .error(
              String.format("Error while performing Master API websocket command %s", command), e);
    }
  }
  @Override
  public void onLiveActivityRuntimeStateChange(
      String uuid, ActivityState runtimeState, String detail) {
    LiveActivity liveActivity = activityRepository.getLiveActivityByUuid(uuid);
    if (liveActivity != null) {
      Map<String, Object> data = Maps.newHashMap();

      data.put(
          MasterApiMessage.MASTER_API_PARAMETER_NAME_STATUS_TYPE,
          MasterApiMessage.MASTER_API_PARAMETER_VALUE_TYPE_STATUS_LIVE_ACTIVITY);
      data.put(MasterApiMessage.MASTER_API_PARAMETER_NAME_ENTITY_UUID, uuid);
      data.put(MasterApiMessage.MASTER_API_PARAMETER_NAME_ENTITY_ID, liveActivity.getId());
      data.put(
          MasterApiMessage.MASTER_API_PARAMETER_NAME_STATUS_RUNTIME_STATE, runtimeState.name());
      data.put(
          MasterApiMessage.MASTER_API_PARAMETER_NAME_STATUS_RUNTIME_STATE_DESCRIPTION,
          runtimeState.getDescription());
      data.put(MasterApiMessage.MASTER_API_PARAMETER_NAME_STATUS_DETAIL, detail);

      data.put(
          MasterApiMessage.MASTER_API_PARAMETER_NAME_STATUS_TIME,
          new Date(spaceEnvironment.getTimeProvider().getCurrentTime()));

      Map<String, Object> message = Maps.newHashMap();
      message.put(
          MasterApiMessage.MASTER_API_MESSAGE_ENVELOPE_TYPE,
          MasterApiMessage.MASTER_API_MESSAGE_TYPE_STATUS_UPDATE);
      message.put(MasterApiMessage.MASTER_API_MESSAGE_ENVELOPE_DATA, data);

      webSocketFactory.sendJson(message);
    } else {
      spaceEnvironment
          .getLog()
          .warn(
              String.format(
                  "Recived status update in web socket master client for unknown live activity UUID %s",
                  uuid));
    }
  }
  @Override
  public void startup() {
    int port =
        spaceEnvironment
            .getSystemConfiguration()
            .getPropertyInteger(
                MasterWebsocketManager.CONFIGURATION_MASTER_WEBSOCKET_PORT,
                MasterWebsocketManager.CONFIGURATION_MASTER_WEBSOCKET_PORT_DEFAULT);

    webServer =
        new NettyWebServer(
            "master", port, spaceEnvironment.getExecutorService(), spaceEnvironment.getLog());

    webSocketFactory =
        new BasicMultipleConnectionWebServerWebSocketHandlerFactory(
            this, spaceEnvironment.getLog());

    webServer.setWebSocketHandlerFactory("", webSocketFactory);

    webServer.startup();

    remoteSpaceControllerClient.addRemoteSpaceControllerClientListener(this);
  }
 @Override
 public void handleWebSocketClose(String connectionId) {
   spaceEnvironment.getLog().info(String.format("Closed web socket connection %s", connectionId));
 }