Skip to content

Commit

Permalink
Add support to RequestGetTopicName and PIPWebSocketLampStatus
Browse files Browse the repository at this point in the history
 - Now handle both RequestGetTopicUuid and RequestGetTopicName
 - A PIPWebSocket can be implemented to retrieve either a specific topicUuid (through the method performRequestGetTopicUuid()), or a list of topicUuid by using the performRequestGetTopicName() method implemented by the AbstractPIPWebSocket
 - The topicUuid can be null: a PIP invoking the performRequestGetTopicName() method only does not the topicUuid to be specified
 - The DHTPersistentMessageClient accepts parsable Persistent messages, as well as Response2RequestGetTopicName messages and Response2RequestGetTopicUuid messages.
 - PIPWebSocketLampStatus implements a PIP that retrieves the status of a specific lamp (specified by the topicUuid)
  • Loading branch information
Daven00 committed Sep 4, 2023
1 parent fbc7794 commit 2f8dad6
Show file tree
Hide file tree
Showing 12 changed files with 307 additions and 63 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package it.cnr.iit.ucs.pipwebsocket;

import com.google.gson.GsonBuilder;
import it.cnr.iit.ucs.exceptions.PIPException;
import it.cnr.iit.ucs.obligationmanager.ObligationInterface;
import it.cnr.iit.ucs.pip.AbstractPIPWebSocket;
import it.cnr.iit.ucs.pipwebsocket.json.DomoLight;
import it.cnr.iit.ucs.pipwebsocket.json.DomoLightRequestPostTopicUuid;
import it.cnr.iit.ucs.properties.components.PipProperties;
import it.cnr.iit.utility.dht.jsonpersistent.JsonInResponse2RequestGetTopicUuid;
import it.cnr.iit.utility.errorhandling.Reject;
import it.cnr.iit.xacml.Attribute;
import oasis.names.tc.xacml.core.schema.wd_17.RequestType;

import java.util.List;
import java.util.logging.Logger;

public class PIPWebSocketLampStatus extends AbstractPIPWebSocket {

private static final Logger log = Logger.getLogger(PIPWebSocketLamps.class.getName());

public PIPWebSocketLampStatus(PipProperties properties) {
super(properties);
setClassForTypeFactory(DomoLightRequestPostTopicUuid.class);
Reject.ifFalse(init(properties), "Error initialising pip : " + properties.getId());
}

@Override
public String retrieve(Attribute attribute) throws PIPException {
String response = performRequestGetTopicUuid();

JsonInResponse2RequestGetTopicUuid jsonInResponse = new GsonBuilder()
.registerTypeAdapterFactory(getTypeFactory())
.create()
.fromJson(response, JsonInResponse2RequestGetTopicUuid.class);

DomoLight domoLight =
((DomoLightRequestPostTopicUuid) jsonInResponse.getResponse().getValue()).getValue();

String value;
if (domoLight.isStatus()) {
value = "true";
} else {
value = "false";
}

// attribute value must always be set after it has been retrieved
attribute.setValue(attribute.getDataType(), value);
return value;
}

@Override
protected Logger getLogger() {
return log;
}


@Override
public void retrieve(RequestType request, List<Attribute> attributeRetrievals) {

}

@Override
public void subscribe(RequestType request, List<Attribute> attributeRetrieval) {

}

@Override
public void update(String json) throws PIPException {

}

@Override
public void performObligation(ObligationInterface obligation) {

}
}
4 changes: 2 additions & 2 deletions UCSDht/src/main/java/it/cnr/iit/ucsdht/UCSDht.java
Original file line number Diff line number Diff line change
Expand Up @@ -512,9 +512,9 @@ public static Status downloadStatus() {
return null;
}

JsonInResponse jsonInResponse = new GsonBuilder()
JsonInResponse2RequestGetTopicUuid jsonInResponse = new GsonBuilder()
.registerTypeAdapterFactory(typeFactory)
.create().fromJson(response, JsonInResponse.class);
.create().fromJson(response, JsonInResponse2RequestGetTopicUuid.class);

StatusRequestPostTopicUuid statusRequestPostTopicUuid =
(StatusRequestPostTopicUuid) jsonInResponse.getResponse().getValue();
Expand Down
60 changes: 52 additions & 8 deletions UCSDht/src/test/python/test-ucs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import datetime

websocket_uri = "ws://localhost:3000/ws"
#websocket_uri = "ws://sifis-device4.iit.cnr.it:3000/ws"
#websocket_uri = "ws://146.48.89.28:3000/ws"

session_id = "None"
def on_message(ws, message):
if "ucs-command" in message:
Expand Down Expand Up @@ -40,8 +43,8 @@ def enter_command():
print(" PEP commands: PAP commands: PIP commands:")
print(" 1 : register 5 : add policy 9: add pip time")
print(" 2 : try access 6 : list policies 10: add pip reader")
print(" 3 : start access 7 : get policy 11: add pip websocket lamps")
print(" 4 : end access 8 : delete policy")
print(" 3 : start access 7 : get policy 11: add pip websocket lamp status")
print(" 4 : end access 8 : delete policy 12: add pip websocket lamps status")
print("")

command = input("Enter command number> ")
Expand Down Expand Up @@ -70,8 +73,10 @@ def send_command(command):
elif command == "10":
add_pip_reader()
elif command == "11":
add_pip_websocket()
add_pip_websocket_lamp_status()
elif command == "12":
add_pip_websocket_lamps_status()
elif command == "13":
unrecognized_command()
elif command == "q":
exit("")
Expand Down Expand Up @@ -391,8 +396,8 @@ def add_pip_reader():
print("\n------ ADD PIP READER -------\n")
print_and_send(ws_req)

def add_pip_websocket():
attribute_id = "eu:sifis-home:1.0:environment:lamps-status"
def add_pip_websocket_lamp_status():
attribute_id = "eu:sifis-home:1.0:environment:lamp-status"
category = "urn:oasis:names:tc:xacml:3.0:attribute-category:environment"
data_type = "http://www.w3.org/2001/XMLSchema#boolean"
dhtUri = "ws://sifis-device4.iit.cnr.it:3000/ws"
Expand All @@ -410,7 +415,7 @@ def add_pip_websocket():
"message": {
"purpose": "ADD_PIP",
"message_id": str(uuid.uuid1()),
"pip_type": "it.cnr.iit.ucs.pipwebsocket.PIPWebSocketLamps",
"pip_type": "it.cnr.iit.ucs.pipwebsocket.PIPWebSocketLampStatus",
"attribute_id": attribute_id,
"category": category,
"data_type": data_type,
Expand All @@ -421,15 +426,54 @@ def add_pip_websocket():
"topicUuid": topicUuid
}
},
"id": "pip-websocket-lamps",
"id": "pip-websocket-lamp-status",
"topic_name": "topic-name",
"topic_uuid": "topic-uuid-the-ucs-is-subscribed-to"
}
}
}
}
}
print("\n-- ADD PIP WEBSOCKET LAMP STATUS --\n")
print_and_send(ws_req)

def add_pip_websocket_lamps_status():
attribute_id = "eu:sifis-home:1.0:environment:all-lamps-are-on"
category = "urn:oasis:names:tc:xacml:3.0:attribute-category:environment"
data_type = "http://www.w3.org/2001/XMLSchema#boolean"
dhtUri = "ws://sifis-device4.iit.cnr.it:3000/ws"
topicName = "domo_light"
refresh_rate = 10000

ws_req = {
"RequestPubMessage": {
"value": {
"timestamp": int(datetime.datetime.now().timestamp()*1000),
"command": {
"command_type": "pip-command",
"value": {
"message": {
"purpose": "ADD_PIP",
"message_id": str(uuid.uuid1()),
"pip_type": "it.cnr.iit.ucs.pipwebsocket.PIPWebSocketLamps",
"attribute_id": attribute_id,
"category": category,
"data_type": data_type,
"refresh_rate": refresh_rate,
"additional_properties" : {
"dhtUri": dhtUri,
"topicName": topicName,
}
},
"id": "pip-websocket-all-lamps-are-on",
"topic_name": "topic-name",
"topic_uuid": "topic-uuid-the-ucs-is-subscribed-to"
}
}
}
}
}
print("\n--- ADD PIP WEBSOCKETLAMPS --\n")
print("\n-- ADD PIP WEBSOCKET LAMPS STATUS --\n")
print_and_send(ws_req)

## UNRECOGNIZED COMMAND
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ public boolean init(PipProperties properties) {
try {
dhtUri = properties.getAdditionalProperties().get("dhtUri");
Reject.ifNull(dhtUri, "DHT URI not specified");

topicName = properties.getAdditionalProperties().get("topicName");
Reject.ifNull(topicName, "Topic name not specified");

// topicUuid can be null since the PIP might perform only
// requests of type RequestGetTopicName
topicUuid = properties.getAdditionalProperties().get("topicUuid");
Reject.ifNull(topicUuid, "Topic UUID not specified");

Reject.ifNull(this.typeFactoryClazz, "Class for TypeFactory not set. " +
"Call setClassForTypeFactory() method before init()");
Expand Down Expand Up @@ -80,6 +83,10 @@ public boolean init(PipProperties properties) {


public String performRequestGetTopicUuid() throws PIPException {
if (topicUuid == null) {
throw new PIPException("Topic UUID is not set");
}

// get the status from the dht
String response = null;
if (isDhtReachable(dhtUri, 2000, 1)) {
Expand All @@ -101,17 +108,38 @@ public String performRequestGetTopicUuid() throws PIPException {
return response;
}

public String performRequestGetTopicName() throws PIPException {
// get the status from the dht
String response = null;
if (isDhtReachable(dhtUri, 2000, 1)) {
RequestGetTopicName requestGetTopicName =
new RequestGetTopicName(topicName);

JsonOutRequestGetTopicName jsonOut = new JsonOutRequestGetTopicName(requestGetTopicName);
String request = new GsonBuilder()
.disableHtmlEscaping()
.serializeNulls()
.create()
.toJson(jsonOut);

response = getResponse(request);
} else {
throw new PIPException("Attribute Manager error: " +
"Unable to connect to the DHT");
}
return response;
}

private String getResponse(String request) throws PIPException {
String response = client.sendRequestAndWaitForResponse(request);
client.closeConnection();

if (response.equals("{\"Response\":{\"value\":{}}}")) {
if (isEmptyResponse(response)) {
int attempts = 5;
for (int i = 1; i <= attempts; i++) {
response = client.sendRequestAndWaitForResponse(request);
client.closeConnection();
if (!response.equals("{\"Response\":{\"value\":{}}}")) {
if (!(isEmptyResponse(response))) {
break;
}
if (i == attempts) {
Expand All @@ -123,6 +151,10 @@ private String getResponse(String request) throws PIPException {
return response;
}

private boolean isEmptyResponse(String message) {
return message.equals("{\"Response\":{\"value\":{}}}") || message.equals("{\"Response\":{\"value\":[]}}");
}

public void setClassForTypeFactory(Class<? extends RequestPostTopicUuid> clazz) {
this.typeFactoryClazz = clazz;
}
Expand Down
Loading

0 comments on commit 2f8dad6

Please sign in to comment.