Fix wrong websocket topics (#3223)

* Fix wrong websocket topics

The topics of the websocket event did not follow the openHAB convention of starting with `openhab/` followed by the component.

Signed-off-by: Jan N. Klug <github@klug.nrw>
This commit is contained in:
J-N-K 2022-12-12 20:49:42 +01:00 committed by GitHub
parent b39f735b9d
commit b842c87f98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 25 deletions

View File

@ -46,6 +46,7 @@ import com.google.gson.reflect.TypeToken;
@SuppressWarnings("unused")
public class EventWebSocket {
public static final String WEBSOCKET_EVENT_TYPE = "WebSocketEvent";
public static final String WEBSOCKET_TOPIC_PREFIX = "openhab/websocket/";
private static final Type STRING_LIST_TYPE = TypeToken.getParameterized(List.class, String.class).getType();
@ -113,33 +114,34 @@ public class EventWebSocket {
case "ItemCommandEvent":
Event itemCommandEvent = itemEventUtility.createCommandEvent(eventDTO);
eventPublisher.post(itemCommandEvent);
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, "/response/success", "", null,
eventDTO.eventId);
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "response/success",
"", null, eventDTO.eventId);
break;
case "ItemStateEvent":
Event itemStateEvent = itemEventUtility.createStateEvent(eventDTO);
eventPublisher.post(itemStateEvent);
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, "/response/success", "", null,
eventDTO.eventId);
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "response/success",
"", null, eventDTO.eventId);
break;
case WEBSOCKET_EVENT_TYPE:
if ("/heartbeat".equals(eventDTO.topic) && "PING".equals(eventDTO.payload)) {
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, "/heartbeat", "PONG", null,
eventDTO.eventId);
} else if ("/filter/type".equals(eventDTO.topic)) {
if ((WEBSOCKET_TOPIC_PREFIX + "heartbeat").equals(eventDTO.topic)
&& "PING".equals(eventDTO.payload)) {
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "heartbeat",
"PONG", null, eventDTO.eventId);
} else if ((WEBSOCKET_TOPIC_PREFIX + "filter/type").equals(eventDTO.topic)) {
typeFilter = Objects.requireNonNullElse(gson.fromJson(eventDTO.payload, STRING_LIST_TYPE),
List.of());
logger.debug("Setting type filter for connection to {}: {}",
remoteEndpoint.getInetSocketAddress(), typeFilter);
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, "/filter/type", eventDTO.payload, null,
eventDTO.eventId);
} else if ("/filter/source".equals(eventDTO.topic)) {
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "filter/type",
eventDTO.payload, null, eventDTO.eventId);
} else if ((WEBSOCKET_TOPIC_PREFIX + "filter/source").equals(eventDTO.topic)) {
sourceFilter = Objects.requireNonNullElse(gson.fromJson(eventDTO.payload, STRING_LIST_TYPE),
List.of());
logger.debug("Setting source filter for connection to {}: {}",
remoteEndpoint.getInetSocketAddress(), typeFilter);
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, "/filter/source", eventDTO.payload, null,
eventDTO.eventId);
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "filter/source",
eventDTO.payload, null, eventDTO.eventId);
} else {
throw new EventProcessingException("Invalid topic or payload in WebSocketEvent");
}
@ -154,13 +156,13 @@ public class EventWebSocket {
}
} catch (EventProcessingException | JsonParseException e) {
logger.warn("Failed to process deserialized event '{}': {}", message, e.getMessage());
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, "/response/failed",
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "response/failed",
"Processing error: " + e.getMessage(), null, eventDTO != null ? eventDTO.eventId : "");
}
} catch (JsonParseException e) {
logger.warn("Could not deserialize '{}'", message);
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, "/response/failed",
responseEvent = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "response/failed",
"Deserialization error: " + e.getMessage(), null, null);
}

View File

@ -19,6 +19,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.openhab.core.io.websocket.EventWebSocket.WEBSOCKET_EVENT_TYPE;
import static org.openhab.core.io.websocket.EventWebSocket.WEBSOCKET_TOPIC_PREFIX;
import java.io.IOException;
import java.net.InetSocketAddress;
@ -106,7 +107,8 @@ public class EventWebSocketTest {
REMOTE_WEBSOCKET_IMPLEMENTATION);
EventDTO eventDTO = new EventDTO(expectedEvent);
eventDTO.eventId = "id-1";
EventDTO expectedResponse = new EventDTO(WEBSOCKET_EVENT_TYPE, "/response/success", "", null, eventDTO.eventId);
EventDTO expectedResponse = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "response/success", "",
null, eventDTO.eventId);
assertEventProcessing(eventDTO, expectedEvent, expectedResponse);
}
@ -127,7 +129,8 @@ public class EventWebSocketTest {
EventDTO eventDTO = new EventDTO(expectedEvent);
eventDTO.eventId = "id-1";
EventDTO expectedResponse = new EventDTO(WEBSOCKET_EVENT_TYPE, "/response/success", "", null, eventDTO.eventId);
EventDTO expectedResponse = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "response/success", "",
null, eventDTO.eventId);
assertEventProcessing(eventDTO, expectedEvent, expectedResponse);
}
@ -149,7 +152,7 @@ public class EventWebSocketTest {
EventDTO eventDTO = new EventDTO(expectedEvent);
eventDTO.payload = "";
EventDTO expectedResponse = new EventDTO(WEBSOCKET_EVENT_TYPE, "/response/failed",
EventDTO expectedResponse = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "response/failed",
"Processing error: Failed to deserialize payload \u0027\u0027.", null, null);
assertEventProcessing(eventDTO, null, expectedResponse);
@ -164,7 +167,7 @@ public class EventWebSocketTest {
eventDTO.eventId = "id-1";
eventDTO.topic = "";
EventDTO expectedResponse = new EventDTO(WEBSOCKET_EVENT_TYPE, "/response/failed",
EventDTO expectedResponse = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "response/failed",
"Processing error: Topic must follow the format {namespace}/{entityType}/{entity}/{action}.", null,
eventDTO.eventId);
@ -173,8 +176,10 @@ public class EventWebSocketTest {
@Test
public void heartBeat() throws IOException {
EventDTO eventDTO = new EventDTO(WEBSOCKET_EVENT_TYPE, "/heartbeat", "PING", null, null);
EventDTO expectedResponse = new EventDTO(WEBSOCKET_EVENT_TYPE, "/heartbeat", "PONG", null, null);
EventDTO eventDTO = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "heartbeat", "PING", null,
null);
EventDTO expectedResponse = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "heartbeat", "PONG",
null, null);
assertEventProcessing(eventDTO, null, expectedResponse);
}
@ -192,8 +197,10 @@ public class EventWebSocketTest {
@Test
public void eventFromBusFilterType() throws IOException {
EventDTO eventDTO = new EventDTO(WEBSOCKET_EVENT_TYPE, "/filter/type", "[\"ItemCommandEvent\"]", null, null);
EventDTO responseEventDTO = new EventDTO(WEBSOCKET_EVENT_TYPE, "/filter/type", eventDTO.payload, null, null);
EventDTO eventDTO = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "filter/type",
"[\"ItemCommandEvent\"]", null, null);
EventDTO responseEventDTO = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "filter/type",
eventDTO.payload, null, null);
eventWebSocket.onText(gson.toJson(eventDTO));
verify(remoteEndpoint).sendString(gson.toJson(responseEventDTO));
@ -211,9 +218,10 @@ public class EventWebSocketTest {
@Test
public void eventFromBusFilterSource() throws IOException {
EventDTO eventDTO = new EventDTO(WEBSOCKET_EVENT_TYPE, "/filter/source",
EventDTO eventDTO = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "filter/source",
"[\"" + REMOTE_WEBSOCKET_IMPLEMENTATION + "\"]", null, null);
EventDTO responseEventDTO = new EventDTO(WEBSOCKET_EVENT_TYPE, "/filter/source", eventDTO.payload, null, null);
EventDTO responseEventDTO = new EventDTO(WEBSOCKET_EVENT_TYPE, WEBSOCKET_TOPIC_PREFIX + "filter/source",
eventDTO.payload, null, null);
eventWebSocket.onText(gson.toJson(eventDTO));
verify(remoteEndpoint).sendString(gson.toJson(responseEventDTO));