[DEV] upgrade client and back to add basic api for logs
This commit is contained in:
parent
31af52dc9e
commit
95902e7312
@ -2,7 +2,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.kar</groupId>
|
<groupId>org.kar</groupId>
|
||||||
<artifactId>karanage</artifactId>
|
<artifactId>karanage</artifactId>
|
||||||
<version>0.2.1</version>
|
<version>0.2.2</version>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
||||||
<maven.compiler.version>3.1</maven.compiler.version>
|
<maven.compiler.version>3.1</maven.compiler.version>
|
||||||
@ -22,7 +22,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>kangaroo-and-rabbit</groupId>
|
<groupId>kangaroo-and-rabbit</groupId>
|
||||||
<artifactId>archidata</artifactId>
|
<artifactId>archidata</artifactId>
|
||||||
<version>0.2.1</version>
|
<version>0.2.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
|||||||
import org.glassfish.jersey.server.ResourceConfig;
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
import org.kar.karanage.api.Front;
|
import org.kar.karanage.api.Front;
|
||||||
import org.kar.karanage.api.HealthCheck;
|
import org.kar.karanage.api.HealthCheck;
|
||||||
|
import org.kar.karanage.api.LogResource;
|
||||||
import org.kar.karanage.api.StateHistoryResource;
|
import org.kar.karanage.api.StateHistoryResource;
|
||||||
import org.kar.karanage.api.StateResource;
|
import org.kar.karanage.api.StateResource;
|
||||||
import org.kar.karanage.api.UserResource;
|
import org.kar.karanage.api.UserResource;
|
||||||
@ -25,8 +26,9 @@ import org.kar.archidata.filter.AuthenticationFilter;
|
|||||||
import org.kar.archidata.filter.CORSFilter;
|
import org.kar.archidata.filter.CORSFilter;
|
||||||
import org.kar.archidata.filter.OptionFilter;
|
import org.kar.archidata.filter.OptionFilter;
|
||||||
import org.kar.archidata.util.ConfigBaseVariable;
|
import org.kar.archidata.util.ConfigBaseVariable;
|
||||||
import org.kar.karanage.model.DataHistory;
|
import org.kar.karanage.model.StateHistory;
|
||||||
import org.kar.karanage.model.DataInstant;
|
import org.kar.karanage.model.StateInstant;
|
||||||
|
import org.kar.karanage.model.DataLog;
|
||||||
import org.kar.karanage.model.Group;
|
import org.kar.karanage.model.Group;
|
||||||
|
|
||||||
public class WebLauncher {
|
public class WebLauncher {
|
||||||
@ -43,9 +45,10 @@ public class WebLauncher {
|
|||||||
// generate the BDD:
|
// generate the BDD:
|
||||||
try {
|
try {
|
||||||
String out = "";
|
String out = "";
|
||||||
out += SqlWrapper.createTable(DataInstant.class);
|
out += SqlWrapper.createTable(StateInstant.class);
|
||||||
out += SqlWrapper.createTable(DataHistory.class);
|
out += SqlWrapper.createTable(StateHistory.class);
|
||||||
out += SqlWrapper.createTable(Group.class);
|
out += SqlWrapper.createTable(Group.class);
|
||||||
|
out += SqlWrapper.createTable(DataLog.class);
|
||||||
System.out.println(out);
|
System.out.println(out);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
@ -75,6 +78,7 @@ public class WebLauncher {
|
|||||||
rc.registerClasses(UserResource.class);
|
rc.registerClasses(UserResource.class);
|
||||||
rc.registerClasses(StateResource.class);
|
rc.registerClasses(StateResource.class);
|
||||||
rc.registerClasses(StateHistoryResource.class);
|
rc.registerClasses(StateHistoryResource.class);
|
||||||
|
rc.registerClasses(LogResource.class);
|
||||||
|
|
||||||
rc.registerClasses(HealthCheck.class);
|
rc.registerClasses(HealthCheck.class);
|
||||||
rc.registerClasses(Front.class);
|
rc.registerClasses(Front.class);
|
||||||
|
167
back/src/org/kar/karanage/api/LogResource.java
Normal file
167
back/src/org/kar/karanage/api/LogResource.java
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
package org.kar.karanage.api;
|
||||||
|
|
||||||
|
import org.kar.archidata.SqlWrapper;
|
||||||
|
import org.kar.archidata.WhereCondition;
|
||||||
|
import org.kar.karanage.model.StateInstant;
|
||||||
|
import org.kar.karanage.model.DataLog;
|
||||||
|
import org.kar.karanage.model.StateHistory;
|
||||||
|
import org.kar.karanage.model.Group;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
|
||||||
|
import org.kar.archidata.annotation.security.PermitAll;
|
||||||
|
import org.kar.archidata.exception.FailException;
|
||||||
|
import org.kar.archidata.exception.InputException;
|
||||||
|
|
||||||
|
import javax.ws.rs.*;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@Path("/log")
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public class LogResource {
|
||||||
|
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{group}/{system}")
|
||||||
|
//@RolesAllowed("USER")
|
||||||
|
@PermitAll
|
||||||
|
public static String get(
|
||||||
|
@PathParam("group") String groupName,
|
||||||
|
@PathParam("system") String system,
|
||||||
|
@QueryParam("since") String since,
|
||||||
|
@QueryParam("sinceId") Integer sinceId,
|
||||||
|
@QueryParam("limit") Integer limit) throws Exception {
|
||||||
|
// Keep Group ID:
|
||||||
|
if (groupName == null || groupName.length() == 0) {
|
||||||
|
throw new InputException("group", "Missing URL parameter /state/{group}/...");
|
||||||
|
}
|
||||||
|
Group group = SqlWrapper.getWhere(Group.class,
|
||||||
|
List.of(
|
||||||
|
new WhereCondition("name", "=", groupName)
|
||||||
|
),
|
||||||
|
false);
|
||||||
|
if (group == null) {
|
||||||
|
throw new InputException("group", "url: /state/{group}/... ==> Unknown group name");
|
||||||
|
}
|
||||||
|
if (system == null || system.length() == 0) {
|
||||||
|
throw new InputException("system", "Missing URL parameter /state/xxx/{system}/...");
|
||||||
|
}
|
||||||
|
if (limit == null || limit == 0) {
|
||||||
|
limit = 100;
|
||||||
|
}
|
||||||
|
if (limit > 100) {
|
||||||
|
limit = 100;
|
||||||
|
}
|
||||||
|
if (limit < 0) {
|
||||||
|
throw new InputException("limit", "Limit must be inside [1..100]");
|
||||||
|
}
|
||||||
|
if (since != null && sinceId != null) {
|
||||||
|
throw new InputException("since,sinceId", "The 2 parameters can not be set at the same time...");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DataLog> datas = null;
|
||||||
|
if (since != null) {
|
||||||
|
Timestamp time = null;
|
||||||
|
try {
|
||||||
|
time = Timestamp.from(Instant.parse(since));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new InputException("since", "url: ?since=... ==> is not an iso 8601 time format");
|
||||||
|
}
|
||||||
|
datas = SqlWrapper.getsWhere(DataLog.class,
|
||||||
|
List.of(
|
||||||
|
new WhereCondition("group", "=", group.id),
|
||||||
|
new WhereCondition("system", "=", system),
|
||||||
|
new WhereCondition("create_date", ">", time)
|
||||||
|
),
|
||||||
|
"create_date",
|
||||||
|
true,
|
||||||
|
limit);
|
||||||
|
if (datas == null) {
|
||||||
|
throw new FailException(Response.Status.NOT_FOUND, "system has no new data or does not exist: '" + system + "'");
|
||||||
|
}
|
||||||
|
} else if (sinceId != null) {
|
||||||
|
datas = SqlWrapper.getsWhere(DataLog.class,
|
||||||
|
List.of(
|
||||||
|
new WhereCondition("group", "=", group.id),
|
||||||
|
new WhereCondition("system", "=", system),
|
||||||
|
new WhereCondition("id", ">", sinceId)
|
||||||
|
),
|
||||||
|
"id",
|
||||||
|
true,
|
||||||
|
limit);
|
||||||
|
if (datas == null) {
|
||||||
|
throw new FailException(Response.Status.NOT_FOUND, "system has no new data or does not exist: '" + system + "'");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
datas = SqlWrapper.getsWhere(DataLog.class,
|
||||||
|
List.of(
|
||||||
|
new WhereCondition("group", "=", group.id),
|
||||||
|
new WhereCondition("system", "=", system)
|
||||||
|
),
|
||||||
|
"id",
|
||||||
|
true,
|
||||||
|
limit);
|
||||||
|
if (datas == null) {
|
||||||
|
throw new FailException(Response.Status.NOT_FOUND, "system does not exist: '" + system + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder out = new StringBuilder("[");
|
||||||
|
boolean first = true;
|
||||||
|
for (DataLog data : datas) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
out.append(",");
|
||||||
|
}
|
||||||
|
out.append("{ \"id\": " + data.id + ", \"time\": \"" + data.create_date.toInstant().toString() + "\", \"data\":" + data.data + "}");
|
||||||
|
}
|
||||||
|
out.append("]");
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("{group}/{system}")
|
||||||
|
@PermitAll
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Response post(
|
||||||
|
@PathParam("group") String groupName,
|
||||||
|
@PathParam("system") String system,
|
||||||
|
@QueryParam("time") String time,
|
||||||
|
@QueryParam("id") Integer client_id,
|
||||||
|
String dataToInsert) throws Exception {
|
||||||
|
Group group = SqlWrapper.getWhere(Group.class,
|
||||||
|
List.of(
|
||||||
|
new WhereCondition("name", "=", groupName)
|
||||||
|
),
|
||||||
|
false);
|
||||||
|
if (group == null) {
|
||||||
|
throw new InputException("group", "url: /log/{group}/... ==> Unknown group name");
|
||||||
|
}
|
||||||
|
DataLog data = new DataLog();
|
||||||
|
data.group = group.id;
|
||||||
|
data.system = system;
|
||||||
|
data.data = dataToInsert;
|
||||||
|
if (client_id != null) {
|
||||||
|
data.client_id = client_id;
|
||||||
|
}
|
||||||
|
if (time != null) {
|
||||||
|
try {
|
||||||
|
data.create_date = Timestamp.from(Instant.parse(time));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new InputException("time", "url: ?time=... ==> is not an iso 8601 time format");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SqlWrapper.insert(data);
|
||||||
|
return Response.status(201).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,8 +2,8 @@ package org.kar.karanage.api;
|
|||||||
|
|
||||||
import org.kar.archidata.SqlWrapper;
|
import org.kar.archidata.SqlWrapper;
|
||||||
import org.kar.archidata.WhereCondition;
|
import org.kar.archidata.WhereCondition;
|
||||||
import org.kar.karanage.model.DataInstant;
|
import org.kar.karanage.model.StateInstant;
|
||||||
import org.kar.karanage.model.DataHistory;
|
import org.kar.karanage.model.StateHistory;
|
||||||
import org.kar.karanage.model.Group;
|
import org.kar.karanage.model.Group;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ public class StateHistoryResource {
|
|||||||
throw new InputException("since,sinceId", "The 2 parameters can not be set at the same time...");
|
throw new InputException("since,sinceId", "The 2 parameters can not be set at the same time...");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DataHistory> datas = null;
|
List<StateHistory> datas = null;
|
||||||
if (since != null) {
|
if (since != null) {
|
||||||
Timestamp time = null;
|
Timestamp time = null;
|
||||||
try {
|
try {
|
||||||
@ -72,7 +72,7 @@ public class StateHistoryResource {
|
|||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new InputException("since", "url: ?since=... ==> is not an iso 8601 time format");
|
throw new InputException("since", "url: ?since=... ==> is not an iso 8601 time format");
|
||||||
}
|
}
|
||||||
datas = SqlWrapper.getsWhere(DataHistory.class,
|
datas = SqlWrapper.getsWhere(StateHistory.class,
|
||||||
List.of(
|
List.of(
|
||||||
new WhereCondition("group", "=", group.id),
|
new WhereCondition("group", "=", group.id),
|
||||||
new WhereCondition("topic", "=", topic),
|
new WhereCondition("topic", "=", topic),
|
||||||
@ -85,7 +85,7 @@ public class StateHistoryResource {
|
|||||||
throw new FailException(Response.Status.NOT_FOUND, "Topic has no new data or does not exist: '" + topic + "'");
|
throw new FailException(Response.Status.NOT_FOUND, "Topic has no new data or does not exist: '" + topic + "'");
|
||||||
}
|
}
|
||||||
} else if (sinceId != null) {
|
} else if (sinceId != null) {
|
||||||
datas = SqlWrapper.getsWhere(DataHistory.class,
|
datas = SqlWrapper.getsWhere(StateHistory.class,
|
||||||
List.of(
|
List.of(
|
||||||
new WhereCondition("group", "=", group.id),
|
new WhereCondition("group", "=", group.id),
|
||||||
new WhereCondition("topic", "=", topic),
|
new WhereCondition("topic", "=", topic),
|
||||||
@ -98,7 +98,7 @@ public class StateHistoryResource {
|
|||||||
throw new FailException(Response.Status.NOT_FOUND, "Topic has no new data or does not exist: '" + topic + "'");
|
throw new FailException(Response.Status.NOT_FOUND, "Topic has no new data or does not exist: '" + topic + "'");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
datas = SqlWrapper.getsWhere(DataHistory.class,
|
datas = SqlWrapper.getsWhere(StateHistory.class,
|
||||||
List.of(
|
List.of(
|
||||||
new WhereCondition("group", "=", group.id),
|
new WhereCondition("group", "=", group.id),
|
||||||
new WhereCondition("topic", "=", topic)
|
new WhereCondition("topic", "=", topic)
|
||||||
@ -113,7 +113,7 @@ public class StateHistoryResource {
|
|||||||
|
|
||||||
StringBuilder out = new StringBuilder("[");
|
StringBuilder out = new StringBuilder("[");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (DataInstant data : datas) {
|
for (StateInstant data : datas) {
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,8 +2,8 @@ package org.kar.karanage.api;
|
|||||||
|
|
||||||
import org.kar.archidata.SqlWrapper;
|
import org.kar.archidata.SqlWrapper;
|
||||||
import org.kar.archidata.WhereCondition;
|
import org.kar.archidata.WhereCondition;
|
||||||
import org.kar.karanage.model.DataInstant;
|
import org.kar.karanage.model.StateInstant;
|
||||||
import org.kar.karanage.model.DataHistory;
|
import org.kar.karanage.model.StateHistory;
|
||||||
import org.kar.karanage.model.Group;
|
import org.kar.karanage.model.Group;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ public class StateResource {
|
|||||||
if (group == null) {
|
if (group == null) {
|
||||||
throw new InputException("group", "url: /state/{group}/... ==> Unknown group name");
|
throw new InputException("group", "url: /state/{group}/... ==> Unknown group name");
|
||||||
}
|
}
|
||||||
DataInstant data = null;
|
StateInstant data = null;
|
||||||
if (since != null) {
|
if (since != null) {
|
||||||
Timestamp time = null;
|
Timestamp time = null;
|
||||||
try {
|
try {
|
||||||
@ -53,7 +53,7 @@ public class StateResource {
|
|||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new InputException("since", "url: ?since=... ==> is not an iso 8601 time format");
|
throw new InputException("since", "url: ?since=... ==> is not an iso 8601 time format");
|
||||||
}
|
}
|
||||||
data = SqlWrapper.getWhere(DataInstant.class,
|
data = SqlWrapper.getWhere(StateInstant.class,
|
||||||
List.of(
|
List.of(
|
||||||
new WhereCondition("group", "=", group.id),
|
new WhereCondition("group", "=", group.id),
|
||||||
new WhereCondition("topic", "=", topic),
|
new WhereCondition("topic", "=", topic),
|
||||||
@ -64,7 +64,7 @@ public class StateResource {
|
|||||||
throw new FailException(Response.Status.NOT_FOUND, "Topic has no new data or does not exist: '" + topic + "'");
|
throw new FailException(Response.Status.NOT_FOUND, "Topic has no new data or does not exist: '" + topic + "'");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
data = SqlWrapper.getWhere(DataInstant.class,
|
data = SqlWrapper.getWhere(StateInstant.class,
|
||||||
List.of(
|
List.of(
|
||||||
new WhereCondition("group", "=", group.id),
|
new WhereCondition("group", "=", group.id),
|
||||||
new WhereCondition("topic", "=", topic)
|
new WhereCondition("topic", "=", topic)
|
||||||
@ -96,7 +96,7 @@ public class StateResource {
|
|||||||
throw new InputException("group", "url: /state/{group}/... ==> Unknown group name");
|
throw new InputException("group", "url: /state/{group}/... ==> Unknown group name");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DataInstant> datas = null;
|
List<StateInstant> datas = null;
|
||||||
if (since != null) {
|
if (since != null) {
|
||||||
Timestamp time = null;
|
Timestamp time = null;
|
||||||
try {
|
try {
|
||||||
@ -104,14 +104,14 @@ public class StateResource {
|
|||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new InputException("since", "url: ?since=... ==> is not an iso 8601 time format");
|
throw new InputException("since", "url: ?since=... ==> is not an iso 8601 time format");
|
||||||
}
|
}
|
||||||
datas = SqlWrapper.getsWhere(DataInstant.class,
|
datas = SqlWrapper.getsWhere(StateInstant.class,
|
||||||
List.of(
|
List.of(
|
||||||
new WhereCondition("group", "=", group.id),
|
new WhereCondition("group", "=", group.id),
|
||||||
new WhereCondition("modify_date", ">", time)
|
new WhereCondition("modify_date", ">", time)
|
||||||
),
|
),
|
||||||
true);
|
true);
|
||||||
} else {
|
} else {
|
||||||
datas = SqlWrapper.getsWhere(DataInstant.class,
|
datas = SqlWrapper.getsWhere(StateInstant.class,
|
||||||
List.of(
|
List.of(
|
||||||
new WhereCondition("group", "=", group.id)
|
new WhereCondition("group", "=", group.id)
|
||||||
),
|
),
|
||||||
@ -119,7 +119,7 @@ public class StateResource {
|
|||||||
}
|
}
|
||||||
StringBuilder out = new StringBuilder("[");
|
StringBuilder out = new StringBuilder("[");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (DataInstant data : datas) {
|
for (StateInstant data : datas) {
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
@ -147,9 +147,10 @@ public class StateResource {
|
|||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public Response post(
|
public Response post(
|
||||||
@PathParam("group") String groupName,
|
@PathParam("group") String groupName,
|
||||||
@PathParam("topic") String topic,
|
@PathParam("topic") String topic,
|
||||||
|
@QueryParam("state") String state,
|
||||||
String dataToInsert) throws Exception {
|
String dataToInsert) throws Exception {
|
||||||
DataInstant previous = null;
|
StateInstant previous = null;
|
||||||
|
|
||||||
Group group = SqlWrapper.getWhere(Group.class,
|
Group group = SqlWrapper.getWhere(Group.class,
|
||||||
List.of(
|
List.of(
|
||||||
@ -160,7 +161,7 @@ public class StateResource {
|
|||||||
throw new InputException("group", "url: /state/{group}/... ==> Unknown group name");
|
throw new InputException("group", "url: /state/{group}/... ==> Unknown group name");
|
||||||
}
|
}
|
||||||
if (group != null) {
|
if (group != null) {
|
||||||
previous = SqlWrapper.getWhere(DataInstant.class,
|
previous = SqlWrapper.getWhere(StateInstant.class,
|
||||||
List.of(
|
List.of(
|
||||||
new WhereCondition("group", "=", group.id),
|
new WhereCondition("group", "=", group.id),
|
||||||
new WhereCondition("topic", "=", topic)
|
new WhereCondition("topic", "=", topic)
|
||||||
@ -169,12 +170,13 @@ public class StateResource {
|
|||||||
}
|
}
|
||||||
if (previous == null) {
|
if (previous == null) {
|
||||||
// insert new data
|
// insert new data
|
||||||
DataInstant data = new DataInstant();
|
StateInstant data = new StateInstant();
|
||||||
data.group = group.id;
|
data.group = group.id;
|
||||||
data.topic = topic;
|
data.topic = topic;
|
||||||
data.data = dataToInsert;
|
data.data = dataToInsert;
|
||||||
|
data.state = state;
|
||||||
previous = SqlWrapper.insert(data);
|
previous = SqlWrapper.insert(data);
|
||||||
DataHistory dataHistory = new DataHistory(previous);
|
StateHistory dataHistory = new StateHistory(previous);
|
||||||
dataHistory.year = true;
|
dataHistory.year = true;
|
||||||
dataHistory.month = true;
|
dataHistory.month = true;
|
||||||
dataHistory.week = true;
|
dataHistory.week = true;
|
||||||
@ -185,9 +187,10 @@ public class StateResource {
|
|||||||
// update Data
|
// update Data
|
||||||
try {
|
try {
|
||||||
previous.data = dataToInsert;
|
previous.data = dataToInsert;
|
||||||
SqlWrapper.update(previous, previous.id, List.of("data"));
|
previous.state = state;
|
||||||
|
SqlWrapper.update(previous, previous.id, List.of("data", "state"));
|
||||||
// add it in history:
|
// add it in history:
|
||||||
DataHistory dataHistory = new DataHistory(previous);
|
StateHistory dataHistory = new StateHistory(previous);
|
||||||
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );
|
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );
|
||||||
OffsetDateTime sqlTime = OffsetDateTime.ofInstant(Instant.ofEpochMilli(previous.modify_date.getTime()), ZoneOffset.UTC);
|
OffsetDateTime sqlTime = OffsetDateTime.ofInstant(Instant.ofEpochMilli(previous.modify_date.getTime()), ZoneOffset.UTC);
|
||||||
|
|
||||||
|
43
back/src/org/kar/karanage/model/DataLog.java
Normal file
43
back/src/org/kar/karanage/model/DataLog.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package org.kar.karanage.model;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
import org.kar.archidata.annotation.SQLAutoIncrement;
|
||||||
|
import org.kar.archidata.annotation.SQLComment;
|
||||||
|
import org.kar.archidata.annotation.SQLDefault;
|
||||||
|
import org.kar.archidata.annotation.SQLForeignKey;
|
||||||
|
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||||
|
import org.kar.archidata.annotation.SQLLimitSize;
|
||||||
|
import org.kar.archidata.annotation.SQLNotNull;
|
||||||
|
import org.kar.archidata.annotation.SQLNotRead;
|
||||||
|
import org.kar.archidata.annotation.SQLPrimaryKey;
|
||||||
|
import org.kar.archidata.annotation.SQLTableName;
|
||||||
|
import org.kar.archidata.annotation.SQLUpdateTime;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
|
||||||
|
@SQLTableName ("log")
|
||||||
|
@SQLIfNotExists
|
||||||
|
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
|
||||||
|
public class DataLog {
|
||||||
|
@SQLAutoIncrement // Add AUTO_INCREMENT modifier
|
||||||
|
@SQLPrimaryKey // Create a PRIMARY KEY based on this field
|
||||||
|
@SQLNotNull
|
||||||
|
@SQLComment("Primary key of the base")
|
||||||
|
public Long id = null;
|
||||||
|
@SQLUpdateTime
|
||||||
|
@SQLNotNull
|
||||||
|
@SQLDefault("now(3)")
|
||||||
|
@SQLComment("When update the object")
|
||||||
|
public Timestamp create_date = null;
|
||||||
|
@SQLComment("Group of the element")
|
||||||
|
@SQLForeignKey("group")
|
||||||
|
public long group;
|
||||||
|
@SQLLimitSize(256)
|
||||||
|
@SQLComment("System of the message")
|
||||||
|
public String system = null;
|
||||||
|
@SQLComment("Client unique internal ID (for synchronisation system)")
|
||||||
|
public Integer client_id = null;
|
||||||
|
@SQLComment("Message to store")
|
||||||
|
public String data = null;
|
||||||
|
}
|
@ -36,15 +36,15 @@ enum TypeData {
|
|||||||
NUMBER, BOOLEAN, JSON, STRING
|
NUMBER, BOOLEAN, JSON, STRING
|
||||||
}
|
}
|
||||||
|
|
||||||
@SQLTableName ("dataHistory")
|
@SQLTableName ("stateHistory")
|
||||||
@SQLIfNotExists
|
@SQLIfNotExists
|
||||||
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
|
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
|
||||||
public class DataHistory extends DataInstant {
|
public class StateHistory extends StateInstant {
|
||||||
// default constructor
|
// default constructor
|
||||||
public DataHistory() {
|
public StateHistory() {
|
||||||
|
|
||||||
}
|
}
|
||||||
public DataHistory(DataInstant other) {
|
public StateHistory(StateInstant other) {
|
||||||
this.group = other.group;
|
this.group = other.group;
|
||||||
this.topic = other.topic;
|
this.topic = other.topic;
|
||||||
this.state = other.state;
|
this.state = other.state;
|
@ -27,10 +27,10 @@ import org.kar.archidata.annotation.SQLUpdateTime;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
|
||||||
@SQLTableName ("data")
|
@SQLTableName ("state")
|
||||||
@SQLIfNotExists
|
@SQLIfNotExists
|
||||||
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
|
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
|
||||||
public class DataInstant {
|
public class StateInstant {
|
||||||
@SQLAutoIncrement // Add AUTO_INCREMENT modifier
|
@SQLAutoIncrement // Add AUTO_INCREMENT modifier
|
||||||
@SQLPrimaryKey // Create a PRIMARY KEY based on this field
|
@SQLPrimaryKey // Create a PRIMARY KEY based on this field
|
||||||
@SQLNotNull
|
@SQLNotNull
|
@ -7,7 +7,7 @@ import subprocess
|
|||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
import karanage
|
from karanage import KaranageState, KaranageConnection, KaranageException, StateSystem
|
||||||
|
|
||||||
cpu_core_count = psutil.cpu_count(logical=False)
|
cpu_core_count = psutil.cpu_count(logical=False)
|
||||||
cpu_thread_count = psutil.cpu_count()
|
cpu_thread_count = psutil.cpu_count()
|
||||||
@ -122,12 +122,12 @@ if __name__ == '__main__':
|
|||||||
# Load arguments:
|
# Load arguments:
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("-c", "--config", type=str, default="/etc/karanage/system.json", help="json configuration file")
|
parser.add_argument("-c", "--config", type=str, default="/etc/karanage/system.json", help="json configuration file")
|
||||||
parser.add_argument("-C", "--connection", type=str, default="/etc/karanage/connection.json", help="json configuration file")
|
parser.add_argument("-C", "--connection", type=str, default=None, help="json configuration file")
|
||||||
|
|
||||||
# This element are read from the connection file:
|
# This element are read from the connection file:
|
||||||
parser.add_argument("-u", "--url", type=str, default="http://localhost:20080/karanage/api", help="Base URL of the web service")
|
parser.add_argument("-u", "--url", type=str, default=None, help="Base URL of the web service")
|
||||||
parser.add_argument("-g", "--group", type=str, default="home", help="Group the the message")
|
parser.add_argument("-g", "--group", type=str, default=None, help="Group the the message")
|
||||||
parser.add_argument("-T", "--token", type=str, default="", help="Token to access to the server")
|
parser.add_argument("-T", "--token", type=str, default=None, help="Token to access to the server")
|
||||||
|
|
||||||
# This element are read from the configuration file:
|
# This element are read from the configuration file:
|
||||||
parser.add_argument("-t", "--topic", type=str, default="PC/system", help="Topic of the message")
|
parser.add_argument("-t", "--topic", type=str, default="PC/system", help="Topic of the message")
|
||||||
@ -158,26 +158,15 @@ if __name__ == '__main__':
|
|||||||
if "topic" not in configuration["config"]:
|
if "topic" not in configuration["config"]:
|
||||||
configuration["config"]["topic"] = args.topic
|
configuration["config"]["topic"] = args.topic
|
||||||
|
|
||||||
|
connection = KaranageConnection(
|
||||||
|
url = args.url,
|
||||||
|
group = args.group,
|
||||||
|
token = args.token,
|
||||||
|
config_file = args.connection
|
||||||
|
)
|
||||||
|
|
||||||
if Path(args.connection).exists():
|
|
||||||
f = open(args.connection, "r")
|
|
||||||
connection = json.loads(f.read())
|
|
||||||
f.close()
|
|
||||||
else:
|
|
||||||
connection = {}
|
|
||||||
# manage the connection model
|
|
||||||
if "url" not in connection:
|
|
||||||
connection["url"] = args.url
|
|
||||||
if "group" not in connection:
|
|
||||||
connection["group"] = args.group
|
|
||||||
if "token" not in connection:
|
|
||||||
connection["token"] = args.token
|
|
||||||
|
|
||||||
# create the rest interface of karanage
|
# create the rest interface of karanage
|
||||||
restInterface = karanage.KaranageREST(
|
stateInterface = KaranageState(connection)
|
||||||
connection["url"],
|
|
||||||
connection["group"],
|
|
||||||
connection["token"])
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
out = {}
|
out = {}
|
||||||
@ -205,7 +194,7 @@ if __name__ == '__main__':
|
|||||||
print(json.dumps(out, indent=4))
|
print(json.dumps(out, indent=4))
|
||||||
# send message to the server:
|
# send message to the server:
|
||||||
try:
|
try:
|
||||||
restInterface.send_state_to_server(configuration["config"]["topic"], out)
|
stateInterface.send(configuration["config"]["topic"], out, state = StateSystem.OK)
|
||||||
except karanage.KarangeException as ex:
|
except KaranageException as ex:
|
||||||
print(f"Can not send to the server: {ex}")
|
print(f"Can not send to the server: {ex}")
|
||||||
time.sleep(configuration["config"]["sleep"])
|
time.sleep(configuration["config"]["sleep"])
|
||||||
|
@ -7,45 +7,33 @@ import subprocess
|
|||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
import karanage
|
from karanage import KaranageException, KaranageConnection, KaranageState
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Load arguments:
|
# Load arguments:
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("-C", "--connection", type=str, default="/etc/karanage/connection.json", help="json configuration file")
|
parser.add_argument("-C", "--connection", type=str, default=None, help="json configuration file")
|
||||||
parser.add_argument("-t", "--topic", type=str, default="", help="Topic of the message")
|
parser.add_argument("-t", "--topic", type=str, default=None, help="Topic of the message")
|
||||||
parser.add_argument("-s", "--since", type=str, default=None, help="Iso date since the value time must be")
|
parser.add_argument("-s", "--since", type=str, default=None, help="Iso date since the value time must be")
|
||||||
|
|
||||||
# This element are read from the connection file:
|
# This element are read from the connection file:
|
||||||
parser.add_argument("-u", "--url", type=str, default="http://localhost:20080/karanage/api", help="Base URL of the web service")
|
parser.add_argument("-u", "--url", type=str, default=None, help="Base URL of the web service")
|
||||||
parser.add_argument("-g", "--group", type=str, default="home", help="Group the the message")
|
parser.add_argument("-g", "--group", type=str, default=None, help="Group the the message")
|
||||||
parser.add_argument("-T", "--token", type=str, default="", help="Token to access to the server")
|
parser.add_argument("-T", "--token", type=str, default=None, help="Token to access to the server")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if Path(args.connection).exists():
|
connection = KaranageConnection(
|
||||||
f = open(args.connection, "r")
|
url = args.url,
|
||||||
connection = json.loads(f.read())
|
group = args.group,
|
||||||
f.close()
|
token = args.token,
|
||||||
else:
|
config_file = args.connection
|
||||||
connection = {}
|
)
|
||||||
# manage the connection model
|
|
||||||
if "url" not in connection:
|
|
||||||
connection["url"] = args.url
|
|
||||||
if "group" not in connection:
|
|
||||||
connection["group"] = args.group
|
|
||||||
if "token" not in connection:
|
|
||||||
connection["token"] = args.token
|
|
||||||
|
|
||||||
# create the rest interface of karanage
|
# create the rest interface of karanage
|
||||||
restInterface = karanage.KaranageREST(
|
stateInterface = KaranageState(connection)
|
||||||
connection["url"],
|
|
||||||
connection["group"],
|
|
||||||
connection["token"])
|
|
||||||
|
|
||||||
if args.topic == "":
|
data = stateInterface.gets(topic=args.topic, since=args.since)
|
||||||
data = restInterface.get_state_all(since=args.since)
|
print(f"Ret = {json.dumps(data, indent=4)}")
|
||||||
print(f"Ret = {json.dumps(data, indent=4)}")
|
|
||||||
else:
|
|
||||||
data = restInterface.get_state_topic(args.topic, since=args.since)
|
|
||||||
print(f"Ret = {json.dumps(data, indent=4)}")
|
|
||||||
|
@ -7,46 +7,36 @@ import subprocess
|
|||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
import karanage
|
from karanage import KaranageConnection, KaranageState, KaranageState
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Load arguments:
|
# Load arguments:
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("-C", "--connection", type=str, default="/etc/karanage/connection.json", help="json configuration file")
|
parser.add_argument("-C", "--connection", type=str, default=None, help="json configuration file")
|
||||||
parser.add_argument("-t", "--topic", type=str, default="", help="Topic of the message")
|
parser.add_argument("-t", "--topic", type=str, default=None, help="Topic of the message")
|
||||||
parser.add_argument("-s", "--since", type=str, default=None, help="Iso date since the value time must be")
|
parser.add_argument("-s", "--since", type=str, default=None, help="Iso date since the value time must be")
|
||||||
parser.add_argument("-S", "--since-id", type=str, default=None, help="Remote BDD id to start request")
|
parser.add_argument("-S", "--since-id", type=str, default=None, help="Remote BDD id to start request")
|
||||||
parser.add_argument("-l", "--limit", type=int, default=100, help="Limit the number of request")
|
parser.add_argument("-l", "--limit", type=int, default=100, help="Limit the number of request")
|
||||||
|
|
||||||
# This element are read from the connection file:
|
# This element are read from the connection file:
|
||||||
parser.add_argument("-u", "--url", type=str, default="http://localhost:20080/karanage/api", help="Base URL of the web service")
|
parser.add_argument("-u", "--url", type=str, default=None, help="Base URL of the web service")
|
||||||
parser.add_argument("-g", "--group", type=str, default="home", help="Group the the message")
|
parser.add_argument("-g", "--group", type=str, default=None, help="Group the the message")
|
||||||
parser.add_argument("-T", "--token", type=str, default="", help="Token to access to the server")
|
parser.add_argument("-T", "--token", type=str, default=None, help="Token to access to the server")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if Path(args.connection).exists():
|
connection = KaranageConnection(
|
||||||
f = open(args.connection, "r")
|
url = args.url,
|
||||||
connection = json.loads(f.read())
|
group = args.group,
|
||||||
f.close()
|
token = args.token,
|
||||||
else:
|
config_file = args.connection
|
||||||
connection = {}
|
)
|
||||||
# manage the connection model
|
|
||||||
if "url" not in connection:
|
|
||||||
connection["url"] = args.url
|
|
||||||
if "group" not in connection:
|
|
||||||
connection["group"] = args.group
|
|
||||||
if "token" not in connection:
|
|
||||||
connection["token"] = args.token
|
|
||||||
|
|
||||||
# create the rest interface of karanage
|
# create the rest interface of karanage
|
||||||
restInterface = karanage.KaranageREST(
|
stateInterface = KaranageState(connection)
|
||||||
connection["url"],
|
|
||||||
connection["group"],
|
|
||||||
connection["token"])
|
|
||||||
|
|
||||||
if args.topic == "":
|
if args.topic is None:
|
||||||
print("Missing TOPIC ...")
|
print("Missing TOPIC ...")
|
||||||
else:
|
else:
|
||||||
data = restInterface.get_state_history_topic(args.topic, since=args.since, since_id=args.since_id, limit=args.limit)
|
data = stateInterface.get_history(topic=args.topic, since=args.since, since_id=args.since_id, limit=args.limit)
|
||||||
print(f"Ret = {json.dumps(data, indent=4)}")
|
print(f"Ret = {json.dumps(data, indent=4)}")
|
@ -1 +1 @@
|
|||||||
0.2.0-dev
|
0.3.0-dev
|
@ -7,4 +7,7 @@
|
|||||||
##
|
##
|
||||||
## @license MPL v2.0 (see license file)
|
## @license MPL v2.0 (see license file)
|
||||||
##
|
##
|
||||||
from .interface import StateSystem, KaranageREST, KarangeSendError, KarangeException
|
from .exception import KaranageException
|
||||||
|
from .connection import KaranageConnection
|
||||||
|
from .state import StateSystem, KaranageState
|
||||||
|
from .log import KaranageLog
|
||||||
|
75
client/python/karanage/karanage/connection.py
Normal file
75
client/python/karanage/karanage/connection.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2023, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license MPL v2.0 (see license file)
|
||||||
|
##
|
||||||
|
import enum
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
from typing import Dict, Optional
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
class KaranageConnection:
|
||||||
|
def __init__(self,
|
||||||
|
url: Optional[str] = None,
|
||||||
|
group: Optional[str] = None,
|
||||||
|
token: Optional[str] = None,
|
||||||
|
config_file: Optional[str] = None,
|
||||||
|
default_values: Optional[str] = None) -> None:
|
||||||
|
"""
|
||||||
|
@brief Initialize the communication class.
|
||||||
|
@param[in] url URL of the karanage API server.
|
||||||
|
@param[in] group Group of the message (token need to have the autorisation to pubhied on it).
|
||||||
|
@param[in] token Token to validate the access on the application.
|
||||||
|
@param[in] config_file path to the configuration file if overload.
|
||||||
|
@param[in] default_values Default configurations.
|
||||||
|
"""
|
||||||
|
self.url = "http://localhost:20080/karanage/api"
|
||||||
|
self.group = "test"
|
||||||
|
self.token = None
|
||||||
|
# load user default value:
|
||||||
|
if default_values is not None:
|
||||||
|
if "url" in default_values:
|
||||||
|
self.url = default_values["url"]
|
||||||
|
if "group" in default_values:
|
||||||
|
self.group = default_values["group"]
|
||||||
|
if "token" in default_values:
|
||||||
|
self.token = default_values["token"]
|
||||||
|
# keep correct config file:
|
||||||
|
if config_file is None:
|
||||||
|
config_file = "/etc/karanage/connection.json"
|
||||||
|
# check if the config exist:
|
||||||
|
if Path(config_file).exists():
|
||||||
|
f = open(config_file, "r")
|
||||||
|
configuaration = json.loads(f.read())
|
||||||
|
f.close()
|
||||||
|
else:
|
||||||
|
configuaration = {}
|
||||||
|
# Update data with config file:
|
||||||
|
if "url" in configuaration:
|
||||||
|
self.url = configuaration["url"]
|
||||||
|
if "group" in configuaration:
|
||||||
|
self.group = configuaration["group"]
|
||||||
|
if "token" in configuaration:
|
||||||
|
self.token = configuaration["token"]
|
||||||
|
# set user command - line configuration:
|
||||||
|
if url is not None:
|
||||||
|
self.url = url
|
||||||
|
if group is not None:
|
||||||
|
self.group = group
|
||||||
|
if token is not None:
|
||||||
|
self.token = token
|
||||||
|
|
||||||
|
def get_url(self, service: str):
|
||||||
|
return f"{self.url}/{service}/{self.group}"
|
||||||
|
|
||||||
|
def get_header(self):
|
||||||
|
header = {}
|
||||||
|
if self.token is not None and len(self.token) >15:
|
||||||
|
header['Authorization'] = f"zota {self.token}"
|
||||||
|
return header
|
21
client/python/karanage/karanage/exception.py
Normal file
21
client/python/karanage/karanage/exception.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2023, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license MPL v2.0 (see license file)
|
||||||
|
##
|
||||||
|
|
||||||
|
class KaranageException(Exception):
|
||||||
|
def __init__(self, message, error_id, error_message):
|
||||||
|
# Call the base class constructor with the parameters it needs
|
||||||
|
super().__init__(message)
|
||||||
|
|
||||||
|
# Now for your custom code...
|
||||||
|
self.error_id = error_id
|
||||||
|
self.error_message = error_message
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{Exception.__str__(self)} Status={self.error_id} message='{self.error_message}'"
|
@ -1,151 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
##
|
|
||||||
## @author Edouard DUPIN
|
|
||||||
##
|
|
||||||
## @copyright 2023, Edouard DUPIN, all right reserved
|
|
||||||
##
|
|
||||||
## @license MPL v2.0 (see license file)
|
|
||||||
##
|
|
||||||
import enum
|
|
||||||
import requests
|
|
||||||
import json
|
|
||||||
from typing import Dict, Optional
|
|
||||||
|
|
||||||
class KarangeSendError(Exception):
|
|
||||||
def __init__(self, message, error_id, error_message):
|
|
||||||
# Call the base class constructor with the parameters it needs
|
|
||||||
super().__init__(message)
|
|
||||||
|
|
||||||
# Now for your custom code...
|
|
||||||
self.error_id = error_id
|
|
||||||
self.error_message = error_message
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{Exception.__str__(self)} Status={self.error_id} message='{self.error_message}'"
|
|
||||||
|
|
||||||
class KarangeException(KarangeSendError):
|
|
||||||
def __init__(self, message, error_id, error_message):
|
|
||||||
# Call the base class constructor with the parameters it needs
|
|
||||||
super().__init__(message, error_id, error_message )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class StateSystem(enum.Enum):
|
|
||||||
OK = "OK"
|
|
||||||
FAIL = "FAIL"
|
|
||||||
DOWN = "DOWN"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Generic karanage sending system.
|
|
||||||
class KaranageREST:
|
|
||||||
def __init__(self, url: str, group: str, token: str) -> None:
|
|
||||||
"""
|
|
||||||
@brief Initialize the communication class.
|
|
||||||
@param[in] url URL of the karanage API server.
|
|
||||||
@param[in] group Group of the message (token need to have the autorisation to pubhied on it).
|
|
||||||
@param[in] token Token to validate the access on the application.
|
|
||||||
"""
|
|
||||||
self.url = url
|
|
||||||
self.group = group
|
|
||||||
self.token = token
|
|
||||||
|
|
||||||
def get_url(self, service: str, topic: Optional[str] = None):
|
|
||||||
if topic is None:
|
|
||||||
return f"{self.url}/{service}/{self.group}"
|
|
||||||
return f"{self.url}/{service}/{self.group}/{topic}"
|
|
||||||
|
|
||||||
def send_state_to_server(self, topic: str, data: Optional[Dict], state: StateSystem = StateSystem.OK) -> None:
|
|
||||||
"""
|
|
||||||
@brief Send a message to the server.
|
|
||||||
@param[in] topic Topic where to publish the data.
|
|
||||||
@param[in] data: Data to send to the server
|
|
||||||
@param[in] state: State of the current system
|
|
||||||
"""
|
|
||||||
if data is None:
|
|
||||||
data = {}
|
|
||||||
param = {
|
|
||||||
"state": state,
|
|
||||||
}
|
|
||||||
header = {}
|
|
||||||
if self.token is not None and len(self.token) >15:
|
|
||||||
header['Authorization'] = f"zota {self.token}"
|
|
||||||
try:
|
|
||||||
ret = requests.post(self.get_url("state", topic), json=data, headers=header, params=param)
|
|
||||||
except requests.exceptions.ConnectionError as ex:
|
|
||||||
raise KarangeException(f"Fail connect server: {self.get_url('state', topic)}", 0, str(ex))
|
|
||||||
if 200 <= ret.status_code <= 299:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
raise KarangeException(f"Fail send message: {self.get_url('state', topic)}", ret.status_code, ret.content.decode("utf-8"))
|
|
||||||
|
|
||||||
def get_state_all(self, since: Optional[str] = None) -> Dict:
|
|
||||||
"""
|
|
||||||
@brief Get all the topic fom the server.
|
|
||||||
@param since ISO1866 time value.
|
|
||||||
@return A dictionnary with the requested data.
|
|
||||||
"""
|
|
||||||
param = { }
|
|
||||||
header = { }
|
|
||||||
if self.token is not None and len(self.token) >15:
|
|
||||||
header['Authorization'] = f"zota {self.token}"
|
|
||||||
if since is not None:
|
|
||||||
param["since"] = since
|
|
||||||
ret = requests.get(self.get_url("state"), headers=header, params=param)
|
|
||||||
if 200 == ret.status_code:
|
|
||||||
return json.loads(ret.content.decode('utf-8'))
|
|
||||||
raise KarangeException(f"Fail get data: {self.get_url('state')}", ret.status_code, ret.content.decode("utf-8"))
|
|
||||||
|
|
||||||
def get_state_topic(self, topic: str, since: Optional[str] = None) -> Dict:
|
|
||||||
"""
|
|
||||||
@brief Get all the topic fom the server.
|
|
||||||
@param since ISO1866 time value.
|
|
||||||
@return A dictionnary with the requested data.
|
|
||||||
"""
|
|
||||||
param = { }
|
|
||||||
header = { }
|
|
||||||
if self.token is not None and len(self.token) >15:
|
|
||||||
header['Authorization'] = f"zota {self.token}"
|
|
||||||
if since is not None:
|
|
||||||
param["since"] = since
|
|
||||||
ret = requests.get(self.get_url("state", topic), headers=header, params=param)
|
|
||||||
#print(ret.content.decode('utf-8'))
|
|
||||||
if 200 == ret.status_code:
|
|
||||||
return json.loads(ret.content.decode('utf-8'))
|
|
||||||
raise KarangeException(f"Fail get data: {self.get_url('state', topic)}", ret.status_code, ret.content.decode("utf-8"))
|
|
||||||
|
|
||||||
def get_state_history_topic(self, topic: str, since: Optional[str] = None, since_id: Optional[int] = None, limit: Optional[int] = None) -> Dict:
|
|
||||||
"""
|
|
||||||
@brief Get all the topic fom the server.
|
|
||||||
@param since ISO1866 time value.
|
|
||||||
@param since_id remote BDD index of tje fielf.
|
|
||||||
@param limit Number of value we want to get
|
|
||||||
@return A dictionnary with the requested data.
|
|
||||||
"""
|
|
||||||
param = { }
|
|
||||||
header = { }
|
|
||||||
if self.token is not None and len(self.token) >15:
|
|
||||||
header['Authorization'] = f"zota {self.token}"
|
|
||||||
if since is not None:
|
|
||||||
param["since"] = since
|
|
||||||
if since_id is not None:
|
|
||||||
param["sinceId"] = since_id
|
|
||||||
if limit is not None:
|
|
||||||
param["limit"] = limit
|
|
||||||
ret = requests.get(self.get_url("state_history", topic), headers=header, params=param)
|
|
||||||
#print(ret.content.decode('utf-8'))
|
|
||||||
if 200 == ret.status_code:
|
|
||||||
return json.loads(ret.content.decode('utf-8'))
|
|
||||||
raise KarangeException(f"Fail get data: {self.get_url('state_history', topic)}", ret.status_code, ret.content.decode("utf-8"))
|
|
||||||
|
|
||||||
|
|
||||||
def get_all(self) -> Dict:
|
|
||||||
"""Deprecated"""
|
|
||||||
return self.get_state_all()
|
|
||||||
def get_topic(self, topic: str) -> Dict:
|
|
||||||
"""Deprecated"""
|
|
||||||
return self.get_state_topic(topic)
|
|
||||||
def send_to_server(self, topic: str, data: Optional[Dict], state: StateSystem = StateSystem.OK) -> None:
|
|
||||||
"""Deprecated"""
|
|
||||||
return self.send_state_to_server(topic, data, state)
|
|
52
client/python/karanage/karanage/log.py
Normal file
52
client/python/karanage/karanage/log.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2023, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license MPL v2.0 (see license file)
|
||||||
|
##
|
||||||
|
import enum
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
from typing import Dict, Optional
|
||||||
|
from .connection import KaranageConnection
|
||||||
|
from .exception import KaranageException
|
||||||
|
|
||||||
|
## Generic karanage sending system.
|
||||||
|
class KaranageLog:
|
||||||
|
def __init__(self, connection: KaranageConnection, system: Optional[str] = None) -> None:
|
||||||
|
"""
|
||||||
|
@brief Initialize the communication class.
|
||||||
|
@param[in] connection Connection interface.
|
||||||
|
"""
|
||||||
|
self.connection = connection
|
||||||
|
self.system = system
|
||||||
|
self.service = "log"
|
||||||
|
|
||||||
|
def get_url(self):
|
||||||
|
if self.system is None:
|
||||||
|
return self.connection.get_url(self.service)
|
||||||
|
return f"{self.connection.get_url(self.service)}/{self.system}"
|
||||||
|
|
||||||
|
def send(self, system: str, data: Dict, id: int = None) -> None:
|
||||||
|
"""
|
||||||
|
@brief Send a message to the server.
|
||||||
|
@param[in] system system where to publish the data.
|
||||||
|
@param[in] data: Data to send to the server
|
||||||
|
@param[in] id: Local internal ID
|
||||||
|
"""
|
||||||
|
param = {}
|
||||||
|
if id is not None:
|
||||||
|
param["id"] = id
|
||||||
|
header = self.connection.get_header()
|
||||||
|
try:
|
||||||
|
ret = requests.post(self.get_url(), json=data, headers=header, params=param)
|
||||||
|
except requests.exceptions.ConnectionError as ex:
|
||||||
|
raise KaranageException(f"Fail connect server: {self.get_url('state', system)}", 0, str(ex))
|
||||||
|
if 200 <= ret.status_code <= 299:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise KaranageException(f"Fail send message: {self.get_url('state', system)}", ret.status_code, ret.content.decode("utf-8"))
|
||||||
|
|
96
client/python/karanage/karanage/state.py
Normal file
96
client/python/karanage/karanage/state.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## @author Edouard DUPIN
|
||||||
|
##
|
||||||
|
## @copyright 2023, Edouard DUPIN, all right reserved
|
||||||
|
##
|
||||||
|
## @license MPL v2.0 (see license file)
|
||||||
|
##
|
||||||
|
import enum
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
from typing import Dict, Optional
|
||||||
|
from .connection import KaranageConnection
|
||||||
|
from .exception import KaranageException
|
||||||
|
|
||||||
|
class StateSystem(enum.Enum):
|
||||||
|
OK = "OK"
|
||||||
|
FAIL = "FAIL"
|
||||||
|
DOWN = "DOWN"
|
||||||
|
|
||||||
|
## Generic karanage sending system.
|
||||||
|
class KaranageState:
|
||||||
|
def __init__(self, connection: KaranageConnection) -> None:
|
||||||
|
"""
|
||||||
|
@brief Initialize the communication class.
|
||||||
|
@param[in] connection Connection interface.
|
||||||
|
"""
|
||||||
|
self.connection = connection
|
||||||
|
|
||||||
|
def get_url(self, service: str, topic: Optional[str] = None):
|
||||||
|
if topic is None:
|
||||||
|
return self.connection.get_url(service)
|
||||||
|
return f"{self.connection.get_url(service)}/{topic}"
|
||||||
|
|
||||||
|
def send(self, topic: str, data: Optional[Dict], state: StateSystem = StateSystem.OK) -> None:
|
||||||
|
"""
|
||||||
|
@brief Send a message to the server.
|
||||||
|
@param[in] topic Topic where to publish the data.
|
||||||
|
@param[in] data: Data to send to the server
|
||||||
|
@param[in] state: State of the current system
|
||||||
|
"""
|
||||||
|
if data is None:
|
||||||
|
data = {}
|
||||||
|
param = {}
|
||||||
|
if state is not None:
|
||||||
|
param["state"] = state
|
||||||
|
header = self.connection.get_header()
|
||||||
|
try:
|
||||||
|
ret = requests.post(self.get_url("state", topic), json=data, headers=header, params=param)
|
||||||
|
except requests.exceptions.ConnectionError as ex:
|
||||||
|
raise KaranageException(f"Fail connect server: {self.get_url('state', topic)}", 0, str(ex))
|
||||||
|
if 200 <= ret.status_code <= 299:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise KaranageException(f"Fail send message: {self.get_url('state', topic)}", ret.status_code, ret.content.decode("utf-8"))
|
||||||
|
|
||||||
|
|
||||||
|
def gets(self, topic: Optional[str] = None, since: Optional[str] = None) -> Dict:
|
||||||
|
"""
|
||||||
|
@brief Get all the topic fom the server.
|
||||||
|
@param since ISO1866 time value.
|
||||||
|
@return A dictionnary with the requested data.
|
||||||
|
"""
|
||||||
|
param = { }
|
||||||
|
header = self.connection.get_header()
|
||||||
|
if since is not None:
|
||||||
|
param["since"] = since
|
||||||
|
ret = requests.get(self.get_url("state", topic), headers=header, params=param)
|
||||||
|
#print(ret.content.decode('utf-8'))
|
||||||
|
if 200 == ret.status_code:
|
||||||
|
return json.loads(ret.content.decode('utf-8'))
|
||||||
|
raise KaranageException(f"Fail get data: {self.get_url('state', topic)}", ret.status_code, ret.content.decode("utf-8"))
|
||||||
|
|
||||||
|
def get_history(self, topic: Optional[str] = None, since: Optional[str] = None, since_id: Optional[int] = None, limit: Optional[int] = None) -> Dict:
|
||||||
|
"""
|
||||||
|
@brief Get all the topic fom the server.
|
||||||
|
@param since ISO1866 time value.
|
||||||
|
@param since_id remote BDD index of tje fielf.
|
||||||
|
@param limit Number of value we want to get
|
||||||
|
@return A dictionnary with the requested data.
|
||||||
|
"""
|
||||||
|
param = { }
|
||||||
|
header = self.connection.get_header()
|
||||||
|
if since is not None:
|
||||||
|
param["since"] = since
|
||||||
|
if since_id is not None:
|
||||||
|
param["sinceId"] = since_id
|
||||||
|
if limit is not None:
|
||||||
|
param["limit"] = limit
|
||||||
|
ret = requests.get(self.get_url("state_history", topic), headers=header, params=param)
|
||||||
|
#print(ret.content.decode('utf-8'))
|
||||||
|
if 200 == ret.status_code:
|
||||||
|
return json.loads(ret.content.decode('utf-8'))
|
||||||
|
raise KaranageException(f"Fail get data: {self.get_url('state_history', topic)}", ret.status_code, ret.content.decode("utf-8"))
|
||||||
|
|
@ -56,4 +56,5 @@ setup(name='karanage',
|
|||||||
|
|
||||||
# https://packaging.python.org/en/latest/tutorials/packaging-projects/
|
# https://packaging.python.org/en/latest/tutorials/packaging-projects/
|
||||||
# python3 -m build
|
# python3 -m build
|
||||||
# python3 -m twine upload dist/*
|
# python3 -m twine upload dist/*
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
0.2.0-dev
|
0.3.0-dev
|
@ -48,11 +48,10 @@ docker-compose up -d
|
|||||||
|
|
||||||
build the local image:
|
build the local image:
|
||||||
|
|
||||||
|
docker login gitea.atria-soft.org
|
||||||
|
|
||||||
docker pull archlinux:base-devel
|
docker pull archlinux:base-devel
|
||||||
docker pull bellsoft/liberica-openjdk-alpine:latest
|
docker pull bellsoft/liberica-openjdk-alpine:latest
|
||||||
|
|
||||||
docker build -t gitea.atria-soft.org/kangaroo-and-rabbit/karanage:latest .
|
docker build -t gitea.atria-soft.org/kangaroo-and-rabbit/karanage:latest .
|
||||||
|
|
||||||
docker login gitea.atria-soft.org
|
|
||||||
|
|
||||||
docker push gitea.atria-soft.org/kangaroo-and-rabbit/karanage:latest
|
docker push gitea.atria-soft.org/kangaroo-and-rabbit/karanage:latest
|
||||||
|
Loading…
Reference in New Issue
Block a user