5050import java .util .stream .Stream ;
5151import java .util .stream .StreamSupport ;
5252import net .opengis .swe .v20 .BinaryEncoding ;
53+ import org .sensorhub .api .command .CommandStatus ;
5354import org .sensorhub .api .command .CommandStreamInfo ;
5455import org .sensorhub .api .command .ICommandData ;
56+ import org .sensorhub .api .command .ICommandStatus ;
5557import org .sensorhub .api .command .ICommandStreamInfo ;
5658import org .sensorhub .api .common .BigId ;
5759import org .sensorhub .api .data .DataStreamInfo ;
8082import org .sensorhub .impl .service .consys .resource .ResourceLink ;
8183import org .sensorhub .impl .service .consys .system .SystemBindingGeoJson ;
8284import org .sensorhub .impl .service .consys .system .SystemBindingSmlJson ;
85+ import org .sensorhub .impl .service .consys .task .CommandBindingJson ;
86+ import org .sensorhub .impl .service .consys .task .CommandBindingSweCommon ;
87+ import org .sensorhub .impl .service .consys .task .CommandHandler ;
88+ import org .sensorhub .impl .service .consys .task .CommandResultBindingSweCommon ;
89+ import org .sensorhub .impl .service .consys .task .CommandStatusBindingJson ;
90+ import org .sensorhub .impl .service .consys .task .CommandStatusHandler .CommandStatusHandlerContextData ;
8391import org .sensorhub .impl .service .consys .task .CommandStreamBindingJson ;
8492import org .sensorhub .impl .service .consys .task .CommandStreamSchemaBindingJson ;
8593import org .sensorhub .utils .Lambdas ;
@@ -101,8 +109,9 @@ public class ConSysApiClient
101109 static final String SYSTEMS_COLLECTION = "systems" ;
102110 static final String DEPLOYMENTS_COLLECTION = "deployments" ;
103111 static final String DATASTREAMS_COLLECTION = "datastreams" ;
104- static final String CONTROLS_COLLECTION = "controlstreams" ;
105112 static final String OBSERVATIONS_COLLECTION = "observations" ;
113+ static final String CONTROLSTREAMS_COLLECTION = "controlstreams" ;
114+ static final String COMMANDS_COLLECTION = "commands" ;
106115 static final String SUBSYSTEMS_COLLECTION = "subsystems" ;
107116 static final String SF_COLLECTION = "samplingFeatures" ;
108117
@@ -842,7 +851,7 @@ public CompletableFuture<String> addControlStream(String systemId, ICommandStrea
842851 binding .serializeCreate (cmdstream );
843852
844853 return sendPostRequest (
845- endpoint .resolve (SYSTEMS_COLLECTION + "/" + systemId + "/" + CONTROLS_COLLECTION ),
854+ endpoint .resolve (SYSTEMS_COLLECTION + "/" + systemId + "/" + CONTROLSTREAMS_COLLECTION ),
846855 ResourceFormat .JSON ,
847856 buffer .toByteArray ());
848857 }
@@ -885,7 +894,7 @@ protected void endJsonCollection(JsonWriter writer, Collection<ResourceLink> lin
885894 binding .endCollection (Collections .emptyList ());
886895
887896 return sendBatchPostRequest (
888- endpoint .resolve (SYSTEMS_COLLECTION + "/" + systemId + "/" + CONTROLS_COLLECTION ),
897+ endpoint .resolve (SYSTEMS_COLLECTION + "/" + systemId + "/" + CONTROLSTREAMS_COLLECTION ),
889898 ResourceFormat .JSON ,
890899 buffer .toByteArray ());
891900 }
@@ -898,7 +907,7 @@ protected void endJsonCollection(JsonWriter writer, Collection<ResourceLink> lin
898907
899908 public CompletableFuture <ICommandStreamInfo > getControlStreamById (String id , ResourceFormat format , boolean fetchSchema )
900909 {
901- var cf1 = sendGetRequest (endpoint .resolve (CONTROLS_COLLECTION + "/" + id ), format , body -> {
910+ var cf1 = sendGetRequest (endpoint .resolve (CONTROLSTREAMS_COLLECTION + "/" + id ), format , body -> {
902911 try
903912 {
904913 var ctx = new RequestContext (body );
@@ -933,7 +942,7 @@ public CompletableFuture<ICommandStreamInfo> getControlStreamById(String id, Res
933942
934943 public CompletableFuture <ICommandStreamInfo > getControlStreamSchema (String id , ResourceFormat obsFormat , ResourceFormat format )
935944 {
936- return sendGetRequest (endpoint .resolve (CONTROLS_COLLECTION + "/" + id + "/schema?obsFormat=" + obsFormat ), format , body -> {
945+ return sendGetRequest (endpoint .resolve (CONTROLSTREAMS_COLLECTION + "/" + id + "/schema?obsFormat=" + obsFormat ), format , body -> {
937946 try
938947 {
939948 var ctx = new RequestContext (body );
@@ -1088,9 +1097,55 @@ public Spliterator<IObsData> trySplit()
10881097 /* Commands */
10891098 /*----------*/
10901099
1091- public CompletableFuture <String > sendCommand (String controlId , ICommandData cmd )
1100+ public CompletableFuture <ICommandStatus > sendCommand (String controlstreamId , ICommandStreamInfo cmdStream , ICommandData cmd )
10921101 {
1093- return null ;
1102+ try
1103+ {
1104+ var buffer = new ByteArrayOutputStream ();
1105+ var ctx = new RequestContext (buffer );
1106+ ctx .setParent (null , controlstreamId , cmd .getCommandStreamID ());
1107+ var contextData = new CommandHandler .CommandHandlerContextData ();
1108+ contextData .csInfo = cmdStream ;
1109+ ctx .setData (contextData );
1110+
1111+ if (cmdStream != null && cmdStream .getRecordEncoding () instanceof BinaryEncoding ) {
1112+ ctx .setData (contextData );
1113+ ctx .setFormat (ResourceFormat .SWE_BINARY );
1114+ var binding = new CommandBindingSweCommon (ctx , new IdEncodersBase32 (), false , null );
1115+ binding .serialize (null , cmd , false );
1116+ } else {
1117+ ctx .setFormat (ResourceFormat .JSON );
1118+ var binding = new CommandBindingJson (ctx , new IdEncodersBase32 (), false , null );
1119+ binding .serialize (null , cmd , false );
1120+ }
1121+
1122+ return sendPostRequestAndReadResponse (
1123+ endpoint .resolve (CONTROLSTREAMS_COLLECTION + "/" + controlstreamId + "/" + COMMANDS_COLLECTION ),
1124+ ctx .getFormat (),
1125+ buffer .toByteArray (),
1126+ responseBody -> {
1127+ try
1128+ {
1129+ var respCtx = new RequestContext (responseBody );
1130+ var respCtxData = new CommandStatusHandlerContextData ();
1131+ respCtxData .csInfo = cmdStream ;
1132+ respCtx .setData (respCtxData );
1133+ respCtx .setFormat (ResourceFormat .JSON );
1134+ var binding = new CommandStatusBindingJson (respCtx , new IdEncodersBase32 (), true , null );
1135+ binding .startCollection ();
1136+ return binding .deserialize ();
1137+ }
1138+ catch (IOException e )
1139+ {
1140+ e .printStackTrace ();
1141+ throw new CompletionException (e );
1142+ }
1143+ });
1144+ }
1145+ catch (IOException e )
1146+ {
1147+ throw new IllegalStateException ("Error initializing binding" , e );
1148+ }
10941149 }
10951150
10961151
@@ -1202,6 +1257,45 @@ protected CompletableFuture<String> sendPostRequest(URI collectionUri, ResourceF
12021257 }
12031258
12041259
1260+ protected <T > CompletableFuture <T > sendPostRequestAndReadResponse (URI collectionUri , ResourceFormat format , byte [] requestBody , Function <InputStream , T > responseBodyMapper )
1261+ {
1262+ //if (!isHttpClientAvailable)
1263+ // return sendPostRequestFallback(collectionUri, format, body);
1264+
1265+ var builder = HttpRequest .newBuilder ()
1266+ .uri (collectionUri )
1267+ .POST (HttpRequest .BodyPublishers .ofByteArray (requestBody ))
1268+ .header (HttpHeaders .ACCEPT , ResourceFormat .JSON .getMimeType ())
1269+ .header (HttpHeaders .CONTENT_TYPE , format .getMimeType ());
1270+
1271+ if (token != null )
1272+ builder .header (HttpHeaders .AUTHORIZATION , "Bearer " + token );
1273+
1274+
1275+ var req = builder .build ();
1276+ BodyHandler <T > bodyHandler = resp -> {
1277+ BodySubscriber <byte []> upstream = BodySubscribers .ofByteArray ();
1278+ return BodySubscribers .mapping (upstream , body -> {
1279+ if (resp .statusCode () == 200 ) {
1280+ var is = new ByteArrayInputStream (body );
1281+ return responseBodyMapper .apply (is );
1282+ } else {
1283+ var error = new String (body );
1284+ throw new CompletionException ("HTTP error " + resp .statusCode () + ": " + error , null );
1285+ }
1286+ });
1287+ };
1288+
1289+ return http .sendAsync (req , bodyHandler )
1290+ .thenApply (resp -> {
1291+ if (resp .statusCode () == 200 )
1292+ return resp .body ();
1293+ else
1294+ throw new CompletionException ("HTTP error " + resp .statusCode (), null );
1295+ });
1296+ }
1297+
1298+
12051299 /**
12061300 * Fallback method for sending requests using HttpURLConnection.
12071301 * This is used when HttpClient is not available (e.g., on Android).
0 commit comments