11package org .imdc .nodered .servlet ;
22
3+ import com .inductiveautomation .ignition .common .Dataset ;
4+ import com .inductiveautomation .ignition .common .TypeUtilities ;
35import com .inductiveautomation .ignition .common .browsing .BrowseFilter ;
46import com .inductiveautomation .ignition .common .browsing .Results ;
57import com .inductiveautomation .ignition .common .model .values .QualifiedValue ;
68import com .inductiveautomation .ignition .common .model .values .QualityCode ;
9+ import com .inductiveautomation .ignition .common .script .builtin .DatasetUtilities ;
710import com .inductiveautomation .ignition .common .tags .browsing .NodeDescription ;
811import com .inductiveautomation .ignition .common .tags .model .TagPath ;
912import com .inductiveautomation .ignition .common .tags .paths .parser .TagPathParser ;
13+ import com .inductiveautomation .ignition .common .util .AuditStatus ;
14+ import com .inductiveautomation .ignition .gateway .audit .AuditContext ;
15+ import com .inductiveautomation .ignition .gateway .audit .AuditProfile ;
16+ import com .inductiveautomation .ignition .gateway .audit .AuditRecord ;
1017import com .inductiveautomation .ignition .gateway .model .GatewayContext ;
1118import org .json .JSONArray ;
1219import org .json .JSONException ;
2128import java .io .BufferedReader ;
2229import java .io .IOException ;
2330import java .text .SimpleDateFormat ;
24- import java .util .ArrayList ;
25- import java .util .Collection ;
26- import java .util .Iterator ;
27- import java .util .List ;
31+ import java .util .*;
2832import java .util .concurrent .ExecutionException ;
2933
3034public class NodeREDServlet extends HttpServlet {
@@ -69,6 +73,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
6973 String contentType = req .getContentType ();
7074 JSONObject input = null ;
7175 JSONObject ret = new JSONObject ();
76+ String ipAddress = req .getRemoteAddr ();
7277
7378 if ("application/json" .equals (contentType )) {
7479 String jsonString = reqToJSON (req );
@@ -157,7 +162,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
157162 if (values .size () != tagPaths .size ()) {
158163 errorMessage = "Number of tag paths (" + tagPaths .size () + ") does not match values (" + values .size () + ")" ;
159164 } else {
160- tagWrite (context , tagPaths , values , result );
165+ tagWrite (context , tagPaths , values , result , ipAddress , validation );
161166 }
162167 }
163168 }
@@ -203,7 +208,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
203208 public static void setTagValue (List <TagPath > tagPaths , List <QualifiedValue > tagValues , JSONObject result ) throws JSONException {
204209 if (tagPaths .size () == 1 ) {
205210 result .put ("tagPath" , tagPaths .get (0 ).toStringFull ());
206- result .put ("value" , tagValues .get (0 ).getValue ());
211+ result .put ("value" , checkObject ( tagValues .get (0 ).getValue () ));
207212 setQuality (result , tagValues .get (0 ).getQuality ());
208213 result .put ("timestamp" , DF .format (tagValues .get (0 ).getTimestamp ()));
209214 } else {
@@ -213,7 +218,7 @@ public static void setTagValue(List<TagPath> tagPaths, List<QualifiedValue> tagV
213218 QualifiedValue tagValue = tagValues .get (i );
214219 JSONObject tagObject = new JSONObject ();
215220 tagObject .put ("tagPath" , tagPath .toStringFull ());
216- tagObject .put ("value" , tagValue .getValue ());
221+ tagObject .put ("value" , checkObject ( tagValue .getValue () ));
217222 setQuality (tagObject , tagValue .getQuality ());
218223 tagObject .put ("timestamp" , DF .format (tagValue .getTimestamp ()));
219224 resultValues .put (tagObject );
@@ -222,6 +227,14 @@ public static void setTagValue(List<TagPath> tagPaths, List<QualifiedValue> tagV
222227 }
223228 }
224229
230+ public static Object checkObject (Object value ) {
231+ if (value instanceof Dataset ) {
232+ return DatasetUtilities .toJSONObject ((Dataset ) value );
233+ }
234+
235+ return value ;
236+ }
237+
225238 public static void setQuality (JSONObject result , QualityCode qual ) throws JSONException {
226239 JSONObject quality = new JSONObject ();
227240 quality .put ("name" , qual .getName ());
@@ -273,29 +286,48 @@ private void tagRead(GatewayContext context, final List<TagPath> tagPaths, JSONO
273286 setTagValue (tagPaths , tagValues , result );
274287 }
275288
276- private void tagWrite (GatewayContext context , final List <TagPath > tagPaths , final List <Object > writeValues , JSONObject result ) throws JSONException , ExecutionException , InterruptedException {
289+ private void tagWrite (GatewayContext context , final List <TagPath > tagPaths , final List <Object > writeValues , JSONObject result , String ipAddress , APITokenValidation validation ) throws JSONException , ExecutionException , InterruptedException {
277290 List <QualityCode > writeResult = context .getTagManager ().writeAsync (tagPaths , writeValues ).get ();
291+
278292 if (tagPaths .size () == 1 ) {
279293 TagPath tagPath = tagPaths .get (0 );
280294 QualityCode quality = writeResult .get (0 );
295+ Object value = writeValues .get (0 );
281296 result .put ("tagPath" , tagPath .toStringFull ());
282- result .put ("value" , writeValues . get ( 0 ) );
297+ result .put ("value" , value );
283298 setQuality (result , quality );
299+ audit (context , ipAddress , validation , tagPath , value , quality );
284300 } else {
285301 JSONArray resultValues = new JSONArray ();
286302 for (int i = 0 ; i < tagPaths .size (); i ++) {
287303 JSONObject tagObject = new JSONObject ();
288304 TagPath tagPath = tagPaths .get (i );
289305 QualityCode quality = writeResult .get (i );
306+ Object value = writeValues .get (i );
290307 tagObject .put ("tagPath" , tagPath .toStringFull ());
291- tagObject .put ("value" , writeValues . get ( i ) );
308+ tagObject .put ("value" , value );
292309 setQuality (tagObject , quality );
293310 resultValues .put (tagObject );
311+ audit (context , ipAddress , validation , tagPath , value , quality );
294312 }
295313 result .put ("values" , resultValues );
296314 }
297315 }
298316
317+ private void audit (GatewayContext context , String ipAddress , APITokenValidation validation , TagPath tagPath , Object writeValue , QualityCode writeResult ) {
318+ if (validation .isAuditProfileDefined ()) {
319+ try {
320+ AuditProfile auditProfile = context .getAuditManager ().getProfile (validation .getAuditProfileName ());
321+ AuditContext auditContext = context .getAuditManager ().getAuditContext ().orElseGet (AuditContext .UNKNOWN );
322+ String qualifiedPath = auditContext .getPath ().extend ("NodeRED" , validation .getTokenName ()).toString ();
323+ AuditRecord auditRecord = auditContext .toRecordBuilder ().setAction ("tag write" ).setActionTarget (tagPath .toStringFull ()).setActionValue (TypeUtilities .toString (writeValue )).setTimestamp (new Date ()).setActor (validation .getToken ()).setActorHost (ipAddress ).setOriginatingSystem (qualifiedPath ).setStatusCode (writeResult .isGood () ? AuditStatus .GOOD .getRawValue () : AuditStatus .BAD .getRawValue ()).build ();
324+ auditProfile .audit (auditRecord );
325+ } catch (Throwable t ) {
326+ logger .error ("Error with audit: " + validation .getAuditProfileName (), t );
327+ }
328+ }
329+ }
330+
299331 private String reqToJSON (HttpServletRequest req ) throws IOException {
300332 StringBuilder sb = new StringBuilder ();
301333 String line ;
0 commit comments