151 changed files with 5585 additions and 688 deletions
File diff suppressed because it is too large
@ -0,0 +1,520 @@ |
|||||
|
{ |
||||
|
"title": "Rule Engine Statistics", |
||||
|
"configuration": { |
||||
|
"widgets": { |
||||
|
"81987f19-3eac-e4ce-b790-d96e9b54d9a0": { |
||||
|
"isSystemType": true, |
||||
|
"bundleAlias": "charts", |
||||
|
"typeAlias": "basic_timeseries", |
||||
|
"type": "timeseries", |
||||
|
"title": "New widget", |
||||
|
"sizeX": 12, |
||||
|
"sizeY": 7, |
||||
|
"config": { |
||||
|
"datasources": [ |
||||
|
{ |
||||
|
"type": "entity", |
||||
|
"dataKeys": [ |
||||
|
{ |
||||
|
"name": "successfulMsgs", |
||||
|
"type": "timeseries", |
||||
|
"label": "${entityName} Successful", |
||||
|
"color": "#4caf50", |
||||
|
"settings": { |
||||
|
"excludeFromStacking": false, |
||||
|
"hideDataByDefault": false, |
||||
|
"disableDataHiding": false, |
||||
|
"removeFromLegend": false, |
||||
|
"showLines": true, |
||||
|
"fillLines": false, |
||||
|
"showPoints": false, |
||||
|
"showPointShape": "circle", |
||||
|
"pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", |
||||
|
"showPointsLineWidth": 5, |
||||
|
"showPointsRadius": 3, |
||||
|
"showSeparateAxis": false, |
||||
|
"axisPosition": "left", |
||||
|
"thresholds": [ |
||||
|
{ |
||||
|
"thresholdValueSource": "predefinedValue" |
||||
|
} |
||||
|
], |
||||
|
"comparisonSettings": { |
||||
|
"showValuesForComparison": true |
||||
|
} |
||||
|
}, |
||||
|
"_hash": 0.15490750967648736 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "failedMsgs", |
||||
|
"type": "timeseries", |
||||
|
"label": "${entityName} Permanent Failures", |
||||
|
"color": "#ef5350", |
||||
|
"settings": { |
||||
|
"excludeFromStacking": false, |
||||
|
"hideDataByDefault": false, |
||||
|
"disableDataHiding": false, |
||||
|
"removeFromLegend": false, |
||||
|
"showLines": true, |
||||
|
"fillLines": false, |
||||
|
"showPoints": false, |
||||
|
"showPointShape": "circle", |
||||
|
"pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", |
||||
|
"showPointsLineWidth": 5, |
||||
|
"showPointsRadius": 3, |
||||
|
"showSeparateAxis": false, |
||||
|
"axisPosition": "left", |
||||
|
"thresholds": [ |
||||
|
{ |
||||
|
"thresholdValueSource": "predefinedValue" |
||||
|
} |
||||
|
], |
||||
|
"comparisonSettings": { |
||||
|
"showValuesForComparison": true |
||||
|
} |
||||
|
}, |
||||
|
"_hash": 0.4186621166514697 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "tmpFailed", |
||||
|
"type": "timeseries", |
||||
|
"label": "${entityName} Processing Failures", |
||||
|
"color": "#ffc107", |
||||
|
"settings": { |
||||
|
"excludeFromStacking": false, |
||||
|
"hideDataByDefault": false, |
||||
|
"disableDataHiding": false, |
||||
|
"removeFromLegend": false, |
||||
|
"showLines": true, |
||||
|
"fillLines": false, |
||||
|
"showPoints": false, |
||||
|
"showPointShape": "circle", |
||||
|
"pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", |
||||
|
"showPointsLineWidth": 5, |
||||
|
"showPointsRadius": 3, |
||||
|
"showSeparateAxis": false, |
||||
|
"axisPosition": "left", |
||||
|
"thresholds": [ |
||||
|
{ |
||||
|
"thresholdValueSource": "predefinedValue" |
||||
|
} |
||||
|
], |
||||
|
"comparisonSettings": { |
||||
|
"showValuesForComparison": true |
||||
|
} |
||||
|
}, |
||||
|
"_hash": 0.49891007198715376 |
||||
|
} |
||||
|
], |
||||
|
"entityAliasId": "140f23dd-e3a0-ed98-6189-03c49d2d8018" |
||||
|
} |
||||
|
], |
||||
|
"timewindow": { |
||||
|
"realtime": { |
||||
|
"interval": 1000, |
||||
|
"timewindowMs": 300000 |
||||
|
}, |
||||
|
"aggregation": { |
||||
|
"type": "NONE", |
||||
|
"limit": 8640 |
||||
|
}, |
||||
|
"hideInterval": false, |
||||
|
"hideAggregation": false, |
||||
|
"hideAggInterval": false |
||||
|
}, |
||||
|
"showTitle": true, |
||||
|
"backgroundColor": "#fff", |
||||
|
"color": "rgba(0, 0, 0, 0.87)", |
||||
|
"padding": "8px", |
||||
|
"settings": { |
||||
|
"shadowSize": 4, |
||||
|
"fontColor": "#545454", |
||||
|
"fontSize": 10, |
||||
|
"xaxis": { |
||||
|
"showLabels": true, |
||||
|
"color": "#545454" |
||||
|
}, |
||||
|
"yaxis": { |
||||
|
"showLabels": true, |
||||
|
"color": "#545454" |
||||
|
}, |
||||
|
"grid": { |
||||
|
"color": "#545454", |
||||
|
"tickColor": "#DDDDDD", |
||||
|
"verticalLines": true, |
||||
|
"horizontalLines": true, |
||||
|
"outlineWidth": 1 |
||||
|
}, |
||||
|
"stack": false, |
||||
|
"tooltipIndividual": false, |
||||
|
"timeForComparison": "months", |
||||
|
"xaxisSecond": { |
||||
|
"axisPosition": "top", |
||||
|
"showLabels": true |
||||
|
} |
||||
|
}, |
||||
|
"title": "Queue Stats", |
||||
|
"dropShadow": true, |
||||
|
"enableFullscreen": true, |
||||
|
"titleStyle": { |
||||
|
"fontSize": "16px", |
||||
|
"fontWeight": 400 |
||||
|
}, |
||||
|
"mobileHeight": null, |
||||
|
"showTitleIcon": false, |
||||
|
"titleIcon": null, |
||||
|
"iconColor": "rgba(0, 0, 0, 0.87)", |
||||
|
"iconSize": "24px", |
||||
|
"titleTooltip": "", |
||||
|
"widgetStyle": {}, |
||||
|
"useDashboardTimewindow": false, |
||||
|
"displayTimewindow": true, |
||||
|
"showLegend": true, |
||||
|
"actions": {}, |
||||
|
"legendConfig": { |
||||
|
"direction": "column", |
||||
|
"position": "bottom", |
||||
|
"showMin": true, |
||||
|
"showMax": true, |
||||
|
"showAvg": false, |
||||
|
"showTotal": true |
||||
|
} |
||||
|
}, |
||||
|
"id": "81987f19-3eac-e4ce-b790-d96e9b54d9a0" |
||||
|
}, |
||||
|
"5eb79712-5c24-3060-7e4f-6af36b8f842d": { |
||||
|
"isSystemType": true, |
||||
|
"bundleAlias": "cards", |
||||
|
"typeAlias": "timeseries_table", |
||||
|
"type": "timeseries", |
||||
|
"title": "New widget", |
||||
|
"sizeX": 24, |
||||
|
"sizeY": 5, |
||||
|
"config": { |
||||
|
"datasources": [ |
||||
|
{ |
||||
|
"type": "entity", |
||||
|
"dataKeys": [ |
||||
|
{ |
||||
|
"name": "ruleEngineException", |
||||
|
"type": "timeseries", |
||||
|
"label": "Rule Chain", |
||||
|
"color": "#2196f3", |
||||
|
"settings": { |
||||
|
"useCellStyleFunction": false, |
||||
|
"useCellContentFunction": true, |
||||
|
"cellContentFunction": "return JSON.parse(value).ruleChainName;" |
||||
|
}, |
||||
|
"_hash": 0.9954481282345906 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "ruleEngineException", |
||||
|
"type": "timeseries", |
||||
|
"label": "Rule Node", |
||||
|
"color": "#4caf50", |
||||
|
"settings": { |
||||
|
"useCellStyleFunction": false, |
||||
|
"useCellContentFunction": true, |
||||
|
"cellContentFunction": "return JSON.parse(value).ruleNodeName;" |
||||
|
}, |
||||
|
"_hash": 0.18580357036589978 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "ruleEngineException", |
||||
|
"type": "timeseries", |
||||
|
"label": "Latest Error", |
||||
|
"color": "#f44336", |
||||
|
"settings": { |
||||
|
"useCellStyleFunction": false, |
||||
|
"useCellContentFunction": true, |
||||
|
"cellContentFunction": "return JSON.parse(value).message;" |
||||
|
}, |
||||
|
"_hash": 0.7255162989552142 |
||||
|
} |
||||
|
], |
||||
|
"entityAliasId": "140f23dd-e3a0-ed98-6189-03c49d2d8018" |
||||
|
} |
||||
|
], |
||||
|
"timewindow": { |
||||
|
"realtime": { |
||||
|
"interval": 1000, |
||||
|
"timewindowMs": 86400000 |
||||
|
}, |
||||
|
"aggregation": { |
||||
|
"type": "NONE", |
||||
|
"limit": 200 |
||||
|
} |
||||
|
}, |
||||
|
"showTitle": true, |
||||
|
"backgroundColor": "rgb(255, 255, 255)", |
||||
|
"color": "rgba(0, 0, 0, 0.87)", |
||||
|
"padding": "8px", |
||||
|
"settings": { |
||||
|
"showTimestamp": true, |
||||
|
"displayPagination": true, |
||||
|
"defaultPageSize": 10 |
||||
|
}, |
||||
|
"title": "Exceptions", |
||||
|
"dropShadow": true, |
||||
|
"enableFullscreen": true, |
||||
|
"titleStyle": { |
||||
|
"fontSize": "16px", |
||||
|
"fontWeight": 400 |
||||
|
}, |
||||
|
"useDashboardTimewindow": false, |
||||
|
"showLegend": false, |
||||
|
"widgetStyle": {}, |
||||
|
"actions": {}, |
||||
|
"showTitleIcon": false, |
||||
|
"titleIcon": null, |
||||
|
"iconColor": "rgba(0, 0, 0, 0.87)", |
||||
|
"iconSize": "24px", |
||||
|
"titleTooltip": "", |
||||
|
"displayTimewindow": true |
||||
|
}, |
||||
|
"id": "5eb79712-5c24-3060-7e4f-6af36b8f842d" |
||||
|
}, |
||||
|
"ad3f1417-87a8-750e-fc67-49a2de1466d4": { |
||||
|
"isSystemType": true, |
||||
|
"bundleAlias": "charts", |
||||
|
"typeAlias": "basic_timeseries", |
||||
|
"type": "timeseries", |
||||
|
"title": "New widget", |
||||
|
"sizeX": 12, |
||||
|
"sizeY": 7, |
||||
|
"config": { |
||||
|
"datasources": [ |
||||
|
{ |
||||
|
"type": "entity", |
||||
|
"dataKeys": [ |
||||
|
{ |
||||
|
"name": "timeoutMsgs", |
||||
|
"type": "timeseries", |
||||
|
"label": "${entityName} Permanent Timeouts", |
||||
|
"color": "#4caf50", |
||||
|
"settings": { |
||||
|
"excludeFromStacking": false, |
||||
|
"hideDataByDefault": false, |
||||
|
"disableDataHiding": false, |
||||
|
"removeFromLegend": false, |
||||
|
"showLines": true, |
||||
|
"fillLines": false, |
||||
|
"showPoints": false, |
||||
|
"showPointShape": "circle", |
||||
|
"pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", |
||||
|
"showPointsLineWidth": 5, |
||||
|
"showPointsRadius": 3, |
||||
|
"showSeparateAxis": false, |
||||
|
"axisPosition": "left", |
||||
|
"thresholds": [ |
||||
|
{ |
||||
|
"thresholdValueSource": "predefinedValue" |
||||
|
} |
||||
|
], |
||||
|
"comparisonSettings": { |
||||
|
"showValuesForComparison": true |
||||
|
} |
||||
|
}, |
||||
|
"_hash": 0.565222981550328 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "tmpTimeout", |
||||
|
"type": "timeseries", |
||||
|
"label": "${entityName} Processing Timeouts", |
||||
|
"color": "#9c27b0", |
||||
|
"settings": { |
||||
|
"excludeFromStacking": false, |
||||
|
"hideDataByDefault": false, |
||||
|
"disableDataHiding": false, |
||||
|
"removeFromLegend": false, |
||||
|
"showLines": true, |
||||
|
"fillLines": false, |
||||
|
"showPoints": false, |
||||
|
"showPointShape": "circle", |
||||
|
"pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", |
||||
|
"showPointsLineWidth": 5, |
||||
|
"showPointsRadius": 3, |
||||
|
"showSeparateAxis": false, |
||||
|
"axisPosition": "left", |
||||
|
"thresholds": [ |
||||
|
{ |
||||
|
"thresholdValueSource": "predefinedValue" |
||||
|
} |
||||
|
], |
||||
|
"comparisonSettings": { |
||||
|
"showValuesForComparison": true |
||||
|
} |
||||
|
}, |
||||
|
"_hash": 0.2679547062508352 |
||||
|
} |
||||
|
], |
||||
|
"entityAliasId": "140f23dd-e3a0-ed98-6189-03c49d2d8018" |
||||
|
} |
||||
|
], |
||||
|
"timewindow": { |
||||
|
"realtime": { |
||||
|
"interval": 1000, |
||||
|
"timewindowMs": 300000 |
||||
|
}, |
||||
|
"aggregation": { |
||||
|
"type": "NONE", |
||||
|
"limit": 8640 |
||||
|
}, |
||||
|
"hideInterval": false, |
||||
|
"hideAggregation": false, |
||||
|
"hideAggInterval": false |
||||
|
}, |
||||
|
"showTitle": true, |
||||
|
"backgroundColor": "#fff", |
||||
|
"color": "rgba(0, 0, 0, 0.87)", |
||||
|
"padding": "8px", |
||||
|
"settings": { |
||||
|
"shadowSize": 4, |
||||
|
"fontColor": "#545454", |
||||
|
"fontSize": 10, |
||||
|
"xaxis": { |
||||
|
"showLabels": true, |
||||
|
"color": "#545454" |
||||
|
}, |
||||
|
"yaxis": { |
||||
|
"showLabels": true, |
||||
|
"color": "#545454" |
||||
|
}, |
||||
|
"grid": { |
||||
|
"color": "#545454", |
||||
|
"tickColor": "#DDDDDD", |
||||
|
"verticalLines": true, |
||||
|
"horizontalLines": true, |
||||
|
"outlineWidth": 1 |
||||
|
}, |
||||
|
"stack": false, |
||||
|
"tooltipIndividual": false, |
||||
|
"timeForComparison": "months", |
||||
|
"xaxisSecond": { |
||||
|
"axisPosition": "top", |
||||
|
"showLabels": true |
||||
|
} |
||||
|
}, |
||||
|
"title": "Processing Failures and Timeouts", |
||||
|
"dropShadow": true, |
||||
|
"enableFullscreen": true, |
||||
|
"titleStyle": { |
||||
|
"fontSize": "16px", |
||||
|
"fontWeight": 400 |
||||
|
}, |
||||
|
"mobileHeight": null, |
||||
|
"showTitleIcon": false, |
||||
|
"titleIcon": null, |
||||
|
"iconColor": "rgba(0, 0, 0, 0.87)", |
||||
|
"iconSize": "24px", |
||||
|
"titleTooltip": "", |
||||
|
"widgetStyle": {}, |
||||
|
"useDashboardTimewindow": false, |
||||
|
"displayTimewindow": true, |
||||
|
"showLegend": true, |
||||
|
"actions": {}, |
||||
|
"legendConfig": { |
||||
|
"direction": "column", |
||||
|
"position": "bottom", |
||||
|
"showMin": true, |
||||
|
"showMax": true, |
||||
|
"showAvg": false, |
||||
|
"showTotal": true |
||||
|
} |
||||
|
}, |
||||
|
"id": "ad3f1417-87a8-750e-fc67-49a2de1466d4" |
||||
|
} |
||||
|
}, |
||||
|
"states": { |
||||
|
"default": { |
||||
|
"name": "Rule Engine Statistics", |
||||
|
"root": true, |
||||
|
"layouts": { |
||||
|
"main": { |
||||
|
"widgets": { |
||||
|
"81987f19-3eac-e4ce-b790-d96e9b54d9a0": { |
||||
|
"sizeX": 12, |
||||
|
"sizeY": 7, |
||||
|
"mobileHeight": null, |
||||
|
"row": 0, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
"5eb79712-5c24-3060-7e4f-6af36b8f842d": { |
||||
|
"sizeX": 24, |
||||
|
"sizeY": 5, |
||||
|
"row": 7, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
"ad3f1417-87a8-750e-fc67-49a2de1466d4": { |
||||
|
"sizeX": 12, |
||||
|
"sizeY": 7, |
||||
|
"mobileHeight": null, |
||||
|
"row": 0, |
||||
|
"col": 12 |
||||
|
} |
||||
|
}, |
||||
|
"gridSettings": { |
||||
|
"backgroundColor": "#eeeeee", |
||||
|
"color": "rgba(0,0,0,0.870588)", |
||||
|
"columns": 24, |
||||
|
"margins": [ |
||||
|
10, |
||||
|
10 |
||||
|
], |
||||
|
"backgroundSizeMode": "100%", |
||||
|
"autoFillHeight": true, |
||||
|
"mobileAutoFillHeight": false, |
||||
|
"mobileRowHeight": 70 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"entityAliases": { |
||||
|
"140f23dd-e3a0-ed98-6189-03c49d2d8018": { |
||||
|
"id": "140f23dd-e3a0-ed98-6189-03c49d2d8018", |
||||
|
"alias": "TbServiceQueues", |
||||
|
"filter": { |
||||
|
"type": "assetType", |
||||
|
"resolveMultiple": true, |
||||
|
"assetType": "TbServiceQueue", |
||||
|
"assetNameFilter": "" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"timewindow": { |
||||
|
"displayValue": "", |
||||
|
"selectedTab": 0, |
||||
|
"hideInterval": false, |
||||
|
"hideAggregation": false, |
||||
|
"hideAggInterval": false, |
||||
|
"realtime": { |
||||
|
"interval": 1000, |
||||
|
"timewindowMs": 60000 |
||||
|
}, |
||||
|
"history": { |
||||
|
"historyType": 0, |
||||
|
"interval": 1000, |
||||
|
"timewindowMs": 60000, |
||||
|
"fixedTimewindow": { |
||||
|
"startTimeMs": 1586176634823, |
||||
|
"endTimeMs": 1586263034823 |
||||
|
} |
||||
|
}, |
||||
|
"aggregation": { |
||||
|
"type": "AVG", |
||||
|
"limit": 25000 |
||||
|
} |
||||
|
}, |
||||
|
"settings": { |
||||
|
"stateControllerId": "entity", |
||||
|
"showTitle": false, |
||||
|
"showDashboardsSelect": true, |
||||
|
"showEntitiesSelect": true, |
||||
|
"showDashboardTimewindow": true, |
||||
|
"showDashboardExport": true, |
||||
|
"toolbarAlwaysOpen": true |
||||
|
} |
||||
|
}, |
||||
|
"name": "Rule Engine Statistics" |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,146 @@ |
|||||
|
{ |
||||
|
"ruleChain": { |
||||
|
"additionalInfo": null, |
||||
|
"name": "Root Rule Chain", |
||||
|
"firstRuleNodeId": null, |
||||
|
"root": true, |
||||
|
"debugMode": false, |
||||
|
"configuration": null |
||||
|
}, |
||||
|
"metadata": { |
||||
|
"firstNodeIndex": 2, |
||||
|
"nodes": [ |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 824, |
||||
|
"layoutY": 156 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode", |
||||
|
"name": "Save Timeseries", |
||||
|
"debugMode": false, |
||||
|
"configuration": { |
||||
|
"defaultTTL": 0 |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 825, |
||||
|
"layoutY": 52 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode", |
||||
|
"name": "Save Client Attributes", |
||||
|
"debugMode": false, |
||||
|
"configuration": { |
||||
|
"scope": "CLIENT_SCOPE" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 347, |
||||
|
"layoutY": 149 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode", |
||||
|
"name": "Message Type Switch", |
||||
|
"debugMode": false, |
||||
|
"configuration": { |
||||
|
"version": 0 |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 825, |
||||
|
"layoutY": 266 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.action.TbLogNode", |
||||
|
"name": "Log RPC from Device", |
||||
|
"debugMode": false, |
||||
|
"configuration": { |
||||
|
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 825, |
||||
|
"layoutY": 379 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.action.TbLogNode", |
||||
|
"name": "Log Other", |
||||
|
"debugMode": false, |
||||
|
"configuration": { |
||||
|
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 825, |
||||
|
"layoutY": 468 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode", |
||||
|
"name": "RPC Call Request", |
||||
|
"debugMode": false, |
||||
|
"configuration": { |
||||
|
"timeoutInSeconds": 60 |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 1069, |
||||
|
"layoutY": 90 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.filter.TbJsFilterNode", |
||||
|
"name": "Is Thermostat?", |
||||
|
"debugMode": false, |
||||
|
"configuration": { |
||||
|
"jsScript": "return metadata[\"deviceType\"] === \"thermostat\";" |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
"connections": [ |
||||
|
{ |
||||
|
"fromIndex": 0, |
||||
|
"toIndex": 6, |
||||
|
"type": "Success" |
||||
|
}, |
||||
|
{ |
||||
|
"fromIndex": 2, |
||||
|
"toIndex": 4, |
||||
|
"type": "Other" |
||||
|
}, |
||||
|
{ |
||||
|
"fromIndex": 2, |
||||
|
"toIndex": 1, |
||||
|
"type": "Post attributes" |
||||
|
}, |
||||
|
{ |
||||
|
"fromIndex": 2, |
||||
|
"toIndex": 0, |
||||
|
"type": "Post telemetry" |
||||
|
}, |
||||
|
{ |
||||
|
"fromIndex": 2, |
||||
|
"toIndex": 3, |
||||
|
"type": "RPC Request from Device" |
||||
|
}, |
||||
|
{ |
||||
|
"fromIndex": 2, |
||||
|
"toIndex": 5, |
||||
|
"type": "RPC Request to Device" |
||||
|
} |
||||
|
], |
||||
|
"ruleChainConnections": [ |
||||
|
{ |
||||
|
"fromIndex": 6, |
||||
|
"targetRuleChainId": { |
||||
|
"entityType": "RULE_CHAIN", |
||||
|
"id": "83d42540-85fd-11ea-aee2-794850541ced" |
||||
|
}, |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 1088, |
||||
|
"layoutY": 203, |
||||
|
"ruleChainNodeId": "rule-chain-node-9" |
||||
|
}, |
||||
|
"type": "True" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,137 @@ |
|||||
|
{ |
||||
|
"ruleChain": { |
||||
|
"additionalInfo": null, |
||||
|
"name": "Thermostat Alarms", |
||||
|
"firstRuleNodeId": null, |
||||
|
"root": false, |
||||
|
"debugMode": false, |
||||
|
"configuration": null |
||||
|
}, |
||||
|
"metadata": { |
||||
|
"firstNodeIndex": 5, |
||||
|
"nodes": [ |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 929, |
||||
|
"layoutY": 67 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.action.TbCreateAlarmNode", |
||||
|
"name": "Create Temp Alarm", |
||||
|
"debugMode": false, |
||||
|
"configuration": { |
||||
|
"alarmType": "High Temperature", |
||||
|
"alarmDetailsBuildJs": "var details = {};\nif (metadata.prevAlarmDetails) {\n details = JSON.parse(metadata.prevAlarmDetails);\n}\ndetails.triggerValue = msg.temperature;\nreturn details;", |
||||
|
"severity": "MAJOR", |
||||
|
"propagate": true, |
||||
|
"useMessageAlarmData": false, |
||||
|
"relationTypes": [] |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 930, |
||||
|
"layoutY": 201 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.action.TbClearAlarmNode", |
||||
|
"name": "Clear Temp Alarm", |
||||
|
"debugMode": false, |
||||
|
"configuration": { |
||||
|
"alarmType": "High Temperature", |
||||
|
"alarmDetailsBuildJs": "var details = {};\nif (metadata.prevAlarmDetails) {\n details = JSON.parse(metadata.prevAlarmDetails);\n}\nreturn details;" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 930, |
||||
|
"layoutY": 131 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.action.TbCreateAlarmNode", |
||||
|
"name": "Create Humidity Alarm", |
||||
|
"debugMode": false, |
||||
|
"configuration": { |
||||
|
"alarmType": "Low Humidity", |
||||
|
"alarmDetailsBuildJs": "var details = {};\nif (metadata.prevAlarmDetails) {\n details = JSON.parse(metadata.prevAlarmDetails);\n}\ndetails.triggerValue = msg.humidity;\nreturn details;", |
||||
|
"severity": "MINOR", |
||||
|
"propagate": true, |
||||
|
"useMessageAlarmData": false, |
||||
|
"relationTypes": [] |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 929, |
||||
|
"layoutY": 275 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.action.TbClearAlarmNode", |
||||
|
"name": "Clear Humidity Alarm", |
||||
|
"debugMode": false, |
||||
|
"configuration": { |
||||
|
"alarmType": "Low Humidity", |
||||
|
"alarmDetailsBuildJs": "var details = {};\nif (metadata.prevAlarmDetails) {\n details = JSON.parse(metadata.prevAlarmDetails);\n}\nreturn details;" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 586, |
||||
|
"layoutY": 148 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.filter.TbJsSwitchNode", |
||||
|
"name": "Check Alarms", |
||||
|
"debugMode": true, |
||||
|
"configuration": { |
||||
|
"jsScript": "var relations = [];\nif(metadata[\"ss_alarmTemperature\"] === \"true\"){\n if(msg.temperature > metadata[\"ss_thresholdTemperature\"]){\n relations.push(\"NewTempAlarm\");\n } else {\n relations.push(\"ClearTempAlarm\");\n }\n}\nif(metadata[\"ss_alarmHumidity\"] === \"true\"){\n if(msg.humidity < metadata[\"ss_thresholdHumidity\"]){\n relations.push(\"NewHumidityAlarm\");\n } else {\n relations.push(\"ClearHumidityAlarm\");\n }\n}\n\nreturn relations;" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"additionalInfo": { |
||||
|
"layoutX": 321, |
||||
|
"layoutY": 149 |
||||
|
}, |
||||
|
"type": "org.thingsboard.rule.engine.metadata.TbGetAttributesNode", |
||||
|
"name": "Fetch Configuration", |
||||
|
"debugMode": true, |
||||
|
"configuration": { |
||||
|
"clientAttributeNames": [], |
||||
|
"sharedAttributeNames": [], |
||||
|
"serverAttributeNames": [ |
||||
|
"alarmTemperature", |
||||
|
"thresholdTemperature", |
||||
|
"alarmHumidity", |
||||
|
"thresholdHumidity" |
||||
|
], |
||||
|
"latestTsKeyNames": [], |
||||
|
"tellFailureIfAbsent": false, |
||||
|
"getLatestValueWithTs": false |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
"connections": [ |
||||
|
{ |
||||
|
"fromIndex": 4, |
||||
|
"toIndex": 0, |
||||
|
"type": "NewTempAlarm" |
||||
|
}, |
||||
|
{ |
||||
|
"fromIndex": 4, |
||||
|
"toIndex": 1, |
||||
|
"type": "ClearTempAlarm" |
||||
|
}, |
||||
|
{ |
||||
|
"fromIndex": 4, |
||||
|
"toIndex": 2, |
||||
|
"type": "NewHumidityAlarm" |
||||
|
}, |
||||
|
{ |
||||
|
"fromIndex": 4, |
||||
|
"toIndex": 3, |
||||
|
"type": "ClearHumidityAlarm" |
||||
|
}, |
||||
|
{ |
||||
|
"fromIndex": 5, |
||||
|
"toIndex": 4, |
||||
|
"type": "Success" |
||||
|
} |
||||
|
], |
||||
|
"ruleChainConnections": null |
||||
|
} |
||||
|
} |
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,90 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.service.queue; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
import java.util.concurrent.ConcurrentMap; |
||||
|
import java.util.concurrent.CountDownLatch; |
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
import java.util.concurrent.atomic.AtomicInteger; |
||||
|
|
||||
|
@Slf4j |
||||
|
public class TbPackProcessingContext<T> { |
||||
|
|
||||
|
private final AtomicInteger pendingCount; |
||||
|
private final CountDownLatch processingTimeoutLatch; |
||||
|
private final ConcurrentMap<UUID, T> ackMap; |
||||
|
private final ConcurrentMap<UUID, T> failedMap; |
||||
|
|
||||
|
public TbPackProcessingContext(CountDownLatch processingTimeoutLatch, |
||||
|
ConcurrentMap<UUID, T> ackMap, |
||||
|
ConcurrentMap<UUID, T> failedMap) { |
||||
|
this.processingTimeoutLatch = processingTimeoutLatch; |
||||
|
this.pendingCount = new AtomicInteger(ackMap.size()); |
||||
|
this.ackMap = ackMap; |
||||
|
this.failedMap = failedMap; |
||||
|
} |
||||
|
|
||||
|
public boolean await(long packProcessingTimeout, TimeUnit milliseconds) throws InterruptedException { |
||||
|
return processingTimeoutLatch.await(packProcessingTimeout, milliseconds); |
||||
|
} |
||||
|
|
||||
|
public void onSuccess(UUID id) { |
||||
|
boolean empty = false; |
||||
|
T msg = ackMap.remove(id); |
||||
|
if (msg != null) { |
||||
|
empty = pendingCount.decrementAndGet() == 0; |
||||
|
} |
||||
|
if (empty) { |
||||
|
processingTimeoutLatch.countDown(); |
||||
|
} else { |
||||
|
if (log.isTraceEnabled()) { |
||||
|
log.trace("Items left: {}", ackMap.size()); |
||||
|
for (T t : ackMap.values()) { |
||||
|
log.trace("left item: {}", t); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void onFailure(UUID id, Throwable t) { |
||||
|
boolean empty = false; |
||||
|
T msg = ackMap.remove(id); |
||||
|
if (msg != null) { |
||||
|
empty = pendingCount.decrementAndGet() == 0; |
||||
|
failedMap.put(id, msg); |
||||
|
if (log.isTraceEnabled()) { |
||||
|
log.trace("Items left: {}", ackMap.size()); |
||||
|
for (T v : ackMap.values()) { |
||||
|
log.trace("left item: {}", v); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (empty) { |
||||
|
processingTimeoutLatch.countDown(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public ConcurrentMap<UUID, T> getAckMap() { |
||||
|
return ackMap; |
||||
|
} |
||||
|
|
||||
|
public ConcurrentMap<UUID, T> getFailedMap() { |
||||
|
return failedMap; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.service.ttl.events; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.scheduling.annotation.Scheduled; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.thingsboard.server.dao.util.PsqlDao; |
||||
|
import org.thingsboard.server.service.ttl.AbstractCleanUpService; |
||||
|
|
||||
|
import java.sql.Connection; |
||||
|
import java.sql.DriverManager; |
||||
|
import java.sql.SQLException; |
||||
|
|
||||
|
@PsqlDao |
||||
|
@Slf4j |
||||
|
@Service |
||||
|
public class EventsCleanUpService extends AbstractCleanUpService { |
||||
|
|
||||
|
@Value("${sql.ttl.events.events_ttl}") |
||||
|
private long ttl; |
||||
|
|
||||
|
@Value("${sql.ttl.events.debug_events_ttl}") |
||||
|
private long debugTtl; |
||||
|
|
||||
|
@Value("${sql.ttl.events.enabled}") |
||||
|
private boolean ttlTaskExecutionEnabled; |
||||
|
|
||||
|
@Scheduled(initialDelayString = "${sql.ttl.events.execution_interval_ms}", fixedDelayString = "${sql.ttl.events.execution_interval_ms}") |
||||
|
public void cleanUp() { |
||||
|
if (ttlTaskExecutionEnabled) { |
||||
|
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { |
||||
|
doCleanUp(conn); |
||||
|
} catch (SQLException e) { |
||||
|
log.error("SQLException occurred during TTL task execution ", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected void doCleanUp(Connection connection) { |
||||
|
long totalEventsRemoved = executeQuery(connection, "call cleanup_events_by_ttl(" + ttl + ", " + debugTtl + ", 0);"); |
||||
|
log.info("Total events removed by TTL: [{}]", totalEventsRemoved); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.service.ttl.timeseries; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.scheduling.annotation.Scheduled; |
||||
|
import org.thingsboard.server.dao.util.PsqlTsAnyDao; |
||||
|
import org.thingsboard.server.service.ttl.AbstractCleanUpService; |
||||
|
|
||||
|
import java.sql.Connection; |
||||
|
import java.sql.DriverManager; |
||||
|
import java.sql.SQLException; |
||||
|
|
||||
|
@PsqlTsAnyDao |
||||
|
@Slf4j |
||||
|
public abstract class AbstractTimeseriesCleanUpService extends AbstractCleanUpService { |
||||
|
|
||||
|
@Value("${sql.ttl.ts.ts_key_value_ttl}") |
||||
|
protected long systemTtl; |
||||
|
|
||||
|
@Value("${sql.ttl.ts.enabled}") |
||||
|
private boolean ttlTaskExecutionEnabled; |
||||
|
|
||||
|
@Scheduled(initialDelayString = "${sql.ttl.ts.execution_interval_ms}", fixedDelayString = "${sql.ttl.ts.execution_interval_ms}") |
||||
|
public void cleanUp() { |
||||
|
if (ttlTaskExecutionEnabled) { |
||||
|
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { |
||||
|
doCleanUp(conn); |
||||
|
} catch (SQLException e) { |
||||
|
log.error("SQLException occurred during TTL task execution ", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,66 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.service.queue; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.junit.Assert; |
||||
|
import org.junit.Test; |
||||
|
import org.junit.runner.RunWith; |
||||
|
import org.mockito.Mockito; |
||||
|
import org.mockito.runners.MockitoJUnitRunner; |
||||
|
import org.thingsboard.server.gen.transport.TransportProtos; |
||||
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
||||
|
import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategy; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||
|
import java.util.concurrent.ConcurrentMap; |
||||
|
import java.util.concurrent.ExecutorService; |
||||
|
import java.util.concurrent.Executors; |
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
|
||||
|
import static org.mockito.Mockito.mock; |
||||
|
import static org.mockito.Mockito.when; |
||||
|
|
||||
|
@Slf4j |
||||
|
@RunWith(MockitoJUnitRunner.class) |
||||
|
public class TbMsgPackProcessingContextTest { |
||||
|
|
||||
|
@Test |
||||
|
public void testHighConcurrencyCase() throws InterruptedException { |
||||
|
TbRuleEngineSubmitStrategy strategyMock = mock(TbRuleEngineSubmitStrategy.class); |
||||
|
int msgCount = 1000; |
||||
|
int parallelCount = 5; |
||||
|
ExecutorService executorService = Executors.newFixedThreadPool(parallelCount); |
||||
|
try { |
||||
|
ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> messages = new ConcurrentHashMap<>(); |
||||
|
for (int i = 0; i < msgCount; i++) { |
||||
|
messages.put(UUID.randomUUID(), new TbProtoQueueMsg<>(UUID.randomUUID(), null)); |
||||
|
} |
||||
|
when(strategyMock.getPendingMap()).thenReturn(messages); |
||||
|
TbMsgPackProcessingContext context = new TbMsgPackProcessingContext(strategyMock); |
||||
|
for (UUID uuid : messages.keySet()) { |
||||
|
for (int i = 0; i < parallelCount; i++) { |
||||
|
executorService.submit(() -> context.onSuccess(uuid)); |
||||
|
} |
||||
|
} |
||||
|
Assert.assertTrue(context.await(10, TimeUnit.SECONDS)); |
||||
|
Mockito.verify(strategyMock, Mockito.times(msgCount)).onSuccess(Mockito.any(UUID.class)); |
||||
|
} finally { |
||||
|
executorService.shutdownNow(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,71 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.queue.azure.servicebus; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import javax.annotation.PostConstruct; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
@Component |
||||
|
@ConditionalOnExpression("'${queue.type:null}'=='service-bus'") |
||||
|
public class TbServiceBusQueueConfigs { |
||||
|
@Value("${queue.service-bus.queue-properties.core}") |
||||
|
private String coreProperties; |
||||
|
@Value("${queue.service-bus.queue-properties.rule-engine}") |
||||
|
private String ruleEngineProperties; |
||||
|
@Value("${queue.service-bus.queue-properties.transport-api}") |
||||
|
private String transportApiProperties; |
||||
|
@Value("${queue.service-bus.queue-properties.notifications}") |
||||
|
private String notificationsProperties; |
||||
|
@Value("${queue.service-bus.queue-properties.js-executor}") |
||||
|
private String jsExecutorProperties; |
||||
|
|
||||
|
@Getter |
||||
|
private Map<String, String> coreConfigs; |
||||
|
@Getter |
||||
|
private Map<String, String> ruleEngineConfigs; |
||||
|
@Getter |
||||
|
private Map<String, String> transportApiConfigs; |
||||
|
@Getter |
||||
|
private Map<String, String> notificationsConfigs; |
||||
|
@Getter |
||||
|
private Map<String, String> jsExecutorConfigs; |
||||
|
|
||||
|
@PostConstruct |
||||
|
private void init() { |
||||
|
coreConfigs = getConfigs(coreProperties); |
||||
|
ruleEngineConfigs = getConfigs(ruleEngineProperties); |
||||
|
transportApiConfigs = getConfigs(transportApiProperties); |
||||
|
notificationsConfigs = getConfigs(notificationsProperties); |
||||
|
jsExecutorConfigs = getConfigs(jsExecutorProperties); |
||||
|
} |
||||
|
|
||||
|
private Map<String, String> getConfigs(String properties) { |
||||
|
Map<String, String> configs = new HashMap<>(); |
||||
|
for (String property : properties.split(";")) { |
||||
|
int delimiterPosition = property.indexOf(":"); |
||||
|
String key = property.substring(0, delimiterPosition); |
||||
|
String value = property.substring(delimiterPosition + 1); |
||||
|
configs.put(key, value); |
||||
|
} |
||||
|
return configs; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,71 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.queue.pubsub; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import javax.annotation.PostConstruct; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
@Component |
||||
|
@ConditionalOnExpression("'${queue.type:null}'=='pubsub'") |
||||
|
public class TbPubSubSubscriptionSettings { |
||||
|
@Value("${queue.pubsub.queue-properties.core}") |
||||
|
private String coreProperties; |
||||
|
@Value("${queue.pubsub.queue-properties.rule-engine}") |
||||
|
private String ruleEngineProperties; |
||||
|
@Value("${queue.pubsub.queue-properties.transport-api}") |
||||
|
private String transportApiProperties; |
||||
|
@Value("${queue.pubsub.queue-properties.notifications}") |
||||
|
private String notificationsProperties; |
||||
|
@Value("${queue.pubsub.queue-properties.js-executor}") |
||||
|
private String jsExecutorProperties; |
||||
|
|
||||
|
@Getter |
||||
|
private Map<String, String> coreSettings; |
||||
|
@Getter |
||||
|
private Map<String, String> ruleEngineSettings; |
||||
|
@Getter |
||||
|
private Map<String, String> transportApiSettings; |
||||
|
@Getter |
||||
|
private Map<String, String> notificationsSettings; |
||||
|
@Getter |
||||
|
private Map<String, String> jsExecutorSettings; |
||||
|
|
||||
|
@PostConstruct |
||||
|
private void init() { |
||||
|
coreSettings = getSettings(coreProperties); |
||||
|
ruleEngineSettings = getSettings(ruleEngineProperties); |
||||
|
transportApiSettings = getSettings(transportApiProperties); |
||||
|
notificationsSettings = getSettings(notificationsProperties); |
||||
|
jsExecutorSettings = getSettings(jsExecutorProperties); |
||||
|
} |
||||
|
|
||||
|
private Map<String, String> getSettings(String properties) { |
||||
|
Map<String, String> configs = new HashMap<>(); |
||||
|
for (String property : properties.split(";")) { |
||||
|
int delimiterPosition = property.indexOf(":"); |
||||
|
String key = property.substring(0, delimiterPosition); |
||||
|
String value = property.substring(delimiterPosition + 1); |
||||
|
configs.put(key, value); |
||||
|
} |
||||
|
return configs; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,98 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.queue.rabbitmq; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import javax.annotation.PostConstruct; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
import java.util.regex.Pattern; |
||||
|
|
||||
|
@Component |
||||
|
@ConditionalOnExpression("'${queue.type:null}'=='rabbitmq'") |
||||
|
public class TbRabbitMqQueueArguments { |
||||
|
@Value("${queue.rabbitmq.queue-properties.core}") |
||||
|
private String coreProperties; |
||||
|
@Value("${queue.rabbitmq.queue-properties.rule-engine}") |
||||
|
private String ruleEngineProperties; |
||||
|
@Value("${queue.rabbitmq.queue-properties.transport-api}") |
||||
|
private String transportApiProperties; |
||||
|
@Value("${queue.rabbitmq.queue-properties.notifications}") |
||||
|
private String notificationsProperties; |
||||
|
@Value("${queue.rabbitmq.queue-properties.js-executor}") |
||||
|
private String jsExecutorProperties; |
||||
|
|
||||
|
@Getter |
||||
|
private Map<String, Object> coreArgs; |
||||
|
@Getter |
||||
|
private Map<String, Object> ruleEngineArgs; |
||||
|
@Getter |
||||
|
private Map<String, Object> transportApiArgs; |
||||
|
@Getter |
||||
|
private Map<String, Object> notificationsArgs; |
||||
|
@Getter |
||||
|
private Map<String, Object> jsExecutorArgs; |
||||
|
|
||||
|
@PostConstruct |
||||
|
private void init() { |
||||
|
coreArgs = getArgs(coreProperties); |
||||
|
ruleEngineArgs = getArgs(ruleEngineProperties); |
||||
|
transportApiArgs = getArgs(transportApiProperties); |
||||
|
notificationsArgs = getArgs(notificationsProperties); |
||||
|
jsExecutorArgs = getArgs(jsExecutorProperties); |
||||
|
} |
||||
|
|
||||
|
private Map<String, Object> getArgs(String properties) { |
||||
|
Map<String, Object> configs = new HashMap<>(); |
||||
|
for (String property : properties.split(";")) { |
||||
|
int delimiterPosition = property.indexOf(":"); |
||||
|
String key = property.substring(0, delimiterPosition); |
||||
|
String strValue = property.substring(delimiterPosition + 1); |
||||
|
configs.put(key, getObjectValue(strValue)); |
||||
|
} |
||||
|
return configs; |
||||
|
} |
||||
|
|
||||
|
private Object getObjectValue(String str) { |
||||
|
if (str.equalsIgnoreCase("true") || str.equalsIgnoreCase("false")) { |
||||
|
return Boolean.valueOf(str); |
||||
|
} else if (isNumeric(str)) { |
||||
|
return getNumericValue(str); |
||||
|
} |
||||
|
return str; |
||||
|
} |
||||
|
|
||||
|
private Object getNumericValue(String str) { |
||||
|
if (str.contains(".")) { |
||||
|
return Double.valueOf(str); |
||||
|
} else { |
||||
|
return Long.valueOf(str); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static final Pattern PATTERN = Pattern.compile("-?\\d+(\\.\\d+)?"); |
||||
|
|
||||
|
public boolean isNumeric(String strNum) { |
||||
|
if (strNum == null) { |
||||
|
return false; |
||||
|
} |
||||
|
return PATTERN.matcher(strNum).matches(); |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue