Commit 0045f00613ac04e27f25ee7c986c7c9b9b17a921
Committed by
GitHub
Merge pull request #4451 from ViacheslavKlimov/master-to-snmp
Merge 'master' into 'develop/snmp'
Showing
82 changed files
with
1583 additions
and
658 deletions
Too many changes to show.
To preserve performance only 82 of 217 files are displayed.
@@ -455,6 +455,24 @@ | @@ -455,6 +455,24 @@ | ||
455 | "dataKeySettingsSchema": "{}\n", | 455 | "dataKeySettingsSchema": "{}\n", |
456 | "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{},\"title\":\"Photo camera input\",\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"showLegend\":false,\"actions\":{}}" | 456 | "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{},\"title\":\"Photo camera input\",\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"showLegend\":false,\"actions\":{}}" |
457 | } | 457 | } |
458 | + }, | ||
459 | + { | ||
460 | + "alias": "update_json_attribute", | ||
461 | + "name": "Update JSON attribute", | ||
462 | + "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUoAAADhCAMAAACZWwyuAAAB71BMVEX////w8PDt7e3z8/Pg4ODAwMDc3Nz19fUZhJQ4lKK9vb17e3v9/f2mpqbj4+P4+Pi+vr58fHzT09P7+/uTxcz2+/ucy9GpqakCAgK93OHNzc0eh5b09PSw1dusrKwvkZ+ampqysrIzMzPV1dXCwsKurq4iiZnZ2dnX19fIyMgrj50ABsiKiopmZmbo8/XQ5+ro6OjPz89JnqqCgoLX6u2cnJwmjJv39/ff39+12N7ExMQ2NjaioqKYmJjs7OzD4OTS0tLKysrh8PLq6uq6uroCCMjDw8OOjo6hzdO0tLQuj56UlJS4uvDZ7O7l5eVvsrw0k6EchZWEhIRwcHDU6ezG4eaGv8d1tb+3t7dCmqeIiIj4+/3j8fO62+AKD8tWpbGgoKBqamouLi7u7u47lqTP0PWr0tgXHM1/u8N6uMFqsLpfqrVNoKxFRUXU1faYyM92dnY7Ozvz+Pry8vK5ubm4uLh+fn5sbGzGx/OipOtzduG42t8uM9KNw8pTo690dHT6+vrt9viOkefb29um0NYfHx/p6vu9vvGqrO2YmulXW9uhztRnrrgmJiYQEBDt7fzk5frf4PjL4+eMj+a/3eJpbN9MUNk7P9SQxMuNwslfX19TU1OcnurI4uY9QdYyN9ImK9BVVVVPT097fuNYWFjSJwPyAAALvElEQVR42uzbTWviQBjA8ad5qgNONI05FCSIshUNKERCSFlM2WIxSKCH5FI8RfoFCrvVYwv7xTfG4susxqgpqJkfHoLM6c9MTCYROI7jOC4doiIRoqrEkhQRuIOJEsEVROI1Dw2pIkPlMQ8PyWMez8ItLOD2QnArAlxyIsEYhK/x5CSMJQGX0Cfu8AmXTCEqbkWUPQaBiDtd8hJXMJ6SbNByeWd3iROMRxIPAhEx09MSd1ATDwIJMdPTEndJNIid4D/kkLk4yMbFZTop2fXdonSZktb2XuFKpwRnBzeoGoeklNZS1tjj+BVu2hDKfYhxKXUXTtnXHIqgXd+esk/pNSK+GrQcjZsbuotBVrKUFmzSGs++b1djZqVV1m01D6crqlSpVOldpYKFSmzKWUCN0nI0bq5bWAwiuHquNNnj+JOlSDWA144OJW86KUcp38oAtQZIPZ/mICQEBvWGcLpw7i6acu0iCkXDtQ1hcos4MtdTOt4VYs2h5dk42y4azj3ejhYpVUyEwEZ1F+BpBJKviQVfWUkZuOTZz0e5ba8FJ4xNWZcLPw0De97vezpYTzmUK1iiL18p5T+aEaymxGRU2OhhTMAbgFISATvCMqU0LgEUo4U/KOreKV9LsSlHAeKtgY+09STr6ylvzABfRuWvlC5i4DCz8oiU4Az6Uwug25blzsMyZb8zDpkQkgj04YSxKSf16FwpTOquzZwrnx5lvT3sLlP21lKSoxY4aM4wANCn10DmKemvaFZ2HuBMMCnDT5QSe205x6R8ufICWqowKQ/92WFJ/lsTID+9vhp29FlKpye1/AbUXELqTTgDbMq60S2PDMRHKutsSqzTGrIpD74YYvUohBr+x1D+O0tZMqaO0wASfPjmWdwjbfgFd0wDUZjY+F/Ke6ptSRl/iZ6Nm3Dc4sq7Se/GMRtbQ7hZvjrR+XZGKimrhoZ7pOSbbKntV/Kt39R20fkDiZSf7Yi4i3rBkzLVJ46g4M7mHH+l4Bjpv+hiXfTyTr9lVk+U38Diqzs1n1l8XeibiJaKLP7O74FEiYdMT/RfE0RVJZICe8txSSRKmU9KEIRm8V0QnitNIWvST6m93whhy3/sm/lTEmEYx7/SOLPbdFgjCDGEWm0FBUVEGRRF0WEmlCgxeFSaeKHpNF1ajWW3V4cddh9/aLs078PqCMOCxjrs55dn3mff9/3hM7x7fGfYrSs1ll9leUWFrmrK+ERXahSk0uc9srTKJ7c31+hKjQJUHnnorc2g0lijK9eVGgWovHF1fUaV5zSVyg54RUaVNzWVearcK5FWWWPcqanMU2VjU1NTI6kcNjbpNJX5HvDGq43pA7510/Q+TaVylcyl/F65z1iuqVSi8vgpX23VqaUfO5c1lUpUrq+V2LXUh6PxnPbhuExxhnHrfi3OKFylbseV8ic/tz/WlRoroFK8V9ZMGad0pUZuKstyBSWMpnJ1qfS0tXmk6hhFHmRfR/sXnQJUVswPJy8dy0Vlvd9fL1WDFXmRfR3tv5hn39oT9+JU5TyyNwBQi8rOz3vWVnurc1HZ5XR2rZhK2n8x68buNbwNPqIq43lCVSrLpB/k1aZcVD5wODoAXOQk9ND3hD39DrzhzR39QgiIhs22Xj1YH4EQL5hjQIQ3C5OO9DrbWaCSZ9dpPu2PjdeuHZK7BPD+JdU0g4nrQVWplPizJxeVAaAVgLvF5na7gT6+rnlgAJZ6p6ujWfCD72uesEWpDxP3qvlrGzA+6hwNh2gdU8mus/m0PzYYjYexkO/3qBLxsbtQnUpf8vDCRi4HNcBFADcXsPDoDcF1FnwlYOFaWV9UpQdjiGfrSCW7TvPTVB/FQl4knlIlfr+H6lRWDZ8uU66yjjOLcM2Syj64DCmV41wd65PK1sl6m9WWUSXNz8zd9jtUiaftg6pTuXX4VFkeKk2c84KIXlTZE2IqRzgT65PKrgF/pEem0jpEKuX7ZDPZQDXNC3swGLSnnkNqUbnfW6PwFb1bgEgr1w0JUSXAVJq4AOszVSNcHTBho3VwRUkl7bOQg9WQMdj+nOo/vnwBMDMoEnwxA0AtKm/MbxE5qUBlhGt5Z9AjKtw3WSwylTFLd7gfrM9Uge/wO3ts6XWfhFf+PlJJ84nFj52XH66LxKli1m5/DQl2wM9MX1aFyl//8koFKvHRY3Y5sO5+2Gxtkau0CpMjYH1SdaFDMNf3p9fpo8LF+hBdp/nEopehH3aJ11QRHxuLL1D5y3hbFSqXAvnAV6JIbJuu1lQuC0eStRs1lctC1aU16njsaCFb8VRW5pCxvWnBauW/5ZXZDvKQJ0K6ednYMarGXHIFVFZ99ib36BTklRlVRjmTXCWNDdaccsmgXaIBSlGPSt9BMa/0KcgrM6rUOyFTSWNSmT2XxB2RucQsFKMalRLztxTklbxVEKJ6FktQXhngOK4OIiOTgjXGszHllA5p1Mo1L5FLErPtd6EcFansXDt8TkFeyff7J4RPTCXllXG3+2JKXX/YYhFVsjHllLFewCLEs+WSc2MoOoWoXFtbu6kzg8pM74+9LlJJeSWQUhfg/Kk+G9MBb+GB3g5kySWfioFF0SlE5b4TV4YvKVQ5ZCWVLK9k6tq4kaVVOjk3YkPIwtuECv4gV+C90uc9pkzlWRvljiyvZOpMmVSiq2WciyALH+ZQfApUuV65SsodKRkCPN2p/NGS6rMx5ZQYCk+Es+SSmAk+Q/EpQOX5mgpf8mGZYpUsd5SpfDBgMugR8hikPhtTTolxwdqDzLkkntlHUHzyV9l5I+lNHmhUrpLljjKVzpg55kC8x2a2hsDGlFMCvVwEmXNJPEpABayOOMPggvpZBSrHnRaPCepnBVRuOFFefmIDlg3TX/buXqVhKIzD+FuonEEJJQ4eKogEOrjFQRRSisEiuIl3YPYOvQId7Kg34OSdGgd1SaD5aPmH8zwQsv8g5Jx3OOf08c0GUP+UUezMXDzA8/3lKHNnZS630Oqf8sAK//5QvkKrG+VVsqygXEQvGyibUc5WlZTl44+gbEJ5u5pm1ZT3/hjKBpSLr5NRDeWFf4WyyR78eVRHeecnUG5PebOOaynt0K8ttNpTzpMsy5LkvIry+uNpZqHVnjK6LMvm4yrKqXd84A2X6PzBd0mZux/KERvHfsYZE884o5ch2/LscxOe5C4orfDFxMJrAFP0oQQllHpBCaVeUEKpF5RQ6gUllHpBCaVeUEKpF5RQ6gUllHpBCaVeUEKpF5RQ6gUllHpBCaVeUEKpF5RQ6gUllHpBCaVeUEKpF5RQ6gUllHpBCaVeUEKpF5RQ6gUllHpBCaVeUEKpF5RQ6gUllHpBuWdK2qLwDj8lIiIiIiIKLpdG45ZFqTP6y407heV/aTfK1Oi3qBtlgNdmfLdrxypyw0AAhifJ2AeDZtcohUAEgZGFrdJVjIsgk2DY5urt9xFu9wn2xWMFLklzV3gb45u/GHD7YSML5s3wwUASSqHcbkIplNtLKIVyewll7onaZR7oB/yfJ/UYZfvLmbMXyscpy2CKxplOKB+mtBwRNRcflLJJvhh/Anybir4nBV9sMeJKyonnZaYO/cm4GX1+JC6xr02dPgAlpaFpFMTq7onUsRkx0WEd5RD42ucP3YWJeMJQI4YTJj7H2tz3TzkBlPR0oQEgkUK6AEzz2mPnxhx6LPsW0RA2XHYc8ebKwXPcP2UPgPTynAk9KV2pTHtcRZkxZ8Ma9dkZvqJmO3KLjnPFTimP1EEm/PyP8tMfSp8p7/R9FWWyy9BMrTnp1lwRA53zNx70UrtTSmjiMhIdXykvdADQpDCT2katoiTWiC1Xli0OmbJyZkQ8m4XR7/XYASQ7JNLwSglxfh4qUl+bETUNsIqyM66YAyfPdaz5hpiYuzzDWLHeKyUcYhEH9Zcy/wzZRApebDUOa2873dWZ2iJG54oQENHVuGRrE+Ju30q5g28qoRTK7SWUQrm9hFIot5dQCuX2kvUrWQrcXrKqKgvUkiRJkiRJkiS9328dj4CaN1dagAAAAABJRU5ErkJggg==", | ||
463 | + "description": "Simple form to input new JSON value for pre-defined attribute/timeseries key.", | ||
464 | + "descriptor": { | ||
465 | + "type": "latest", | ||
466 | + "sizeX": 7.5, | ||
467 | + "sizeY": 3, | ||
468 | + "resources": [], | ||
469 | + "templateHtml": "<tb-json-input-widget \n [ctx]=\"ctx\">\n</tb-json-input-widget>", | ||
470 | + "templateCss": ".attribute-update-form {\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n.attribute-update-form__grid {\n display: flex;\n}\n.grid__element:first-child {\n flex: 1;\n}\n.grid__element:last-child {\n margin-top: 19px;\n margin-left: 7px;\n}\n.grid__element {\n display: flex;\n}\n\n.attribute-update-form .mat-button.mat-icon-button {\n width: 32px;\n min-width: 32px;\n height: 32px;\n min-height: 32px;\n padding: 0 !important;\n margin: 0 !important;\n line-height: 20px;\n}\n\n.attribute-update-form .mat-icon-button mat-icon {\n width: 20px;\n min-width: 20px;\n height: 20px;\n min-height: 20px;\n font-size: 20px;\n}\n\n.tb-toast {\n font-size: 14px!important;\n}", | ||
471 | + "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.jsonInputWidget.onDataUpdated();\n}\n\nself.onResize = function() {\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1,\n singleEntity: true\n }\n}\n\nself.onDestroy = function() {\n}", | ||
472 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"AdvancedSettings\",\n \"properties\": {\n \"widgetTitle\": {\n \"title\": \"Widget title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"widgetMode\": {\n \"title\": \"Widget mode\",\n \"type\": \"string\",\n \"default\": \"ATTRIBUTE\"\n },\n \"attributeScope\": {\n \"title\": \"Attribute scope\",\n \"type\": \"string\",\n \"default\": \"SERVER_SCOPE\"\n },\n \"showLabel\":{\n \"title\": \"Show label\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"labelValue\": {\n \"title\": \"Label\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"attributeRequired\": {\n \"title\": \"Value required\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"showResultMessage\": {\n \"title\": \"Show result message\",\n \"type\": \"boolean\",\n \"default\": true\n }\n },\n \"required\": []\n },\n \"form\": [\n \"widgetTitle\",\n {\n \"key\": \"widgetMode\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"ATTRIBUTE\",\n \"label\": \"Update attribute\"\n },\n {\n \"value\": \"TIME_SERIES\",\n \"label\": \"Update timeseries\"\n }\n ]\n },\n {\n \"key\": \"attributeScope\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"condition\": \"model.widgetMode === 'ATTRIBUTE'\",\n \"items\": [\n {\n \"value\": \"SERVER_SCOPE\",\n \"label\": \"Server attribute\"\n },\n {\n \"value\": \"SHARED_SCOPE\",\n \"label\": \"Shared attribute\"\n }\n ]\n },\n \"showLabel\",\n {\n \"key\": \"labelValue\",\n \"condition\": \"model.showLabel\"\n },\n \"attributeRequired\",\n \"showResultMessage\"\n ]\n}", | ||
473 | + "dataKeySettingsSchema": "{}", | ||
474 | + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"attributeScope\":\"SERVER_SCOPE\",\"showLabel\":true,\"attributeRequired\":true,\"showResultMessage\":true},\"title\":\"Update JSON attribute\",\"showTitleIcon\":false,\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"showLegend\":false}" | ||
475 | + } | ||
458 | } | 476 | } |
459 | ] | 477 | ] |
460 | } | 478 | } |
@@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping; | @@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping; | ||
21 | @Controller | 21 | @Controller |
22 | public class WebConfig { | 22 | public class WebConfig { |
23 | 23 | ||
24 | - @RequestMapping(value = "/{path:^(?!api$)(?!assets$)(?!static$)(?!webjars$)[^\\.]*}/**") | 24 | + @RequestMapping(value = {"/assets", "/assets/", "/{path:^(?!api$)(?!assets$)(?!static$)(?!webjars$)[^\\.]*}/**"}) |
25 | public String redirect() { | 25 | public String redirect() { |
26 | return "forward:/index.html"; | 26 | return "forward:/index.html"; |
27 | } | 27 | } |
@@ -46,8 +46,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | @@ -46,8 +46,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | ||
46 | import org.thingsboard.server.service.security.permission.Operation; | 46 | import org.thingsboard.server.service.security.permission.Operation; |
47 | import org.thingsboard.server.service.security.permission.Resource; | 47 | import org.thingsboard.server.service.security.permission.Resource; |
48 | 48 | ||
49 | -import java.util.UUID; | ||
50 | - | ||
51 | @RestController | 49 | @RestController |
52 | @TbCoreComponent | 50 | @TbCoreComponent |
53 | @RequestMapping("/api") | 51 | @RequestMapping("/api") |
@@ -177,7 +175,6 @@ public class AlarmController extends BaseController { | @@ -177,7 +175,6 @@ public class AlarmController extends BaseController { | ||
177 | @RequestParam(required = false) String sortOrder, | 175 | @RequestParam(required = false) String sortOrder, |
178 | @RequestParam(required = false) Long startTime, | 176 | @RequestParam(required = false) Long startTime, |
179 | @RequestParam(required = false) Long endTime, | 177 | @RequestParam(required = false) Long endTime, |
180 | - @RequestParam(required = false) String offset, | ||
181 | @RequestParam(required = false) Boolean fetchOriginator | 178 | @RequestParam(required = false) Boolean fetchOriginator |
182 | ) throws ThingsboardException { | 179 | ) throws ThingsboardException { |
183 | checkParameter("EntityId", strEntityId); | 180 | checkParameter("EntityId", strEntityId); |
@@ -191,12 +188,9 @@ public class AlarmController extends BaseController { | @@ -191,12 +188,9 @@ public class AlarmController extends BaseController { | ||
191 | } | 188 | } |
192 | checkEntityId(entityId, Operation.READ); | 189 | checkEntityId(entityId, Operation.READ); |
193 | TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime); | 190 | TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime); |
194 | - UUID idOffsetUuid = null; | ||
195 | - if (StringUtils.isNotEmpty(offset)) { | ||
196 | - idOffsetUuid = toUUID(offset); | ||
197 | - } | 191 | + |
198 | try { | 192 | try { |
199 | - return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(entityId, pageLink, alarmSearchStatus, alarmStatus, fetchOriginator, idOffsetUuid)).get()); | 193 | + return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(entityId, pageLink, alarmSearchStatus, alarmStatus, fetchOriginator)).get()); |
200 | } catch (Exception e) { | 194 | } catch (Exception e) { |
201 | throw handleException(e); | 195 | throw handleException(e); |
202 | } | 196 | } |
@@ -110,7 +110,6 @@ import org.thingsboard.server.dao.model.ModelConstants; | @@ -110,7 +110,6 @@ import org.thingsboard.server.dao.model.ModelConstants; | ||
110 | import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService; | 110 | import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService; |
111 | import org.thingsboard.server.dao.oauth2.OAuth2Service; | 111 | import org.thingsboard.server.dao.oauth2.OAuth2Service; |
112 | import org.thingsboard.server.dao.relation.RelationService; | 112 | import org.thingsboard.server.dao.relation.RelationService; |
113 | -import org.thingsboard.server.dao.resource.TbResourceService; | ||
114 | import org.thingsboard.server.dao.rule.RuleChainService; | 113 | import org.thingsboard.server.dao.rule.RuleChainService; |
115 | import org.thingsboard.server.dao.tenant.TbTenantProfileCache; | 114 | import org.thingsboard.server.dao.tenant.TbTenantProfileCache; |
116 | import org.thingsboard.server.dao.tenant.TenantProfileService; | 115 | import org.thingsboard.server.dao.tenant.TenantProfileService; |
@@ -130,6 +129,7 @@ import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService; | @@ -130,6 +129,7 @@ import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService; | ||
130 | import org.thingsboard.server.service.lwm2m.LwM2MModelsRepository; | 129 | import org.thingsboard.server.service.lwm2m.LwM2MModelsRepository; |
131 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; | 130 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; |
132 | import org.thingsboard.server.service.queue.TbClusterService; | 131 | import org.thingsboard.server.service.queue.TbClusterService; |
132 | +import org.thingsboard.server.service.resource.TbResourceService; | ||
133 | import org.thingsboard.server.service.security.model.SecurityUser; | 133 | import org.thingsboard.server.service.security.model.SecurityUser; |
134 | import org.thingsboard.server.service.security.permission.AccessControlService; | 134 | import org.thingsboard.server.service.security.permission.AccessControlService; |
135 | import org.thingsboard.server.service.security.permission.Operation; | 135 | import org.thingsboard.server.service.security.permission.Operation; |
@@ -18,12 +18,14 @@ package org.thingsboard.server.controller; | @@ -18,12 +18,14 @@ package org.thingsboard.server.controller; | ||
18 | import org.springframework.beans.factory.annotation.Autowired; | 18 | import org.springframework.beans.factory.annotation.Autowired; |
19 | import org.springframework.security.access.prepost.PreAuthorize; | 19 | import org.springframework.security.access.prepost.PreAuthorize; |
20 | import org.springframework.web.bind.annotation.PathVariable; | 20 | import org.springframework.web.bind.annotation.PathVariable; |
21 | +import org.springframework.web.bind.annotation.RequestBody; | ||
21 | import org.springframework.web.bind.annotation.RequestMapping; | 22 | import org.springframework.web.bind.annotation.RequestMapping; |
22 | import org.springframework.web.bind.annotation.RequestMethod; | 23 | import org.springframework.web.bind.annotation.RequestMethod; |
23 | import org.springframework.web.bind.annotation.RequestParam; | 24 | import org.springframework.web.bind.annotation.RequestParam; |
24 | import org.springframework.web.bind.annotation.ResponseBody; | 25 | import org.springframework.web.bind.annotation.ResponseBody; |
25 | import org.springframework.web.bind.annotation.RestController; | 26 | import org.springframework.web.bind.annotation.RestController; |
26 | import org.thingsboard.server.common.data.Event; | 27 | import org.thingsboard.server.common.data.Event; |
28 | +import org.thingsboard.server.common.data.event.EventFilter; | ||
27 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 29 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
28 | import org.thingsboard.server.common.data.id.EntityId; | 30 | import org.thingsboard.server.common.data.id.EntityId; |
29 | import org.thingsboard.server.common.data.id.EntityIdFactory; | 31 | import org.thingsboard.server.common.data.id.EntityIdFactory; |
@@ -31,6 +33,7 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -31,6 +33,7 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
31 | import org.thingsboard.server.common.data.page.PageData; | 33 | import org.thingsboard.server.common.data.page.PageData; |
32 | import org.thingsboard.server.common.data.page.TimePageLink; | 34 | import org.thingsboard.server.common.data.page.TimePageLink; |
33 | import org.thingsboard.server.dao.event.EventService; | 35 | import org.thingsboard.server.dao.event.EventService; |
36 | +import org.thingsboard.server.dao.model.ModelConstants; | ||
34 | import org.thingsboard.server.queue.util.TbCoreComponent; | 37 | import org.thingsboard.server.queue.util.TbCoreComponent; |
35 | import org.thingsboard.server.service.security.permission.Operation; | 38 | import org.thingsboard.server.service.security.permission.Operation; |
36 | 39 | ||
@@ -101,4 +104,38 @@ public class EventController extends BaseController { | @@ -101,4 +104,38 @@ public class EventController extends BaseController { | ||
101 | } | 104 | } |
102 | } | 105 | } |
103 | 106 | ||
107 | + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | ||
108 | + @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.POST) | ||
109 | + @ResponseBody | ||
110 | + public PageData<Event> getEvents( | ||
111 | + @PathVariable("entityType") String strEntityType, | ||
112 | + @PathVariable("entityId") String strEntityId, | ||
113 | + @RequestParam("tenantId") String strTenantId, | ||
114 | + @RequestParam int pageSize, | ||
115 | + @RequestParam int page, | ||
116 | + @RequestBody EventFilter eventFilter, | ||
117 | + @RequestParam(required = false) String textSearch, | ||
118 | + @RequestParam(required = false) String sortProperty, | ||
119 | + @RequestParam(required = false) String sortOrder, | ||
120 | + @RequestParam(required = false) Long startTime, | ||
121 | + @RequestParam(required = false) Long endTime) throws ThingsboardException { | ||
122 | + checkParameter("EntityId", strEntityId); | ||
123 | + checkParameter("EntityType", strEntityType); | ||
124 | + try { | ||
125 | + TenantId tenantId = new TenantId(toUUID(strTenantId)); | ||
126 | + | ||
127 | + EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId); | ||
128 | + checkEntityId(entityId, Operation.READ); | ||
129 | + | ||
130 | + if(sortProperty != null && sortProperty.equals("createdTime") && eventFilter.hasFilterForJsonBody()) { | ||
131 | + sortProperty = ModelConstants.CREATED_TIME_PROPERTY; | ||
132 | + } | ||
133 | + | ||
134 | + TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime); | ||
135 | + return checkNotNull(eventService.findEventsByFilter(tenantId, entityId, eventFilter, pageLink)); | ||
136 | + } catch (Exception e) { | ||
137 | + throw handleException(e); | ||
138 | + } | ||
139 | + } | ||
140 | + | ||
104 | } | 141 | } |
@@ -244,7 +244,8 @@ public class RuleChainController extends BaseController { | @@ -244,7 +244,8 @@ public class RuleChainController extends BaseController { | ||
244 | } | 244 | } |
245 | 245 | ||
246 | RuleChain ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId(), Operation.WRITE); | 246 | RuleChain ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId(), Operation.WRITE); |
247 | - RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData)); | 247 | + checkNotNull(ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData) ? true : null); |
248 | + RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaData.getRuleChainId())); | ||
248 | 249 | ||
249 | if (RuleChainType.CORE.equals(ruleChain.getType())) { | 250 | if (RuleChainType.CORE.equals(ruleChain.getType())) { |
250 | tbClusterService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED); | 251 | tbClusterService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED); |
@@ -36,8 +36,8 @@ import org.thingsboard.server.common.data.lwm2m.LwM2mObject; | @@ -36,8 +36,8 @@ import org.thingsboard.server.common.data.lwm2m.LwM2mObject; | ||
36 | import org.thingsboard.server.common.data.page.PageData; | 36 | import org.thingsboard.server.common.data.page.PageData; |
37 | import org.thingsboard.server.common.data.page.PageLink; | 37 | import org.thingsboard.server.common.data.page.PageLink; |
38 | import org.thingsboard.server.common.data.security.Authority; | 38 | import org.thingsboard.server.common.data.security.Authority; |
39 | -import org.thingsboard.server.dao.resource.TbResourceService; | ||
40 | import org.thingsboard.server.queue.util.TbCoreComponent; | 39 | import org.thingsboard.server.queue.util.TbCoreComponent; |
40 | +import org.thingsboard.server.service.resource.TbResourceService; | ||
41 | import org.thingsboard.server.service.security.permission.Operation; | 41 | import org.thingsboard.server.service.security.permission.Operation; |
42 | import org.thingsboard.server.service.security.permission.Resource; | 42 | import org.thingsboard.server.service.security.permission.Resource; |
43 | 43 | ||
@@ -52,12 +52,6 @@ public class TbResourceController extends BaseController { | @@ -52,12 +52,6 @@ public class TbResourceController extends BaseController { | ||
52 | 52 | ||
53 | public static final String RESOURCE_ID = "resourceId"; | 53 | public static final String RESOURCE_ID = "resourceId"; |
54 | 54 | ||
55 | - private final TbResourceService resourceService; | ||
56 | - | ||
57 | - public TbResourceController(TbResourceService resourceService) { | ||
58 | - this.resourceService = resourceService; | ||
59 | - } | ||
60 | - | ||
61 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") | 55 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") |
62 | @RequestMapping(value = "/resource/{resourceId}/download", method = RequestMethod.GET) | 56 | @RequestMapping(value = "/resource/{resourceId}/download", method = RequestMethod.GET) |
63 | @ResponseBody | 57 | @ResponseBody |
@@ -40,8 +40,6 @@ public class DeviceProfileMsgConstructor { | @@ -40,8 +40,6 @@ public class DeviceProfileMsgConstructor { | ||
40 | .setName(deviceProfile.getName()) | 40 | .setName(deviceProfile.getName()) |
41 | .setDefault(deviceProfile.isDefault()) | 41 | .setDefault(deviceProfile.isDefault()) |
42 | .setType(deviceProfile.getType().name()) | 42 | .setType(deviceProfile.getType().name()) |
43 | - .setTransportType(deviceProfile.getTransportType().name()) | ||
44 | - .setProvisionType(deviceProfile.getProvisionType().name()) | ||
45 | .setProfileDataBytes(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile.getProfileData()))); | 43 | .setProfileDataBytes(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile.getProfileData()))); |
46 | // TODO: voba - should this be always null at the moment?? | 44 | // TODO: voba - should this be always null at the moment?? |
47 | // if (deviceProfile.getDefaultRuleChainId() != null) { | 45 | // if (deviceProfile.getDefaultRuleChainId() != null) { |
@@ -54,6 +52,12 @@ public class DeviceProfileMsgConstructor { | @@ -54,6 +52,12 @@ public class DeviceProfileMsgConstructor { | ||
54 | if (deviceProfile.getDescription() != null) { | 52 | if (deviceProfile.getDescription() != null) { |
55 | builder.setDescription(deviceProfile.getDescription()); | 53 | builder.setDescription(deviceProfile.getDescription()); |
56 | } | 54 | } |
55 | + if (deviceProfile.getTransportType() != null) { | ||
56 | + builder.setTransportType(deviceProfile.getTransportType().name()); | ||
57 | + } | ||
58 | + if (deviceProfile.getProvisionType() != null) { | ||
59 | + builder.setProvisionType(deviceProfile.getProvisionType().name()); | ||
60 | + } | ||
57 | if (deviceProfile.getProvisionDeviceKey() != null) { | 61 | if (deviceProfile.getProvisionDeviceKey() != null) { |
58 | builder.setProvisionDeviceKey(deviceProfile.getProvisionDeviceKey()); | 62 | builder.setProvisionDeviceKey(deviceProfile.getProvisionDeviceKey()); |
59 | } | 63 | } |
@@ -15,13 +15,13 @@ | @@ -15,13 +15,13 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.service.edge.rpc.constructor; | 16 | package org.thingsboard.server.service.edge.rpc.constructor; |
17 | 17 | ||
18 | +import com.google.gson.reflect.TypeToken; | ||
18 | import com.google.gson.Gson; | 19 | import com.google.gson.Gson; |
19 | import com.google.gson.JsonArray; | 20 | import com.google.gson.JsonArray; |
20 | import com.google.gson.JsonElement; | 21 | import com.google.gson.JsonElement; |
21 | import com.google.gson.JsonObject; | 22 | import com.google.gson.JsonObject; |
22 | import lombok.extern.slf4j.Slf4j; | 23 | import lombok.extern.slf4j.Slf4j; |
23 | import org.springframework.stereotype.Component; | 24 | import org.springframework.stereotype.Component; |
24 | -import org.thingsboard.server.common.data.audit.ActionType; | ||
25 | import org.thingsboard.server.common.data.edge.EdgeEventActionType; | 25 | import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
26 | import org.thingsboard.server.common.data.id.EntityId; | 26 | import org.thingsboard.server.common.data.id.EntityId; |
27 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; | 27 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; |
@@ -82,7 +82,7 @@ public class EntityDataMsgConstructor { | @@ -82,7 +82,7 @@ public class EntityDataMsgConstructor { | ||
82 | AttributeDeleteMsg.Builder attributeDeleteMsg = AttributeDeleteMsg.newBuilder(); | 82 | AttributeDeleteMsg.Builder attributeDeleteMsg = AttributeDeleteMsg.newBuilder(); |
83 | attributeDeleteMsg.setScope(entityData.getAsJsonObject().getAsJsonPrimitive("scope").getAsString()); | 83 | attributeDeleteMsg.setScope(entityData.getAsJsonObject().getAsJsonPrimitive("scope").getAsString()); |
84 | JsonArray jsonArray = entityData.getAsJsonObject().getAsJsonArray("keys"); | 84 | JsonArray jsonArray = entityData.getAsJsonObject().getAsJsonArray("keys"); |
85 | - List<String> keys = new Gson().fromJson(jsonArray.toString(), List.class); | 85 | + List<String> keys = new Gson().fromJson(jsonArray.toString(), new TypeToken<>(){}.getType()); |
86 | attributeDeleteMsg.addAllAttributeNames(keys); | 86 | attributeDeleteMsg.addAllAttributeNames(keys); |
87 | attributeDeleteMsg.build(); | 87 | attributeDeleteMsg.build(); |
88 | builder.setAttributeDeleteMsg(attributeDeleteMsg); | 88 | builder.setAttributeDeleteMsg(attributeDeleteMsg); |
application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
@@ -58,11 +58,8 @@ import org.thingsboard.server.common.data.page.PageLink; | @@ -58,11 +58,8 @@ import org.thingsboard.server.common.data.page.PageLink; | ||
58 | import org.thingsboard.server.common.data.query.BooleanFilterPredicate; | 58 | import org.thingsboard.server.common.data.query.BooleanFilterPredicate; |
59 | import org.thingsboard.server.common.data.query.DynamicValue; | 59 | import org.thingsboard.server.common.data.query.DynamicValue; |
60 | import org.thingsboard.server.common.data.query.DynamicValueSourceType; | 60 | import org.thingsboard.server.common.data.query.DynamicValueSourceType; |
61 | -import org.thingsboard.server.common.data.query.EntityKey; | ||
62 | -import org.thingsboard.server.common.data.query.EntityKeyType; | ||
63 | import org.thingsboard.server.common.data.query.EntityKeyValueType; | 61 | import org.thingsboard.server.common.data.query.EntityKeyValueType; |
64 | import org.thingsboard.server.common.data.query.FilterPredicateValue; | 62 | import org.thingsboard.server.common.data.query.FilterPredicateValue; |
65 | -import org.thingsboard.server.common.data.query.KeyFilter; | ||
66 | import org.thingsboard.server.common.data.query.NumericFilterPredicate; | 63 | import org.thingsboard.server.common.data.query.NumericFilterPredicate; |
67 | import org.thingsboard.server.common.data.rule.RuleChainType; | 64 | import org.thingsboard.server.common.data.rule.RuleChainType; |
68 | import org.thingsboard.server.common.data.security.Authority; | 65 | import org.thingsboard.server.common.data.security.Authority; |
@@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; | @@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; | ||
35 | import org.thingsboard.server.dao.dashboard.DashboardService; | 35 | import org.thingsboard.server.dao.dashboard.DashboardService; |
36 | import org.thingsboard.server.dao.exception.DataValidationException; | 36 | import org.thingsboard.server.dao.exception.DataValidationException; |
37 | import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService; | 37 | import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService; |
38 | -import org.thingsboard.server.dao.resource.TbResourceService; | 38 | +import org.thingsboard.server.dao.resource.ResourceService; |
39 | import org.thingsboard.server.dao.rule.RuleChainService; | 39 | import org.thingsboard.server.dao.rule.RuleChainService; |
40 | import org.thingsboard.server.dao.widget.WidgetTypeService; | 40 | import org.thingsboard.server.dao.widget.WidgetTypeService; |
41 | import org.thingsboard.server.dao.widget.WidgetsBundleService; | 41 | import org.thingsboard.server.dao.widget.WidgetsBundleService; |
@@ -97,7 +97,7 @@ public class InstallScripts { | @@ -97,7 +97,7 @@ public class InstallScripts { | ||
97 | private OAuth2ConfigTemplateService oAuth2TemplateService; | 97 | private OAuth2ConfigTemplateService oAuth2TemplateService; |
98 | 98 | ||
99 | @Autowired | 99 | @Autowired |
100 | - private TbResourceService resourceService; | 100 | + private ResourceService resourceService; |
101 | 101 | ||
102 | private Path getTenantRuleChainsDir() { | 102 | private Path getTenantRuleChainsDir() { |
103 | return Paths.get(getDataDir(), JSON_DIR, TENANT_DIR, RULE_CHAINS_DIR); | 103 | return Paths.get(getDataDir(), JSON_DIR, TENANT_DIR, RULE_CHAINS_DIR); |
@@ -259,18 +259,12 @@ public class InstallScripts { | @@ -259,18 +259,12 @@ public class InstallScripts { | ||
259 | try { | 259 | try { |
260 | createDefaultRuleChains(tenantId); | 260 | createDefaultRuleChains(tenantId); |
261 | createDefaultRuleChain(tenantId, "Thermostat"); | 261 | createDefaultRuleChain(tenantId, "Thermostat"); |
262 | - loadEdgeDemoRuleChains(tenantId); | ||
263 | } catch (Exception e) { | 262 | } catch (Exception e) { |
264 | log.error("Unable to load dashboard from json", e); | 263 | log.error("Unable to load dashboard from json", e); |
265 | throw new RuntimeException("Unable to load dashboard from json", e); | 264 | throw new RuntimeException("Unable to load dashboard from json", e); |
266 | } | 265 | } |
267 | } | 266 | } |
268 | 267 | ||
269 | - private void loadEdgeDemoRuleChains(TenantId tenantId) throws Exception { | ||
270 | - Path edgeDemoRuleChainsDir = Paths.get(getDataDir(), JSON_DIR, DEMO_DIR, EDGE_MANAGEMENT, RULE_CHAINS_DIR); | ||
271 | - loadRuleChainsFromPath(tenantId, edgeDemoRuleChainsDir); | ||
272 | - } | ||
273 | - | ||
274 | public void createOAuth2Templates() throws Exception { | 268 | public void createOAuth2Templates() throws Exception { |
275 | Path oauth2ConfigTemplatesDir = Paths.get(getDataDir(), JSON_DIR, SYSTEM_DIR, OAUTH2_CONFIG_TEMPLATES_DIR); | 269 | Path oauth2ConfigTemplatesDir = Paths.get(getDataDir(), JSON_DIR, SYSTEM_DIR, OAUTH2_CONFIG_TEMPLATES_DIR); |
276 | try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(oauth2ConfigTemplatesDir, path -> path.toString().endsWith(JSON_EXT))) { | 270 | try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(oauth2ConfigTemplatesDir, path -> path.toString().endsWith(JSON_EXT))) { |
@@ -159,7 +159,7 @@ public class CassandraDbHelper { | @@ -159,7 +159,7 @@ public class CassandraDbHelper { | ||
159 | } else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMESTAMP) { | 159 | } else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMESTAMP) { |
160 | str = ""+row.getInstant(index).toEpochMilli(); | 160 | str = ""+row.getInstant(index).toEpochMilli(); |
161 | } else if (type.getProtocolCode() == ProtocolConstants.DataType.BOOLEAN) { | 161 | } else if (type.getProtocolCode() == ProtocolConstants.DataType.BOOLEAN) { |
162 | - str = new Boolean(row.getBoolean(index)).toString(); | 162 | + str = Boolean.valueOf(row.getBoolean(index)).toString(); |
163 | } else { | 163 | } else { |
164 | str = row.getString(index); | 164 | str = row.getString(index); |
165 | } | 165 | } |
application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java
renamed from
dao/src/main/java/org/thingsboard/server/dao/resource/BaseTbResourceService.java
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.dao.resource; | 16 | +package org.thingsboard.server.service.resource; |
17 | 17 | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | import org.apache.commons.lang3.StringUtils; | 19 | import org.apache.commons.lang3.StringUtils; |
@@ -21,12 +21,12 @@ import org.eclipse.leshan.core.model.DDFFileParser; | @@ -21,12 +21,12 @@ import org.eclipse.leshan.core.model.DDFFileParser; | ||
21 | import org.eclipse.leshan.core.model.DefaultDDFFileValidator; | 21 | import org.eclipse.leshan.core.model.DefaultDDFFileValidator; |
22 | import org.eclipse.leshan.core.model.InvalidDDFFileException; | 22 | import org.eclipse.leshan.core.model.InvalidDDFFileException; |
23 | import org.eclipse.leshan.core.model.ObjectModel; | 23 | import org.eclipse.leshan.core.model.ObjectModel; |
24 | -import org.hibernate.exception.ConstraintViolationException; | ||
25 | import org.springframework.stereotype.Service; | 24 | import org.springframework.stereotype.Service; |
26 | import org.thingsboard.server.common.data.ResourceType; | 25 | import org.thingsboard.server.common.data.ResourceType; |
27 | import org.thingsboard.server.common.data.TbResource; | 26 | import org.thingsboard.server.common.data.TbResource; |
28 | import org.thingsboard.server.common.data.TbResourceInfo; | 27 | import org.thingsboard.server.common.data.TbResourceInfo; |
29 | -import org.thingsboard.server.common.data.Tenant; | 28 | +import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
29 | +import org.thingsboard.server.common.data.exception.ThingsboardException; | ||
30 | import org.thingsboard.server.common.data.id.TbResourceId; | 30 | import org.thingsboard.server.common.data.id.TbResourceId; |
31 | import org.thingsboard.server.common.data.id.TenantId; | 31 | import org.thingsboard.server.common.data.id.TenantId; |
32 | import org.thingsboard.server.common.data.lwm2m.LwM2mInstance; | 32 | import org.thingsboard.server.common.data.lwm2m.LwM2mInstance; |
@@ -35,11 +35,7 @@ import org.thingsboard.server.common.data.lwm2m.LwM2mResourceObserve; | @@ -35,11 +35,7 @@ import org.thingsboard.server.common.data.lwm2m.LwM2mResourceObserve; | ||
35 | import org.thingsboard.server.common.data.page.PageData; | 35 | import org.thingsboard.server.common.data.page.PageData; |
36 | import org.thingsboard.server.common.data.page.PageLink; | 36 | import org.thingsboard.server.common.data.page.PageLink; |
37 | import org.thingsboard.server.dao.exception.DataValidationException; | 37 | import org.thingsboard.server.dao.exception.DataValidationException; |
38 | -import org.thingsboard.server.dao.model.ModelConstants; | ||
39 | -import org.thingsboard.server.dao.service.DataValidator; | ||
40 | -import org.thingsboard.server.dao.service.PaginatedRemover; | ||
41 | -import org.thingsboard.server.dao.service.Validator; | ||
42 | -import org.thingsboard.server.dao.tenant.TenantDao; | 38 | +import org.thingsboard.server.dao.resource.ResourceService; |
43 | 39 | ||
44 | import java.io.ByteArrayInputStream; | 40 | import java.io.ByteArrayInputStream; |
45 | import java.io.IOException; | 41 | import java.io.IOException; |
@@ -47,7 +43,6 @@ import java.util.ArrayList; | @@ -47,7 +43,6 @@ import java.util.ArrayList; | ||
47 | import java.util.Base64; | 43 | import java.util.Base64; |
48 | import java.util.Comparator; | 44 | import java.util.Comparator; |
49 | import java.util.List; | 45 | import java.util.List; |
50 | -import java.util.Optional; | ||
51 | import java.util.stream.Collectors; | 46 | import java.util.stream.Collectors; |
52 | 47 | ||
53 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; | 48 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; |
@@ -55,139 +50,120 @@ import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPA | @@ -55,139 +50,120 @@ import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPA | ||
55 | import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID; | 50 | import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID; |
56 | import static org.thingsboard.server.dao.service.Validator.validateId; | 51 | import static org.thingsboard.server.dao.service.Validator.validateId; |
57 | 52 | ||
58 | -@Service | ||
59 | @Slf4j | 53 | @Slf4j |
60 | -public class BaseTbResourceService implements TbResourceService { | 54 | +@Service |
55 | +public class DefaultTbResourceService implements TbResourceService { | ||
61 | 56 | ||
62 | - public static final String INCORRECT_RESOURCE_ID = "Incorrect resourceId "; | ||
63 | - private final TbResourceDao resourceDao; | ||
64 | - private final TbResourceInfoDao resourceInfoDao; | ||
65 | - private final TenantDao tenantDao; | 57 | + private final ResourceService resourceService; |
66 | private final DDFFileParser ddfFileParser; | 58 | private final DDFFileParser ddfFileParser; |
67 | 59 | ||
68 | - public BaseTbResourceService(TbResourceDao resourceDao, TbResourceInfoDao resourceInfoDao, TenantDao tenantDao) { | ||
69 | - this.resourceDao = resourceDao; | ||
70 | - this.resourceInfoDao = resourceInfoDao; | ||
71 | - this.tenantDao = tenantDao; | 60 | + public DefaultTbResourceService(ResourceService resourceService) { |
61 | + this.resourceService = resourceService; | ||
72 | this.ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator()); | 62 | this.ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator()); |
73 | } | 63 | } |
74 | 64 | ||
75 | @Override | 65 | @Override |
76 | - public TbResource saveResource(TbResource resource) throws InvalidDDFFileException, IOException { | 66 | + public TbResource saveResource(TbResource resource) throws ThingsboardException { |
77 | log.trace("Executing saveResource [{}]", resource); | 67 | log.trace("Executing saveResource [{}]", resource); |
78 | if (StringUtils.isEmpty(resource.getData())) { | 68 | if (StringUtils.isEmpty(resource.getData())) { |
79 | throw new DataValidationException("Resource data should be specified!"); | 69 | throw new DataValidationException("Resource data should be specified!"); |
80 | } | 70 | } |
81 | if (ResourceType.LWM2M_MODEL.equals(resource.getResourceType())) { | 71 | if (ResourceType.LWM2M_MODEL.equals(resource.getResourceType())) { |
82 | - List<ObjectModel> objectModels = | ||
83 | - ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getData())), resource.getSearchText()); | ||
84 | - if (!objectModels.isEmpty()) { | ||
85 | - ObjectModel objectModel = objectModels.get(0); | ||
86 | - | ||
87 | - String resourceKey = objectModel.id + LWM2M_SEPARATOR_KEY + objectModel.getVersion(); | ||
88 | - String name = objectModel.name; | ||
89 | - resource.setResourceKey(resourceKey); | ||
90 | - if (resource.getId() == null) { | ||
91 | - resource.setTitle(name + " id=" + objectModel.id + " v" + objectModel.getVersion()); | 72 | + try { |
73 | + List<ObjectModel> objectModels = | ||
74 | + ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getData())), resource.getSearchText()); | ||
75 | + if (!objectModels.isEmpty()) { | ||
76 | + ObjectModel objectModel = objectModels.get(0); | ||
77 | + | ||
78 | + String resourceKey = objectModel.id + LWM2M_SEPARATOR_KEY + objectModel.getVersion(); | ||
79 | + String name = objectModel.name; | ||
80 | + resource.setResourceKey(resourceKey); | ||
81 | + if (resource.getId() == null) { | ||
82 | + resource.setTitle(name + " id=" + objectModel.id + " v" + objectModel.getVersion()); | ||
83 | + } | ||
84 | + resource.setSearchText(resourceKey + LWM2M_SEPARATOR_SEARCH_TEXT + name); | ||
85 | + } else { | ||
86 | + throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText())); | ||
92 | } | 87 | } |
93 | - resource.setSearchText(resourceKey + LWM2M_SEPARATOR_SEARCH_TEXT + name); | ||
94 | - } else { | 88 | + } catch (InvalidDDFFileException | IOException e) { |
89 | + throw new ThingsboardException(e, ThingsboardErrorCode.GENERAL); | ||
90 | + } | ||
91 | + if (resource.getResourceType().equals(ResourceType.LWM2M_MODEL) && toLwM2mObject(resource) == null) { | ||
95 | throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText())); | 92 | throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText())); |
96 | } | 93 | } |
97 | } else { | 94 | } else { |
98 | resource.setResourceKey(resource.getFileName()); | 95 | resource.setResourceKey(resource.getFileName()); |
99 | } | 96 | } |
100 | 97 | ||
101 | - resourceValidator.validate(resource, TbResourceInfo::getTenantId); | ||
102 | - | ||
103 | - try { | ||
104 | - return resourceDao.save(resource.getTenantId(), resource); | ||
105 | - } catch (Exception t) { | ||
106 | - ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); | ||
107 | - if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("resource_unq_key")) { | ||
108 | - String field = ResourceType.LWM2M_MODEL.equals(resource.getResourceType()) ? "resourceKey" : "fileName"; | ||
109 | - throw new DataValidationException("Resource with such " + field + " already exists!"); | ||
110 | - } else { | ||
111 | - throw t; | ||
112 | - } | ||
113 | - } | ||
114 | - | 98 | + return resourceService.saveResource(resource); |
115 | } | 99 | } |
116 | 100 | ||
117 | @Override | 101 | @Override |
118 | - public TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceKey) { | ||
119 | - log.trace("Executing getResource [{}] [{}] [{}]", tenantId, resourceType, resourceKey); | ||
120 | - return resourceDao.getResource(tenantId, resourceType, resourceKey); | 102 | + public TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId) { |
103 | + return resourceService.getResource(tenantId, resourceType, resourceId); | ||
121 | } | 104 | } |
122 | 105 | ||
123 | @Override | 106 | @Override |
124 | public TbResource findResourceById(TenantId tenantId, TbResourceId resourceId) { | 107 | public TbResource findResourceById(TenantId tenantId, TbResourceId resourceId) { |
125 | - log.trace("Executing findResourceById [{}] [{}]", tenantId, resourceId); | ||
126 | - Validator.validateId(resourceId, INCORRECT_RESOURCE_ID + resourceId); | ||
127 | - return resourceDao.findById(tenantId, resourceId.getId()); | 108 | + return resourceService.findResourceById(tenantId, resourceId); |
128 | } | 109 | } |
129 | 110 | ||
130 | @Override | 111 | @Override |
131 | public TbResourceInfo findResourceInfoById(TenantId tenantId, TbResourceId resourceId) { | 112 | public TbResourceInfo findResourceInfoById(TenantId tenantId, TbResourceId resourceId) { |
132 | - log.trace("Executing findResourceInfoById [{}] [{}]", tenantId, resourceId); | ||
133 | - Validator.validateId(resourceId, INCORRECT_RESOURCE_ID + resourceId); | ||
134 | - return resourceInfoDao.findById(tenantId, resourceId.getId()); | ||
135 | - } | ||
136 | - | ||
137 | - @Override | ||
138 | - public void deleteResource(TenantId tenantId, TbResourceId resourceId) { | ||
139 | - log.trace("Executing deleteResource [{}] [{}]", tenantId, resourceId); | ||
140 | - Validator.validateId(resourceId, INCORRECT_RESOURCE_ID + resourceId); | ||
141 | - resourceDao.removeById(tenantId, resourceId.getId()); | 113 | + return resourceService.findResourceInfoById(tenantId, resourceId); |
142 | } | 114 | } |
143 | 115 | ||
144 | @Override | 116 | @Override |
145 | public PageData<TbResourceInfo> findAllTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink) { | 117 | public PageData<TbResourceInfo> findAllTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink) { |
146 | - log.trace("Executing findAllTenantResourcesByTenantId [{}]", tenantId); | ||
147 | - validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
148 | - return resourceInfoDao.findAllTenantResourcesByTenantId(tenantId.getId(), pageLink); | 118 | + return resourceService.findAllTenantResourcesByTenantId(tenantId, pageLink); |
149 | } | 119 | } |
150 | 120 | ||
151 | @Override | 121 | @Override |
152 | public PageData<TbResourceInfo> findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink) { | 122 | public PageData<TbResourceInfo> findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink) { |
153 | - log.trace("Executing findTenantResourcesByTenantId [{}]", tenantId); | ||
154 | - validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
155 | - return resourceInfoDao.findTenantResourcesByTenantId(tenantId.getId(), pageLink); | 123 | + return resourceService.findTenantResourcesByTenantId(tenantId, pageLink); |
156 | } | 124 | } |
157 | 125 | ||
158 | @Override | 126 | @Override |
159 | - public List<LwM2mObject> findLwM2mObjectPage(TenantId tenantId, String sortProperty, String sortOrder, PageLink pageLink) { | 127 | + public List<LwM2mObject> findLwM2mObject(TenantId tenantId, String sortOrder, String sortProperty, String[] objectIds) { |
160 | log.trace("Executing findByTenantId [{}]", tenantId); | 128 | log.trace("Executing findByTenantId [{}]", tenantId); |
161 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | 129 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); |
162 | - PageData<TbResource> resourcePageData = resourceDao.findResourcesByTenantIdAndResourceType( | ||
163 | - tenantId, | ||
164 | - ResourceType.LWM2M_MODEL, pageLink); | ||
165 | - return resourcePageData.getData().stream() | 130 | + List<TbResource> resources = resourceService.findTenantResourcesByResourceTypeAndObjectIds(tenantId, ResourceType.LWM2M_MODEL, |
131 | + objectIds); | ||
132 | + return resources.stream() | ||
166 | .map(this::toLwM2mObject) | 133 | .map(this::toLwM2mObject) |
167 | .sorted(getComparator(sortProperty, sortOrder)) | 134 | .sorted(getComparator(sortProperty, sortOrder)) |
168 | .collect(Collectors.toList()); | 135 | .collect(Collectors.toList()); |
169 | } | 136 | } |
170 | 137 | ||
171 | @Override | 138 | @Override |
172 | - public List<LwM2mObject> findLwM2mObject(TenantId tenantId, String sortOrder, | ||
173 | - String sortProperty, | ||
174 | - String[] objectIds) { | 139 | + public List<LwM2mObject> findLwM2mObjectPage(TenantId tenantId, String sortProperty, String sortOrder, PageLink pageLink) { |
175 | log.trace("Executing findByTenantId [{}]", tenantId); | 140 | log.trace("Executing findByTenantId [{}]", tenantId); |
176 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | 141 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); |
177 | - List<TbResource> resources = resourceDao.findResourcesByTenantIdAndResourceType(tenantId, ResourceType.LWM2M_MODEL, | ||
178 | - objectIds, | ||
179 | - null); | ||
180 | - return resources.stream() | 142 | + PageData<TbResource> resourcePageData = resourceService.findTenantResourcesByResourceTypeAndPageLink(tenantId, ResourceType.LWM2M_MODEL, pageLink); |
143 | + return resourcePageData.getData().stream() | ||
181 | .map(this::toLwM2mObject) | 144 | .map(this::toLwM2mObject) |
182 | .sorted(getComparator(sortProperty, sortOrder)) | 145 | .sorted(getComparator(sortProperty, sortOrder)) |
183 | .collect(Collectors.toList()); | 146 | .collect(Collectors.toList()); |
184 | } | 147 | } |
185 | 148 | ||
186 | @Override | 149 | @Override |
150 | + public void deleteResource(TenantId tenantId, TbResourceId resourceId) { | ||
151 | + resourceService.deleteResource(tenantId, resourceId); | ||
152 | + } | ||
153 | + | ||
154 | + @Override | ||
187 | public void deleteResourcesByTenantId(TenantId tenantId) { | 155 | public void deleteResourcesByTenantId(TenantId tenantId) { |
188 | - log.trace("Executing deleteResourcesByTenantId, tenantId [{}]", tenantId); | ||
189 | - validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
190 | - tenantResourcesRemover.removeEntities(tenantId, tenantId); | 156 | + resourceService.deleteResourcesByTenantId(tenantId); |
157 | + } | ||
158 | + | ||
159 | + private Comparator<? super LwM2mObject> getComparator(String sortProperty, String sortOrder) { | ||
160 | + Comparator<LwM2mObject> comparator; | ||
161 | + if ("name".equals(sortProperty)) { | ||
162 | + comparator = Comparator.comparing(LwM2mObject::getName); | ||
163 | + } else { | ||
164 | + comparator = Comparator.comparingLong(LwM2mObject::getId); | ||
165 | + } | ||
166 | + return "DESC".equals(sortOrder) ? comparator.reversed() : comparator; | ||
191 | } | 167 | } |
192 | 168 | ||
193 | private LwM2mObject toLwM2mObject(TbResource resource) { | 169 | private LwM2mObject toLwM2mObject(TbResource resource) { |
@@ -223,69 +199,4 @@ public class BaseTbResourceService implements TbResourceService { | @@ -223,69 +199,4 @@ public class BaseTbResourceService implements TbResourceService { | ||
223 | return null; | 199 | return null; |
224 | } | 200 | } |
225 | } | 201 | } |
226 | - | ||
227 | - private Comparator<? super LwM2mObject> getComparator(String sortProperty, String sortOrder) { | ||
228 | - Comparator<LwM2mObject> comparator; | ||
229 | - if ("name".equals(sortProperty)) { | ||
230 | - comparator = Comparator.comparing(LwM2mObject::getName); | ||
231 | - } else { | ||
232 | - comparator = Comparator.comparingLong(LwM2mObject::getId); | ||
233 | - } | ||
234 | - return "DESC".equals(sortOrder) ? comparator.reversed() : comparator; | ||
235 | - } | ||
236 | - | ||
237 | - private DataValidator<TbResource> resourceValidator = new DataValidator<>() { | ||
238 | - | ||
239 | - @Override | ||
240 | - protected void validateDataImpl(TenantId tenantId, TbResource resource) { | ||
241 | - if (StringUtils.isEmpty(resource.getTitle())) { | ||
242 | - throw new DataValidationException("Resource title should be specified!"); | ||
243 | - } | ||
244 | - if (resource.getResourceType() == null) { | ||
245 | - throw new DataValidationException("Resource type should be specified!"); | ||
246 | - } | ||
247 | - if (StringUtils.isEmpty(resource.getFileName())) { | ||
248 | - throw new DataValidationException("Resource file name should be specified!"); | ||
249 | - } | ||
250 | - if (StringUtils.isEmpty(resource.getResourceKey())) { | ||
251 | - throw new DataValidationException("Resource key should be specified!"); | ||
252 | - } | ||
253 | - if (resource.getTenantId() == null) { | ||
254 | - resource.setTenantId(new TenantId(ModelConstants.NULL_UUID)); | ||
255 | - } | ||
256 | - if (!resource.getTenantId().getId().equals(ModelConstants.NULL_UUID)) { | ||
257 | - Tenant tenant = tenantDao.findById(tenantId, resource.getTenantId().getId()); | ||
258 | - if (tenant == null) { | ||
259 | - throw new DataValidationException("Resource is referencing to non-existent tenant!"); | ||
260 | - } | ||
261 | - } | ||
262 | - if (resource.getResourceType().equals(ResourceType.LWM2M_MODEL) && toLwM2mObject(resource) == null) { | ||
263 | - throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText())); | ||
264 | - } | ||
265 | - } | ||
266 | - }; | ||
267 | - | ||
268 | - private PaginatedRemover<TenantId, TbResource> tenantResourcesRemover = | ||
269 | - new PaginatedRemover<>() { | ||
270 | - | ||
271 | - @Override | ||
272 | - protected PageData<TbResource> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) { | ||
273 | - return resourceDao.findAllByTenantId(id, pageLink); | ||
274 | - } | ||
275 | - | ||
276 | - @Override | ||
277 | - protected void removeEntity(TenantId tenantId, TbResource entity) { | ||
278 | - deleteResource(tenantId, new TbResourceId(entity.getUuidId())); | ||
279 | - } | ||
280 | - }; | ||
281 | - | ||
282 | - protected Optional<ConstraintViolationException> extractConstraintViolationException(Exception t) { | ||
283 | - if (t instanceof ConstraintViolationException) { | ||
284 | - return Optional.of((ConstraintViolationException) t); | ||
285 | - } else if (t.getCause() instanceof ConstraintViolationException) { | ||
286 | - return Optional.of((ConstraintViolationException) (t.getCause())); | ||
287 | - } else { | ||
288 | - return Optional.empty(); | ||
289 | - } | ||
290 | - } | ||
291 | } | 202 | } |
application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java
renamed from
common/dao-api/src/main/java/org/thingsboard/server/dao/resource/TbResourceService.java
@@ -13,24 +13,23 @@ | @@ -13,24 +13,23 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.dao.resource; | 16 | +package org.thingsboard.server.service.resource; |
17 | 17 | ||
18 | -import org.eclipse.leshan.core.model.InvalidDDFFileException; | 18 | +import org.thingsboard.server.common.data.ResourceType; |
19 | import org.thingsboard.server.common.data.TbResource; | 19 | import org.thingsboard.server.common.data.TbResource; |
20 | import org.thingsboard.server.common.data.TbResourceInfo; | 20 | import org.thingsboard.server.common.data.TbResourceInfo; |
21 | -import org.thingsboard.server.common.data.ResourceType; | 21 | +import org.thingsboard.server.common.data.exception.ThingsboardException; |
22 | import org.thingsboard.server.common.data.id.TbResourceId; | 22 | import org.thingsboard.server.common.data.id.TbResourceId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 23 | import org.thingsboard.server.common.data.id.TenantId; |
24 | import org.thingsboard.server.common.data.lwm2m.LwM2mObject; | 24 | import org.thingsboard.server.common.data.lwm2m.LwM2mObject; |
25 | import org.thingsboard.server.common.data.page.PageData; | 25 | import org.thingsboard.server.common.data.page.PageData; |
26 | import org.thingsboard.server.common.data.page.PageLink; | 26 | import org.thingsboard.server.common.data.page.PageLink; |
27 | 27 | ||
28 | -import java.io.IOException; | ||
29 | import java.util.List; | 28 | import java.util.List; |
30 | 29 | ||
31 | - | ||
32 | public interface TbResourceService { | 30 | public interface TbResourceService { |
33 | - TbResource saveResource(TbResource resource) throws InvalidDDFFileException, IOException; | 31 | + |
32 | + TbResource saveResource(TbResource resource) throws ThingsboardException; | ||
34 | 33 | ||
35 | TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); | 34 | TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); |
36 | 35 | ||
@@ -55,4 +54,5 @@ public interface TbResourceService { | @@ -55,4 +54,5 @@ public interface TbResourceService { | ||
55 | void deleteResource(TenantId tenantId, TbResourceId resourceId); | 54 | void deleteResource(TenantId tenantId, TbResourceId resourceId); |
56 | 55 | ||
57 | void deleteResourcesByTenantId(TenantId tenantId); | 56 | void deleteResourcesByTenantId(TenantId tenantId); |
57 | + | ||
58 | } | 58 | } |
@@ -17,8 +17,10 @@ package org.thingsboard.server.service.security.auth.oauth2; | @@ -17,8 +17,10 @@ package org.thingsboard.server.service.security.auth.oauth2; | ||
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.ObjectMapper; | 18 | import com.fasterxml.jackson.databind.ObjectMapper; |
19 | import com.fasterxml.jackson.databind.node.ObjectNode; | 19 | import com.fasterxml.jackson.databind.node.ObjectNode; |
20 | +import lombok.Getter; | ||
20 | import lombok.extern.slf4j.Slf4j; | 21 | import lombok.extern.slf4j.Slf4j; |
21 | import org.springframework.beans.factory.annotation.Autowired; | 22 | import org.springframework.beans.factory.annotation.Autowired; |
23 | +import org.springframework.beans.factory.annotation.Value; | ||
22 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | 24 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
23 | import org.springframework.security.core.userdetails.UsernameNotFoundException; | 25 | import org.springframework.security.core.userdetails.UsernameNotFoundException; |
24 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | 26 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
@@ -85,6 +87,10 @@ public abstract class AbstractOAuth2ClientMapper { | @@ -85,6 +87,10 @@ public abstract class AbstractOAuth2ClientMapper { | ||
85 | @Autowired | 87 | @Autowired |
86 | protected TbClusterService tbClusterService; | 88 | protected TbClusterService tbClusterService; |
87 | 89 | ||
90 | + @Value("${edges.enabled}") | ||
91 | + @Getter | ||
92 | + private boolean edgesEnabled; | ||
93 | + | ||
88 | private final Lock userCreationLock = new ReentrantLock(); | 94 | private final Lock userCreationLock = new ReentrantLock(); |
89 | 95 | ||
90 | protected SecurityUser getOrCreateSecurityUserFromOAuth2User(OAuth2User oauth2User, OAuth2ClientRegistrationInfo clientRegistration) { | 96 | protected SecurityUser getOrCreateSecurityUserFromOAuth2User(OAuth2User oauth2User, OAuth2ClientRegistrationInfo clientRegistration) { |
@@ -171,6 +177,9 @@ public abstract class AbstractOAuth2ClientMapper { | @@ -171,6 +177,9 @@ public abstract class AbstractOAuth2ClientMapper { | ||
171 | tenant.setTitle(tenantName); | 177 | tenant.setTitle(tenantName); |
172 | tenant = tenantService.saveTenant(tenant); | 178 | tenant = tenantService.saveTenant(tenant); |
173 | installScripts.createDefaultRuleChains(tenant.getId()); | 179 | installScripts.createDefaultRuleChains(tenant.getId()); |
180 | + if (edgesEnabled) { | ||
181 | + installScripts.createDefaultEdgeRuleChains(tenant.getId()); | ||
182 | + } | ||
174 | tenantProfileCache.evict(tenant.getId()); | 183 | tenantProfileCache.evict(tenant.getId()); |
175 | tbClusterService.onTenantChange(tenant, null); | 184 | tbClusterService.onTenantChange(tenant, null); |
176 | tbClusterService.onEntityStateChange(tenant.getId(), tenant.getId(), | 185 | tbClusterService.onEntityStateChange(tenant.getId(), tenant.getId(), |
@@ -57,7 +57,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionFailedException; | @@ -57,7 +57,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionFailedException; | ||
57 | import org.thingsboard.server.dao.device.provision.ProvisionRequest; | 57 | import org.thingsboard.server.dao.device.provision.ProvisionRequest; |
58 | import org.thingsboard.server.dao.device.provision.ProvisionResponse; | 58 | import org.thingsboard.server.dao.device.provision.ProvisionResponse; |
59 | import org.thingsboard.server.dao.relation.RelationService; | 59 | import org.thingsboard.server.dao.relation.RelationService; |
60 | -import org.thingsboard.server.dao.resource.TbResourceService; | 60 | +import org.thingsboard.server.dao.resource.ResourceService; |
61 | import org.thingsboard.server.dao.tenant.TbTenantProfileCache; | 61 | import org.thingsboard.server.dao.tenant.TbTenantProfileCache; |
62 | import org.thingsboard.server.gen.transport.TransportProtos; | 62 | import org.thingsboard.server.gen.transport.TransportProtos; |
63 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; | 63 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; |
@@ -117,7 +117,7 @@ public class DefaultTransportApiService implements TransportApiService { | @@ -117,7 +117,7 @@ public class DefaultTransportApiService implements TransportApiService { | ||
117 | private final TbClusterService tbClusterService; | 117 | private final TbClusterService tbClusterService; |
118 | private final DataDecodingEncodingService dataDecodingEncodingService; | 118 | private final DataDecodingEncodingService dataDecodingEncodingService; |
119 | private final DeviceProvisionService deviceProvisionService; | 119 | private final DeviceProvisionService deviceProvisionService; |
120 | - private final TbResourceService resourceService; | 120 | + private final ResourceService resourceService; |
121 | 121 | ||
122 | private final ConcurrentMap<String, ReentrantLock> deviceCreationLocks = new ConcurrentHashMap<>(); | 122 | private final ConcurrentMap<String, ReentrantLock> deviceCreationLocks = new ConcurrentHashMap<>(); |
123 | 123 | ||
@@ -126,7 +126,7 @@ public class DefaultTransportApiService implements TransportApiService { | @@ -126,7 +126,7 @@ public class DefaultTransportApiService implements TransportApiService { | ||
126 | RelationService relationService, DeviceCredentialsService deviceCredentialsService, | 126 | RelationService relationService, DeviceCredentialsService deviceCredentialsService, |
127 | DeviceStateService deviceStateService, DbCallbackExecutorService dbCallbackExecutorService, | 127 | DeviceStateService deviceStateService, DbCallbackExecutorService dbCallbackExecutorService, |
128 | TbClusterService tbClusterService, DataDecodingEncodingService dataDecodingEncodingService, | 128 | TbClusterService tbClusterService, DataDecodingEncodingService dataDecodingEncodingService, |
129 | - DeviceProvisionService deviceProvisionService, TbResourceService resourceService) { | 129 | + DeviceProvisionService deviceProvisionService, ResourceService resourceService) { |
130 | this.deviceProfileCache = deviceProfileCache; | 130 | this.deviceProfileCache = deviceProfileCache; |
131 | this.tenantProfileCache = tenantProfileCache; | 131 | this.tenantProfileCache = tenantProfileCache; |
132 | this.apiUsageStateService = apiUsageStateService; | 132 | this.apiUsageStateService = apiUsageStateService; |
1 | - ______ __ _ __ __ | ||
2 | - /_ __/ / /_ (_) ____ ____ _ _____ / /_ ____ ____ _ _____ ____/ / | ||
3 | - / / / __ \ / / / __ \ / __ `/ / ___/ / __ \ / __ \ / __ `/ / ___/ / __ / | ||
4 | - / / / / / / / / / / / / / /_/ / (__ ) / /_/ // /_/ // /_/ / / / / /_/ / | ||
5 | -/_/ /_/ /_/ /_/ /_/ /_/ \__, / /____/ /_.___/ \____/ \__,_/ /_/ \__,_/ | 1 | + ______ __ _ ____ __ |
2 | + /_ __/ / /_ (_) ____ ____ _ _____ / __ ) ____ ____ _ _____ ____/ / | ||
3 | + / / / __ \ / / / __ \ / __ `/ / ___/ / __ | / __ \ / __ `/ / ___/ / __ / | ||
4 | + / / / / / / / / / / / / / /_/ / (__ ) / /_/ / / /_/ // /_/ / / / / /_/ / | ||
5 | +/_/ /_/ /_/ /_/ /_/ /_/ \__, / /____/ /_____/ \____/ \__,_/ /_/ \__,_/ | ||
6 | /____/ | 6 | /____/ |
7 | 7 | ||
8 | =================================================== | 8 | =================================================== |
@@ -38,6 +38,9 @@ | @@ -38,6 +38,9 @@ | ||
38 | <!-- <logger name="org.eclipse.californium.scandium.DTLSConnector" level="TRACE" />--> | 38 | <!-- <logger name="org.eclipse.californium.scandium.DTLSConnector" level="TRACE" />--> |
39 | <!-- <logger name="org.eclipse.californium.scandium.dtls.Handshaker" level="DEBUG" />--> | 39 | <!-- <logger name="org.eclipse.californium.scandium.dtls.Handshaker" level="DEBUG" />--> |
40 | 40 | ||
41 | + <!-- Top Rule Nodes by max execution time --> | ||
42 | +<!-- <logger name="org.thingsboard.server.service.queue.TbMsgPackProcessingContext" level="DEBUG" /> --> | ||
43 | + | ||
41 | <logger name="com.microsoft.azure.servicebus.primitives.CoreMessageReceiver" level="OFF" /> | 44 | <logger name="com.microsoft.azure.servicebus.primitives.CoreMessageReceiver" level="OFF" /> |
42 | 45 | ||
43 | <root level="INFO"> | 46 | <root level="INFO"> |
@@ -243,6 +243,7 @@ sql: | @@ -243,6 +243,7 @@ sql: | ||
243 | batch_max_delay: "${SQL_TS_LATEST_BATCH_MAX_DELAY_MS:100}" | 243 | batch_max_delay: "${SQL_TS_LATEST_BATCH_MAX_DELAY_MS:100}" |
244 | stats_print_interval_ms: "${SQL_TS_LATEST_BATCH_STATS_PRINT_MS:10000}" | 244 | stats_print_interval_ms: "${SQL_TS_LATEST_BATCH_STATS_PRINT_MS:10000}" |
245 | batch_threads: "${SQL_TS_LATEST_BATCH_THREADS:4}" | 245 | batch_threads: "${SQL_TS_LATEST_BATCH_THREADS:4}" |
246 | + update_by_latest_ts: "${SQL_TS_UPDATE_BY_LATEST_TIMESTAMP:true}" | ||
246 | # Specify whether to sort entities before batch update. Should be enabled for cluster mode to avoid deadlocks | 247 | # Specify whether to sort entities before batch update. Should be enabled for cluster mode to avoid deadlocks |
247 | batch_sort: "${SQL_BATCH_SORT:false}" | 248 | batch_sort: "${SQL_BATCH_SORT:false}" |
248 | # Specify whether to remove null characters from strValue of attributes and timeseries before insert | 249 | # Specify whether to remove null characters from strValue of attributes and timeseries before insert |
@@ -516,7 +517,7 @@ js: | @@ -516,7 +517,7 @@ js: | ||
516 | # Built-in JVM JavaScript environment properties | 517 | # Built-in JVM JavaScript environment properties |
517 | local: | 518 | local: |
518 | # Use Sandboxed (secured) JVM JavaScript environment | 519 | # Use Sandboxed (secured) JVM JavaScript environment |
519 | - use_js_sandbox: "${USE_LOCAL_JS_SANDBOX:false}" | 520 | + use_js_sandbox: "${USE_LOCAL_JS_SANDBOX:true}" |
520 | # Specify thread pool size for JavaScript sandbox resource monitor | 521 | # Specify thread pool size for JavaScript sandbox resource monitor |
521 | monitor_thread_pool_size: "${LOCAL_JS_SANDBOX_MONITOR_THREAD_POOL_SIZE:4}" | 522 | monitor_thread_pool_size: "${LOCAL_JS_SANDBOX_MONITOR_THREAD_POOL_SIZE:4}" |
522 | # Maximum CPU time in milliseconds allowed for script execution | 523 | # Maximum CPU time in milliseconds allowed for script execution |
@@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.security.Authority; | @@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.security.Authority; | ||
38 | import org.thingsboard.server.dao.model.ModelConstants; | 38 | import org.thingsboard.server.dao.model.ModelConstants; |
39 | import org.thingsboard.server.edge.imitator.EdgeImitator; | 39 | import org.thingsboard.server.edge.imitator.EdgeImitator; |
40 | import org.thingsboard.server.gen.edge.AssetUpdateMsg; | 40 | import org.thingsboard.server.gen.edge.AssetUpdateMsg; |
41 | +import org.thingsboard.server.gen.edge.DeviceProfileUpdateMsg; | ||
41 | import org.thingsboard.server.gen.edge.DeviceUpdateMsg; | 42 | import org.thingsboard.server.gen.edge.DeviceUpdateMsg; |
42 | import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; | 43 | import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; |
43 | import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; | 44 | import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; |
@@ -672,28 +673,32 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest { | @@ -672,28 +673,32 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest { | ||
672 | edgeImitator.ignoreType(UserCredentialsUpdateMsg.class); | 673 | edgeImitator.ignoreType(UserCredentialsUpdateMsg.class); |
673 | edgeImitator.expectMessageAmount(7); | 674 | edgeImitator.expectMessageAmount(7); |
674 | edgeImitator.connect(); | 675 | edgeImitator.connect(); |
675 | - edgeImitator.waitForMessages(); | 676 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
676 | 677 | ||
677 | Assert.assertEquals(7, edgeImitator.getDownlinkMsgs().size()); | 678 | Assert.assertEquals(7, edgeImitator.getDownlinkMsgs().size()); |
678 | Assert.assertTrue(edgeImitator.findMessageByType(RuleChainUpdateMsg.class).isPresent()); | 679 | Assert.assertTrue(edgeImitator.findMessageByType(RuleChainUpdateMsg.class).isPresent()); |
680 | + Assert.assertTrue(edgeImitator.findMessageByType(DeviceProfileUpdateMsg.class).isPresent()); | ||
679 | Assert.assertTrue(edgeImitator.findMessageByType(DeviceUpdateMsg.class).isPresent()); | 681 | Assert.assertTrue(edgeImitator.findMessageByType(DeviceUpdateMsg.class).isPresent()); |
680 | Assert.assertTrue(edgeImitator.findMessageByType(AssetUpdateMsg.class).isPresent()); | 682 | Assert.assertTrue(edgeImitator.findMessageByType(AssetUpdateMsg.class).isPresent()); |
681 | Assert.assertTrue(edgeImitator.findMessageByType(UserUpdateMsg.class).isPresent()); | 683 | Assert.assertTrue(edgeImitator.findMessageByType(UserUpdateMsg.class).isPresent()); |
682 | 684 | ||
683 | edgeImitator.getDownlinkMsgs().clear(); | 685 | edgeImitator.getDownlinkMsgs().clear(); |
684 | 686 | ||
685 | - edgeImitator.expectMessageAmount(4); | 687 | + edgeImitator.expectMessageAmount(7); |
686 | doPost("/api/edge/sync/" + edge.getId()); | 688 | doPost("/api/edge/sync/" + edge.getId()); |
687 | - edgeImitator.waitForMessages(); | 689 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
688 | 690 | ||
689 | - Assert.assertEquals(4, edgeImitator.getDownlinkMsgs().size()); | 691 | + Assert.assertEquals(7, edgeImitator.getDownlinkMsgs().size()); |
690 | Assert.assertTrue(edgeImitator.findMessageByType(RuleChainUpdateMsg.class).isPresent()); | 692 | Assert.assertTrue(edgeImitator.findMessageByType(RuleChainUpdateMsg.class).isPresent()); |
693 | + Assert.assertTrue(edgeImitator.findMessageByType(DeviceProfileUpdateMsg.class).isPresent()); | ||
691 | Assert.assertTrue(edgeImitator.findMessageByType(DeviceUpdateMsg.class).isPresent()); | 694 | Assert.assertTrue(edgeImitator.findMessageByType(DeviceUpdateMsg.class).isPresent()); |
692 | Assert.assertTrue(edgeImitator.findMessageByType(AssetUpdateMsg.class).isPresent()); | 695 | Assert.assertTrue(edgeImitator.findMessageByType(AssetUpdateMsg.class).isPresent()); |
693 | Assert.assertTrue(edgeImitator.findMessageByType(UserUpdateMsg.class).isPresent()); | 696 | Assert.assertTrue(edgeImitator.findMessageByType(UserUpdateMsg.class).isPresent()); |
694 | 697 | ||
695 | edgeImitator.allowIgnoredTypes(); | 698 | edgeImitator.allowIgnoredTypes(); |
696 | - edgeImitator.disconnect(); | 699 | + try { |
700 | + edgeImitator.disconnect(); | ||
701 | + } catch (Exception ignored) {} | ||
697 | 702 | ||
698 | doDelete("/api/device/" + savedDevice.getId().getId().toString()) | 703 | doDelete("/api/device/" + savedDevice.getId().getId().toString()) |
699 | .andExpect(status().isOk()); | 704 | .andExpect(status().isOk()); |
@@ -42,7 +42,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | @@ -42,7 +42,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | ||
42 | public class BaseEdgeEventControllerTest extends AbstractControllerTest { | 42 | public class BaseEdgeEventControllerTest extends AbstractControllerTest { |
43 | 43 | ||
44 | private Tenant savedTenant; | 44 | private Tenant savedTenant; |
45 | - private TenantId tenantId; | ||
46 | private User tenantAdmin; | 45 | private User tenantAdmin; |
47 | 46 | ||
48 | @Before | 47 | @Before |
@@ -52,7 +51,6 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { | @@ -52,7 +51,6 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { | ||
52 | Tenant tenant = new Tenant(); | 51 | Tenant tenant = new Tenant(); |
53 | tenant.setTitle("My tenant"); | 52 | tenant.setTitle("My tenant"); |
54 | savedTenant = doPost("/api/tenant", tenant, Tenant.class); | 53 | savedTenant = doPost("/api/tenant", tenant, Tenant.class); |
55 | - tenantId = savedTenant.getId(); | ||
56 | Assert.assertNotNull(savedTenant); | 54 | Assert.assertNotNull(savedTenant); |
57 | 55 | ||
58 | tenantAdmin = new User(); | 56 | tenantAdmin = new User(); |
@@ -63,6 +61,10 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { | @@ -63,6 +61,10 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { | ||
63 | tenantAdmin.setLastName("Downs"); | 61 | tenantAdmin.setLastName("Downs"); |
64 | 62 | ||
65 | tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); | 63 | tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); |
64 | + // sleep 1 seconds to avoid CREDENTIALS updated message for the user | ||
65 | + // user credentials is going to be stored and updated event pushed to edge notification service | ||
66 | + // while service will be processing this event edge could be already added and additional message will be pushed | ||
67 | + Thread.sleep(1000); | ||
66 | } | 68 | } |
67 | 69 | ||
68 | @After | 70 | @After |
@@ -75,7 +77,6 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { | @@ -75,7 +77,6 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { | ||
75 | 77 | ||
76 | @Test | 78 | @Test |
77 | public void testGetEdgeEvents() throws Exception { | 79 | public void testGetEdgeEvents() throws Exception { |
78 | - Thread.sleep(500); | ||
79 | Edge edge = constructEdge("TestEdge", "default"); | 80 | Edge edge = constructEdge("TestEdge", "default"); |
80 | edge = doPost("/api/edge", edge, Edge.class); | 81 | edge = doPost("/api/edge", edge, Edge.class); |
81 | 82 | ||
@@ -83,29 +84,31 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { | @@ -83,29 +84,31 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { | ||
83 | Device savedDevice = doPost("/api/device", device, Device.class); | 84 | Device savedDevice = doPost("/api/device", device, Device.class); |
84 | 85 | ||
85 | doPost("/api/edge/" + edge.getId().toString() + "/device/" + savedDevice.getId().toString(), Device.class); | 86 | doPost("/api/edge/" + edge.getId().toString() + "/device/" + savedDevice.getId().toString(), Device.class); |
86 | - Thread.sleep(500); | ||
87 | 87 | ||
88 | Asset asset = constructAsset("TestAsset", "default"); | 88 | Asset asset = constructAsset("TestAsset", "default"); |
89 | Asset savedAsset = doPost("/api/asset", asset, Asset.class); | 89 | Asset savedAsset = doPost("/api/asset", asset, Asset.class); |
90 | 90 | ||
91 | doPost("/api/edge/" + edge.getId().toString() + "/asset/" + savedAsset.getId().toString(), Asset.class); | 91 | doPost("/api/edge/" + edge.getId().toString() + "/asset/" + savedAsset.getId().toString(), Asset.class); |
92 | - Thread.sleep(500); | ||
93 | 92 | ||
94 | EntityRelation relation = new EntityRelation(savedAsset.getId(), savedDevice.getId(), EntityRelation.CONTAINS_TYPE); | 93 | EntityRelation relation = new EntityRelation(savedAsset.getId(), savedDevice.getId(), EntityRelation.CONTAINS_TYPE); |
95 | 94 | ||
96 | doPost("/api/relation", relation); | 95 | doPost("/api/relation", relation); |
97 | - Thread.sleep(500); | ||
98 | 96 | ||
99 | - List<EdgeEvent> edgeEvents = doGetTypedWithTimePageLink("/api/edge/" + edge.getId().toString() + "/events?", | ||
100 | - new TypeReference<PageData<EdgeEvent>>() { | ||
101 | - }, new TimePageLink(4)).getData(); | ||
102 | - | ||
103 | - Assert.assertFalse(edgeEvents.isEmpty()); | 97 | + // wait while edge event for the relation entity persisted to DB |
98 | + Thread.sleep(100); | ||
99 | + List<EdgeEvent> edgeEvents; | ||
100 | + int attempt = 1; | ||
101 | + do { | ||
102 | + edgeEvents = doGetTypedWithTimePageLink("/api/edge/" + edge.getId().toString() + "/events?", | ||
103 | + new TypeReference<PageData<EdgeEvent>>() {}, new TimePageLink(4)).getData(); | ||
104 | + attempt++; | ||
105 | + Thread.sleep(100); | ||
106 | + } while (edgeEvents.size() != 4 && attempt < 5); | ||
104 | Assert.assertEquals(4, edgeEvents.size()); | 107 | Assert.assertEquals(4, edgeEvents.size()); |
105 | - Assert.assertEquals(EdgeEventType.RULE_CHAIN, edgeEvents.get(0).getType()); | ||
106 | - Assert.assertEquals(EdgeEventType.DEVICE, edgeEvents.get(1).getType()); | ||
107 | - Assert.assertEquals(EdgeEventType.ASSET, edgeEvents.get(2).getType()); | ||
108 | - Assert.assertEquals(EdgeEventType.RELATION, edgeEvents.get(3).getType()); | 108 | + Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.RULE_CHAIN.equals(ee.getType()))); |
109 | + Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.DEVICE.equals(ee.getType()))); | ||
110 | + Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.ASSET.equals(ee.getType()))); | ||
111 | + Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.RELATION.equals(ee.getType()))); | ||
109 | } | 112 | } |
110 | 113 | ||
111 | private Device constructDevice(String name, String type) { | 114 | private Device constructDevice(String name, String type) { |
@@ -32,10 +32,12 @@ import org.junit.Assert; | @@ -32,10 +32,12 @@ import org.junit.Assert; | ||
32 | import org.junit.Before; | 32 | import org.junit.Before; |
33 | import org.junit.Test; | 33 | import org.junit.Test; |
34 | import org.springframework.beans.factory.annotation.Autowired; | 34 | import org.springframework.beans.factory.annotation.Autowired; |
35 | +import org.thingsboard.common.util.JacksonUtil; | ||
35 | import org.thingsboard.server.common.data.Customer; | 36 | import org.thingsboard.server.common.data.Customer; |
36 | import org.thingsboard.server.common.data.Dashboard; | 37 | import org.thingsboard.server.common.data.Dashboard; |
37 | import org.thingsboard.server.common.data.DataConstants; | 38 | import org.thingsboard.server.common.data.DataConstants; |
38 | import org.thingsboard.server.common.data.Device; | 39 | import org.thingsboard.server.common.data.Device; |
40 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
39 | import org.thingsboard.server.common.data.EntityType; | 41 | import org.thingsboard.server.common.data.EntityType; |
40 | import org.thingsboard.server.common.data.EntityView; | 42 | import org.thingsboard.server.common.data.EntityView; |
41 | import org.thingsboard.server.common.data.Tenant; | 43 | import org.thingsboard.server.common.data.Tenant; |
@@ -45,6 +47,15 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo; | @@ -45,6 +47,15 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo; | ||
45 | import org.thingsboard.server.common.data.alarm.AlarmSeverity; | 47 | import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
46 | import org.thingsboard.server.common.data.alarm.AlarmStatus; | 48 | import org.thingsboard.server.common.data.alarm.AlarmStatus; |
47 | import org.thingsboard.server.common.data.asset.Asset; | 49 | import org.thingsboard.server.common.data.asset.Asset; |
50 | +import org.thingsboard.server.common.data.device.profile.AlarmCondition; | ||
51 | +import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter; | ||
52 | +import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey; | ||
53 | +import org.thingsboard.server.common.data.device.profile.AlarmConditionKeyType; | ||
54 | +import org.thingsboard.server.common.data.device.profile.AlarmRule; | ||
55 | +import org.thingsboard.server.common.data.device.profile.AllowCreateNewDevicesDeviceProfileProvisionConfiguration; | ||
56 | +import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; | ||
57 | +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; | ||
58 | +import org.thingsboard.server.common.data.device.profile.SimpleAlarmConditionSpec; | ||
48 | import org.thingsboard.server.common.data.edge.Edge; | 59 | import org.thingsboard.server.common.data.edge.Edge; |
49 | import org.thingsboard.server.common.data.edge.EdgeEvent; | 60 | import org.thingsboard.server.common.data.edge.EdgeEvent; |
50 | import org.thingsboard.server.common.data.edge.EdgeEventActionType; | 61 | import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
@@ -57,6 +68,9 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -57,6 +68,9 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
57 | import org.thingsboard.server.common.data.id.UserId; | 68 | import org.thingsboard.server.common.data.id.UserId; |
58 | import org.thingsboard.server.common.data.page.PageData; | 69 | import org.thingsboard.server.common.data.page.PageData; |
59 | import org.thingsboard.server.common.data.page.PageLink; | 70 | import org.thingsboard.server.common.data.page.PageLink; |
71 | +import org.thingsboard.server.common.data.query.EntityKeyValueType; | ||
72 | +import org.thingsboard.server.common.data.query.FilterPredicateValue; | ||
73 | +import org.thingsboard.server.common.data.query.NumericFilterPredicate; | ||
60 | import org.thingsboard.server.common.data.relation.EntityRelation; | 74 | import org.thingsboard.server.common.data.relation.EntityRelation; |
61 | import org.thingsboard.server.common.data.relation.RelationTypeGroup; | 75 | import org.thingsboard.server.common.data.relation.RelationTypeGroup; |
62 | import org.thingsboard.server.common.data.rule.RuleChain; | 76 | import org.thingsboard.server.common.data.rule.RuleChain; |
@@ -71,7 +85,6 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; | @@ -71,7 +85,6 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; | ||
71 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; | 85 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; |
72 | import org.thingsboard.server.controller.AbstractControllerTest; | 86 | import org.thingsboard.server.controller.AbstractControllerTest; |
73 | import org.thingsboard.server.dao.edge.EdgeEventService; | 87 | import org.thingsboard.server.dao.edge.EdgeEventService; |
74 | -import org.thingsboard.common.util.JacksonUtil; | ||
75 | import org.thingsboard.server.edge.imitator.EdgeImitator; | 88 | import org.thingsboard.server.edge.imitator.EdgeImitator; |
76 | import org.thingsboard.server.gen.edge.AlarmUpdateMsg; | 89 | import org.thingsboard.server.gen.edge.AlarmUpdateMsg; |
77 | import org.thingsboard.server.gen.edge.AssetUpdateMsg; | 90 | import org.thingsboard.server.gen.edge.AssetUpdateMsg; |
@@ -81,6 +94,7 @@ import org.thingsboard.server.gen.edge.CustomerUpdateMsg; | @@ -81,6 +94,7 @@ import org.thingsboard.server.gen.edge.CustomerUpdateMsg; | ||
81 | import org.thingsboard.server.gen.edge.DashboardUpdateMsg; | 94 | import org.thingsboard.server.gen.edge.DashboardUpdateMsg; |
82 | import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; | 95 | import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; |
83 | import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; | 96 | import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; |
97 | +import org.thingsboard.server.gen.edge.DeviceProfileUpdateMsg; | ||
84 | import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; | 98 | import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; |
85 | import org.thingsboard.server.gen.edge.DeviceUpdateMsg; | 99 | import org.thingsboard.server.gen.edge.DeviceUpdateMsg; |
86 | import org.thingsboard.server.gen.edge.EdgeConfiguration; | 100 | import org.thingsboard.server.gen.edge.EdgeConfiguration; |
@@ -106,6 +120,7 @@ import java.util.List; | @@ -106,6 +120,7 @@ import java.util.List; | ||
106 | import java.util.Map; | 120 | import java.util.Map; |
107 | import java.util.Optional; | 121 | import java.util.Optional; |
108 | import java.util.Random; | 122 | import java.util.Random; |
123 | +import java.util.TreeMap; | ||
109 | import java.util.UUID; | 124 | import java.util.UUID; |
110 | import java.util.concurrent.TimeUnit; | 125 | import java.util.concurrent.TimeUnit; |
111 | 126 | ||
@@ -114,6 +129,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | @@ -114,6 +129,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | ||
114 | @Slf4j | 129 | @Slf4j |
115 | abstract public class BaseEdgeTest extends AbstractControllerTest { | 130 | abstract public class BaseEdgeTest extends AbstractControllerTest { |
116 | 131 | ||
132 | + private static final String CUSTOM_DEVICE_PROFILE_NAME = "Thermostat"; | ||
133 | + | ||
117 | private Tenant savedTenant; | 134 | private Tenant savedTenant; |
118 | private TenantId tenantId; | 135 | private TenantId tenantId; |
119 | private User tenantAdmin; | 136 | private User tenantAdmin; |
@@ -145,17 +162,25 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -145,17 +162,25 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
145 | tenantAdmin.setLastName("Downs"); | 162 | tenantAdmin.setLastName("Downs"); |
146 | 163 | ||
147 | tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); | 164 | tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); |
165 | + // sleep 1 seconds to avoid CREDENTIALS updated message for the user | ||
166 | + // user credentials is going to be stored and updated event pushed to edge notification service | ||
167 | + // while service will be processing this event edge could be already added and additional message will be pushed | ||
168 | + Thread.sleep(1000); | ||
169 | + | ||
148 | installation(); | 170 | installation(); |
149 | 171 | ||
150 | edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret()); | 172 | edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret()); |
151 | - // should be less, but events from SyncEdgeService stack with events from controller. will be fixed in next releases | ||
152 | - edgeImitator.expectMessageAmount(7); | 173 | + // TODO: voba - should be less, but events from SyncEdgeService stack with events from controller. will be fixed in next releases |
174 | + // so ideally sync process should check current edge queue and add only missing entities to the edge queue | ||
175 | + edgeImitator.expectMessageAmount(10); | ||
153 | edgeImitator.connect(); | 176 | edgeImitator.connect(); |
154 | } | 177 | } |
155 | 178 | ||
156 | @After | 179 | @After |
157 | public void afterTest() throws Exception { | 180 | public void afterTest() throws Exception { |
158 | - edgeImitator.disconnect(); | 181 | + try { |
182 | + edgeImitator.disconnect(); | ||
183 | + } catch (Exception ignored) {} | ||
159 | 184 | ||
160 | loginSysAdmin(); | 185 | loginSysAdmin(); |
161 | 186 | ||
@@ -163,23 +188,63 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -163,23 +188,63 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
163 | .andExpect(status().isOk()); | 188 | .andExpect(status().isOk()); |
164 | } | 189 | } |
165 | 190 | ||
166 | - | ||
167 | @Test | 191 | @Test |
168 | public void test() throws Exception { | 192 | public void test() throws Exception { |
169 | testReceivedInitialData(); | 193 | testReceivedInitialData(); |
194 | + int expectedDownlinkSize = 10; | ||
195 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
196 | + | ||
170 | testDevices(); | 197 | testDevices(); |
198 | + expectedDownlinkSize = expectedDownlinkSize + 4; | ||
199 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
200 | + | ||
171 | testAssets(); | 201 | testAssets(); |
202 | + expectedDownlinkSize = expectedDownlinkSize + 4; | ||
203 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
204 | + | ||
172 | testRuleChains(); | 205 | testRuleChains(); |
206 | + expectedDownlinkSize = expectedDownlinkSize + 3; | ||
207 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
208 | + | ||
173 | testDashboards(); | 209 | testDashboards(); |
210 | + expectedDownlinkSize = expectedDownlinkSize + 3; | ||
211 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
212 | + | ||
174 | testRelations(); | 213 | testRelations(); |
214 | + expectedDownlinkSize = expectedDownlinkSize + 2; | ||
215 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
216 | + | ||
175 | testAlarms(); | 217 | testAlarms(); |
218 | + expectedDownlinkSize = expectedDownlinkSize + 3; | ||
219 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
220 | + | ||
176 | testEntityView(); | 221 | testEntityView(); |
222 | + expectedDownlinkSize = expectedDownlinkSize + 2; | ||
223 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
224 | + | ||
177 | testCustomer(); | 225 | testCustomer(); |
226 | + expectedDownlinkSize = expectedDownlinkSize + 2; | ||
227 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
228 | + | ||
178 | testWidgetsBundleAndWidgetType(); | 229 | testWidgetsBundleAndWidgetType(); |
230 | + expectedDownlinkSize = expectedDownlinkSize + 4; | ||
231 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
232 | + | ||
179 | testTimeseries(); | 233 | testTimeseries(); |
234 | + expectedDownlinkSize = expectedDownlinkSize + 1; | ||
235 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
236 | + | ||
180 | testAttributes(); | 237 | testAttributes(); |
238 | + expectedDownlinkSize = expectedDownlinkSize + 3; | ||
239 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
240 | + | ||
181 | testSendMessagesToCloud(); | 241 | testSendMessagesToCloud(); |
242 | + expectedDownlinkSize = expectedDownlinkSize + 9; | ||
243 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
244 | + | ||
182 | testRpcCall(); | 245 | testRpcCall(); |
246 | + expectedDownlinkSize = expectedDownlinkSize + 1; | ||
247 | + Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); | ||
183 | } | 248 | } |
184 | 249 | ||
185 | private Device findDeviceByName(String deviceName) throws Exception { | 250 | private Device findDeviceByName(String deviceName) throws Exception { |
@@ -204,10 +269,10 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -204,10 +269,10 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
204 | return asset; | 269 | return asset; |
205 | } | 270 | } |
206 | 271 | ||
207 | - private Device saveDevice(String deviceName) throws Exception { | 272 | + private Device saveDevice(String deviceName, String type) throws Exception { |
208 | Device device = new Device(); | 273 | Device device = new Device(); |
209 | device.setName(deviceName); | 274 | device.setName(deviceName); |
210 | - device.setType("test"); | 275 | + device.setType(type); |
211 | return doPost("/api/device", device, Device.class); | 276 | return doPost("/api/device", device, Device.class); |
212 | } | 277 | } |
213 | 278 | ||
@@ -233,7 +298,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -233,7 +298,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
233 | edgeImitator.expectMessageAmount(1); | 298 | edgeImitator.expectMessageAmount(1); |
234 | edgeEventService.saveAsync(edgeEvent); | 299 | edgeEventService.saveAsync(edgeEvent); |
235 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); | 300 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); |
236 | - edgeImitator.waitForMessages(); | 301 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
237 | 302 | ||
238 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 303 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
239 | Assert.assertTrue(latestMessage instanceof DeviceRpcCallMsg); | 304 | Assert.assertTrue(latestMessage instanceof DeviceRpcCallMsg); |
@@ -243,7 +308,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -243,7 +308,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
243 | 308 | ||
244 | private void testReceivedInitialData() throws Exception { | 309 | private void testReceivedInitialData() throws Exception { |
245 | log.info("Checking received data"); | 310 | log.info("Checking received data"); |
246 | - edgeImitator.waitForMessages(); | 311 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
247 | 312 | ||
248 | EdgeConfiguration configuration = edgeImitator.getConfiguration(); | 313 | EdgeConfiguration configuration = edgeImitator.getConfiguration(); |
249 | Assert.assertNotNull(configuration); | 314 | Assert.assertNotNull(configuration); |
@@ -253,9 +318,9 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -253,9 +318,9 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
253 | UserId userId = edgeImitator.getUserId(); | 318 | UserId userId = edgeImitator.getUserId(); |
254 | Assert.assertNotNull(userId); | 319 | Assert.assertNotNull(userId); |
255 | 320 | ||
256 | - Optional<DeviceUpdateMsg> optionalMsg1 = edgeImitator.findMessageByType(DeviceUpdateMsg.class); | ||
257 | - Assert.assertTrue(optionalMsg1.isPresent()); | ||
258 | - DeviceUpdateMsg deviceUpdateMsg = optionalMsg1.get(); | 321 | + Optional<DeviceUpdateMsg> deviceUpdateMsgOpt = edgeImitator.findMessageByType(DeviceUpdateMsg.class); |
322 | + Assert.assertTrue(deviceUpdateMsgOpt.isPresent()); | ||
323 | + DeviceUpdateMsg deviceUpdateMsg = deviceUpdateMsgOpt.get(); | ||
259 | Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); | 324 | Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); |
260 | UUID deviceUUID = new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()); | 325 | UUID deviceUUID = new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()); |
261 | Device device = doGet("/api/device/" + deviceUUID.toString(), Device.class); | 326 | Device device = doGet("/api/device/" + deviceUUID.toString(), Device.class); |
@@ -264,9 +329,25 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -264,9 +329,25 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
264 | new TypeReference<PageData<Device>>() {}, new PageLink(100)).getData(); | 329 | new TypeReference<PageData<Device>>() {}, new PageLink(100)).getData(); |
265 | Assert.assertTrue(edgeDevices.contains(device)); | 330 | Assert.assertTrue(edgeDevices.contains(device)); |
266 | 331 | ||
267 | - Optional<AssetUpdateMsg> optionalMsg2 = edgeImitator.findMessageByType(AssetUpdateMsg.class); | ||
268 | - Assert.assertTrue(optionalMsg2.isPresent()); | ||
269 | - AssetUpdateMsg assetUpdateMsg = optionalMsg2.get(); | 332 | + List<DeviceProfileUpdateMsg> deviceProfileUpdateMsgList = edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class); |
333 | + Assert.assertEquals(3, deviceProfileUpdateMsgList.size()); | ||
334 | + Optional<DeviceProfileUpdateMsg> deviceProfileUpdateMsgOpt = | ||
335 | + deviceProfileUpdateMsgList.stream().filter(dfum -> CUSTOM_DEVICE_PROFILE_NAME.equals(dfum.getName())).findAny(); | ||
336 | + Assert.assertTrue(deviceProfileUpdateMsgOpt.isPresent()); | ||
337 | + DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceProfileUpdateMsgOpt.get(); | ||
338 | + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); | ||
339 | + UUID deviceProfileUUID = new UUID(deviceProfileUpdateMsg.getIdMSB(), deviceProfileUpdateMsg.getIdLSB()); | ||
340 | + DeviceProfile deviceProfile = doGet("/api/deviceProfile/" + deviceProfileUUID.toString(), DeviceProfile.class); | ||
341 | + Assert.assertNotNull(deviceProfile); | ||
342 | + Assert.assertNotNull(deviceProfile.getProfileData()); | ||
343 | + Assert.assertNotNull(deviceProfile.getProfileData().getAlarms()); | ||
344 | + Assert.assertNotNull(deviceProfile.getProfileData().getAlarms().get(0).getClearRule()); | ||
345 | + | ||
346 | + testAutoGeneratedCodeByProtobuf(deviceProfileUpdateMsg); | ||
347 | + | ||
348 | + Optional<AssetUpdateMsg> assetUpdateMsgOpt = edgeImitator.findMessageByType(AssetUpdateMsg.class); | ||
349 | + Assert.assertTrue(assetUpdateMsgOpt.isPresent()); | ||
350 | + AssetUpdateMsg assetUpdateMsg = assetUpdateMsgOpt.get(); | ||
270 | Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); | 351 | Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); |
271 | UUID assetUUID = new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB()); | 352 | UUID assetUUID = new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB()); |
272 | Asset asset = doGet("/api/asset/" + assetUUID.toString(), Asset.class); | 353 | Asset asset = doGet("/api/asset/" + assetUUID.toString(), Asset.class); |
@@ -277,9 +358,9 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -277,9 +358,9 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
277 | 358 | ||
278 | testAutoGeneratedCodeByProtobuf(assetUpdateMsg); | 359 | testAutoGeneratedCodeByProtobuf(assetUpdateMsg); |
279 | 360 | ||
280 | - Optional<RuleChainUpdateMsg> optionalMsg3 = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); | ||
281 | - Assert.assertTrue(optionalMsg3.isPresent()); | ||
282 | - RuleChainUpdateMsg ruleChainUpdateMsg = optionalMsg3.get(); | 361 | + Optional<RuleChainUpdateMsg> ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); |
362 | + Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); | ||
363 | + RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); | ||
283 | Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); | 364 | Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); |
284 | UUID ruleChainUUID = new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()); | 365 | UUID ruleChainUUID = new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()); |
285 | RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID.toString(), RuleChain.class); | 366 | RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID.toString(), RuleChain.class); |
@@ -296,13 +377,12 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -296,13 +377,12 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
296 | private void testDevices() throws Exception { | 377 | private void testDevices() throws Exception { |
297 | log.info("Testing devices"); | 378 | log.info("Testing devices"); |
298 | 379 | ||
299 | - Device savedDevice = saveDevice("Edge Device 2"); | ||
300 | - | 380 | + // 1 |
301 | edgeImitator.expectMessageAmount(1); | 381 | edgeImitator.expectMessageAmount(1); |
382 | + Device savedDevice = saveDevice("Edge Device 2", "Default"); | ||
302 | doPost("/api/edge/" + edge.getId().getId().toString() | 383 | doPost("/api/edge/" + edge.getId().getId().toString() |
303 | + "/device/" + savedDevice.getId().getId().toString(), Device.class); | 384 | + "/device/" + savedDevice.getId().getId().toString(), Device.class); |
304 | - edgeImitator.waitForMessages(); | ||
305 | - | 385 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
306 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 386 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
307 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); | 387 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); |
308 | DeviceUpdateMsg deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; | 388 | DeviceUpdateMsg deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; |
@@ -312,11 +392,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -312,11 +392,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
312 | Assert.assertEquals(deviceUpdateMsg.getName(), savedDevice.getName()); | 392 | Assert.assertEquals(deviceUpdateMsg.getName(), savedDevice.getName()); |
313 | Assert.assertEquals(deviceUpdateMsg.getType(), savedDevice.getType()); | 393 | Assert.assertEquals(deviceUpdateMsg.getType(), savedDevice.getType()); |
314 | 394 | ||
395 | + // 2 | ||
315 | edgeImitator.expectMessageAmount(1); | 396 | edgeImitator.expectMessageAmount(1); |
316 | doDelete("/api/edge/" + edge.getId().getId().toString() | 397 | doDelete("/api/edge/" + edge.getId().getId().toString() |
317 | + "/device/" + savedDevice.getId().getId().toString(), Device.class); | 398 | + "/device/" + savedDevice.getId().getId().toString(), Device.class); |
318 | - edgeImitator.waitForMessages(); | ||
319 | - | 399 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
320 | latestMessage = edgeImitator.getLatestMessage(); | 400 | latestMessage = edgeImitator.getLatestMessage(); |
321 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); | 401 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); |
322 | deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; | 402 | deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; |
@@ -324,11 +404,34 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -324,11 +404,34 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
324 | Assert.assertEquals(deviceUpdateMsg.getIdMSB(), savedDevice.getUuidId().getMostSignificantBits()); | 404 | Assert.assertEquals(deviceUpdateMsg.getIdMSB(), savedDevice.getUuidId().getMostSignificantBits()); |
325 | Assert.assertEquals(deviceUpdateMsg.getIdLSB(), savedDevice.getUuidId().getLeastSignificantBits()); | 405 | Assert.assertEquals(deviceUpdateMsg.getIdLSB(), savedDevice.getUuidId().getLeastSignificantBits()); |
326 | 406 | ||
407 | + // 3 | ||
327 | edgeImitator.expectMessageAmount(1); | 408 | edgeImitator.expectMessageAmount(1); |
328 | doDelete("/api/device/" + savedDevice.getId().getId().toString()) | 409 | doDelete("/api/device/" + savedDevice.getId().getId().toString()) |
329 | .andExpect(status().isOk()); | 410 | .andExpect(status().isOk()); |
330 | - edgeImitator.waitForMessages(); | 411 | + // we should not get any message because device is not assigned to edge any more |
412 | + Assert.assertFalse(edgeImitator.waitForMessages(1)); | ||
331 | 413 | ||
414 | + // 4 | ||
415 | + edgeImitator.expectMessageAmount(1); | ||
416 | + savedDevice = saveDevice("Edge Device 3", "Default"); | ||
417 | + doPost("/api/edge/" + edge.getId().getId().toString() | ||
418 | + + "/device/" + savedDevice.getId().getId().toString(), Device.class); | ||
419 | + Assert.assertTrue(edgeImitator.waitForMessages()); | ||
420 | + latestMessage = edgeImitator.getLatestMessage(); | ||
421 | + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); | ||
422 | + deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; | ||
423 | + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); | ||
424 | + Assert.assertEquals(deviceUpdateMsg.getIdMSB(), savedDevice.getUuidId().getMostSignificantBits()); | ||
425 | + Assert.assertEquals(deviceUpdateMsg.getIdLSB(), savedDevice.getUuidId().getLeastSignificantBits()); | ||
426 | + Assert.assertEquals(deviceUpdateMsg.getName(), savedDevice.getName()); | ||
427 | + Assert.assertEquals(deviceUpdateMsg.getType(), savedDevice.getType()); | ||
428 | + | ||
429 | + // 5 | ||
430 | + edgeImitator.expectMessageAmount(1); | ||
431 | + doDelete("/api/device/" + savedDevice.getId().getId().toString()) | ||
432 | + .andExpect(status().isOk()); | ||
433 | + // in this case we should get messages because device was assigned to edge | ||
434 | + Assert.assertTrue(edgeImitator.waitForMessages()); | ||
332 | latestMessage = edgeImitator.getLatestMessage(); | 435 | latestMessage = edgeImitator.getLatestMessage(); |
333 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); | 436 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); |
334 | deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; | 437 | deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; |
@@ -342,13 +445,13 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -342,13 +445,13 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
342 | 445 | ||
343 | private void testAssets() throws Exception { | 446 | private void testAssets() throws Exception { |
344 | log.info("Testing assets"); | 447 | log.info("Testing assets"); |
345 | - Asset savedAsset = saveAsset("Edge Asset 2"); | ||
346 | 448 | ||
449 | + // 1 | ||
347 | edgeImitator.expectMessageAmount(1); | 450 | edgeImitator.expectMessageAmount(1); |
451 | + Asset savedAsset = saveAsset("Edge Asset 2"); | ||
348 | doPost("/api/edge/" + edge.getId().getId().toString() | 452 | doPost("/api/edge/" + edge.getId().getId().toString() |
349 | + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); | 453 | + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); |
350 | - edgeImitator.waitForMessages(); | ||
351 | - | 454 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
352 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 455 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
353 | Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); | 456 | Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); |
354 | AssetUpdateMsg assetUpdateMsg = (AssetUpdateMsg) latestMessage; | 457 | AssetUpdateMsg assetUpdateMsg = (AssetUpdateMsg) latestMessage; |
@@ -358,11 +461,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -358,11 +461,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
358 | Assert.assertEquals(assetUpdateMsg.getName(), savedAsset.getName()); | 461 | Assert.assertEquals(assetUpdateMsg.getName(), savedAsset.getName()); |
359 | Assert.assertEquals(assetUpdateMsg.getType(), savedAsset.getType()); | 462 | Assert.assertEquals(assetUpdateMsg.getType(), savedAsset.getType()); |
360 | 463 | ||
464 | + // 2 | ||
361 | edgeImitator.expectMessageAmount(1); | 465 | edgeImitator.expectMessageAmount(1); |
362 | doDelete("/api/edge/" + edge.getId().getId().toString() | 466 | doDelete("/api/edge/" + edge.getId().getId().toString() |
363 | + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); | 467 | + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); |
364 | - edgeImitator.waitForMessages(); | ||
365 | - | 468 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
366 | latestMessage = edgeImitator.getLatestMessage(); | 469 | latestMessage = edgeImitator.getLatestMessage(); |
367 | Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); | 470 | Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); |
368 | assetUpdateMsg = (AssetUpdateMsg) latestMessage; | 471 | assetUpdateMsg = (AssetUpdateMsg) latestMessage; |
@@ -370,11 +473,32 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -370,11 +473,32 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
370 | Assert.assertEquals(assetUpdateMsg.getIdMSB(), savedAsset.getUuidId().getMostSignificantBits()); | 473 | Assert.assertEquals(assetUpdateMsg.getIdMSB(), savedAsset.getUuidId().getMostSignificantBits()); |
371 | Assert.assertEquals(assetUpdateMsg.getIdLSB(), savedAsset.getUuidId().getLeastSignificantBits()); | 474 | Assert.assertEquals(assetUpdateMsg.getIdLSB(), savedAsset.getUuidId().getLeastSignificantBits()); |
372 | 475 | ||
476 | + // 3 | ||
373 | edgeImitator.expectMessageAmount(1); | 477 | edgeImitator.expectMessageAmount(1); |
374 | doDelete("/api/asset/" + savedAsset.getId().getId().toString()) | 478 | doDelete("/api/asset/" + savedAsset.getId().getId().toString()) |
375 | .andExpect(status().isOk()); | 479 | .andExpect(status().isOk()); |
376 | - edgeImitator.waitForMessages(); | 480 | + Assert.assertFalse(edgeImitator.waitForMessages(1)); |
377 | 481 | ||
482 | + // 4 | ||
483 | + edgeImitator.expectMessageAmount(1); | ||
484 | + savedAsset = saveAsset("Edge Asset 3"); | ||
485 | + doPost("/api/edge/" + edge.getId().getId().toString() | ||
486 | + + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); | ||
487 | + Assert.assertTrue(edgeImitator.waitForMessages()); | ||
488 | + latestMessage = edgeImitator.getLatestMessage(); | ||
489 | + Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); | ||
490 | + assetUpdateMsg = (AssetUpdateMsg) latestMessage; | ||
491 | + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); | ||
492 | + Assert.assertEquals(assetUpdateMsg.getIdMSB(), savedAsset.getUuidId().getMostSignificantBits()); | ||
493 | + Assert.assertEquals(assetUpdateMsg.getIdLSB(), savedAsset.getUuidId().getLeastSignificantBits()); | ||
494 | + Assert.assertEquals(assetUpdateMsg.getName(), savedAsset.getName()); | ||
495 | + Assert.assertEquals(assetUpdateMsg.getType(), savedAsset.getType()); | ||
496 | + | ||
497 | + // 5 | ||
498 | + edgeImitator.expectMessageAmount(1); | ||
499 | + doDelete("/api/asset/" + savedAsset.getId().getId().toString()) | ||
500 | + .andExpect(status().isOk()); | ||
501 | + Assert.assertTrue(edgeImitator.waitForMessages()); | ||
378 | latestMessage = edgeImitator.getLatestMessage(); | 502 | latestMessage = edgeImitator.getLatestMessage(); |
379 | Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); | 503 | Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); |
380 | assetUpdateMsg = (AssetUpdateMsg) latestMessage; | 504 | assetUpdateMsg = (AssetUpdateMsg) latestMessage; |
@@ -387,21 +511,21 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -387,21 +511,21 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
387 | 511 | ||
388 | private void testRuleChains() throws Exception { | 512 | private void testRuleChains() throws Exception { |
389 | log.info("Testing RuleChains"); | 513 | log.info("Testing RuleChains"); |
514 | + | ||
515 | + // 1 | ||
516 | + edgeImitator.expectMessageAmount(1); | ||
390 | RuleChain ruleChain = new RuleChain(); | 517 | RuleChain ruleChain = new RuleChain(); |
391 | ruleChain.setName("Edge Test Rule Chain"); | 518 | ruleChain.setName("Edge Test Rule Chain"); |
392 | ruleChain.setType(RuleChainType.EDGE); | 519 | ruleChain.setType(RuleChainType.EDGE); |
393 | RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); | 520 | RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); |
394 | - | ||
395 | createRuleChainMetadata(savedRuleChain); | 521 | createRuleChainMetadata(savedRuleChain); |
396 | - | ||
397 | - // Wait before rule chain metadata saved to database before rule chain is assigned to edge | 522 | + // sleep 1 seconds to avoid ENTITY_UPDATED_RPC_MESSAGE for the rule chain |
523 | + // rule chain metadata is going to be stored and updated event pushed to edge notification service | ||
524 | + // while service will be processing this event assignment rule chain to edge will be completed if bad timing | ||
398 | Thread.sleep(1000); | 525 | Thread.sleep(1000); |
399 | - | ||
400 | - edgeImitator.expectMessageAmount(1); | ||
401 | doPost("/api/edge/" + edge.getId().getId().toString() | 526 | doPost("/api/edge/" + edge.getId().getId().toString() |
402 | + "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); | 527 | + "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); |
403 | - edgeImitator.waitForMessages(); | ||
404 | - | 528 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
405 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 529 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
406 | Assert.assertTrue(latestMessage instanceof RuleChainUpdateMsg); | 530 | Assert.assertTrue(latestMessage instanceof RuleChainUpdateMsg); |
407 | RuleChainUpdateMsg ruleChainUpdateMsg = (RuleChainUpdateMsg) latestMessage; | 531 | RuleChainUpdateMsg ruleChainUpdateMsg = (RuleChainUpdateMsg) latestMessage; |
@@ -410,13 +534,14 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -410,13 +534,14 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
410 | Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); | 534 | Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); |
411 | Assert.assertEquals(ruleChainUpdateMsg.getName(), savedRuleChain.getName()); | 535 | Assert.assertEquals(ruleChainUpdateMsg.getName(), savedRuleChain.getName()); |
412 | 536 | ||
537 | + // 2 | ||
413 | testRuleChainMetadataRequestMsg(savedRuleChain.getId()); | 538 | testRuleChainMetadataRequestMsg(savedRuleChain.getId()); |
414 | 539 | ||
540 | + // 3 | ||
415 | edgeImitator.expectMessageAmount(1); | 541 | edgeImitator.expectMessageAmount(1); |
416 | doDelete("/api/edge/" + edge.getId().getId().toString() | 542 | doDelete("/api/edge/" + edge.getId().getId().toString() |
417 | + "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); | 543 | + "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); |
418 | - edgeImitator.waitForMessages(); | ||
419 | - | 544 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
420 | latestMessage = edgeImitator.getLatestMessage(); | 545 | latestMessage = edgeImitator.getLatestMessage(); |
421 | Assert.assertTrue(latestMessage instanceof RuleChainUpdateMsg); | 546 | Assert.assertTrue(latestMessage instanceof RuleChainUpdateMsg); |
422 | ruleChainUpdateMsg = (RuleChainUpdateMsg) latestMessage; | 547 | ruleChainUpdateMsg = (RuleChainUpdateMsg) latestMessage; |
@@ -424,17 +549,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -424,17 +549,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
424 | Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), savedRuleChain.getUuidId().getMostSignificantBits()); | 549 | Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), savedRuleChain.getUuidId().getMostSignificantBits()); |
425 | Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); | 550 | Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); |
426 | 551 | ||
552 | + // 4 | ||
427 | edgeImitator.expectMessageAmount(1); | 553 | edgeImitator.expectMessageAmount(1); |
428 | doDelete("/api/ruleChain/" + savedRuleChain.getId().getId().toString()) | 554 | doDelete("/api/ruleChain/" + savedRuleChain.getId().getId().toString()) |
429 | .andExpect(status().isOk()); | 555 | .andExpect(status().isOk()); |
430 | - edgeImitator.waitForMessages(); | ||
431 | - | ||
432 | - latestMessage = edgeImitator.getLatestMessage(); | ||
433 | - Assert.assertTrue(latestMessage instanceof RuleChainUpdateMsg); | ||
434 | - ruleChainUpdateMsg = (RuleChainUpdateMsg) latestMessage; | ||
435 | - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); | ||
436 | - Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), savedRuleChain.getUuidId().getMostSignificantBits()); | ||
437 | - Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); | 556 | + Assert.assertFalse(edgeImitator.waitForMessages(1)); |
438 | 557 | ||
439 | log.info("RuleChains tested successfully"); | 558 | log.info("RuleChains tested successfully"); |
440 | } | 559 | } |
@@ -452,8 +571,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -452,8 +571,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
452 | edgeImitator.expectResponsesAmount(1); | 571 | edgeImitator.expectResponsesAmount(1); |
453 | edgeImitator.expectMessageAmount(1); | 572 | edgeImitator.expectMessageAmount(1); |
454 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 573 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
455 | - edgeImitator.waitForResponses(); | ||
456 | - edgeImitator.waitForMessages(); | 574 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
575 | + Assert.assertTrue(edgeImitator.waitForMessages()); | ||
457 | 576 | ||
458 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 577 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
459 | Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); | 578 | Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); |
@@ -502,15 +621,15 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -502,15 +621,15 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
502 | 621 | ||
503 | private void testDashboards() throws Exception { | 622 | private void testDashboards() throws Exception { |
504 | log.info("Testing Dashboards"); | 623 | log.info("Testing Dashboards"); |
624 | + | ||
625 | + // 1 | ||
626 | + edgeImitator.expectMessageAmount(1); | ||
505 | Dashboard dashboard = new Dashboard(); | 627 | Dashboard dashboard = new Dashboard(); |
506 | dashboard.setTitle("Edge Test Dashboard"); | 628 | dashboard.setTitle("Edge Test Dashboard"); |
507 | Dashboard savedDashboard = doPost("/api/dashboard", dashboard, Dashboard.class); | 629 | Dashboard savedDashboard = doPost("/api/dashboard", dashboard, Dashboard.class); |
508 | - | ||
509 | - edgeImitator.expectMessageAmount(1); | ||
510 | doPost("/api/edge/" + edge.getId().getId().toString() | 630 | doPost("/api/edge/" + edge.getId().getId().toString() |
511 | + "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); | 631 | + "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); |
512 | - edgeImitator.waitForMessages(); | ||
513 | - | 632 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
514 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 633 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
515 | Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); | 634 | Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); |
516 | DashboardUpdateMsg dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; | 635 | DashboardUpdateMsg dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; |
@@ -518,25 +637,24 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -518,25 +637,24 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
518 | Assert.assertEquals(dashboardUpdateMsg.getIdMSB(), savedDashboard.getUuidId().getMostSignificantBits()); | 637 | Assert.assertEquals(dashboardUpdateMsg.getIdMSB(), savedDashboard.getUuidId().getMostSignificantBits()); |
519 | Assert.assertEquals(dashboardUpdateMsg.getIdLSB(), savedDashboard.getUuidId().getLeastSignificantBits()); | 638 | Assert.assertEquals(dashboardUpdateMsg.getIdLSB(), savedDashboard.getUuidId().getLeastSignificantBits()); |
520 | Assert.assertEquals(dashboardUpdateMsg.getTitle(), savedDashboard.getName()); | 639 | Assert.assertEquals(dashboardUpdateMsg.getTitle(), savedDashboard.getName()); |
521 | - | ||
522 | testAutoGeneratedCodeByProtobuf(dashboardUpdateMsg); | 640 | testAutoGeneratedCodeByProtobuf(dashboardUpdateMsg); |
523 | 641 | ||
642 | + // 2 | ||
524 | edgeImitator.expectMessageAmount(1); | 643 | edgeImitator.expectMessageAmount(1); |
525 | savedDashboard.setTitle("Updated Edge Test Dashboard"); | 644 | savedDashboard.setTitle("Updated Edge Test Dashboard"); |
526 | doPost("/api/dashboard", savedDashboard, Dashboard.class); | 645 | doPost("/api/dashboard", savedDashboard, Dashboard.class); |
527 | - edgeImitator.waitForMessages(); | ||
528 | - | 646 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
529 | latestMessage = edgeImitator.getLatestMessage(); | 647 | latestMessage = edgeImitator.getLatestMessage(); |
530 | Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); | 648 | Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); |
531 | dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; | 649 | dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; |
532 | Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); | 650 | Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); |
533 | Assert.assertEquals(dashboardUpdateMsg.getTitle(), savedDashboard.getName()); | 651 | Assert.assertEquals(dashboardUpdateMsg.getTitle(), savedDashboard.getName()); |
534 | 652 | ||
653 | + // 3 | ||
535 | edgeImitator.expectMessageAmount(1); | 654 | edgeImitator.expectMessageAmount(1); |
536 | doDelete("/api/edge/" + edge.getId().getId().toString() | 655 | doDelete("/api/edge/" + edge.getId().getId().toString() |
537 | + "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); | 656 | + "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); |
538 | - edgeImitator.waitForMessages(); | ||
539 | - | 657 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
540 | latestMessage = edgeImitator.getLatestMessage(); | 658 | latestMessage = edgeImitator.getLatestMessage(); |
541 | Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); | 659 | Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); |
542 | dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; | 660 | dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; |
@@ -544,17 +662,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -544,17 +662,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
544 | Assert.assertEquals(dashboardUpdateMsg.getIdMSB(), savedDashboard.getUuidId().getMostSignificantBits()); | 662 | Assert.assertEquals(dashboardUpdateMsg.getIdMSB(), savedDashboard.getUuidId().getMostSignificantBits()); |
545 | Assert.assertEquals(dashboardUpdateMsg.getIdLSB(), savedDashboard.getUuidId().getLeastSignificantBits()); | 663 | Assert.assertEquals(dashboardUpdateMsg.getIdLSB(), savedDashboard.getUuidId().getLeastSignificantBits()); |
546 | 664 | ||
665 | + // 4 | ||
547 | edgeImitator.expectMessageAmount(1); | 666 | edgeImitator.expectMessageAmount(1); |
548 | doDelete("/api/dashboard/" + savedDashboard.getId().getId().toString()) | 667 | doDelete("/api/dashboard/" + savedDashboard.getId().getId().toString()) |
549 | .andExpect(status().isOk()); | 668 | .andExpect(status().isOk()); |
550 | - edgeImitator.waitForMessages(); | ||
551 | - | ||
552 | - latestMessage = edgeImitator.getLatestMessage(); | ||
553 | - Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); | ||
554 | - dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; | ||
555 | - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); | ||
556 | - Assert.assertEquals(dashboardUpdateMsg.getIdMSB(), savedDashboard.getUuidId().getMostSignificantBits()); | ||
557 | - Assert.assertEquals(dashboardUpdateMsg.getIdLSB(), savedDashboard.getUuidId().getLeastSignificantBits()); | 669 | + Assert.assertFalse(edgeImitator.waitForMessages(1)); |
558 | 670 | ||
559 | log.info("Dashboards tested successfully"); | 671 | log.info("Dashboards tested successfully"); |
560 | } | 672 | } |
@@ -562,19 +674,17 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -562,19 +674,17 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
562 | private void testRelations() throws Exception { | 674 | private void testRelations() throws Exception { |
563 | log.info("Testing Relations"); | 675 | log.info("Testing Relations"); |
564 | 676 | ||
677 | + // 1 | ||
678 | + edgeImitator.expectMessageAmount(1); | ||
565 | Device device = findDeviceByName("Edge Device 1"); | 679 | Device device = findDeviceByName("Edge Device 1"); |
566 | Asset asset = findAssetByName("Edge Asset 1"); | 680 | Asset asset = findAssetByName("Edge Asset 1"); |
567 | - | ||
568 | EntityRelation relation = new EntityRelation(); | 681 | EntityRelation relation = new EntityRelation(); |
569 | relation.setType("test"); | 682 | relation.setType("test"); |
570 | relation.setFrom(device.getId()); | 683 | relation.setFrom(device.getId()); |
571 | relation.setTo(asset.getId()); | 684 | relation.setTo(asset.getId()); |
572 | relation.setTypeGroup(RelationTypeGroup.COMMON); | 685 | relation.setTypeGroup(RelationTypeGroup.COMMON); |
573 | - | ||
574 | - edgeImitator.expectMessageAmount(1); | ||
575 | doPost("/api/relation", relation); | 686 | doPost("/api/relation", relation); |
576 | - edgeImitator.waitForMessages(); | ||
577 | - | 687 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
578 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 688 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
579 | Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); | 689 | Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); |
580 | RelationUpdateMsg relationUpdateMsg = (RelationUpdateMsg) latestMessage; | 690 | RelationUpdateMsg relationUpdateMsg = (RelationUpdateMsg) latestMessage; |
@@ -588,6 +698,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -588,6 +698,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
588 | Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); | 698 | Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); |
589 | Assert.assertEquals(relationUpdateMsg.getTypeGroup(), relation.getTypeGroup().name()); | 699 | Assert.assertEquals(relationUpdateMsg.getTypeGroup(), relation.getTypeGroup().name()); |
590 | 700 | ||
701 | + // 2 | ||
591 | edgeImitator.expectMessageAmount(1); | 702 | edgeImitator.expectMessageAmount(1); |
592 | doDelete("/api/relation?" + | 703 | doDelete("/api/relation?" + |
593 | "fromId=" + relation.getFrom().getId().toString() + | 704 | "fromId=" + relation.getFrom().getId().toString() + |
@@ -597,8 +708,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -597,8 +708,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
597 | "&toId=" + relation.getTo().getId().toString() + | 708 | "&toId=" + relation.getTo().getId().toString() + |
598 | "&toType=" + relation.getTo().getEntityType().name()) | 709 | "&toType=" + relation.getTo().getEntityType().name()) |
599 | .andExpect(status().isOk()); | 710 | .andExpect(status().isOk()); |
600 | - edgeImitator.waitForMessages(); | ||
601 | - | 711 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
602 | latestMessage = edgeImitator.getLatestMessage(); | 712 | latestMessage = edgeImitator.getLatestMessage(); |
603 | Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); | 713 | Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); |
604 | relationUpdateMsg = (RelationUpdateMsg) latestMessage; | 714 | relationUpdateMsg = (RelationUpdateMsg) latestMessage; |
@@ -617,18 +727,17 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -617,18 +727,17 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
617 | 727 | ||
618 | private void testAlarms() throws Exception { | 728 | private void testAlarms() throws Exception { |
619 | log.info("Testing Alarms"); | 729 | log.info("Testing Alarms"); |
620 | - Device device = findDeviceByName("Edge Device 1"); | ||
621 | 730 | ||
731 | + // 1 | ||
732 | + edgeImitator.expectMessageAmount(1); | ||
733 | + Device device = findDeviceByName("Edge Device 1"); | ||
622 | Alarm alarm = new Alarm(); | 734 | Alarm alarm = new Alarm(); |
623 | alarm.setOriginator(device.getId()); | 735 | alarm.setOriginator(device.getId()); |
624 | alarm.setStatus(AlarmStatus.ACTIVE_UNACK); | 736 | alarm.setStatus(AlarmStatus.ACTIVE_UNACK); |
625 | alarm.setType("alarm"); | 737 | alarm.setType("alarm"); |
626 | alarm.setSeverity(AlarmSeverity.CRITICAL); | 738 | alarm.setSeverity(AlarmSeverity.CRITICAL); |
627 | - | ||
628 | - edgeImitator.expectMessageAmount(1); | ||
629 | Alarm savedAlarm = doPost("/api/alarm", alarm, Alarm.class); | 739 | Alarm savedAlarm = doPost("/api/alarm", alarm, Alarm.class); |
630 | - edgeImitator.waitForMessages(); | ||
631 | - | 740 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
632 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 741 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
633 | Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); | 742 | Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); |
634 | AlarmUpdateMsg alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; | 743 | AlarmUpdateMsg alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; |
@@ -639,10 +748,10 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -639,10 +748,10 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
639 | Assert.assertEquals(alarmUpdateMsg.getStatus(), savedAlarm.getStatus().name()); | 748 | Assert.assertEquals(alarmUpdateMsg.getStatus(), savedAlarm.getStatus().name()); |
640 | Assert.assertEquals(alarmUpdateMsg.getSeverity(), savedAlarm.getSeverity().name()); | 749 | Assert.assertEquals(alarmUpdateMsg.getSeverity(), savedAlarm.getSeverity().name()); |
641 | 750 | ||
751 | + // 2 | ||
642 | edgeImitator.expectMessageAmount(1); | 752 | edgeImitator.expectMessageAmount(1); |
643 | doPost("/api/alarm/" + savedAlarm.getId().getId().toString() + "/ack"); | 753 | doPost("/api/alarm/" + savedAlarm.getId().getId().toString() + "/ack"); |
644 | - edgeImitator.waitForMessages(); | ||
645 | - | 754 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
646 | latestMessage = edgeImitator.getLatestMessage(); | 755 | latestMessage = edgeImitator.getLatestMessage(); |
647 | Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); | 756 | Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); |
648 | alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; | 757 | alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; |
@@ -652,10 +761,10 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -652,10 +761,10 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
652 | Assert.assertEquals(alarmUpdateMsg.getOriginatorName(), device.getName()); | 761 | Assert.assertEquals(alarmUpdateMsg.getOriginatorName(), device.getName()); |
653 | Assert.assertEquals(alarmUpdateMsg.getStatus(), AlarmStatus.ACTIVE_ACK.name()); | 762 | Assert.assertEquals(alarmUpdateMsg.getStatus(), AlarmStatus.ACTIVE_ACK.name()); |
654 | 763 | ||
764 | + // 3 | ||
655 | edgeImitator.expectMessageAmount(1); | 765 | edgeImitator.expectMessageAmount(1); |
656 | doPost("/api/alarm/" + savedAlarm.getId().getId().toString() + "/clear"); | 766 | doPost("/api/alarm/" + savedAlarm.getId().getId().toString() + "/clear"); |
657 | - edgeImitator.waitForMessages(); | ||
658 | - | 767 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
659 | latestMessage = edgeImitator.getLatestMessage(); | 768 | latestMessage = edgeImitator.getLatestMessage(); |
660 | Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); | 769 | Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); |
661 | alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; | 770 | alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; |
@@ -665,26 +774,29 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -665,26 +774,29 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
665 | Assert.assertEquals(alarmUpdateMsg.getOriginatorName(), device.getName()); | 774 | Assert.assertEquals(alarmUpdateMsg.getOriginatorName(), device.getName()); |
666 | Assert.assertEquals(alarmUpdateMsg.getStatus(), AlarmStatus.CLEARED_ACK.name()); | 775 | Assert.assertEquals(alarmUpdateMsg.getStatus(), AlarmStatus.CLEARED_ACK.name()); |
667 | 776 | ||
777 | + // 4 | ||
778 | + edgeImitator.expectMessageAmount(1); | ||
668 | doDelete("/api/alarm/" + savedAlarm.getId().getId().toString()) | 779 | doDelete("/api/alarm/" + savedAlarm.getId().getId().toString()) |
669 | .andExpect(status().isOk()); | 780 | .andExpect(status().isOk()); |
781 | + Assert.assertFalse(edgeImitator.waitForMessages(1)); | ||
782 | + | ||
670 | log.info("Alarms tested successfully"); | 783 | log.info("Alarms tested successfully"); |
671 | } | 784 | } |
672 | 785 | ||
673 | private void testEntityView() throws Exception { | 786 | private void testEntityView() throws Exception { |
674 | log.info("Testing EntityView"); | 787 | log.info("Testing EntityView"); |
675 | - Device device = findDeviceByName("Edge Device 1"); | ||
676 | 788 | ||
789 | + // 1 | ||
790 | + edgeImitator.expectMessageAmount(1); | ||
791 | + Device device = findDeviceByName("Edge Device 1"); | ||
677 | EntityView entityView = new EntityView(); | 792 | EntityView entityView = new EntityView(); |
678 | entityView.setName("Edge EntityView 1"); | 793 | entityView.setName("Edge EntityView 1"); |
679 | entityView.setType("test"); | 794 | entityView.setType("test"); |
680 | entityView.setEntityId(device.getId()); | 795 | entityView.setEntityId(device.getId()); |
681 | EntityView savedEntityView = doPost("/api/entityView", entityView, EntityView.class); | 796 | EntityView savedEntityView = doPost("/api/entityView", entityView, EntityView.class); |
682 | - | ||
683 | - edgeImitator.expectMessageAmount(1); | ||
684 | doPost("/api/edge/" + edge.getId().getId().toString() | 797 | doPost("/api/edge/" + edge.getId().getId().toString() |
685 | + "/entityView/" + savedEntityView.getId().getId().toString(), EntityView.class); | 798 | + "/entityView/" + savedEntityView.getId().getId().toString(), EntityView.class); |
686 | - edgeImitator.waitForMessages(); | ||
687 | - | 799 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
688 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 800 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
689 | Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); | 801 | Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); |
690 | EntityViewUpdateMsg entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; | 802 | EntityViewUpdateMsg entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; |
@@ -697,11 +809,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -697,11 +809,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
697 | Assert.assertEquals(entityViewUpdateMsg.getEntityIdLSB(), device.getUuidId().getLeastSignificantBits()); | 809 | Assert.assertEquals(entityViewUpdateMsg.getEntityIdLSB(), device.getUuidId().getLeastSignificantBits()); |
698 | Assert.assertEquals(entityViewUpdateMsg.getEntityType().name(), device.getId().getEntityType().name()); | 810 | Assert.assertEquals(entityViewUpdateMsg.getEntityType().name(), device.getId().getEntityType().name()); |
699 | 811 | ||
812 | + // 2 | ||
700 | edgeImitator.expectMessageAmount(1); | 813 | edgeImitator.expectMessageAmount(1); |
701 | doDelete("/api/edge/" + edge.getId().getId().toString() | 814 | doDelete("/api/edge/" + edge.getId().getId().toString() |
702 | + "/entityView/" + savedEntityView.getId().getId().toString(), EntityView.class); | 815 | + "/entityView/" + savedEntityView.getId().getId().toString(), EntityView.class); |
703 | - edgeImitator.waitForMessages(); | ||
704 | - | 816 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
705 | latestMessage = edgeImitator.getLatestMessage(); | 817 | latestMessage = edgeImitator.getLatestMessage(); |
706 | Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); | 818 | Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); |
707 | entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; | 819 | entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; |
@@ -709,17 +821,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -709,17 +821,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
709 | Assert.assertEquals(entityViewUpdateMsg.getIdMSB(), savedEntityView.getUuidId().getMostSignificantBits()); | 821 | Assert.assertEquals(entityViewUpdateMsg.getIdMSB(), savedEntityView.getUuidId().getMostSignificantBits()); |
710 | Assert.assertEquals(entityViewUpdateMsg.getIdLSB(), savedEntityView.getUuidId().getLeastSignificantBits()); | 822 | Assert.assertEquals(entityViewUpdateMsg.getIdLSB(), savedEntityView.getUuidId().getLeastSignificantBits()); |
711 | 823 | ||
824 | + // 3 | ||
712 | edgeImitator.expectMessageAmount(1); | 825 | edgeImitator.expectMessageAmount(1); |
713 | doDelete("/api/entityView/" + savedEntityView.getId().getId().toString()) | 826 | doDelete("/api/entityView/" + savedEntityView.getId().getId().toString()) |
714 | .andExpect(status().isOk()); | 827 | .andExpect(status().isOk()); |
715 | - edgeImitator.waitForMessages(); | ||
716 | - | ||
717 | - latestMessage = edgeImitator.getLatestMessage(); | ||
718 | - Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); | ||
719 | - entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; | ||
720 | - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); | ||
721 | - Assert.assertEquals(entityViewUpdateMsg.getIdMSB(), savedEntityView.getUuidId().getMostSignificantBits()); | ||
722 | - Assert.assertEquals(entityViewUpdateMsg.getIdLSB(), savedEntityView.getUuidId().getLeastSignificantBits()); | 828 | + Assert.assertFalse(edgeImitator.waitForMessages(1)); |
723 | 829 | ||
724 | log.info("EntityView tested successfully"); | 830 | log.info("EntityView tested successfully"); |
725 | } | 831 | } |
@@ -727,15 +833,14 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -727,15 +833,14 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
727 | private void testCustomer() throws Exception { | 833 | private void testCustomer() throws Exception { |
728 | log.info("Testing Customer"); | 834 | log.info("Testing Customer"); |
729 | 835 | ||
836 | + // 1 | ||
837 | + edgeImitator.expectMessageAmount(1); | ||
730 | Customer customer = new Customer(); | 838 | Customer customer = new Customer(); |
731 | customer.setTitle("Edge Customer 1"); | 839 | customer.setTitle("Edge Customer 1"); |
732 | Customer savedCustomer = doPost("/api/customer", customer, Customer.class); | 840 | Customer savedCustomer = doPost("/api/customer", customer, Customer.class); |
733 | - | ||
734 | - edgeImitator.expectMessageAmount(1); | ||
735 | doPost("/api/customer/" + savedCustomer.getId().getId().toString() | 841 | doPost("/api/customer/" + savedCustomer.getId().getId().toString() |
736 | + "/edge/" + edge.getId().getId().toString(), Edge.class); | 842 | + "/edge/" + edge.getId().getId().toString(), Edge.class); |
737 | - edgeImitator.waitForMessages(); | ||
738 | - | 843 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
739 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 844 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
740 | Assert.assertTrue(latestMessage instanceof CustomerUpdateMsg); | 845 | Assert.assertTrue(latestMessage instanceof CustomerUpdateMsg); |
741 | CustomerUpdateMsg customerUpdateMsg = (CustomerUpdateMsg) latestMessage; | 846 | CustomerUpdateMsg customerUpdateMsg = (CustomerUpdateMsg) latestMessage; |
@@ -743,13 +848,12 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -743,13 +848,12 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
743 | Assert.assertEquals(customerUpdateMsg.getIdMSB(), savedCustomer.getUuidId().getMostSignificantBits()); | 848 | Assert.assertEquals(customerUpdateMsg.getIdMSB(), savedCustomer.getUuidId().getMostSignificantBits()); |
744 | Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits()); | 849 | Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits()); |
745 | Assert.assertEquals(customerUpdateMsg.getTitle(), savedCustomer.getTitle()); | 850 | Assert.assertEquals(customerUpdateMsg.getTitle(), savedCustomer.getTitle()); |
746 | - | ||
747 | testAutoGeneratedCodeByProtobuf(customerUpdateMsg); | 851 | testAutoGeneratedCodeByProtobuf(customerUpdateMsg); |
748 | 852 | ||
853 | + // 2 | ||
749 | edgeImitator.expectMessageAmount(1); | 854 | edgeImitator.expectMessageAmount(1); |
750 | doDelete("/api/customer/edge/" + edge.getId().getId().toString(), Edge.class); | 855 | doDelete("/api/customer/edge/" + edge.getId().getId().toString(), Edge.class); |
751 | - edgeImitator.waitForMessages(); | ||
752 | - | 856 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
753 | latestMessage = edgeImitator.getLatestMessage(); | 857 | latestMessage = edgeImitator.getLatestMessage(); |
754 | Assert.assertTrue(latestMessage instanceof CustomerUpdateMsg); | 858 | Assert.assertTrue(latestMessage instanceof CustomerUpdateMsg); |
755 | customerUpdateMsg = (CustomerUpdateMsg) latestMessage; | 859 | customerUpdateMsg = (CustomerUpdateMsg) latestMessage; |
@@ -757,17 +861,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -757,17 +861,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
757 | Assert.assertEquals(customerUpdateMsg.getIdMSB(), savedCustomer.getUuidId().getMostSignificantBits()); | 861 | Assert.assertEquals(customerUpdateMsg.getIdMSB(), savedCustomer.getUuidId().getMostSignificantBits()); |
758 | Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits()); | 862 | Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits()); |
759 | 863 | ||
864 | + // 3 | ||
760 | edgeImitator.expectMessageAmount(1); | 865 | edgeImitator.expectMessageAmount(1); |
761 | doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) | 866 | doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) |
762 | .andExpect(status().isOk()); | 867 | .andExpect(status().isOk()); |
763 | - edgeImitator.waitForMessages(); | ||
764 | - | ||
765 | - latestMessage = edgeImitator.getLatestMessage(); | ||
766 | - Assert.assertTrue(latestMessage instanceof CustomerUpdateMsg); | ||
767 | - customerUpdateMsg = (CustomerUpdateMsg) latestMessage; | ||
768 | - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, customerUpdateMsg.getMsgType()); | ||
769 | - Assert.assertEquals(customerUpdateMsg.getIdMSB(), savedCustomer.getUuidId().getMostSignificantBits()); | ||
770 | - Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits()); | 868 | + Assert.assertFalse(edgeImitator.waitForMessages(1)); |
771 | 869 | ||
772 | log.info("Customer tested successfully"); | 870 | log.info("Customer tested successfully"); |
773 | } | 871 | } |
@@ -775,13 +873,12 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -775,13 +873,12 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
775 | private void testWidgetsBundleAndWidgetType() throws Exception { | 873 | private void testWidgetsBundleAndWidgetType() throws Exception { |
776 | log.info("Testing WidgetsBundle and WidgetType"); | 874 | log.info("Testing WidgetsBundle and WidgetType"); |
777 | 875 | ||
876 | + // 1 | ||
877 | + edgeImitator.expectMessageAmount(1); | ||
778 | WidgetsBundle widgetsBundle = new WidgetsBundle(); | 878 | WidgetsBundle widgetsBundle = new WidgetsBundle(); |
779 | widgetsBundle.setTitle("Test Widget Bundle"); | 879 | widgetsBundle.setTitle("Test Widget Bundle"); |
780 | - | ||
781 | - edgeImitator.expectMessageAmount(1); | ||
782 | WidgetsBundle savedWidgetsBundle = doPost("/api/widgetsBundle", widgetsBundle, WidgetsBundle.class); | 880 | WidgetsBundle savedWidgetsBundle = doPost("/api/widgetsBundle", widgetsBundle, WidgetsBundle.class); |
783 | - edgeImitator.waitForMessages(); | ||
784 | - | 881 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
785 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 882 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
786 | Assert.assertTrue(latestMessage instanceof WidgetsBundleUpdateMsg); | 883 | Assert.assertTrue(latestMessage instanceof WidgetsBundleUpdateMsg); |
787 | WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = (WidgetsBundleUpdateMsg) latestMessage; | 884 | WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = (WidgetsBundleUpdateMsg) latestMessage; |
@@ -790,20 +887,18 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -790,20 +887,18 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
790 | Assert.assertEquals(widgetsBundleUpdateMsg.getIdLSB(), savedWidgetsBundle.getUuidId().getLeastSignificantBits()); | 887 | Assert.assertEquals(widgetsBundleUpdateMsg.getIdLSB(), savedWidgetsBundle.getUuidId().getLeastSignificantBits()); |
791 | Assert.assertEquals(widgetsBundleUpdateMsg.getAlias(), savedWidgetsBundle.getAlias()); | 888 | Assert.assertEquals(widgetsBundleUpdateMsg.getAlias(), savedWidgetsBundle.getAlias()); |
792 | Assert.assertEquals(widgetsBundleUpdateMsg.getTitle(), savedWidgetsBundle.getTitle()); | 889 | Assert.assertEquals(widgetsBundleUpdateMsg.getTitle(), savedWidgetsBundle.getTitle()); |
793 | - | ||
794 | testAutoGeneratedCodeByProtobuf(widgetsBundleUpdateMsg); | 890 | testAutoGeneratedCodeByProtobuf(widgetsBundleUpdateMsg); |
795 | 891 | ||
892 | + // 2 | ||
893 | + edgeImitator.expectMessageAmount(1); | ||
796 | WidgetType widgetType = new WidgetType(); | 894 | WidgetType widgetType = new WidgetType(); |
797 | widgetType.setName("Test Widget Type"); | 895 | widgetType.setName("Test Widget Type"); |
798 | widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); | 896 | widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); |
799 | ObjectNode descriptor = mapper.createObjectNode(); | 897 | ObjectNode descriptor = mapper.createObjectNode(); |
800 | descriptor.put("key", "value"); | 898 | descriptor.put("key", "value"); |
801 | widgetType.setDescriptor(descriptor); | 899 | widgetType.setDescriptor(descriptor); |
802 | - | ||
803 | - edgeImitator.expectMessageAmount(1); | ||
804 | WidgetType savedWidgetType = doPost("/api/widgetType", widgetType, WidgetType.class); | 900 | WidgetType savedWidgetType = doPost("/api/widgetType", widgetType, WidgetType.class); |
805 | - edgeImitator.waitForMessages(); | ||
806 | - | 901 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
807 | latestMessage = edgeImitator.getLatestMessage(); | 902 | latestMessage = edgeImitator.getLatestMessage(); |
808 | Assert.assertTrue(latestMessage instanceof WidgetTypeUpdateMsg); | 903 | Assert.assertTrue(latestMessage instanceof WidgetTypeUpdateMsg); |
809 | WidgetTypeUpdateMsg widgetTypeUpdateMsg = (WidgetTypeUpdateMsg) latestMessage; | 904 | WidgetTypeUpdateMsg widgetTypeUpdateMsg = (WidgetTypeUpdateMsg) latestMessage; |
@@ -814,11 +909,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -814,11 +909,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
814 | Assert.assertEquals(widgetTypeUpdateMsg.getName(), savedWidgetType.getName()); | 909 | Assert.assertEquals(widgetTypeUpdateMsg.getName(), savedWidgetType.getName()); |
815 | Assert.assertEquals(JacksonUtil.toJsonNode(widgetTypeUpdateMsg.getDescriptorJson()), savedWidgetType.getDescriptor()); | 910 | Assert.assertEquals(JacksonUtil.toJsonNode(widgetTypeUpdateMsg.getDescriptorJson()), savedWidgetType.getDescriptor()); |
816 | 911 | ||
912 | + // 3 | ||
817 | edgeImitator.expectMessageAmount(1); | 913 | edgeImitator.expectMessageAmount(1); |
818 | doDelete("/api/widgetType/" + savedWidgetType.getId().getId().toString()) | 914 | doDelete("/api/widgetType/" + savedWidgetType.getId().getId().toString()) |
819 | .andExpect(status().isOk()); | 915 | .andExpect(status().isOk()); |
820 | - edgeImitator.waitForMessages(); | ||
821 | - | 916 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
822 | latestMessage = edgeImitator.getLatestMessage(); | 917 | latestMessage = edgeImitator.getLatestMessage(); |
823 | Assert.assertTrue(latestMessage instanceof WidgetTypeUpdateMsg); | 918 | Assert.assertTrue(latestMessage instanceof WidgetTypeUpdateMsg); |
824 | widgetTypeUpdateMsg = (WidgetTypeUpdateMsg) latestMessage; | 919 | widgetTypeUpdateMsg = (WidgetTypeUpdateMsg) latestMessage; |
@@ -826,11 +921,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -826,11 +921,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
826 | Assert.assertEquals(widgetTypeUpdateMsg.getIdMSB(), savedWidgetType.getUuidId().getMostSignificantBits()); | 921 | Assert.assertEquals(widgetTypeUpdateMsg.getIdMSB(), savedWidgetType.getUuidId().getMostSignificantBits()); |
827 | Assert.assertEquals(widgetTypeUpdateMsg.getIdLSB(), savedWidgetType.getUuidId().getLeastSignificantBits()); | 922 | Assert.assertEquals(widgetTypeUpdateMsg.getIdLSB(), savedWidgetType.getUuidId().getLeastSignificantBits()); |
828 | 923 | ||
924 | + // 4 | ||
829 | edgeImitator.expectMessageAmount(1); | 925 | edgeImitator.expectMessageAmount(1); |
830 | doDelete("/api/widgetsBundle/" + savedWidgetsBundle.getId().getId().toString()) | 926 | doDelete("/api/widgetsBundle/" + savedWidgetsBundle.getId().getId().toString()) |
831 | .andExpect(status().isOk()); | 927 | .andExpect(status().isOk()); |
832 | - edgeImitator.waitForMessages(); | ||
833 | - | 928 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
834 | latestMessage = edgeImitator.getLatestMessage(); | 929 | latestMessage = edgeImitator.getLatestMessage(); |
835 | Assert.assertTrue(latestMessage instanceof WidgetsBundleUpdateMsg); | 930 | Assert.assertTrue(latestMessage instanceof WidgetsBundleUpdateMsg); |
836 | widgetsBundleUpdateMsg = (WidgetsBundleUpdateMsg) latestMessage; | 931 | widgetsBundleUpdateMsg = (WidgetsBundleUpdateMsg) latestMessage; |
@@ -843,15 +938,15 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -843,15 +938,15 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
843 | 938 | ||
844 | private void testTimeseries() throws Exception { | 939 | private void testTimeseries() throws Exception { |
845 | log.info("Testing timeseries"); | 940 | log.info("Testing timeseries"); |
846 | - Device device = findDeviceByName("Edge Device 1"); | ||
847 | 941 | ||
942 | + edgeImitator.expectMessageAmount(1); | ||
943 | + Device device = findDeviceByName("Edge Device 1"); | ||
848 | String timeseriesData = "{\"data\":{\"temperature\":25},\"ts\":" + System.currentTimeMillis() + "}"; | 944 | String timeseriesData = "{\"data\":{\"temperature\":25},\"ts\":" + System.currentTimeMillis() + "}"; |
849 | JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); | 945 | JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); |
850 | - EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); | ||
851 | - edgeImitator.expectMessageAmount(1); | ||
852 | - edgeEventService.saveAsync(edgeEvent1); | 946 | + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); |
947 | + edgeEventService.saveAsync(edgeEvent); | ||
853 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); | 948 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); |
854 | - edgeImitator.waitForMessages(); | 949 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
855 | 950 | ||
856 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 951 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
857 | Assert.assertTrue(latestMessage instanceof EntityDataProto); | 952 | Assert.assertTrue(latestMessage instanceof EntityDataProto); |
@@ -890,7 +985,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -890,7 +985,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
890 | edgeImitator.expectMessageAmount(1); | 985 | edgeImitator.expectMessageAmount(1); |
891 | edgeEventService.saveAsync(edgeEvent); | 986 | edgeEventService.saveAsync(edgeEvent); |
892 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); | 987 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); |
893 | - edgeImitator.waitForMessages(); | 988 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
894 | 989 | ||
895 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 990 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
896 | Assert.assertTrue(latestMessage instanceof EntityDataProto); | 991 | Assert.assertTrue(latestMessage instanceof EntityDataProto); |
@@ -916,7 +1011,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -916,7 +1011,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
916 | edgeImitator.expectMessageAmount(1); | 1011 | edgeImitator.expectMessageAmount(1); |
917 | edgeEventService.saveAsync(edgeEvent); | 1012 | edgeEventService.saveAsync(edgeEvent); |
918 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); | 1013 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); |
919 | - edgeImitator.waitForMessages(); | 1014 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
920 | 1015 | ||
921 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 1016 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
922 | Assert.assertTrue(latestMessage instanceof EntityDataProto); | 1017 | Assert.assertTrue(latestMessage instanceof EntityDataProto); |
@@ -941,7 +1036,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -941,7 +1036,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
941 | edgeImitator.expectMessageAmount(1); | 1036 | edgeImitator.expectMessageAmount(1); |
942 | edgeEventService.saveAsync(edgeEvent1); | 1037 | edgeEventService.saveAsync(edgeEvent1); |
943 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); | 1038 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); |
944 | - edgeImitator.waitForMessages(); | 1039 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
945 | 1040 | ||
946 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 1041 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
947 | Assert.assertTrue(latestMessage instanceof EntityDataProto); | 1042 | Assert.assertTrue(latestMessage instanceof EntityDataProto); |
@@ -996,8 +1091,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -996,8 +1091,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
996 | 1091 | ||
997 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1092 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
998 | 1093 | ||
999 | - edgeImitator.waitForResponses(); | ||
1000 | - edgeImitator.waitForMessages(); | 1094 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1095 | + Assert.assertTrue(edgeImitator.waitForMessages()); | ||
1001 | 1096 | ||
1002 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 1097 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
1003 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); | 1098 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); |
@@ -1013,7 +1108,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1013,7 +1108,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1013 | 1108 | ||
1014 | private void sendDeviceWithNameThatAlreadyExistsOnCloud() throws Exception { | 1109 | private void sendDeviceWithNameThatAlreadyExistsOnCloud() throws Exception { |
1015 | String deviceOnCloudName = RandomStringUtils.randomAlphanumeric(15); | 1110 | String deviceOnCloudName = RandomStringUtils.randomAlphanumeric(15); |
1016 | - Device deviceOnCloud = saveDevice(deviceOnCloudName); | 1111 | + Device deviceOnCloud = saveDevice(deviceOnCloudName, "Default"); |
1017 | 1112 | ||
1018 | UUID uuid = Uuids.timeBased(); | 1113 | UUID uuid = Uuids.timeBased(); |
1019 | 1114 | ||
@@ -1033,8 +1128,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1033,8 +1128,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1033 | 1128 | ||
1034 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1129 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1035 | 1130 | ||
1036 | - edgeImitator.waitForResponses(); | ||
1037 | - edgeImitator.waitForMessages(); | 1131 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1132 | + Assert.assertTrue(edgeImitator.waitForMessages()); | ||
1038 | 1133 | ||
1039 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 1134 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
1040 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); | 1135 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); |
@@ -1063,7 +1158,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1063,7 +1158,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1063 | 1158 | ||
1064 | edgeImitator.expectMessageAmount(1); | 1159 | edgeImitator.expectMessageAmount(1); |
1065 | doPost("/api/relation", relation); | 1160 | doPost("/api/relation", relation); |
1066 | - edgeImitator.waitForMessages(); | 1161 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
1067 | 1162 | ||
1068 | UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); | 1163 | UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); |
1069 | RelationRequestMsg.Builder relationRequestMsgBuilder = RelationRequestMsg.newBuilder(); | 1164 | RelationRequestMsg.Builder relationRequestMsgBuilder = RelationRequestMsg.newBuilder(); |
@@ -1078,8 +1173,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1078,8 +1173,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1078 | edgeImitator.expectResponsesAmount(1); | 1173 | edgeImitator.expectResponsesAmount(1); |
1079 | edgeImitator.expectMessageAmount(1); | 1174 | edgeImitator.expectMessageAmount(1); |
1080 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1175 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1081 | - edgeImitator.waitForResponses(); | ||
1082 | - edgeImitator.waitForMessages(); | 1176 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1177 | + Assert.assertTrue(edgeImitator.waitForMessages()); | ||
1083 | 1178 | ||
1084 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 1179 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
1085 | Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); | 1180 | Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); |
@@ -1115,7 +1210,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1115,7 +1210,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1115 | 1210 | ||
1116 | edgeImitator.expectResponsesAmount(1); | 1211 | edgeImitator.expectResponsesAmount(1); |
1117 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1212 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1118 | - edgeImitator.waitForResponses(); | 1213 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1119 | 1214 | ||
1120 | 1215 | ||
1121 | List<AlarmInfo> alarms = doGetTypedWithPageLink("/api/alarm/{entityType}/{entityId}?", | 1216 | List<AlarmInfo> alarms = doGetTypedWithPageLink("/api/alarm/{entityType}/{entityId}?", |
@@ -1158,7 +1253,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1158,7 +1253,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1158 | 1253 | ||
1159 | edgeImitator.expectResponsesAmount(1); | 1254 | edgeImitator.expectResponsesAmount(1); |
1160 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1255 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1161 | - edgeImitator.waitForResponses(); | 1256 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1162 | 1257 | ||
1163 | EntityRelation relation = doGet("/api/relation?" + | 1258 | EntityRelation relation = doGet("/api/relation?" + |
1164 | "&fromId=" + device2.getId().getId().toString() + | 1259 | "&fromId=" + device2.getId().getId().toString() + |
@@ -1212,7 +1307,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1212,7 +1307,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1212 | testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder2); | 1307 | testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder2); |
1213 | 1308 | ||
1214 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder2.build()); | 1309 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder2.build()); |
1215 | - edgeImitator.waitForResponses(); | 1310 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1216 | 1311 | ||
1217 | // Wait before device attributes saved to database before requesting them from controller | 1312 | // Wait before device attributes saved to database before requesting them from controller |
1218 | Thread.sleep(1000); | 1313 | Thread.sleep(1000); |
@@ -1243,8 +1338,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1243,8 +1338,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1243 | edgeImitator.expectResponsesAmount(1); | 1338 | edgeImitator.expectResponsesAmount(1); |
1244 | edgeImitator.expectMessageAmount(1); | 1339 | edgeImitator.expectMessageAmount(1); |
1245 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1340 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1246 | - edgeImitator.waitForResponses(); | ||
1247 | - edgeImitator.waitForMessages(); | 1341 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1342 | + Assert.assertTrue(edgeImitator.waitForMessages());; | ||
1248 | 1343 | ||
1249 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 1344 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
1250 | Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); | 1345 | Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); |
@@ -1270,8 +1365,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1270,8 +1365,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1270 | edgeImitator.expectResponsesAmount(1); | 1365 | edgeImitator.expectResponsesAmount(1); |
1271 | edgeImitator.expectMessageAmount(1); | 1366 | edgeImitator.expectMessageAmount(1); |
1272 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1367 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1273 | - edgeImitator.waitForResponses(); | ||
1274 | - edgeImitator.waitForMessages(); | 1368 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1369 | + Assert.assertTrue(edgeImitator.waitForMessages()); | ||
1275 | 1370 | ||
1276 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 1371 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
1277 | Assert.assertTrue(latestMessage instanceof UserCredentialsUpdateMsg); | 1372 | Assert.assertTrue(latestMessage instanceof UserCredentialsUpdateMsg); |
@@ -1299,8 +1394,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1299,8 +1394,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1299 | edgeImitator.expectResponsesAmount(1); | 1394 | edgeImitator.expectResponsesAmount(1); |
1300 | edgeImitator.expectMessageAmount(1); | 1395 | edgeImitator.expectMessageAmount(1); |
1301 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1396 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1302 | - edgeImitator.waitForResponses(); | ||
1303 | - edgeImitator.waitForMessages(); | 1397 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1398 | + Assert.assertTrue(edgeImitator.waitForMessages()); | ||
1304 | 1399 | ||
1305 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 1400 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
1306 | Assert.assertTrue(latestMessage instanceof DeviceCredentialsUpdateMsg); | 1401 | Assert.assertTrue(latestMessage instanceof DeviceCredentialsUpdateMsg); |
@@ -1327,7 +1422,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1327,7 +1422,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1327 | 1422 | ||
1328 | edgeImitator.expectResponsesAmount(1); | 1423 | edgeImitator.expectResponsesAmount(1); |
1329 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1424 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1330 | - edgeImitator.waitForResponses(); | 1425 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1331 | } | 1426 | } |
1332 | 1427 | ||
1333 | private void sendDeviceRpcResponse() throws Exception { | 1428 | private void sendDeviceRpcResponse() throws Exception { |
@@ -1352,7 +1447,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1352,7 +1447,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1352 | 1447 | ||
1353 | edgeImitator.expectResponsesAmount(1); | 1448 | edgeImitator.expectResponsesAmount(1); |
1354 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1449 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1355 | - edgeImitator.waitForResponses(); | 1450 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1356 | } | 1451 | } |
1357 | 1452 | ||
1358 | private void sendAttributesRequest() throws Exception { | 1453 | private void sendAttributesRequest() throws Exception { |
@@ -1383,8 +1478,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1383,8 +1478,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1383 | edgeImitator.expectResponsesAmount(1); | 1478 | edgeImitator.expectResponsesAmount(1); |
1384 | edgeImitator.expectMessageAmount(1); | 1479 | edgeImitator.expectMessageAmount(1); |
1385 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1480 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1386 | - edgeImitator.waitForResponses(); | ||
1387 | - edgeImitator.waitForMessages(); | 1481 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1482 | + Assert.assertTrue(edgeImitator.waitForMessages()); | ||
1388 | 1483 | ||
1389 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 1484 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
1390 | Assert.assertTrue(latestMessage instanceof EntityDataProto); | 1485 | Assert.assertTrue(latestMessage instanceof EntityDataProto); |
@@ -1416,7 +1511,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1416,7 +1511,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1416 | 1511 | ||
1417 | edgeImitator.expectResponsesAmount(1); | 1512 | edgeImitator.expectResponsesAmount(1); |
1418 | edgeImitator.sendUplinkMsg(upLinkMsgBuilder.build()); | 1513 | edgeImitator.sendUplinkMsg(upLinkMsgBuilder.build()); |
1419 | - edgeImitator.waitForResponses(); | 1514 | + Assert.assertTrue(edgeImitator.waitForResponses()); |
1420 | device = doGet("/api/device/" + device.getId().getId().toString(), Device.class); | 1515 | device = doGet("/api/device/" + device.getId().getId().toString(), Device.class); |
1421 | Assert.assertNotNull(device); | 1516 | Assert.assertNotNull(device); |
1422 | List<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", | 1517 | List<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", |
@@ -1428,7 +1523,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1428,7 +1523,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1428 | private void installation() throws Exception { | 1523 | private void installation() throws Exception { |
1429 | edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); | 1524 | edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); |
1430 | 1525 | ||
1431 | - Device savedDevice = saveDevice("Edge Device 1"); | 1526 | + DeviceProfile deviceProfile = this.createDeviceProfile(CUSTOM_DEVICE_PROFILE_NAME, null); |
1527 | + extendDeviceProfileData(deviceProfile); | ||
1528 | + doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); | ||
1529 | + | ||
1530 | + Device savedDevice = saveDevice("Edge Device 1", CUSTOM_DEVICE_PROFILE_NAME); | ||
1432 | doPost("/api/edge/" + edge.getId().getId().toString() | 1531 | doPost("/api/edge/" + edge.getId().getId().toString() |
1433 | + "/device/" + savedDevice.getId().getId().toString(), Device.class); | 1532 | + "/device/" + savedDevice.getId().getId().toString(), Device.class); |
1434 | 1533 | ||
@@ -1437,6 +1536,35 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1437,6 +1536,35 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1437 | + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); | 1536 | + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); |
1438 | } | 1537 | } |
1439 | 1538 | ||
1539 | + private void extendDeviceProfileData(DeviceProfile deviceProfile) { | ||
1540 | + DeviceProfileData profileData = deviceProfile.getProfileData(); | ||
1541 | + List<DeviceProfileAlarm> alarms = new ArrayList<>(); | ||
1542 | + DeviceProfileAlarm deviceProfileAlarm = new DeviceProfileAlarm(); | ||
1543 | + deviceProfileAlarm.setAlarmType("High Temperature"); | ||
1544 | + AlarmRule alarmRule = new AlarmRule(); | ||
1545 | + alarmRule.setAlarmDetails("Alarm Details"); | ||
1546 | + AlarmCondition alarmCondition = new AlarmCondition(); | ||
1547 | + alarmCondition.setSpec(new SimpleAlarmConditionSpec()); | ||
1548 | + List<AlarmConditionFilter> condition = new ArrayList<>(); | ||
1549 | + AlarmConditionFilter alarmConditionFilter = new AlarmConditionFilter(); | ||
1550 | + alarmConditionFilter.setKey(new AlarmConditionFilterKey(AlarmConditionKeyType.ATTRIBUTE, "temperature")); | ||
1551 | + NumericFilterPredicate predicate = new NumericFilterPredicate(); | ||
1552 | + predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER); | ||
1553 | + predicate.setValue(new FilterPredicateValue<>(55.0)); | ||
1554 | + alarmConditionFilter.setPredicate(predicate); | ||
1555 | + alarmConditionFilter.setValueType(EntityKeyValueType.NUMERIC); | ||
1556 | + condition.add(alarmConditionFilter); | ||
1557 | + alarmCondition.setCondition(condition); | ||
1558 | + alarmRule.setCondition(alarmCondition); | ||
1559 | + deviceProfileAlarm.setClearRule(alarmRule); | ||
1560 | + TreeMap<AlarmSeverity, AlarmRule> createRules = new TreeMap<>(); | ||
1561 | + createRules.put(AlarmSeverity.CRITICAL, alarmRule); | ||
1562 | + deviceProfileAlarm.setCreateRules(createRules); | ||
1563 | + alarms.add(deviceProfileAlarm); | ||
1564 | + profileData.setAlarms(alarms); | ||
1565 | + profileData.setProvisionConfiguration(new AllowCreateNewDevicesDeviceProfileProvisionConfiguration("123")); | ||
1566 | + } | ||
1567 | + | ||
1440 | private EdgeEvent constructEdgeEvent(TenantId tenantId, EdgeId edgeId, EdgeEventActionType edgeEventAction, UUID entityId, EdgeEventType edgeEventType, JsonNode entityBody) { | 1568 | private EdgeEvent constructEdgeEvent(TenantId tenantId, EdgeId edgeId, EdgeEventActionType edgeEventAction, UUID entityId, EdgeEventType edgeEventType, JsonNode entityBody) { |
1441 | EdgeEvent edgeEvent = new EdgeEvent(); | 1569 | EdgeEvent edgeEvent = new EdgeEvent(); |
1442 | edgeEvent.setEdgeId(edgeId); | 1570 | edgeEvent.setEdgeId(edgeId); |
@@ -32,6 +32,7 @@ import org.thingsboard.server.gen.edge.CustomerUpdateMsg; | @@ -32,6 +32,7 @@ import org.thingsboard.server.gen.edge.CustomerUpdateMsg; | ||
32 | import org.thingsboard.server.gen.edge.DashboardUpdateMsg; | 32 | import org.thingsboard.server.gen.edge.DashboardUpdateMsg; |
33 | import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; | 33 | import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; |
34 | import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; | 34 | import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; |
35 | +import org.thingsboard.server.gen.edge.DeviceProfileUpdateMsg; | ||
35 | import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; | 36 | import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; |
36 | import org.thingsboard.server.gen.edge.DeviceUpdateMsg; | 37 | import org.thingsboard.server.gen.edge.DeviceUpdateMsg; |
37 | import org.thingsboard.server.gen.edge.DownlinkMsg; | 38 | import org.thingsboard.server.gen.edge.DownlinkMsg; |
@@ -58,6 +59,7 @@ import java.util.concurrent.CountDownLatch; | @@ -58,6 +59,7 @@ import java.util.concurrent.CountDownLatch; | ||
58 | import java.util.concurrent.TimeUnit; | 59 | import java.util.concurrent.TimeUnit; |
59 | import java.util.concurrent.locks.Lock; | 60 | import java.util.concurrent.locks.Lock; |
60 | import java.util.concurrent.locks.ReentrantLock; | 61 | import java.util.concurrent.locks.ReentrantLock; |
62 | +import java.util.stream.Collectors; | ||
61 | 63 | ||
62 | @Slf4j | 64 | @Slf4j |
63 | public class EdgeImitator { | 65 | public class EdgeImitator { |
@@ -154,88 +156,93 @@ public class EdgeImitator { | @@ -154,88 +156,93 @@ public class EdgeImitator { | ||
154 | 156 | ||
155 | private ListenableFuture<List<Void>> processDownlinkMsg(DownlinkMsg downlinkMsg) { | 157 | private ListenableFuture<List<Void>> processDownlinkMsg(DownlinkMsg downlinkMsg) { |
156 | List<ListenableFuture<Void>> result = new ArrayList<>(); | 158 | List<ListenableFuture<Void>> result = new ArrayList<>(); |
157 | - if (downlinkMsg.getDeviceUpdateMsgList() != null && !downlinkMsg.getDeviceUpdateMsgList().isEmpty()) { | 159 | + if (downlinkMsg.getDeviceUpdateMsgCount() > 0) { |
158 | for (DeviceUpdateMsg deviceUpdateMsg: downlinkMsg.getDeviceUpdateMsgList()) { | 160 | for (DeviceUpdateMsg deviceUpdateMsg: downlinkMsg.getDeviceUpdateMsgList()) { |
159 | result.add(saveDownlinkMsg(deviceUpdateMsg)); | 161 | result.add(saveDownlinkMsg(deviceUpdateMsg)); |
160 | } | 162 | } |
161 | } | 163 | } |
162 | - if (downlinkMsg.getDeviceCredentialsUpdateMsgList() != null && !downlinkMsg.getDeviceCredentialsUpdateMsgList().isEmpty()) { | 164 | + if (downlinkMsg.getDeviceProfileUpdateMsgCount() > 0) { |
165 | + for (DeviceProfileUpdateMsg deviceProfileUpdateMsg : downlinkMsg.getDeviceProfileUpdateMsgList()) { | ||
166 | + result.add(saveDownlinkMsg(deviceProfileUpdateMsg)); | ||
167 | + } | ||
168 | + } | ||
169 | + if (downlinkMsg.getDeviceCredentialsUpdateMsgCount() > 0) { | ||
163 | for (DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg: downlinkMsg.getDeviceCredentialsUpdateMsgList()) { | 170 | for (DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg: downlinkMsg.getDeviceCredentialsUpdateMsgList()) { |
164 | result.add(saveDownlinkMsg(deviceCredentialsUpdateMsg)); | 171 | result.add(saveDownlinkMsg(deviceCredentialsUpdateMsg)); |
165 | } | 172 | } |
166 | } | 173 | } |
167 | - if (downlinkMsg.getAssetUpdateMsgList() != null && !downlinkMsg.getAssetUpdateMsgList().isEmpty()) { | 174 | + if (downlinkMsg.getAssetUpdateMsgCount() > 0) { |
168 | for (AssetUpdateMsg assetUpdateMsg: downlinkMsg.getAssetUpdateMsgList()) { | 175 | for (AssetUpdateMsg assetUpdateMsg: downlinkMsg.getAssetUpdateMsgList()) { |
169 | result.add(saveDownlinkMsg(assetUpdateMsg)); | 176 | result.add(saveDownlinkMsg(assetUpdateMsg)); |
170 | } | 177 | } |
171 | } | 178 | } |
172 | - if (downlinkMsg.getRuleChainUpdateMsgList() != null && !downlinkMsg.getRuleChainUpdateMsgList().isEmpty()) { | 179 | + if (downlinkMsg.getRuleChainUpdateMsgCount() > 0) { |
173 | for (RuleChainUpdateMsg ruleChainUpdateMsg: downlinkMsg.getRuleChainUpdateMsgList()) { | 180 | for (RuleChainUpdateMsg ruleChainUpdateMsg: downlinkMsg.getRuleChainUpdateMsgList()) { |
174 | result.add(saveDownlinkMsg(ruleChainUpdateMsg)); | 181 | result.add(saveDownlinkMsg(ruleChainUpdateMsg)); |
175 | } | 182 | } |
176 | } | 183 | } |
177 | - if (downlinkMsg.getRuleChainMetadataUpdateMsgList() != null && !downlinkMsg.getRuleChainMetadataUpdateMsgList().isEmpty()) { | 184 | + if (downlinkMsg.getRuleChainMetadataUpdateMsgCount() > 0) { |
178 | for (RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg: downlinkMsg.getRuleChainMetadataUpdateMsgList()) { | 185 | for (RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg: downlinkMsg.getRuleChainMetadataUpdateMsgList()) { |
179 | result.add(saveDownlinkMsg(ruleChainMetadataUpdateMsg)); | 186 | result.add(saveDownlinkMsg(ruleChainMetadataUpdateMsg)); |
180 | } | 187 | } |
181 | } | 188 | } |
182 | - if (downlinkMsg.getDashboardUpdateMsgList() != null && !downlinkMsg.getDashboardUpdateMsgList().isEmpty()) { | 189 | + if (downlinkMsg.getDashboardUpdateMsgCount() > 0) { |
183 | for (DashboardUpdateMsg dashboardUpdateMsg: downlinkMsg.getDashboardUpdateMsgList()) { | 190 | for (DashboardUpdateMsg dashboardUpdateMsg: downlinkMsg.getDashboardUpdateMsgList()) { |
184 | result.add(saveDownlinkMsg(dashboardUpdateMsg)); | 191 | result.add(saveDownlinkMsg(dashboardUpdateMsg)); |
185 | } | 192 | } |
186 | } | 193 | } |
187 | - if (downlinkMsg.getRelationUpdateMsgList() != null && !downlinkMsg.getRelationUpdateMsgList().isEmpty()) { | 194 | + if (downlinkMsg.getRelationUpdateMsgCount() > 0) { |
188 | for (RelationUpdateMsg relationUpdateMsg: downlinkMsg.getRelationUpdateMsgList()) { | 195 | for (RelationUpdateMsg relationUpdateMsg: downlinkMsg.getRelationUpdateMsgList()) { |
189 | result.add(saveDownlinkMsg(relationUpdateMsg)); | 196 | result.add(saveDownlinkMsg(relationUpdateMsg)); |
190 | } | 197 | } |
191 | } | 198 | } |
192 | - if (downlinkMsg.getAlarmUpdateMsgList() != null && !downlinkMsg.getAlarmUpdateMsgList().isEmpty()) { | 199 | + if (downlinkMsg.getAlarmUpdateMsgCount() > 0) { |
193 | for (AlarmUpdateMsg alarmUpdateMsg: downlinkMsg.getAlarmUpdateMsgList()) { | 200 | for (AlarmUpdateMsg alarmUpdateMsg: downlinkMsg.getAlarmUpdateMsgList()) { |
194 | result.add(saveDownlinkMsg(alarmUpdateMsg)); | 201 | result.add(saveDownlinkMsg(alarmUpdateMsg)); |
195 | } | 202 | } |
196 | } | 203 | } |
197 | - if (downlinkMsg.getEntityDataList() != null && !downlinkMsg.getEntityDataList().isEmpty()) { | 204 | + if (downlinkMsg.getEntityDataCount() > 0) { |
198 | for (EntityDataProto entityData: downlinkMsg.getEntityDataList()) { | 205 | for (EntityDataProto entityData: downlinkMsg.getEntityDataList()) { |
199 | result.add(saveDownlinkMsg(entityData)); | 206 | result.add(saveDownlinkMsg(entityData)); |
200 | } | 207 | } |
201 | } | 208 | } |
202 | - if (downlinkMsg.getEntityViewUpdateMsgList() != null && !downlinkMsg.getEntityViewUpdateMsgList().isEmpty()) { | 209 | + if (downlinkMsg.getEntityViewUpdateMsgCount() > 0) { |
203 | for (EntityViewUpdateMsg entityViewUpdateMsg: downlinkMsg.getEntityViewUpdateMsgList()) { | 210 | for (EntityViewUpdateMsg entityViewUpdateMsg: downlinkMsg.getEntityViewUpdateMsgList()) { |
204 | result.add(saveDownlinkMsg(entityViewUpdateMsg)); | 211 | result.add(saveDownlinkMsg(entityViewUpdateMsg)); |
205 | } | 212 | } |
206 | } | 213 | } |
207 | - if (downlinkMsg.getCustomerUpdateMsgList() != null && !downlinkMsg.getCustomerUpdateMsgList().isEmpty()) { | 214 | + if (downlinkMsg.getCustomerUpdateMsgCount() > 0) { |
208 | for (CustomerUpdateMsg customerUpdateMsg: downlinkMsg.getCustomerUpdateMsgList()) { | 215 | for (CustomerUpdateMsg customerUpdateMsg: downlinkMsg.getCustomerUpdateMsgList()) { |
209 | result.add(saveDownlinkMsg(customerUpdateMsg)); | 216 | result.add(saveDownlinkMsg(customerUpdateMsg)); |
210 | } | 217 | } |
211 | } | 218 | } |
212 | - if (downlinkMsg.getWidgetsBundleUpdateMsgList() != null && !downlinkMsg.getWidgetsBundleUpdateMsgList().isEmpty()) { | 219 | + if (downlinkMsg.getWidgetsBundleUpdateMsgCount() > 0) { |
213 | for (WidgetsBundleUpdateMsg widgetsBundleUpdateMsg: downlinkMsg.getWidgetsBundleUpdateMsgList()) { | 220 | for (WidgetsBundleUpdateMsg widgetsBundleUpdateMsg: downlinkMsg.getWidgetsBundleUpdateMsgList()) { |
214 | result.add(saveDownlinkMsg(widgetsBundleUpdateMsg)); | 221 | result.add(saveDownlinkMsg(widgetsBundleUpdateMsg)); |
215 | } | 222 | } |
216 | } | 223 | } |
217 | - if (downlinkMsg.getWidgetTypeUpdateMsgList() != null && !downlinkMsg.getWidgetTypeUpdateMsgList().isEmpty()) { | 224 | + if (downlinkMsg.getWidgetTypeUpdateMsgCount() > 0) { |
218 | for (WidgetTypeUpdateMsg widgetTypeUpdateMsg: downlinkMsg.getWidgetTypeUpdateMsgList()) { | 225 | for (WidgetTypeUpdateMsg widgetTypeUpdateMsg: downlinkMsg.getWidgetTypeUpdateMsgList()) { |
219 | result.add(saveDownlinkMsg(widgetTypeUpdateMsg)); | 226 | result.add(saveDownlinkMsg(widgetTypeUpdateMsg)); |
220 | } | 227 | } |
221 | } | 228 | } |
222 | - if (downlinkMsg.getUserUpdateMsgList() != null && !downlinkMsg.getUserUpdateMsgList().isEmpty()) { | 229 | + if (downlinkMsg.getUserUpdateMsgCount() > 0) { |
223 | for (UserUpdateMsg userUpdateMsg: downlinkMsg.getUserUpdateMsgList()) { | 230 | for (UserUpdateMsg userUpdateMsg: downlinkMsg.getUserUpdateMsgList()) { |
224 | onUserUpdate(userUpdateMsg); | 231 | onUserUpdate(userUpdateMsg); |
225 | result.add(saveDownlinkMsg(userUpdateMsg)); | 232 | result.add(saveDownlinkMsg(userUpdateMsg)); |
226 | } | 233 | } |
227 | } | 234 | } |
228 | - if (downlinkMsg.getUserCredentialsUpdateMsgList() != null && !downlinkMsg.getUserCredentialsUpdateMsgList().isEmpty()) { | 235 | + if (downlinkMsg.getUserCredentialsUpdateMsgCount() > 0) { |
229 | for (UserCredentialsUpdateMsg userCredentialsUpdateMsg: downlinkMsg.getUserCredentialsUpdateMsgList()) { | 236 | for (UserCredentialsUpdateMsg userCredentialsUpdateMsg: downlinkMsg.getUserCredentialsUpdateMsgList()) { |
230 | result.add(saveDownlinkMsg(userCredentialsUpdateMsg)); | 237 | result.add(saveDownlinkMsg(userCredentialsUpdateMsg)); |
231 | } | 238 | } |
232 | } | 239 | } |
233 | - if (downlinkMsg.getDeviceRpcCallMsgList() != null && !downlinkMsg.getDeviceRpcCallMsgList().isEmpty()) { | 240 | + if (downlinkMsg.getDeviceRpcCallMsgCount() > 0) { |
234 | for (DeviceRpcCallMsg deviceRpcCallMsg: downlinkMsg.getDeviceRpcCallMsgList()) { | 241 | for (DeviceRpcCallMsg deviceRpcCallMsg: downlinkMsg.getDeviceRpcCallMsgList()) { |
235 | result.add(saveDownlinkMsg(deviceRpcCallMsg)); | 242 | result.add(saveDownlinkMsg(deviceRpcCallMsg)); |
236 | } | 243 | } |
237 | } | 244 | } |
238 | - if (downlinkMsg.getDeviceCredentialsRequestMsgList() != null && !downlinkMsg.getDeviceCredentialsRequestMsgList().isEmpty()) { | 245 | + if (downlinkMsg.getDeviceCredentialsRequestMsgCount() > 0) { |
239 | for (DeviceCredentialsRequestMsg deviceCredentialsRequestMsg: downlinkMsg.getDeviceCredentialsRequestMsgList()) { | 246 | for (DeviceCredentialsRequestMsg deviceCredentialsRequestMsg: downlinkMsg.getDeviceCredentialsRequestMsgList()) { |
240 | result.add(saveDownlinkMsg(deviceCredentialsRequestMsg)); | 247 | result.add(saveDownlinkMsg(deviceCredentialsRequestMsg)); |
241 | } | 248 | } |
@@ -256,21 +263,28 @@ public class EdgeImitator { | @@ -256,21 +263,28 @@ public class EdgeImitator { | ||
256 | return Futures.immediateFuture(null); | 263 | return Futures.immediateFuture(null); |
257 | } | 264 | } |
258 | 265 | ||
259 | - public void waitForMessages() throws InterruptedException { | ||
260 | - messagesLatch.await(5, TimeUnit.SECONDS); | 266 | + public boolean waitForMessages() throws InterruptedException { |
267 | + return waitForMessages(5); | ||
268 | + } | ||
269 | + | ||
270 | + public boolean waitForMessages(int timeout) throws InterruptedException { | ||
271 | + return messagesLatch.await(timeout, TimeUnit.SECONDS); | ||
261 | } | 272 | } |
262 | 273 | ||
263 | public void expectMessageAmount(int messageAmount) { | 274 | public void expectMessageAmount(int messageAmount) { |
264 | messagesLatch = new CountDownLatch(messageAmount); | 275 | messagesLatch = new CountDownLatch(messageAmount); |
265 | } | 276 | } |
266 | 277 | ||
267 | - public void waitForResponses() throws InterruptedException { responsesLatch.await(5, TimeUnit.SECONDS); } | 278 | + public boolean waitForResponses() throws InterruptedException { |
279 | + return responsesLatch.await(5, TimeUnit.SECONDS); | ||
280 | + } | ||
268 | 281 | ||
269 | public void expectResponsesAmount(int messageAmount) { | 282 | public void expectResponsesAmount(int messageAmount) { |
270 | responsesLatch = new CountDownLatch(messageAmount); | 283 | responsesLatch = new CountDownLatch(messageAmount); |
271 | } | 284 | } |
272 | 285 | ||
273 | - public <T> Optional<T> findMessageByType(Class<T> tClass) { | 286 | + @SuppressWarnings("unchecked") |
287 | + public <T extends AbstractMessage> Optional<T> findMessageByType(Class<T> tClass) { | ||
274 | Optional<T> result; | 288 | Optional<T> result; |
275 | try { | 289 | try { |
276 | lock.lock(); | 290 | lock.lock(); |
@@ -281,6 +295,18 @@ public class EdgeImitator { | @@ -281,6 +295,18 @@ public class EdgeImitator { | ||
281 | return result; | 295 | return result; |
282 | } | 296 | } |
283 | 297 | ||
298 | + @SuppressWarnings("unchecked") | ||
299 | + public <T extends AbstractMessage> List<T> findAllMessagesByType(Class<T> tClass) { | ||
300 | + List<T> result; | ||
301 | + try { | ||
302 | + lock.lock(); | ||
303 | + result = (List<T>) downlinkMsgs.stream().filter(downlinkMsg -> downlinkMsg.getClass().isAssignableFrom(tClass)).collect(Collectors.toList()); | ||
304 | + } finally { | ||
305 | + lock.unlock(); | ||
306 | + } | ||
307 | + return result; | ||
308 | + } | ||
309 | + | ||
284 | public AbstractMessage getLatestMessage() { | 310 | public AbstractMessage getLatestMessage() { |
285 | return downlinkMsgs.get(downlinkMsgs.size() - 1); | 311 | return downlinkMsgs.get(downlinkMsgs.size() - 1); |
286 | } | 312 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service; | ||
17 | + | ||
18 | +import org.junit.BeforeClass; | ||
19 | +import org.junit.ClassRule; | ||
20 | +import org.junit.extensions.cpsuite.ClasspathSuite; | ||
21 | +import org.junit.runner.RunWith; | ||
22 | +import org.thingsboard.server.dao.CustomSqlUnit; | ||
23 | +import org.thingsboard.server.queue.memory.InMemoryStorage; | ||
24 | + | ||
25 | +import java.util.Arrays; | ||
26 | + | ||
27 | +@RunWith(ClasspathSuite.class) | ||
28 | +@ClasspathSuite.ClassnameFilters({ | ||
29 | + "org.thingsboard.server.service.resource.*Test", | ||
30 | + }) | ||
31 | +public class ServiceSqlTestSuite { | ||
32 | + | ||
33 | + @ClassRule | ||
34 | + public static CustomSqlUnit sqlUnit = new CustomSqlUnit( | ||
35 | + Arrays.asList("sql/schema-types-hsql.sql", "sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql"), | ||
36 | + "sql/hsql/drop-all-tables.sql", | ||
37 | + "sql-test.properties"); | ||
38 | + | ||
39 | + @BeforeClass | ||
40 | + public static void cleanupInMemStorage(){ | ||
41 | + InMemoryStorage.getInstance().cleanup(); | ||
42 | + } | ||
43 | +} |
application/src/test/java/org/thingsboard/server/service/resource/BaseTbResourceServiceTest.java
renamed from
dao/src/test/java/org/thingsboard/server/dao/service/BaseTbResourceServiceTest.java
@@ -13,28 +13,37 @@ | @@ -13,28 +13,37 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.dao.service; | 16 | +package org.thingsboard.server.service.resource; |
17 | 17 | ||
18 | import com.datastax.oss.driver.api.core.uuid.Uuids; | 18 | import com.datastax.oss.driver.api.core.uuid.Uuids; |
19 | import org.junit.After; | 19 | import org.junit.After; |
20 | import org.junit.Assert; | 20 | import org.junit.Assert; |
21 | import org.junit.Before; | 21 | import org.junit.Before; |
22 | import org.junit.Test; | 22 | import org.junit.Test; |
23 | +import org.springframework.beans.factory.annotation.Autowired; | ||
23 | import org.thingsboard.server.common.data.ResourceType; | 24 | import org.thingsboard.server.common.data.ResourceType; |
24 | import org.thingsboard.server.common.data.TbResource; | 25 | import org.thingsboard.server.common.data.TbResource; |
25 | import org.thingsboard.server.common.data.TbResourceInfo; | 26 | import org.thingsboard.server.common.data.TbResourceInfo; |
26 | import org.thingsboard.server.common.data.Tenant; | 27 | import org.thingsboard.server.common.data.Tenant; |
28 | +import org.thingsboard.server.common.data.User; | ||
27 | import org.thingsboard.server.common.data.id.TenantId; | 29 | import org.thingsboard.server.common.data.id.TenantId; |
28 | import org.thingsboard.server.common.data.page.PageData; | 30 | import org.thingsboard.server.common.data.page.PageData; |
29 | import org.thingsboard.server.common.data.page.PageLink; | 31 | import org.thingsboard.server.common.data.page.PageLink; |
32 | +import org.thingsboard.server.common.data.security.Authority; | ||
33 | +import org.thingsboard.server.controller.AbstractControllerTest; | ||
30 | import org.thingsboard.server.dao.exception.DataValidationException; | 34 | import org.thingsboard.server.dao.exception.DataValidationException; |
35 | +import org.thingsboard.server.dao.service.AbstractServiceTest; | ||
36 | +import org.thingsboard.server.dao.service.DaoSqlTest; | ||
31 | 37 | ||
32 | import java.util.ArrayList; | 38 | import java.util.ArrayList; |
33 | import java.util.Base64; | 39 | import java.util.Base64; |
34 | import java.util.Collections; | 40 | import java.util.Collections; |
35 | import java.util.List; | 41 | import java.util.List; |
36 | 42 | ||
37 | -public abstract class BaseTbResourceServiceTest extends AbstractServiceTest { | 43 | +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
44 | + | ||
45 | +@DaoSqlTest | ||
46 | +public class BaseTbResourceServiceTest extends AbstractControllerTest { | ||
38 | 47 | ||
39 | private static final String LWM2M_TEST_MODEL = "<LWM2M xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://www.openmobilealliance.org/tech/profiles/LWM2M-v1_1.xsd\">\n" + | 48 | private static final String LWM2M_TEST_MODEL = "<LWM2M xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://www.openmobilealliance.org/tech/profiles/LWM2M-v1_1.xsd\">\n" + |
40 | "<Object ObjectType=\"MODefinition\">\n" + | 49 | "<Object ObjectType=\"MODefinition\">\n" + |
@@ -67,18 +76,38 @@ public abstract class BaseTbResourceServiceTest extends AbstractServiceTest { | @@ -67,18 +76,38 @@ public abstract class BaseTbResourceServiceTest extends AbstractServiceTest { | ||
67 | 76 | ||
68 | private TenantId tenantId; | 77 | private TenantId tenantId; |
69 | 78 | ||
79 | + @Autowired | ||
80 | + private TbResourceService resourceService; | ||
81 | + | ||
82 | + private Tenant savedTenant; | ||
83 | + private User tenantAdmin; | ||
84 | + | ||
70 | @Before | 85 | @Before |
71 | - public void before() { | 86 | + public void beforeTest() throws Exception { |
87 | + loginSysAdmin(); | ||
88 | + | ||
72 | Tenant tenant = new Tenant(); | 89 | Tenant tenant = new Tenant(); |
73 | tenant.setTitle("My tenant"); | 90 | tenant.setTitle("My tenant"); |
74 | - Tenant savedTenant = tenantService.saveTenant(tenant); | ||
75 | - Assert.assertNotNull(savedTenant); | 91 | + savedTenant = doPost("/api/tenant", tenant, Tenant.class); |
76 | tenantId = savedTenant.getId(); | 92 | tenantId = savedTenant.getId(); |
93 | + Assert.assertNotNull(savedTenant); | ||
94 | + | ||
95 | + tenantAdmin = new User(); | ||
96 | + tenantAdmin.setAuthority(Authority.TENANT_ADMIN); | ||
97 | + tenantAdmin.setTenantId(savedTenant.getId()); | ||
98 | + tenantAdmin.setEmail("tenant2@thingsboard.org"); | ||
99 | + tenantAdmin.setFirstName("Joe"); | ||
100 | + tenantAdmin.setLastName("Downs"); | ||
101 | + | ||
102 | + tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); | ||
77 | } | 103 | } |
78 | 104 | ||
79 | @After | 105 | @After |
80 | - public void after() { | ||
81 | - tenantService.deleteTenant(tenantId); | 106 | + public void afterTest() throws Exception { |
107 | + loginSysAdmin(); | ||
108 | + | ||
109 | + doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) | ||
110 | + .andExpect(status().isOk()); | ||
82 | } | 111 | } |
83 | 112 | ||
84 | @Test | 113 | @Test |
@@ -239,9 +268,10 @@ public abstract class BaseTbResourceServiceTest extends AbstractServiceTest { | @@ -239,9 +268,10 @@ public abstract class BaseTbResourceServiceTest extends AbstractServiceTest { | ||
239 | 268 | ||
240 | @Test | 269 | @Test |
241 | public void testFindTenantResourcesByTenantId() throws Exception { | 270 | public void testFindTenantResourcesByTenantId() throws Exception { |
271 | + loginSysAdmin(); | ||
242 | Tenant tenant = new Tenant(); | 272 | Tenant tenant = new Tenant(); |
243 | tenant.setTitle("Test tenant"); | 273 | tenant.setTitle("Test tenant"); |
244 | - tenant = tenantService.saveTenant(tenant); | 274 | + tenant = doPost("/api/tenant", tenant, Tenant.class); |
245 | 275 | ||
246 | TenantId tenantId = tenant.getId(); | 276 | TenantId tenantId = tenant.getId(); |
247 | 277 | ||
@@ -279,14 +309,17 @@ public abstract class BaseTbResourceServiceTest extends AbstractServiceTest { | @@ -279,14 +309,17 @@ public abstract class BaseTbResourceServiceTest extends AbstractServiceTest { | ||
279 | Assert.assertFalse(pageData.hasNext()); | 309 | Assert.assertFalse(pageData.hasNext()); |
280 | Assert.assertTrue(pageData.getData().isEmpty()); | 310 | Assert.assertTrue(pageData.getData().isEmpty()); |
281 | 311 | ||
282 | - tenantService.deleteTenant(tenantId); | 312 | + doDelete("/api/tenant/" + tenantId.getId().toString()) |
313 | + .andExpect(status().isOk()); | ||
283 | } | 314 | } |
284 | 315 | ||
285 | @Test | 316 | @Test |
286 | public void testFindAllTenantResourcesByTenantId() throws Exception { | 317 | public void testFindAllTenantResourcesByTenantId() throws Exception { |
318 | + loginSysAdmin(); | ||
319 | + | ||
287 | Tenant tenant = new Tenant(); | 320 | Tenant tenant = new Tenant(); |
288 | tenant.setTitle("Test tenant"); | 321 | tenant.setTitle("Test tenant"); |
289 | - tenant = tenantService.saveTenant(tenant); | 322 | + tenant = doPost("/api/tenant", tenant, Tenant.class); |
290 | 323 | ||
291 | TenantId tenantId = tenant.getId(); | 324 | TenantId tenantId = tenant.getId(); |
292 | 325 | ||
@@ -344,7 +377,8 @@ public abstract class BaseTbResourceServiceTest extends AbstractServiceTest { | @@ -344,7 +377,8 @@ public abstract class BaseTbResourceServiceTest extends AbstractServiceTest { | ||
344 | Assert.assertFalse(pageData.hasNext()); | 377 | Assert.assertFalse(pageData.hasNext()); |
345 | Assert.assertTrue(pageData.getData().isEmpty()); | 378 | Assert.assertTrue(pageData.getData().isEmpty()); |
346 | 379 | ||
347 | - tenantService.deleteTenant(tenantId); | 380 | + doDelete("/api/tenant/" + tenantId.getId().toString()) |
381 | + .andExpect(status().isOk()); | ||
348 | } | 382 | } |
349 | 383 | ||
350 | } | 384 | } |
@@ -15,35 +15,11 @@ | @@ -15,35 +15,11 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.transport; | 16 | package org.thingsboard.server.transport; |
17 | 17 | ||
18 | -import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
20 | -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; | ||
21 | -import org.eclipse.paho.client.mqttv3.MqttConnectOptions; | ||
22 | -import org.eclipse.paho.client.mqttv3.MqttException; | ||
23 | -import org.eclipse.paho.client.mqttv3.MqttMessage; | ||
24 | -import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; | ||
25 | -import org.junit.Assert; | ||
26 | -import org.springframework.util.StringUtils; | ||
27 | import org.thingsboard.server.common.data.Device; | 19 | import org.thingsboard.server.common.data.Device; |
28 | import org.thingsboard.server.common.data.DeviceProfile; | 20 | import org.thingsboard.server.common.data.DeviceProfile; |
29 | -import org.thingsboard.server.common.data.DeviceProfileProvisionType; | ||
30 | -import org.thingsboard.server.common.data.DeviceProfileType; | ||
31 | -import org.thingsboard.server.common.data.DeviceTransportType; | ||
32 | import org.thingsboard.server.common.data.Tenant; | 21 | import org.thingsboard.server.common.data.Tenant; |
33 | -import org.thingsboard.server.common.data.TransportPayloadType; | ||
34 | import org.thingsboard.server.common.data.User; | 22 | import org.thingsboard.server.common.data.User; |
35 | -import org.thingsboard.server.common.data.device.profile.AllowCreateNewDevicesDeviceProfileProvisionConfiguration; | ||
36 | -import org.thingsboard.server.common.data.device.profile.CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration; | ||
37 | -import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; | ||
38 | -import org.thingsboard.server.common.data.device.profile.DeviceProfileData; | ||
39 | -import org.thingsboard.server.common.data.device.profile.DeviceProfileProvisionConfiguration; | ||
40 | -import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfileProvisionConfiguration; | ||
41 | -import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration; | ||
42 | -import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; | ||
43 | -import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; | ||
44 | -import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; | ||
45 | -import org.thingsboard.server.common.data.security.Authority; | ||
46 | -import org.thingsboard.server.common.data.security.DeviceCredentials; | ||
47 | import org.thingsboard.server.controller.AbstractControllerTest; | 23 | import org.thingsboard.server.controller.AbstractControllerTest; |
48 | import org.thingsboard.server.gen.transport.TransportProtos; | 24 | import org.thingsboard.server.gen.transport.TransportProtos; |
49 | 25 | ||
@@ -51,8 +27,6 @@ import java.util.ArrayList; | @@ -51,8 +27,6 @@ import java.util.ArrayList; | ||
51 | import java.util.List; | 27 | import java.util.List; |
52 | import java.util.concurrent.atomic.AtomicInteger; | 28 | import java.util.concurrent.atomic.AtomicInteger; |
53 | 29 | ||
54 | -import static org.junit.Assert.assertEquals; | ||
55 | -import static org.junit.Assert.assertNotNull; | ||
56 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | 30 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
57 | 31 | ||
58 | @Slf4j | 32 | @Slf4j |
@@ -105,6 +79,22 @@ public abstract class AbstractTransportIntegrationTest extends AbstractControlle | @@ -105,6 +79,22 @@ public abstract class AbstractTransportIntegrationTest extends AbstractControlle | ||
105 | " }\n" + | 79 | " }\n" + |
106 | "}"; | 80 | "}"; |
107 | 81 | ||
82 | + protected static final String DEVICE_RPC_RESPONSE_PROTO_SCHEMA = "syntax =\"proto3\";\n" + | ||
83 | + "package rpc;\n" + | ||
84 | + "\n" + | ||
85 | + "message RpcResponseMsg {\n" + | ||
86 | + " string payload = 1;\n" + | ||
87 | + "}"; | ||
88 | + | ||
89 | + protected static final String DEVICE_RPC_REQUEST_PROTO_SCHEMA = "syntax =\"proto3\";\n" + | ||
90 | + "package rpc;\n" + | ||
91 | + "\n" + | ||
92 | + "message RpcRequestMsg {\n" + | ||
93 | + " string method = 1;\n" + | ||
94 | + " int32 requestId = 2;\n" + | ||
95 | + " string params = 3;\n" + | ||
96 | + "}"; | ||
97 | + | ||
108 | protected Tenant savedTenant; | 98 | protected Tenant savedTenant; |
109 | protected User tenantAdmin; | 99 | protected User tenantAdmin; |
110 | 100 |
@@ -53,7 +53,7 @@ import static org.junit.Assert.assertNotNull; | @@ -53,7 +53,7 @@ import static org.junit.Assert.assertNotNull; | ||
53 | public abstract class AbstractCoapIntegrationTest extends AbstractTransportIntegrationTest { | 53 | public abstract class AbstractCoapIntegrationTest extends AbstractTransportIntegrationTest { |
54 | 54 | ||
55 | protected void processBeforeTest(String deviceName, CoapDeviceType coapDeviceType, TransportPayloadType payloadType) throws Exception { | 55 | protected void processBeforeTest(String deviceName, CoapDeviceType coapDeviceType, TransportPayloadType payloadType) throws Exception { |
56 | - this.processBeforeTest(deviceName, coapDeviceType, payloadType, null, null, DeviceProfileProvisionType.DISABLED, null, null); | 56 | + this.processBeforeTest(deviceName, coapDeviceType, payloadType, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
57 | } | 57 | } |
58 | 58 | ||
59 | protected void processBeforeTest(String deviceName, | 59 | protected void processBeforeTest(String deviceName, |
@@ -61,8 +61,11 @@ public abstract class AbstractCoapIntegrationTest extends AbstractTransportInteg | @@ -61,8 +61,11 @@ public abstract class AbstractCoapIntegrationTest extends AbstractTransportInteg | ||
61 | TransportPayloadType payloadType, | 61 | TransportPayloadType payloadType, |
62 | String telemetryProtoSchema, | 62 | String telemetryProtoSchema, |
63 | String attributesProtoSchema, | 63 | String attributesProtoSchema, |
64 | - DeviceProfileProvisionType provisionType, | ||
65 | - String provisionKey, String provisionSecret | 64 | + String rpcResponseProtoSchema, |
65 | + String rpcRequestProtoSchema, | ||
66 | + String provisionKey, | ||
67 | + String provisionSecret, | ||
68 | + DeviceProfileProvisionType provisionType | ||
66 | ) throws Exception { | 69 | ) throws Exception { |
67 | loginSysAdmin(); | 70 | loginSysAdmin(); |
68 | 71 | ||
@@ -85,7 +88,7 @@ public abstract class AbstractCoapIntegrationTest extends AbstractTransportInteg | @@ -85,7 +88,7 @@ public abstract class AbstractCoapIntegrationTest extends AbstractTransportInteg | ||
85 | device.setType("default"); | 88 | device.setType("default"); |
86 | 89 | ||
87 | if (coapDeviceType != null) { | 90 | if (coapDeviceType != null) { |
88 | - DeviceProfile coapDeviceProfile = createCoapDeviceProfile(payloadType, coapDeviceType, attributesProtoSchema, provisionType, provisionKey, provisionSecret, telemetryProtoSchema); | 91 | + DeviceProfile coapDeviceProfile = createCoapDeviceProfile(payloadType, coapDeviceType, provisionSecret, provisionType, provisionKey, attributesProtoSchema, telemetryProtoSchema, rpcResponseProtoSchema, rpcRequestProtoSchema); |
89 | deviceProfile = doPost("/api/deviceProfile", coapDeviceProfile, DeviceProfile.class); | 92 | deviceProfile = doPost("/api/deviceProfile", coapDeviceProfile, DeviceProfile.class); |
90 | device.setType(deviceProfile.getName()); | 93 | device.setType(deviceProfile.getName()); |
91 | device.setDeviceProfileId(deviceProfile.getId()); | 94 | device.setDeviceProfileId(deviceProfile.getId()); |
@@ -103,8 +106,9 @@ public abstract class AbstractCoapIntegrationTest extends AbstractTransportInteg | @@ -103,8 +106,9 @@ public abstract class AbstractCoapIntegrationTest extends AbstractTransportInteg | ||
103 | } | 106 | } |
104 | 107 | ||
105 | protected DeviceProfile createCoapDeviceProfile(TransportPayloadType transportPayloadType, CoapDeviceType coapDeviceType, | 108 | protected DeviceProfile createCoapDeviceProfile(TransportPayloadType transportPayloadType, CoapDeviceType coapDeviceType, |
106 | - String attributesProtoSchema, DeviceProfileProvisionType provisionType, | ||
107 | - String provisionKey, String provisionSecret, String telemetryProtoSchema) { | 109 | + String provisionSecret, DeviceProfileProvisionType provisionType, |
110 | + String provisionKey, String attributesProtoSchema, | ||
111 | + String telemetryProtoSchema, String rpcResponseProtoSchema, String rpcRequestProtoSchema) { | ||
108 | DeviceProfile deviceProfile = new DeviceProfile(); | 112 | DeviceProfile deviceProfile = new DeviceProfile(); |
109 | deviceProfile.setName(transportPayloadType.name()); | 113 | deviceProfile.setName(transportPayloadType.name()); |
110 | deviceProfile.setType(DeviceProfileType.DEFAULT); | 114 | deviceProfile.setType(DeviceProfileType.DEFAULT); |
@@ -127,8 +131,16 @@ public abstract class AbstractCoapIntegrationTest extends AbstractTransportInteg | @@ -127,8 +131,16 @@ public abstract class AbstractCoapIntegrationTest extends AbstractTransportInteg | ||
127 | if (StringUtils.isEmpty(attributesProtoSchema)) { | 131 | if (StringUtils.isEmpty(attributesProtoSchema)) { |
128 | attributesProtoSchema = DEVICE_ATTRIBUTES_PROTO_SCHEMA; | 132 | attributesProtoSchema = DEVICE_ATTRIBUTES_PROTO_SCHEMA; |
129 | } | 133 | } |
134 | + if (StringUtils.isEmpty(rpcResponseProtoSchema)) { | ||
135 | + rpcResponseProtoSchema = DEVICE_RPC_RESPONSE_PROTO_SCHEMA; | ||
136 | + } | ||
137 | + if (StringUtils.isEmpty(rpcRequestProtoSchema)) { | ||
138 | + rpcRequestProtoSchema = DEVICE_RPC_REQUEST_PROTO_SCHEMA; | ||
139 | + } | ||
130 | protoTransportPayloadConfiguration.setDeviceTelemetryProtoSchema(telemetryProtoSchema); | 140 | protoTransportPayloadConfiguration.setDeviceTelemetryProtoSchema(telemetryProtoSchema); |
131 | protoTransportPayloadConfiguration.setDeviceAttributesProtoSchema(attributesProtoSchema); | 141 | protoTransportPayloadConfiguration.setDeviceAttributesProtoSchema(attributesProtoSchema); |
142 | + protoTransportPayloadConfiguration.setDeviceRpcResponseProtoSchema(rpcResponseProtoSchema); | ||
143 | + protoTransportPayloadConfiguration.setDeviceRpcRequestProtoSchema(rpcRequestProtoSchema); | ||
132 | transportPayloadTypeConfiguration = protoTransportPayloadConfiguration; | 144 | transportPayloadTypeConfiguration = protoTransportPayloadConfiguration; |
133 | } else { | 145 | } else { |
134 | transportPayloadTypeConfiguration = new JsonTransportPayloadConfiguration(); | 146 | transportPayloadTypeConfiguration = new JsonTransportPayloadConfiguration(); |
@@ -79,7 +79,7 @@ public abstract class AbstractCoapAttributesRequestProtoIntegrationTest extends | @@ -79,7 +79,7 @@ public abstract class AbstractCoapAttributesRequestProtoIntegrationTest extends | ||
79 | @Test | 79 | @Test |
80 | public void testRequestAttributesValuesFromTheServer() throws Exception { | 80 | public void testRequestAttributesValuesFromTheServer() throws Exception { |
81 | super.processBeforeTest("Test Request attribute values from the server proto", CoapDeviceType.DEFAULT, | 81 | super.processBeforeTest("Test Request attribute values from the server proto", CoapDeviceType.DEFAULT, |
82 | - TransportPayloadType.PROTOBUF, null, ATTRIBUTES_SCHEMA_STR, DeviceProfileProvisionType.DISABLED, null, null); | 82 | + TransportPayloadType.PROTOBUF, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
83 | processTestRequestAttributesValuesFromTheServer(); | 83 | processTestRequestAttributesValuesFromTheServer(); |
84 | } | 84 | } |
85 | 85 |
@@ -88,7 +88,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | @@ -88,7 +88,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | ||
88 | 88 | ||
89 | 89 | ||
90 | private void processTestProvisioningDisabledDevice() throws Exception { | 90 | private void processTestProvisioningDisabledDevice() throws Exception { |
91 | - super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, DeviceProfileProvisionType.DISABLED, null, null); | 91 | + super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
92 | byte[] result = createCoapClientAndPublish().getPayload(); | 92 | byte[] result = createCoapClientAndPublish().getPayload(); |
93 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 93 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
94 | Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); | 94 | Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); |
@@ -97,7 +97,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | @@ -97,7 +97,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | ||
97 | 97 | ||
98 | 98 | ||
99 | private void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { | 99 | private void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { |
100 | - super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 100 | + super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
101 | byte[] result = createCoapClientAndPublish().getPayload(); | 101 | byte[] result = createCoapClientAndPublish().getPayload(); |
102 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 102 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
103 | 103 | ||
@@ -113,7 +113,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | @@ -113,7 +113,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | ||
113 | 113 | ||
114 | 114 | ||
115 | private void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception { | 115 | private void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception { |
116 | - super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 116 | + super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
117 | String requestCredentials = ",\"credentialsType\": \"ACCESS_TOKEN\",\"token\": \"test_token\""; | 117 | String requestCredentials = ",\"credentialsType\": \"ACCESS_TOKEN\",\"token\": \"test_token\""; |
118 | byte[] result = createCoapClientAndPublish(requestCredentials).getPayload(); | 118 | byte[] result = createCoapClientAndPublish(requestCredentials).getPayload(); |
119 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 119 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
@@ -132,7 +132,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | @@ -132,7 +132,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | ||
132 | 132 | ||
133 | 133 | ||
134 | private void processTestProvisioningCreateNewDeviceWithCert() throws Exception { | 134 | private void processTestProvisioningCreateNewDeviceWithCert() throws Exception { |
135 | - super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 135 | + super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
136 | String requestCredentials = ",\"credentialsType\": \"X509_CERTIFICATE\",\"hash\": \"testHash\""; | 136 | String requestCredentials = ",\"credentialsType\": \"X509_CERTIFICATE\",\"hash\": \"testHash\""; |
137 | byte[] result = createCoapClientAndPublish(requestCredentials).getPayload(); | 137 | byte[] result = createCoapClientAndPublish(requestCredentials).getPayload(); |
138 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 138 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
@@ -156,7 +156,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | @@ -156,7 +156,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | ||
156 | } | 156 | } |
157 | 157 | ||
158 | private void processTestProvisioningCheckPreProvisionedDevice() throws Exception { | 158 | private void processTestProvisioningCheckPreProvisionedDevice() throws Exception { |
159 | - super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, "testProvisionKey", "testProvisionSecret"); | 159 | + super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); |
160 | byte[] result = createCoapClientAndPublish().getPayload(); | 160 | byte[] result = createCoapClientAndPublish().getPayload(); |
161 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 161 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
162 | 162 | ||
@@ -167,7 +167,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | @@ -167,7 +167,7 @@ public abstract class AbstractCoapProvisionJsonDeviceTest extends AbstractCoapIn | ||
167 | } | 167 | } |
168 | 168 | ||
169 | private void processTestProvisioningWithBadKeyDevice() throws Exception { | 169 | private void processTestProvisioningWithBadKeyDevice() throws Exception { |
170 | - super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, "testProvisionKeyOrig", "testProvisionSecret"); | 170 | + super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.JSON, null, null, null, null, "testProvisionKeyOrig", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); |
171 | byte[] result = createCoapClientAndPublish().getPayload(); | 171 | byte[] result = createCoapClientAndPublish().getPayload(); |
172 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 172 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
173 | Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); | 173 | Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); |
@@ -92,14 +92,14 @@ public abstract class AbstractCoapProvisionProtoDeviceTest extends AbstractCoapI | @@ -92,14 +92,14 @@ public abstract class AbstractCoapProvisionProtoDeviceTest extends AbstractCoapI | ||
92 | 92 | ||
93 | 93 | ||
94 | private void processTestProvisioningDisabledDevice() throws Exception { | 94 | private void processTestProvisioningDisabledDevice() throws Exception { |
95 | - super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, DeviceProfileProvisionType.DISABLED, null, null); | 95 | + super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
96 | ProvisionDeviceResponseMsg result = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish().getPayload()); | 96 | ProvisionDeviceResponseMsg result = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish().getPayload()); |
97 | Assert.assertNotNull(result); | 97 | Assert.assertNotNull(result); |
98 | Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), result.getStatus().toString()); | 98 | Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), result.getStatus().toString()); |
99 | } | 99 | } |
100 | 100 | ||
101 | private void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { | 101 | private void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { |
102 | - super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 102 | + super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
103 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish().getPayload()); | 103 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish().getPayload()); |
104 | 104 | ||
105 | Device createdDevice = deviceService.findDeviceByTenantIdAndName(savedTenant.getTenantId(), "Test Provision device"); | 105 | Device createdDevice = deviceService.findDeviceByTenantIdAndName(savedTenant.getTenantId(), "Test Provision device"); |
@@ -113,7 +113,7 @@ public abstract class AbstractCoapProvisionProtoDeviceTest extends AbstractCoapI | @@ -113,7 +113,7 @@ public abstract class AbstractCoapProvisionProtoDeviceTest extends AbstractCoapI | ||
113 | } | 113 | } |
114 | 114 | ||
115 | private void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception { | 115 | private void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception { |
116 | - super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 116 | + super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
117 | CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceTokenRequestMsg(ValidateDeviceTokenRequestMsg.newBuilder().setToken("test_token").build()).build(); | 117 | CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceTokenRequestMsg(ValidateDeviceTokenRequestMsg.newBuilder().setToken("test_token").build()).build(); |
118 | 118 | ||
119 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish(createTestsProvisionMessage(CredentialsType.ACCESS_TOKEN, requestCredentials)).getPayload()); | 119 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish(createTestsProvisionMessage(CredentialsType.ACCESS_TOKEN, requestCredentials)).getPayload()); |
@@ -131,7 +131,7 @@ public abstract class AbstractCoapProvisionProtoDeviceTest extends AbstractCoapI | @@ -131,7 +131,7 @@ public abstract class AbstractCoapProvisionProtoDeviceTest extends AbstractCoapI | ||
131 | } | 131 | } |
132 | 132 | ||
133 | private void processTestProvisioningCreateNewDeviceWithCert() throws Exception { | 133 | private void processTestProvisioningCreateNewDeviceWithCert() throws Exception { |
134 | - super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 134 | + super.processBeforeTest("Test Provision device3", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
135 | CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceX509CertRequestMsg(ValidateDeviceX509CertRequestMsg.newBuilder().setHash("testHash").build()).build(); | 135 | CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceX509CertRequestMsg(ValidateDeviceX509CertRequestMsg.newBuilder().setHash("testHash").build()).build(); |
136 | 136 | ||
137 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish(createTestsProvisionMessage(CredentialsType.X509_CERTIFICATE, requestCredentials)).getPayload()); | 137 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish(createTestsProvisionMessage(CredentialsType.X509_CERTIFICATE, requestCredentials)).getPayload()); |
@@ -155,7 +155,7 @@ public abstract class AbstractCoapProvisionProtoDeviceTest extends AbstractCoapI | @@ -155,7 +155,7 @@ public abstract class AbstractCoapProvisionProtoDeviceTest extends AbstractCoapI | ||
155 | } | 155 | } |
156 | 156 | ||
157 | private void processTestProvisioningCheckPreProvisionedDevice() throws Exception { | 157 | private void processTestProvisioningCheckPreProvisionedDevice() throws Exception { |
158 | - super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, "testProvisionKey", "testProvisionSecret"); | 158 | + super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); |
159 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish().getPayload()); | 159 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish().getPayload()); |
160 | 160 | ||
161 | DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(savedTenant.getTenantId(), savedDevice.getId()); | 161 | DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(savedTenant.getTenantId(), savedDevice.getId()); |
@@ -165,7 +165,7 @@ public abstract class AbstractCoapProvisionProtoDeviceTest extends AbstractCoapI | @@ -165,7 +165,7 @@ public abstract class AbstractCoapProvisionProtoDeviceTest extends AbstractCoapI | ||
165 | } | 165 | } |
166 | 166 | ||
167 | private void processTestProvisioningWithBadKeyDevice() throws Exception { | 167 | private void processTestProvisioningWithBadKeyDevice() throws Exception { |
168 | - super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, "testProvisionKeyOrig", "testProvisionSecret"); | 168 | + super.processBeforeTest("Test Provision device", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, null, null, "testProvisionKeyOrig", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); |
169 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish().getPayload()); | 169 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createCoapClientAndPublish().getPayload()); |
170 | Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.getStatus().toString()); | 170 | Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.getStatus().toString()); |
171 | } | 171 | } |
@@ -124,7 +124,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC | @@ -124,7 +124,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC | ||
124 | return COAP_BASE_URL + token + "/" + FeatureType.RPC.name().toLowerCase() + "/" + requestId; | 124 | return COAP_BASE_URL + token + "/" + FeatureType.RPC.name().toLowerCase() + "/" + requestId; |
125 | } | 125 | } |
126 | 126 | ||
127 | - private class TestCoapCallback implements CoapHandler { | 127 | + protected class TestCoapCallback implements CoapHandler { |
128 | 128 | ||
129 | private final CoapClient client; | 129 | private final CoapClient client; |
130 | private final CountDownLatch latch; | 130 | private final CountDownLatch latch; |
@@ -136,7 +136,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC | @@ -136,7 +136,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC | ||
136 | 136 | ||
137 | private Integer observe; | 137 | private Integer observe; |
138 | 138 | ||
139 | - private TestCoapCallback(CoapClient client, CountDownLatch latch, boolean isOneWayRpc) { | 139 | + TestCoapCallback(CoapClient client, CountDownLatch latch, boolean isOneWayRpc) { |
140 | this.client = client; | 140 | this.client = client; |
141 | this.latch = latch; | 141 | this.latch = latch; |
142 | this.isOneWayRpc = isOneWayRpc; | 142 | this.isOneWayRpc = isOneWayRpc; |
@@ -144,7 +144,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC | @@ -144,7 +144,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC | ||
144 | 144 | ||
145 | @Override | 145 | @Override |
146 | public void onLoad(CoapResponse response) { | 146 | public void onLoad(CoapResponse response) { |
147 | - log.warn("coap response: {}, {}", response, response.getCode()); | 147 | + log.warn("coap response: {}, {}", response.getResponseText(), response.getCode()); |
148 | assertNotNull(response.getPayload()); | 148 | assertNotNull(response.getPayload()); |
149 | assertEquals(response.getCode(), CoAP.ResponseCode.CONTENT); | 149 | assertEquals(response.getCode(), CoAP.ResponseCode.CONTENT); |
150 | observe = response.getOptions().getObserve(); | 150 | observe = response.getOptions().getObserve(); |
@@ -36,12 +36,12 @@ public abstract class AbstractCoapServerSideRpcJsonIntegrationTest extends Abstr | @@ -36,12 +36,12 @@ public abstract class AbstractCoapServerSideRpcJsonIntegrationTest extends Abstr | ||
36 | } | 36 | } |
37 | 37 | ||
38 | @Test | 38 | @Test |
39 | - public void testServerMqttOneWayRpc() throws Exception { | 39 | + public void testServerCoapOneWayRpc() throws Exception { |
40 | processOneWayRpcTest(); | 40 | processOneWayRpcTest(); |
41 | } | 41 | } |
42 | 42 | ||
43 | @Test | 43 | @Test |
44 | - public void testServerMqttTwoWayRpc() throws Exception { | 44 | + public void testServerCoapTwoWayRpc() throws Exception { |
45 | processTwoWayRpcTest(); | 45 | processTwoWayRpcTest(); |
46 | } | 46 | } |
47 | 47 |
@@ -15,26 +15,62 @@ | @@ -15,26 +15,62 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.transport.coap.rpc; | 16 | package org.thingsboard.server.transport.coap.rpc; |
17 | 17 | ||
18 | +import com.github.os72.protobuf.dynamic.DynamicSchema; | ||
19 | +import com.google.protobuf.Descriptors; | ||
20 | +import com.google.protobuf.DynamicMessage; | ||
21 | +import com.google.protobuf.InvalidProtocolBufferException; | ||
22 | +import com.squareup.wire.schema.internal.parser.ProtoFileElement; | ||
18 | import lombok.extern.slf4j.Slf4j; | 23 | import lombok.extern.slf4j.Slf4j; |
19 | import org.eclipse.californium.core.CoapClient; | 24 | import org.eclipse.californium.core.CoapClient; |
20 | import org.eclipse.californium.core.CoapHandler; | 25 | import org.eclipse.californium.core.CoapHandler; |
26 | +import org.eclipse.californium.core.CoapObserveRelation; | ||
21 | import org.eclipse.californium.core.CoapResponse; | 27 | import org.eclipse.californium.core.CoapResponse; |
28 | +import org.eclipse.californium.core.coap.CoAP; | ||
22 | import org.eclipse.californium.core.coap.MediaTypeRegistry; | 29 | import org.eclipse.californium.core.coap.MediaTypeRegistry; |
30 | +import org.eclipse.californium.core.coap.Request; | ||
23 | import org.junit.After; | 31 | import org.junit.After; |
24 | import org.junit.Before; | 32 | import org.junit.Before; |
25 | import org.junit.Test; | 33 | import org.junit.Test; |
26 | import org.thingsboard.server.common.data.CoapDeviceType; | 34 | import org.thingsboard.server.common.data.CoapDeviceType; |
35 | +import org.thingsboard.server.common.data.DeviceProfileProvisionType; | ||
27 | import org.thingsboard.server.common.data.TransportPayloadType; | 36 | import org.thingsboard.server.common.data.TransportPayloadType; |
28 | -import org.thingsboard.server.gen.transport.TransportProtos; | 37 | +import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration; |
38 | +import org.thingsboard.server.common.data.device.profile.CoapDeviceTypeConfiguration; | ||
39 | +import org.thingsboard.server.common.data.device.profile.DefaultCoapDeviceTypeConfiguration; | ||
40 | +import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; | ||
41 | +import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; | ||
42 | +import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; | ||
43 | +import org.thingsboard.server.common.msg.session.FeatureType; | ||
29 | 44 | ||
45 | +import java.util.List; | ||
30 | import java.util.concurrent.CountDownLatch; | 46 | import java.util.concurrent.CountDownLatch; |
47 | +import java.util.concurrent.TimeUnit; | ||
48 | + | ||
49 | +import static org.junit.Assert.assertEquals; | ||
50 | +import static org.junit.Assert.assertNotNull; | ||
51 | +import static org.junit.Assert.assertTrue; | ||
52 | +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
31 | 53 | ||
32 | @Slf4j | 54 | @Slf4j |
33 | public abstract class AbstractCoapServerSideRpcProtoIntegrationTest extends AbstractCoapServerSideRpcIntegrationTest { | 55 | public abstract class AbstractCoapServerSideRpcProtoIntegrationTest extends AbstractCoapServerSideRpcIntegrationTest { |
34 | 56 | ||
57 | + private static final String RPC_REQUEST_PROTO_SCHEMA = "syntax =\"proto3\";\n" + | ||
58 | + "package rpc;\n" + | ||
59 | + "\n" + | ||
60 | + "message RpcRequestMsg {\n" + | ||
61 | + " string method = 1;\n" + | ||
62 | + " int32 requestId = 2;\n" + | ||
63 | + " Params params = 3;\n" + | ||
64 | + "\n" + | ||
65 | + " message Params {\n" + | ||
66 | + " string pin = 1;\n" + | ||
67 | + " int32 value = 2;\n" + | ||
68 | + " }\n" + | ||
69 | + "}"; | ||
70 | + | ||
35 | @Before | 71 | @Before |
36 | public void beforeTest() throws Exception { | 72 | public void beforeTest() throws Exception { |
37 | - processBeforeTest("RPC test device", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF); | 73 | + processBeforeTest("RPC test device", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED); |
38 | } | 74 | } |
39 | 75 | ||
40 | @After | 76 | @After |
@@ -43,33 +79,91 @@ public abstract class AbstractCoapServerSideRpcProtoIntegrationTest extends Abst | @@ -43,33 +79,91 @@ public abstract class AbstractCoapServerSideRpcProtoIntegrationTest extends Abst | ||
43 | } | 79 | } |
44 | 80 | ||
45 | @Test | 81 | @Test |
46 | - public void testServerMqttOneWayRpc() throws Exception { | 82 | + public void testServerCoapOneWayRpc() throws Exception { |
47 | processOneWayRpcTest(); | 83 | processOneWayRpcTest(); |
48 | } | 84 | } |
49 | 85 | ||
50 | @Test | 86 | @Test |
51 | - public void testServerMqttTwoWayRpc() throws Exception { | 87 | + public void testServerCoapTwoWayRpc() throws Exception { |
52 | processTwoWayRpcTest(); | 88 | processTwoWayRpcTest(); |
53 | } | 89 | } |
54 | 90 | ||
91 | + protected void processTwoWayRpcTest() throws Exception { | ||
92 | + CoapClient client = getCoapClient(FeatureType.RPC); | ||
93 | + client.useCONs(); | ||
94 | + | ||
95 | + CountDownLatch latch = new CountDownLatch(1); | ||
96 | + TestCoapCallback testCoapCallback = new TestCoapCallback(client, latch, false); | ||
97 | + | ||
98 | + Request request = Request.newGet().setObserve(); | ||
99 | + request.setType(CoAP.Type.CON); | ||
100 | + CoapObserveRelation observeRelation = client.observe(request, testCoapCallback); | ||
101 | + | ||
102 | + String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; | ||
103 | + String deviceId = savedDevice.getId().getId().toString(); | ||
104 | + | ||
105 | + String expected = "{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}"; | ||
106 | + | ||
107 | + String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | ||
108 | + latch.await(3, TimeUnit.SECONDS); | ||
109 | + | ||
110 | + assertEquals(expected, result); | ||
111 | + assertEquals(0, testCoapCallback.getObserve().intValue()); | ||
112 | + observeRelation.proactiveCancel(); | ||
113 | + assertTrue(observeRelation.isCanceled()); | ||
114 | + } | ||
115 | + | ||
55 | @Override | 116 | @Override |
56 | protected void processOnLoadResponse(CoapResponse response, CoapClient client, Integer observe, CountDownLatch latch) { | 117 | protected void processOnLoadResponse(CoapResponse response, CoapClient client, Integer observe, CountDownLatch latch) { |
57 | client.setURI(getRpcResponseFeatureTokenUrl(accessToken, observe)); | 118 | client.setURI(getRpcResponseFeatureTokenUrl(accessToken, observe)); |
58 | - TransportProtos.ToDeviceRpcResponseMsg toDeviceRpcResponseMsg = TransportProtos.ToDeviceRpcResponseMsg.newBuilder() | ||
59 | - .setPayload(DEVICE_RESPONSE) | ||
60 | - .setRequestId(observe) | ||
61 | - .build(); | ||
62 | - client.post(new CoapHandler() { | ||
63 | - @Override | ||
64 | - public void onLoad(CoapResponse response) { | ||
65 | - log.warn("Command Response Ack: {}, {}", response.getCode(), response.getResponseText()); | ||
66 | - latch.countDown(); | ||
67 | - } | 119 | + ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = getProtoTransportPayloadConfiguration(); |
120 | + ProtoFileElement rpcRequestProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(RPC_REQUEST_PROTO_SCHEMA); | ||
121 | + DynamicSchema rpcRequestProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcRequestProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_REQUEST_PROTO_SCHEMA); | ||
68 | 122 | ||
69 | - @Override | ||
70 | - public void onError() { | ||
71 | - log.warn("Command Response Ack Error, No connect"); | 123 | + byte[] requestPayload = response.getPayload(); |
124 | + DynamicMessage.Builder rpcRequestMsg = rpcRequestProtoSchema.newMessageBuilder("RpcRequestMsg"); | ||
125 | + Descriptors.Descriptor rpcRequestMsgDescriptor = rpcRequestMsg.getDescriptorForType(); | ||
126 | + assertNotNull(rpcRequestMsgDescriptor); | ||
127 | + try { | ||
128 | + DynamicMessage dynamicMessage = DynamicMessage.parseFrom(rpcRequestMsgDescriptor, requestPayload); | ||
129 | + List<Descriptors.FieldDescriptor> fields = rpcRequestMsgDescriptor.getFields(); | ||
130 | + for (Descriptors.FieldDescriptor fieldDescriptor: fields) { | ||
131 | + assertTrue(dynamicMessage.hasField(fieldDescriptor)); | ||
72 | } | 132 | } |
73 | - }, toDeviceRpcResponseMsg.toByteArray(), MediaTypeRegistry.APPLICATION_JSON); | 133 | + ProtoFileElement rpcResponseProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(DEVICE_RPC_RESPONSE_PROTO_SCHEMA); |
134 | + DynamicSchema rpcResponseProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcResponseProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_RESPONSE_PROTO_SCHEMA); | ||
135 | + DynamicMessage.Builder rpcResponseBuilder = rpcResponseProtoSchema.newMessageBuilder("RpcResponseMsg"); | ||
136 | + Descriptors.Descriptor rpcResponseMsgDescriptor = rpcResponseBuilder.getDescriptorForType(); | ||
137 | + assertNotNull(rpcResponseMsgDescriptor); | ||
138 | + DynamicMessage rpcResponseMsg = rpcResponseBuilder | ||
139 | + .setField(rpcResponseMsgDescriptor.findFieldByName("payload"), DEVICE_RESPONSE) | ||
140 | + .build(); | ||
141 | + client.post(new CoapHandler() { | ||
142 | + @Override | ||
143 | + public void onLoad(CoapResponse response) { | ||
144 | + log.warn("Command Response Ack: {}, {}", response.getCode(), response.getResponseText()); | ||
145 | + latch.countDown(); | ||
146 | + } | ||
147 | + | ||
148 | + @Override | ||
149 | + public void onError() { | ||
150 | + log.warn("Command Response Ack Error, No connect"); | ||
151 | + } | ||
152 | + }, rpcResponseMsg.toByteArray(), MediaTypeRegistry.APPLICATION_JSON); | ||
153 | + } catch (InvalidProtocolBufferException e) { | ||
154 | + log.warn("Command Response Ack Error, Invalid response received: ", e); | ||
155 | + } | ||
156 | + } | ||
157 | + | ||
158 | + private ProtoTransportPayloadConfiguration getProtoTransportPayloadConfiguration() { | ||
159 | + DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration(); | ||
160 | + assertTrue(transportConfiguration instanceof CoapDeviceProfileTransportConfiguration); | ||
161 | + CoapDeviceProfileTransportConfiguration coapDeviceProfileTransportConfiguration = (CoapDeviceProfileTransportConfiguration) transportConfiguration; | ||
162 | + CoapDeviceTypeConfiguration coapDeviceTypeConfiguration = coapDeviceProfileTransportConfiguration.getCoapDeviceTypeConfiguration(); | ||
163 | + assertTrue(coapDeviceTypeConfiguration instanceof DefaultCoapDeviceTypeConfiguration); | ||
164 | + DefaultCoapDeviceTypeConfiguration defaultCoapDeviceTypeConfiguration = (DefaultCoapDeviceTypeConfiguration) coapDeviceTypeConfiguration; | ||
165 | + TransportPayloadTypeConfiguration transportPayloadTypeConfiguration = defaultCoapDeviceTypeConfiguration.getTransportPayloadTypeConfiguration(); | ||
166 | + assertTrue(transportPayloadTypeConfiguration instanceof ProtoTransportPayloadConfiguration); | ||
167 | + return (ProtoTransportPayloadConfiguration) transportPayloadTypeConfiguration; | ||
74 | } | 168 | } |
75 | } | 169 | } |
@@ -114,7 +114,7 @@ public abstract class AbstractCoapTimeseriesProtoIntegrationTest extends Abstrac | @@ -114,7 +114,7 @@ public abstract class AbstractCoapTimeseriesProtoIntegrationTest extends Abstrac | ||
114 | " }\n" + | 114 | " }\n" + |
115 | " }\n" + | 115 | " }\n" + |
116 | "}"; | 116 | "}"; |
117 | - super.processBeforeTest("Test Post Telemetry device proto payload", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, schemaStr, null, DeviceProfileProvisionType.DISABLED, null, null); | 117 | + super.processBeforeTest("Test Post Telemetry device proto payload", CoapDeviceType.DEFAULT, TransportPayloadType.PROTOBUF, schemaStr, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
118 | DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration(); | 118 | DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration(); |
119 | assertTrue(transportConfiguration instanceof CoapDeviceProfileTransportConfiguration); | 119 | assertTrue(transportConfiguration instanceof CoapDeviceProfileTransportConfiguration); |
120 | CoapDeviceProfileTransportConfiguration coapDeviceProfileTransportConfiguration = (CoapDeviceProfileTransportConfiguration) transportConfiguration; | 120 | CoapDeviceProfileTransportConfiguration coapDeviceProfileTransportConfiguration = (CoapDeviceProfileTransportConfiguration) transportConfiguration; |
@@ -62,7 +62,7 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg | @@ -62,7 +62,7 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg | ||
62 | protected DeviceProfile deviceProfile; | 62 | protected DeviceProfile deviceProfile; |
63 | 63 | ||
64 | protected void processBeforeTest (String deviceName, String gatewayName, TransportPayloadType payloadType, String telemetryTopic, String attributesTopic) throws Exception { | 64 | protected void processBeforeTest (String deviceName, String gatewayName, TransportPayloadType payloadType, String telemetryTopic, String attributesTopic) throws Exception { |
65 | - this.processBeforeTest(deviceName, gatewayName, payloadType, telemetryTopic, attributesTopic, null, null, DeviceProfileProvisionType.DISABLED, null, null); | 65 | + this.processBeforeTest(deviceName, gatewayName, payloadType, telemetryTopic, attributesTopic, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
66 | } | 66 | } |
67 | 67 | ||
68 | protected void processBeforeTest(String deviceName, | 68 | protected void processBeforeTest(String deviceName, |
@@ -72,9 +72,12 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg | @@ -72,9 +72,12 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg | ||
72 | String attributesTopic, | 72 | String attributesTopic, |
73 | String telemetryProtoSchema, | 73 | String telemetryProtoSchema, |
74 | String attributesProtoSchema, | 74 | String attributesProtoSchema, |
75 | - DeviceProfileProvisionType provisionType, | ||
76 | - String provisionKey, String provisionSecret | ||
77 | - ) throws Exception { | 75 | + String rpcResponseProtoSchema, |
76 | + String rpcRequestProtoSchema, | ||
77 | + String provisionKey, | ||
78 | + String provisionSecret, | ||
79 | + DeviceProfileProvisionType provisionType | ||
80 | + ) throws Exception { | ||
78 | loginSysAdmin(); | 81 | loginSysAdmin(); |
79 | 82 | ||
80 | Tenant tenant = new Tenant(); | 83 | Tenant tenant = new Tenant(); |
@@ -103,7 +106,7 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg | @@ -103,7 +106,7 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg | ||
103 | gateway.setAdditionalInfo(additionalInfo); | 106 | gateway.setAdditionalInfo(additionalInfo); |
104 | 107 | ||
105 | if (payloadType != null) { | 108 | if (payloadType != null) { |
106 | - DeviceProfile mqttDeviceProfile = createMqttDeviceProfile(payloadType, telemetryTopic, attributesTopic, telemetryProtoSchema, attributesProtoSchema, provisionType, provisionKey, provisionSecret); | 109 | + DeviceProfile mqttDeviceProfile = createMqttDeviceProfile(payloadType, telemetryTopic, attributesTopic, telemetryProtoSchema, attributesProtoSchema, rpcResponseProtoSchema, rpcRequestProtoSchema, provisionKey, provisionSecret, provisionType); |
107 | deviceProfile = doPost("/api/deviceProfile", mqttDeviceProfile, DeviceProfile.class); | 110 | deviceProfile = doPost("/api/deviceProfile", mqttDeviceProfile, DeviceProfile.class); |
108 | device.setType(deviceProfile.getName()); | 111 | device.setType(deviceProfile.getName()); |
109 | device.setDeviceProfileId(deviceProfile.getId()); | 112 | device.setDeviceProfileId(deviceProfile.getId()); |
@@ -157,8 +160,9 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg | @@ -157,8 +160,9 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg | ||
157 | protected DeviceProfile createMqttDeviceProfile(TransportPayloadType transportPayloadType, | 160 | protected DeviceProfile createMqttDeviceProfile(TransportPayloadType transportPayloadType, |
158 | String telemetryTopic, String attributesTopic, | 161 | String telemetryTopic, String attributesTopic, |
159 | String telemetryProtoSchema, String attributesProtoSchema, | 162 | String telemetryProtoSchema, String attributesProtoSchema, |
160 | - DeviceProfileProvisionType provisionType, | ||
161 | - String provisionKey, String provisionSecret) { | 163 | + String rpcResponseProtoSchema, String rpcRequestProtoSchema, |
164 | + String provisionKey, String provisionSecret, | ||
165 | + DeviceProfileProvisionType provisionType) { | ||
162 | DeviceProfile deviceProfile = new DeviceProfile(); | 166 | DeviceProfile deviceProfile = new DeviceProfile(); |
163 | deviceProfile.setName(transportPayloadType.name()); | 167 | deviceProfile.setName(transportPayloadType.name()); |
164 | deviceProfile.setType(DeviceProfileType.DEFAULT); | 168 | deviceProfile.setType(DeviceProfileType.DEFAULT); |
@@ -186,8 +190,16 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg | @@ -186,8 +190,16 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg | ||
186 | if (StringUtils.isEmpty(attributesProtoSchema)) { | 190 | if (StringUtils.isEmpty(attributesProtoSchema)) { |
187 | attributesProtoSchema = DEVICE_ATTRIBUTES_PROTO_SCHEMA; | 191 | attributesProtoSchema = DEVICE_ATTRIBUTES_PROTO_SCHEMA; |
188 | } | 192 | } |
193 | + if (StringUtils.isEmpty(rpcResponseProtoSchema)) { | ||
194 | + rpcResponseProtoSchema = DEVICE_RPC_RESPONSE_PROTO_SCHEMA; | ||
195 | + } | ||
196 | + if (StringUtils.isEmpty(rpcRequestProtoSchema)) { | ||
197 | + rpcRequestProtoSchema = DEVICE_RPC_REQUEST_PROTO_SCHEMA; | ||
198 | + } | ||
189 | protoTransportPayloadConfiguration.setDeviceTelemetryProtoSchema(telemetryProtoSchema); | 199 | protoTransportPayloadConfiguration.setDeviceTelemetryProtoSchema(telemetryProtoSchema); |
190 | protoTransportPayloadConfiguration.setDeviceAttributesProtoSchema(attributesProtoSchema); | 200 | protoTransportPayloadConfiguration.setDeviceAttributesProtoSchema(attributesProtoSchema); |
201 | + protoTransportPayloadConfiguration.setDeviceRpcResponseProtoSchema(rpcResponseProtoSchema); | ||
202 | + protoTransportPayloadConfiguration.setDeviceRpcRequestProtoSchema(rpcRequestProtoSchema); | ||
191 | transportPayloadTypeConfiguration = protoTransportPayloadConfiguration; | 203 | transportPayloadTypeConfiguration = protoTransportPayloadConfiguration; |
192 | } | 204 | } |
193 | mqttDeviceProfileTransportConfiguration.setTransportPayloadTypeConfiguration(transportPayloadTypeConfiguration); | 205 | mqttDeviceProfileTransportConfiguration.setTransportPayloadTypeConfiguration(transportPayloadTypeConfiguration); |
@@ -83,7 +83,7 @@ public abstract class AbstractMqttAttributesRequestProtoIntegrationTest extends | @@ -83,7 +83,7 @@ public abstract class AbstractMqttAttributesRequestProtoIntegrationTest extends | ||
83 | @Test | 83 | @Test |
84 | public void testRequestAttributesValuesFromTheServer() throws Exception { | 84 | public void testRequestAttributesValuesFromTheServer() throws Exception { |
85 | super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto", | 85 | super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto", |
86 | - TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, DeviceProfileProvisionType.DISABLED, null, null); | 86 | + TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
87 | processTestRequestAttributesValuesFromTheServer(); | 87 | processTestRequestAttributesValuesFromTheServer(); |
88 | } | 88 | } |
89 | 89 |
@@ -94,7 +94,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | @@ -94,7 +94,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | ||
94 | 94 | ||
95 | 95 | ||
96 | protected void processTestProvisioningDisabledDevice() throws Exception { | 96 | protected void processTestProvisioningDisabledDevice() throws Exception { |
97 | - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, DeviceProfileProvisionType.DISABLED, null, null); | 97 | + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
98 | byte[] result = createMqttClientAndPublish().getPayloadBytes(); | 98 | byte[] result = createMqttClientAndPublish().getPayloadBytes(); |
99 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 99 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
100 | Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); | 100 | Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); |
@@ -103,7 +103,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | @@ -103,7 +103,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | ||
103 | 103 | ||
104 | 104 | ||
105 | protected void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { | 105 | protected void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { |
106 | - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 106 | + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
107 | byte[] result = createMqttClientAndPublish().getPayloadBytes(); | 107 | byte[] result = createMqttClientAndPublish().getPayloadBytes(); |
108 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 108 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
109 | 109 | ||
@@ -119,7 +119,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | @@ -119,7 +119,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | ||
119 | 119 | ||
120 | 120 | ||
121 | protected void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception { | 121 | protected void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception { |
122 | - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 122 | + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
123 | String requestCredentials = ",\"credentialsType\": \"ACCESS_TOKEN\",\"token\": \"test_token\""; | 123 | String requestCredentials = ",\"credentialsType\": \"ACCESS_TOKEN\",\"token\": \"test_token\""; |
124 | byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); | 124 | byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); |
125 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 125 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
@@ -138,7 +138,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | @@ -138,7 +138,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | ||
138 | 138 | ||
139 | 139 | ||
140 | protected void processTestProvisioningCreateNewDeviceWithCert() throws Exception { | 140 | protected void processTestProvisioningCreateNewDeviceWithCert() throws Exception { |
141 | - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 141 | + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
142 | String requestCredentials = ",\"credentialsType\": \"X509_CERTIFICATE\",\"hash\": \"testHash\""; | 142 | String requestCredentials = ",\"credentialsType\": \"X509_CERTIFICATE\",\"hash\": \"testHash\""; |
143 | byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); | 143 | byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); |
144 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 144 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
@@ -163,7 +163,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | @@ -163,7 +163,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | ||
163 | 163 | ||
164 | 164 | ||
165 | protected void processTestProvisioningCreateNewDeviceWithMqttBasic() throws Exception { | 165 | protected void processTestProvisioningCreateNewDeviceWithMqttBasic() throws Exception { |
166 | - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 166 | + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
167 | String requestCredentials = ",\"credentialsType\": \"MQTT_BASIC\",\"clientId\": \"test_clientId\",\"username\": \"test_username\",\"password\": \"test_password\""; | 167 | String requestCredentials = ",\"credentialsType\": \"MQTT_BASIC\",\"clientId\": \"test_clientId\",\"username\": \"test_username\",\"password\": \"test_password\""; |
168 | byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); | 168 | byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); |
169 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 169 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
@@ -188,7 +188,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | @@ -188,7 +188,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | ||
188 | } | 188 | } |
189 | 189 | ||
190 | protected void processTestProvisioningCheckPreProvisionedDevice() throws Exception { | 190 | protected void processTestProvisioningCheckPreProvisionedDevice() throws Exception { |
191 | - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, "testProvisionKey", "testProvisionSecret"); | 191 | + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); |
192 | byte[] result = createMqttClientAndPublish().getPayloadBytes(); | 192 | byte[] result = createMqttClientAndPublish().getPayloadBytes(); |
193 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 193 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
194 | 194 | ||
@@ -199,7 +199,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | @@ -199,7 +199,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn | ||
199 | } | 199 | } |
200 | 200 | ||
201 | protected void processTestProvisioningWithBadKeyDevice() throws Exception { | 201 | protected void processTestProvisioningWithBadKeyDevice() throws Exception { |
202 | - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, "testProvisionKeyOrig", "testProvisionSecret"); | 202 | + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKeyOrig", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); |
203 | byte[] result = createMqttClientAndPublish().getPayloadBytes(); | 203 | byte[] result = createMqttClientAndPublish().getPayloadBytes(); |
204 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); | 204 | JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); |
205 | Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); | 205 | Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); |
@@ -101,14 +101,14 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | @@ -101,14 +101,14 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | ||
101 | 101 | ||
102 | 102 | ||
103 | protected void processTestProvisioningDisabledDevice() throws Exception { | 103 | protected void processTestProvisioningDisabledDevice() throws Exception { |
104 | - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, DeviceProfileProvisionType.DISABLED, null, null); | 104 | + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
105 | ProvisionDeviceResponseMsg result = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); | 105 | ProvisionDeviceResponseMsg result = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); |
106 | Assert.assertNotNull(result); | 106 | Assert.assertNotNull(result); |
107 | Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), result.getStatus().toString()); | 107 | Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), result.getStatus().toString()); |
108 | } | 108 | } |
109 | 109 | ||
110 | protected void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { | 110 | protected void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { |
111 | - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 111 | + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
112 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); | 112 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); |
113 | 113 | ||
114 | Device createdDevice = deviceService.findDeviceByTenantIdAndName(savedTenant.getTenantId(), "Test Provision device"); | 114 | Device createdDevice = deviceService.findDeviceByTenantIdAndName(savedTenant.getTenantId(), "Test Provision device"); |
@@ -122,7 +122,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | @@ -122,7 +122,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | ||
122 | } | 122 | } |
123 | 123 | ||
124 | protected void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception { | 124 | protected void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception { |
125 | - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null,null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 125 | + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null,null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
126 | CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceTokenRequestMsg(ValidateDeviceTokenRequestMsg.newBuilder().setToken("test_token").build()).build(); | 126 | CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceTokenRequestMsg(ValidateDeviceTokenRequestMsg.newBuilder().setToken("test_token").build()).build(); |
127 | 127 | ||
128 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.ACCESS_TOKEN, requestCredentials)).getPayloadBytes()); | 128 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.ACCESS_TOKEN, requestCredentials)).getPayloadBytes()); |
@@ -140,7 +140,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | @@ -140,7 +140,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | ||
140 | } | 140 | } |
141 | 141 | ||
142 | protected void processTestProvisioningCreateNewDeviceWithCert() throws Exception { | 142 | protected void processTestProvisioningCreateNewDeviceWithCert() throws Exception { |
143 | - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 143 | + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
144 | CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceX509CertRequestMsg(ValidateDeviceX509CertRequestMsg.newBuilder().setHash("testHash").build()).build(); | 144 | CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceX509CertRequestMsg(ValidateDeviceX509CertRequestMsg.newBuilder().setHash("testHash").build()).build(); |
145 | 145 | ||
146 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.X509_CERTIFICATE, requestCredentials)).getPayloadBytes()); | 146 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.X509_CERTIFICATE, requestCredentials)).getPayloadBytes()); |
@@ -164,7 +164,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | @@ -164,7 +164,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | ||
164 | } | 164 | } |
165 | 165 | ||
166 | protected void processTestProvisioningCreateNewDeviceWithMqttBasic() throws Exception { | 166 | protected void processTestProvisioningCreateNewDeviceWithMqttBasic() throws Exception { |
167 | - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, "testProvisionKey", "testProvisionSecret"); | 167 | + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); |
168 | CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateBasicMqttCredRequestMsg( | 168 | CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateBasicMqttCredRequestMsg( |
169 | ValidateBasicMqttCredRequestMsg.newBuilder() | 169 | ValidateBasicMqttCredRequestMsg.newBuilder() |
170 | .setClientId("test_clientId") | 170 | .setClientId("test_clientId") |
@@ -195,7 +195,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | @@ -195,7 +195,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | ||
195 | } | 195 | } |
196 | 196 | ||
197 | protected void processTestProvisioningCheckPreProvisionedDevice() throws Exception { | 197 | protected void processTestProvisioningCheckPreProvisionedDevice() throws Exception { |
198 | - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, "testProvisionKey", "testProvisionSecret"); | 198 | + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); |
199 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); | 199 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); |
200 | 200 | ||
201 | DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(savedTenant.getTenantId(), savedDevice.getId()); | 201 | DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(savedTenant.getTenantId(), savedDevice.getId()); |
@@ -205,7 +205,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | @@ -205,7 +205,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI | ||
205 | } | 205 | } |
206 | 206 | ||
207 | protected void processTestProvisioningWithBadKeyDevice() throws Exception { | 207 | protected void processTestProvisioningWithBadKeyDevice() throws Exception { |
208 | - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, "testProvisionKeyOrig", "testProvisionSecret"); | 208 | + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKeyOrig", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); |
209 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); | 209 | ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); |
210 | Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.getStatus().toString()); | 210 | Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.getStatus().toString()); |
211 | } | 211 | } |
@@ -180,7 +180,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM | @@ -180,7 +180,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM | ||
180 | return message; | 180 | return message; |
181 | } | 181 | } |
182 | 182 | ||
183 | - private class TestMqttCallback implements MqttCallback { | 183 | + protected class TestMqttCallback implements MqttCallback { |
184 | 184 | ||
185 | private final MqttAsyncClient client; | 185 | private final MqttAsyncClient client; |
186 | private final CountDownLatch latch; | 186 | private final CountDownLatch latch; |
@@ -15,25 +15,60 @@ | @@ -15,25 +15,60 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.transport.mqtt.rpc; | 16 | package org.thingsboard.server.transport.mqtt.rpc; |
17 | 17 | ||
18 | +import com.github.os72.protobuf.dynamic.DynamicSchema; | ||
19 | +import com.google.protobuf.Descriptors; | ||
20 | +import com.google.protobuf.DynamicMessage; | ||
18 | import com.google.protobuf.InvalidProtocolBufferException; | 21 | import com.google.protobuf.InvalidProtocolBufferException; |
22 | +import com.squareup.wire.schema.internal.parser.ProtoFileElement; | ||
19 | import lombok.extern.slf4j.Slf4j; | 23 | import lombok.extern.slf4j.Slf4j; |
24 | +import org.eclipse.californium.core.CoapHandler; | ||
25 | +import org.eclipse.californium.core.CoapResponse; | ||
26 | +import org.eclipse.californium.core.coap.MediaTypeRegistry; | ||
20 | import org.eclipse.paho.client.mqttv3.MqttAsyncClient; | 27 | import org.eclipse.paho.client.mqttv3.MqttAsyncClient; |
21 | import org.eclipse.paho.client.mqttv3.MqttException; | 28 | import org.eclipse.paho.client.mqttv3.MqttException; |
22 | import org.eclipse.paho.client.mqttv3.MqttMessage; | 29 | import org.eclipse.paho.client.mqttv3.MqttMessage; |
30 | +import org.jetbrains.annotations.NotNull; | ||
23 | import org.junit.After; | 31 | import org.junit.After; |
32 | +import org.junit.Assert; | ||
24 | import org.junit.Before; | 33 | import org.junit.Before; |
25 | import org.junit.Test; | 34 | import org.junit.Test; |
35 | +import org.thingsboard.server.common.data.DeviceProfileProvisionType; | ||
26 | import org.thingsboard.server.common.data.TransportPayloadType; | 36 | import org.thingsboard.server.common.data.TransportPayloadType; |
37 | +import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; | ||
38 | +import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; | ||
27 | import org.thingsboard.server.common.data.device.profile.MqttTopics; | 39 | import org.thingsboard.server.common.data.device.profile.MqttTopics; |
40 | +import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; | ||
41 | +import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; | ||
28 | import org.thingsboard.server.gen.transport.TransportApiProtos; | 42 | import org.thingsboard.server.gen.transport.TransportApiProtos; |
29 | -import org.thingsboard.server.gen.transport.TransportProtos; | 43 | + |
44 | +import java.util.List; | ||
45 | +import java.util.concurrent.CountDownLatch; | ||
46 | +import java.util.concurrent.TimeUnit; | ||
47 | + | ||
48 | +import static org.junit.Assert.assertNotNull; | ||
49 | +import static org.junit.Assert.assertTrue; | ||
50 | +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
30 | 51 | ||
31 | @Slf4j | 52 | @Slf4j |
32 | public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { | 53 | public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { |
33 | 54 | ||
55 | + private static final String RPC_REQUEST_PROTO_SCHEMA = "syntax =\"proto3\";\n" + | ||
56 | + "package rpc;\n" + | ||
57 | + "\n" + | ||
58 | + "message RpcRequestMsg {\n" + | ||
59 | + " string method = 1;\n" + | ||
60 | + " int32 requestId = 2;\n" + | ||
61 | + " Params params = 3;\n" + | ||
62 | + "\n" + | ||
63 | + " message Params {\n" + | ||
64 | + " string pin = 1;\n" + | ||
65 | + " int32 value = 2;\n" + | ||
66 | + " }\n" + | ||
67 | + "}"; | ||
68 | + | ||
34 | @Before | 69 | @Before |
35 | public void beforeTest() throws Exception { | 70 | public void beforeTest() throws Exception { |
36 | - processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null); | 71 | + processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED); |
37 | } | 72 | } |
38 | 73 | ||
39 | @After | 74 | @After |
@@ -83,14 +118,55 @@ public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends Abst | @@ -83,14 +118,55 @@ public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends Abst | ||
83 | return builder.build(); | 118 | return builder.build(); |
84 | } | 119 | } |
85 | 120 | ||
121 | + protected void processTwoWayRpcTest() throws Exception { | ||
122 | + MqttAsyncClient client = getMqttAsyncClient(accessToken); | ||
123 | + client.subscribe(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC, 1); | ||
124 | + | ||
125 | + CountDownLatch latch = new CountDownLatch(1); | ||
126 | + TestMqttCallback callback = new TestMqttCallback(client, latch); | ||
127 | + client.setCallback(callback); | ||
128 | + | ||
129 | + Thread.sleep(1000); | ||
130 | + | ||
131 | + String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; | ||
132 | + String deviceId = savedDevice.getId().getId().toString(); | ||
133 | + | ||
134 | + String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | ||
135 | + String expected = "{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}"; | ||
136 | + latch.await(3, TimeUnit.SECONDS); | ||
137 | + Assert.assertEquals(expected, result); | ||
138 | + } | ||
139 | + | ||
86 | protected MqttMessage processMessageArrived(String requestTopic, MqttMessage mqttMessage) throws MqttException, InvalidProtocolBufferException { | 140 | protected MqttMessage processMessageArrived(String requestTopic, MqttMessage mqttMessage) throws MqttException, InvalidProtocolBufferException { |
87 | MqttMessage message = new MqttMessage(); | 141 | MqttMessage message = new MqttMessage(); |
88 | if (requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC)) { | 142 | if (requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC)) { |
89 | - TransportProtos.ToDeviceRpcResponseMsg toDeviceRpcResponseMsg = TransportProtos.ToDeviceRpcResponseMsg.newBuilder() | ||
90 | - .setPayload(DEVICE_RESPONSE) | ||
91 | - .setRequestId(0) | 143 | + ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = getProtoTransportPayloadConfiguration(); |
144 | + ProtoFileElement rpcRequestProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(RPC_REQUEST_PROTO_SCHEMA); | ||
145 | + DynamicSchema rpcRequestProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcRequestProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_REQUEST_PROTO_SCHEMA); | ||
146 | + | ||
147 | + byte[] requestPayload = mqttMessage.getPayload(); | ||
148 | + DynamicMessage.Builder rpcRequestMsg = rpcRequestProtoSchema.newMessageBuilder("RpcRequestMsg"); | ||
149 | + Descriptors.Descriptor rpcRequestMsgDescriptor = rpcRequestMsg.getDescriptorForType(); | ||
150 | + assertNotNull(rpcRequestMsgDescriptor); | ||
151 | + try { | ||
152 | + DynamicMessage dynamicMessage = DynamicMessage.parseFrom(rpcRequestMsgDescriptor, requestPayload); | ||
153 | + List<Descriptors.FieldDescriptor> fields = rpcRequestMsgDescriptor.getFields(); | ||
154 | + for (Descriptors.FieldDescriptor fieldDescriptor: fields) { | ||
155 | + assertTrue(dynamicMessage.hasField(fieldDescriptor)); | ||
156 | + } | ||
157 | + ProtoFileElement transportProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(DEVICE_RPC_RESPONSE_PROTO_SCHEMA); | ||
158 | + DynamicSchema rpcResponseProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(transportProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_RESPONSE_PROTO_SCHEMA); | ||
159 | + | ||
160 | + DynamicMessage.Builder rpcResponseBuilder = rpcResponseProtoSchema.newMessageBuilder("RpcResponseMsg"); | ||
161 | + Descriptors.Descriptor rpcResponseMsgDescriptor = rpcResponseBuilder.getDescriptorForType(); | ||
162 | + assertNotNull(rpcResponseMsgDescriptor); | ||
163 | + DynamicMessage rpcResponseMsg = rpcResponseBuilder | ||
164 | + .setField(rpcResponseMsgDescriptor.findFieldByName("payload"), DEVICE_RESPONSE) | ||
92 | .build(); | 165 | .build(); |
93 | - message.setPayload(toDeviceRpcResponseMsg.toByteArray()); | 166 | + message.setPayload(rpcResponseMsg.toByteArray()); |
167 | + } catch (InvalidProtocolBufferException e) { | ||
168 | + log.warn("Command Response Ack Error, Invalid response received: ", e); | ||
169 | + } | ||
94 | } else { | 170 | } else { |
95 | TransportApiProtos.GatewayDeviceRpcRequestMsg msg = TransportApiProtos.GatewayDeviceRpcRequestMsg.parseFrom(mqttMessage.getPayload()); | 171 | TransportApiProtos.GatewayDeviceRpcRequestMsg msg = TransportApiProtos.GatewayDeviceRpcRequestMsg.parseFrom(mqttMessage.getPayload()); |
96 | String deviceName = msg.getDeviceName(); | 172 | String deviceName = msg.getDeviceName(); |
@@ -105,6 +181,14 @@ public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends Abst | @@ -105,6 +181,14 @@ public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends Abst | ||
105 | return message; | 181 | return message; |
106 | } | 182 | } |
107 | 183 | ||
184 | + private ProtoTransportPayloadConfiguration getProtoTransportPayloadConfiguration() { | ||
185 | + DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration(); | ||
186 | + assertTrue(transportConfiguration instanceof MqttDeviceProfileTransportConfiguration); | ||
187 | + MqttDeviceProfileTransportConfiguration mqttTransportConfiguration = (MqttDeviceProfileTransportConfiguration) transportConfiguration; | ||
188 | + TransportPayloadTypeConfiguration transportPayloadTypeConfiguration = mqttTransportConfiguration.getTransportPayloadTypeConfiguration(); | ||
189 | + assertTrue(transportPayloadTypeConfiguration instanceof ProtoTransportPayloadConfiguration); | ||
190 | + return (ProtoTransportPayloadConfiguration) transportPayloadTypeConfiguration; | ||
191 | + } | ||
108 | 192 | ||
109 | 193 | ||
110 | } | 194 | } |
@@ -119,7 +119,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac | @@ -119,7 +119,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac | ||
119 | " }\n" + | 119 | " }\n" + |
120 | " }\n" + | 120 | " }\n" + |
121 | "}"; | 121 | "}"; |
122 | - super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, POST_DATA_TELEMETRY_TOPIC, null, schemaStr, null, DeviceProfileProvisionType.DISABLED, null, null); | 122 | + super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, POST_DATA_TELEMETRY_TOPIC, null, schemaStr, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
123 | List<String> expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); | 123 | List<String> expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); |
124 | DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration(); | 124 | DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration(); |
125 | assertTrue(transportConfiguration instanceof MqttDeviceProfileTransportConfiguration); | 125 | assertTrue(transportConfiguration instanceof MqttDeviceProfileTransportConfiguration); |
@@ -172,7 +172,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac | @@ -172,7 +172,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac | ||
172 | 172 | ||
173 | @Test | 173 | @Test |
174 | public void testPushMqttTelemetryGateway() throws Exception { | 174 | public void testPushMqttTelemetryGateway() throws Exception { |
175 | - super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, null, null, null, null, DeviceProfileProvisionType.DISABLED, null, null); | 175 | + super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
176 | TransportApiProtos.GatewayTelemetryMsg.Builder gatewayTelemetryMsgProtoBuilder = TransportApiProtos.GatewayTelemetryMsg.newBuilder(); | 176 | TransportApiProtos.GatewayTelemetryMsg.Builder gatewayTelemetryMsgProtoBuilder = TransportApiProtos.GatewayTelemetryMsg.newBuilder(); |
177 | List<String> expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); | 177 | List<String> expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); |
178 | String deviceName1 = "Device A"; | 178 | String deviceName1 = "Device A"; |
@@ -186,7 +186,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac | @@ -186,7 +186,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac | ||
186 | 186 | ||
187 | @Test | 187 | @Test |
188 | public void testGatewayConnect() throws Exception { | 188 | public void testGatewayConnect() throws Exception { |
189 | - super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, POST_DATA_TELEMETRY_TOPIC, null, null, null, DeviceProfileProvisionType.DISABLED, null, null); | 189 | + super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, POST_DATA_TELEMETRY_TOPIC, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); |
190 | String deviceName = "Device A"; | 190 | String deviceName = "Device A"; |
191 | TransportApiProtos.ConnectMsg connectMsgProto = getConnectProto(deviceName); | 191 | TransportApiProtos.ConnectMsg connectMsgProto = getConnectProto(deviceName); |
192 | MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); | 192 | MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); |
@@ -102,4 +102,6 @@ public interface DeviceService { | @@ -102,4 +102,6 @@ public interface DeviceService { | ||
102 | PageData<Device> findDevicesByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, PageLink pageLink); | 102 | PageData<Device> findDevicesByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, PageLink pageLink); |
103 | 103 | ||
104 | PageData<Device> findDevicesByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, PageLink pageLink); | 104 | PageData<Device> findDevicesByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, PageLink pageLink); |
105 | + | ||
106 | + long countByTenantId(TenantId tenantId); | ||
105 | } | 107 | } |
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.event; | @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.event; | ||
17 | 17 | ||
18 | import com.google.common.util.concurrent.ListenableFuture; | 18 | import com.google.common.util.concurrent.ListenableFuture; |
19 | import org.thingsboard.server.common.data.Event; | 19 | import org.thingsboard.server.common.data.Event; |
20 | +import org.thingsboard.server.common.data.event.EventFilter; | ||
20 | import org.thingsboard.server.common.data.id.EntityId; | 21 | import org.thingsboard.server.common.data.id.EntityId; |
21 | import org.thingsboard.server.common.data.id.TenantId; | 22 | import org.thingsboard.server.common.data.id.TenantId; |
22 | import org.thingsboard.server.common.data.page.PageData; | 23 | import org.thingsboard.server.common.data.page.PageData; |
@@ -41,6 +42,8 @@ public interface EventService { | @@ -41,6 +42,8 @@ public interface EventService { | ||
41 | 42 | ||
42 | List<Event> findLatestEvents(TenantId tenantId, EntityId entityId, String eventType, int limit); | 43 | List<Event> findLatestEvents(TenantId tenantId, EntityId entityId, String eventType, int limit); |
43 | 44 | ||
45 | + PageData<Event> findEventsByFilter(TenantId tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink); | ||
46 | + | ||
44 | void removeEvents(TenantId tenantId, EntityId entityId); | 47 | void removeEvents(TenantId tenantId, EntityId entityId); |
45 | 48 | ||
46 | } | 49 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.resource; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.data.ResourceType; | ||
19 | +import org.thingsboard.server.common.data.TbResource; | ||
20 | +import org.thingsboard.server.common.data.TbResourceInfo; | ||
21 | +import org.thingsboard.server.common.data.id.TbResourceId; | ||
22 | +import org.thingsboard.server.common.data.id.TenantId; | ||
23 | +import org.thingsboard.server.common.data.page.PageData; | ||
24 | +import org.thingsboard.server.common.data.page.PageLink; | ||
25 | + | ||
26 | +import java.util.List; | ||
27 | + | ||
28 | +public interface ResourceService { | ||
29 | + TbResource saveResource(TbResource resource); | ||
30 | + | ||
31 | + TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); | ||
32 | + | ||
33 | + TbResource findResourceById(TenantId tenantId, TbResourceId resourceId); | ||
34 | + | ||
35 | + TbResourceInfo findResourceInfoById(TenantId tenantId, TbResourceId resourceId); | ||
36 | + | ||
37 | + PageData<TbResourceInfo> findAllTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink); | ||
38 | + | ||
39 | + PageData<TbResourceInfo> findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink); | ||
40 | + | ||
41 | + List<TbResource> findTenantResourcesByResourceTypeAndObjectIds(TenantId tenantId, ResourceType lwm2mModel, String[] objectIds); | ||
42 | + | ||
43 | + PageData<TbResource> findTenantResourcesByResourceTypeAndPageLink(TenantId tenantId, ResourceType lwm2mModel, PageLink pageLink); | ||
44 | + | ||
45 | + void deleteResource(TenantId tenantId, TbResourceId resourceId); | ||
46 | + | ||
47 | + void deleteResourcesByTenantId(TenantId tenantId); | ||
48 | + | ||
49 | + | ||
50 | +} |
@@ -43,7 +43,7 @@ public interface RuleChainService { | @@ -43,7 +43,7 @@ public interface RuleChainService { | ||
43 | 43 | ||
44 | boolean setRootRuleChain(TenantId tenantId, RuleChainId ruleChainId); | 44 | boolean setRootRuleChain(TenantId tenantId, RuleChainId ruleChainId); |
45 | 45 | ||
46 | - RuleChainMetaData saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData); | 46 | + boolean saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData); |
47 | 47 | ||
48 | RuleChainMetaData loadRuleChainMetaData(TenantId tenantId, RuleChainId ruleChainId); | 48 | RuleChainMetaData loadRuleChainMetaData(TenantId tenantId, RuleChainId ruleChainId); |
49 | 49 |
@@ -91,10 +91,6 @@ | @@ -91,10 +91,6 @@ | ||
91 | <groupId>org.apache.commons</groupId> | 91 | <groupId>org.apache.commons</groupId> |
92 | <artifactId>commons-lang3</artifactId> | 92 | <artifactId>commons-lang3</artifactId> |
93 | </dependency> | 93 | </dependency> |
94 | - <dependency> | ||
95 | - <groupId>org.eclipse.leshan</groupId> | ||
96 | - <artifactId>leshan-core</artifactId> | ||
97 | - </dependency> | ||
98 | </dependencies> | 94 | </dependencies> |
99 | 95 | ||
100 | <build> | 96 | <build> |
@@ -19,14 +19,18 @@ import com.fasterxml.jackson.annotation.JsonProperty; | @@ -19,14 +19,18 @@ import com.fasterxml.jackson.annotation.JsonProperty; | ||
19 | import org.thingsboard.server.common.data.id.CustomerId; | 19 | import org.thingsboard.server.common.data.id.CustomerId; |
20 | import org.thingsboard.server.common.data.id.DashboardId; | 20 | import org.thingsboard.server.common.data.id.DashboardId; |
21 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
22 | +import org.thingsboard.server.common.data.validation.NoXss; | ||
22 | 23 | ||
24 | +import javax.validation.Valid; | ||
23 | import java.util.HashSet; | 25 | import java.util.HashSet; |
24 | import java.util.Set; | 26 | import java.util.Set; |
25 | 27 | ||
26 | public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId { | 28 | public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId { |
27 | 29 | ||
28 | private TenantId tenantId; | 30 | private TenantId tenantId; |
31 | + @NoXss | ||
29 | private String title; | 32 | private String title; |
33 | + @Valid | ||
30 | private Set<ShortCustomerInfo> assignedCustomers; | 34 | private Set<ShortCustomerInfo> assignedCustomers; |
31 | 35 | ||
32 | public DashboardInfo() { | 36 | public DashboardInfo() { |
@@ -19,6 +19,7 @@ import lombok.AllArgsConstructor; | @@ -19,6 +19,7 @@ import lombok.AllArgsConstructor; | ||
19 | import lombok.Getter; | 19 | import lombok.Getter; |
20 | import lombok.Setter; | 20 | import lombok.Setter; |
21 | import org.thingsboard.server.common.data.id.CustomerId; | 21 | import org.thingsboard.server.common.data.id.CustomerId; |
22 | +import org.thingsboard.server.common.data.validation.NoXss; | ||
22 | 23 | ||
23 | /** | 24 | /** |
24 | * Created by igor on 2/27/18. | 25 | * Created by igor on 2/27/18. |
@@ -31,6 +32,7 @@ public class ShortCustomerInfo { | @@ -31,6 +32,7 @@ public class ShortCustomerInfo { | ||
31 | private CustomerId customerId; | 32 | private CustomerId customerId; |
32 | 33 | ||
33 | @Getter @Setter | 34 | @Getter @Setter |
35 | + @NoXss | ||
34 | private String title; | 36 | private String title; |
35 | 37 | ||
36 | @Getter @Setter | 38 | @Getter @Setter |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data; | ||
17 | + | ||
18 | +public class StringUtils { | ||
19 | + | ||
20 | + public static boolean isEmpty(String source) { | ||
21 | + return source == null || source.isEmpty(); | ||
22 | + } | ||
23 | + | ||
24 | + public static boolean isNotEmpty(String source) { | ||
25 | + return source != null && !source.isEmpty(); | ||
26 | + } | ||
27 | +} |
@@ -19,6 +19,7 @@ import lombok.Data; | @@ -19,6 +19,7 @@ import lombok.Data; | ||
19 | import lombok.EqualsAndHashCode; | 19 | import lombok.EqualsAndHashCode; |
20 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
21 | import org.thingsboard.server.common.data.id.TbResourceId; | 21 | import org.thingsboard.server.common.data.id.TbResourceId; |
22 | +import org.thingsboard.server.common.data.validation.NoXss; | ||
22 | 23 | ||
23 | @Slf4j | 24 | @Slf4j |
24 | @Data | 25 | @Data |
@@ -27,6 +28,7 @@ public class TbResource extends TbResourceInfo { | @@ -27,6 +28,7 @@ public class TbResource extends TbResourceInfo { | ||
27 | 28 | ||
28 | private static final long serialVersionUID = 7379609705527272306L; | 29 | private static final long serialVersionUID = 7379609705527272306L; |
29 | 30 | ||
31 | + @NoXss | ||
30 | private String fileName; | 32 | private String fileName; |
31 | 33 | ||
32 | private String data; | 34 | private String data; |
@@ -20,6 +20,7 @@ import lombok.EqualsAndHashCode; | @@ -20,6 +20,7 @@ import lombok.EqualsAndHashCode; | ||
20 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
21 | import org.thingsboard.server.common.data.id.TbResourceId; | 21 | import org.thingsboard.server.common.data.id.TbResourceId; |
22 | import org.thingsboard.server.common.data.id.TenantId; | 22 | import org.thingsboard.server.common.data.id.TenantId; |
23 | +import org.thingsboard.server.common.data.validation.NoXss; | ||
23 | 24 | ||
24 | @Slf4j | 25 | @Slf4j |
25 | @Data | 26 | @Data |
@@ -27,6 +28,7 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -27,6 +28,7 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
27 | public class TbResourceInfo extends SearchTextBased<TbResourceId> implements HasTenantId { | 28 | public class TbResourceInfo extends SearchTextBased<TbResourceId> implements HasTenantId { |
28 | 29 | ||
29 | private TenantId tenantId; | 30 | private TenantId tenantId; |
31 | + @NoXss | ||
30 | private String title; | 32 | private String title; |
31 | private ResourceType resourceType; | 33 | private ResourceType resourceType; |
32 | private String resourceKey; | 34 | private String resourceKey; |
@@ -19,11 +19,8 @@ import lombok.AllArgsConstructor; | @@ -19,11 +19,8 @@ import lombok.AllArgsConstructor; | ||
19 | import lombok.Builder; | 19 | import lombok.Builder; |
20 | import lombok.Data; | 20 | import lombok.Data; |
21 | import org.thingsboard.server.common.data.id.EntityId; | 21 | import org.thingsboard.server.common.data.id.EntityId; |
22 | -import org.thingsboard.server.common.data.id.TenantId; | ||
23 | import org.thingsboard.server.common.data.page.TimePageLink; | 22 | import org.thingsboard.server.common.data.page.TimePageLink; |
24 | 23 | ||
25 | -import java.util.UUID; | ||
26 | - | ||
27 | /** | 24 | /** |
28 | * Created by ashvayka on 11.05.17. | 25 | * Created by ashvayka on 11.05.17. |
29 | */ | 26 | */ |
@@ -37,6 +34,5 @@ public class AlarmQuery { | @@ -37,6 +34,5 @@ public class AlarmQuery { | ||
37 | private AlarmSearchStatus searchStatus; | 34 | private AlarmSearchStatus searchStatus; |
38 | private AlarmStatus status; | 35 | private AlarmStatus status; |
39 | private Boolean fetchOriginator; | 36 | private Boolean fetchOriginator; |
40 | - private UUID idOffset; | ||
41 | 37 | ||
42 | } | 38 | } |
@@ -25,6 +25,7 @@ import java.util.List; | @@ -25,6 +25,7 @@ import java.util.List; | ||
25 | public class DeviceProfileData implements Serializable { | 25 | public class DeviceProfileData implements Serializable { |
26 | 26 | ||
27 | private DeviceProfileConfiguration configuration; | 27 | private DeviceProfileConfiguration configuration; |
28 | + @Valid | ||
28 | private DeviceProfileTransportConfiguration transportConfiguration; | 29 | private DeviceProfileTransportConfiguration transportConfiguration; |
29 | private DeviceProfileProvisionConfiguration provisionConfiguration; | 30 | private DeviceProfileProvisionConfiguration provisionConfiguration; |
30 | @Valid | 31 | @Valid |
@@ -17,11 +17,14 @@ package org.thingsboard.server.common.data.device.profile; | @@ -17,11 +17,14 @@ package org.thingsboard.server.common.data.device.profile; | ||
17 | 17 | ||
18 | import lombok.Data; | 18 | import lombok.Data; |
19 | import org.thingsboard.server.common.data.DeviceTransportType; | 19 | import org.thingsboard.server.common.data.DeviceTransportType; |
20 | +import org.thingsboard.server.common.data.validation.NoXss; | ||
20 | 21 | ||
21 | @Data | 22 | @Data |
22 | public class MqttDeviceProfileTransportConfiguration implements DeviceProfileTransportConfiguration { | 23 | public class MqttDeviceProfileTransportConfiguration implements DeviceProfileTransportConfiguration { |
23 | 24 | ||
25 | + @NoXss | ||
24 | private String deviceTelemetryTopic = MqttTopics.DEVICE_TELEMETRY_TOPIC; | 26 | private String deviceTelemetryTopic = MqttTopics.DEVICE_TELEMETRY_TOPIC; |
27 | + @NoXss | ||
25 | private String deviceAttributesTopic = MqttTopics.DEVICE_ATTRIBUTES_TOPIC; | 28 | private String deviceAttributesTopic = MqttTopics.DEVICE_ATTRIBUTES_TOPIC; |
26 | private TransportPayloadTypeConfiguration transportPayloadTypeConfiguration; | 29 | private TransportPayloadTypeConfiguration transportPayloadTypeConfiguration; |
27 | 30 |
@@ -15,7 +15,6 @@ | @@ -15,7 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.common.data.device.profile; | 16 | package org.thingsboard.server.common.data.device.profile; |
17 | 17 | ||
18 | -import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | import com.github.os72.protobuf.dynamic.DynamicSchema; | 18 | import com.github.os72.protobuf.dynamic.DynamicSchema; |
20 | import com.github.os72.protobuf.dynamic.EnumDefinition; | 19 | import com.github.os72.protobuf.dynamic.EnumDefinition; |
21 | import com.github.os72.protobuf.dynamic.MessageDefinition; | 20 | import com.github.os72.protobuf.dynamic.MessageDefinition; |
@@ -46,9 +45,13 @@ public class ProtoTransportPayloadConfiguration implements TransportPayloadTypeC | @@ -46,9 +45,13 @@ public class ProtoTransportPayloadConfiguration implements TransportPayloadTypeC | ||
46 | public static final Location LOCATION = new Location("", "", -1, -1); | 45 | public static final Location LOCATION = new Location("", "", -1, -1); |
47 | public static final String ATTRIBUTES_PROTO_SCHEMA = "attributes proto schema"; | 46 | public static final String ATTRIBUTES_PROTO_SCHEMA = "attributes proto schema"; |
48 | public static final String TELEMETRY_PROTO_SCHEMA = "telemetry proto schema"; | 47 | public static final String TELEMETRY_PROTO_SCHEMA = "telemetry proto schema"; |
48 | + public static final String RPC_RESPONSE_PROTO_SCHEMA = "rpc response proto schema"; | ||
49 | + public static final String RPC_REQUEST_PROTO_SCHEMA = "rpc request proto schema"; | ||
49 | 50 | ||
50 | private String deviceTelemetryProtoSchema; | 51 | private String deviceTelemetryProtoSchema; |
51 | private String deviceAttributesProtoSchema; | 52 | private String deviceAttributesProtoSchema; |
53 | + private String deviceRpcRequestProtoSchema; | ||
54 | + private String deviceRpcResponseProtoSchema; | ||
52 | 55 | ||
53 | @Override | 56 | @Override |
54 | public TransportPayloadType getTransportPayloadType() { | 57 | public TransportPayloadType getTransportPayloadType() { |
@@ -63,13 +66,45 @@ public class ProtoTransportPayloadConfiguration implements TransportPayloadTypeC | @@ -63,13 +66,45 @@ public class ProtoTransportPayloadConfiguration implements TransportPayloadTypeC | ||
63 | return getDescriptor(deviceAttributesProtoSchema, ATTRIBUTES_PROTO_SCHEMA); | 66 | return getDescriptor(deviceAttributesProtoSchema, ATTRIBUTES_PROTO_SCHEMA); |
64 | } | 67 | } |
65 | 68 | ||
69 | + public Descriptors.Descriptor getRpcResponseDynamicMessageDescriptor(String deviceRpcResponseProtoSchema) { | ||
70 | + return getDescriptor(deviceRpcResponseProtoSchema, RPC_RESPONSE_PROTO_SCHEMA); | ||
71 | + } | ||
72 | + | ||
73 | + public DynamicMessage.Builder getRpcRequestDynamicMessageBuilder(String deviceRpcRequestProtoSchema) { | ||
74 | + return getDynamicMessageBuilder(deviceRpcRequestProtoSchema, RPC_REQUEST_PROTO_SCHEMA); | ||
75 | + } | ||
76 | + | ||
77 | + public String getDeviceRpcResponseProtoSchema() { | ||
78 | + if (!isEmptyStr(deviceRpcResponseProtoSchema)) { | ||
79 | + return deviceRpcResponseProtoSchema; | ||
80 | + } else { | ||
81 | + return "syntax =\"proto3\";\n" + | ||
82 | + "package rpc;\n" + | ||
83 | + "\n" + | ||
84 | + "message RpcResponseMsg {\n" + | ||
85 | + " string payload = 1;\n" + | ||
86 | + "}"; | ||
87 | + } | ||
88 | + } | ||
89 | + | ||
90 | + public String getDeviceRpcRequestProtoSchema() { | ||
91 | + if (!isEmptyStr(deviceRpcRequestProtoSchema)) { | ||
92 | + return deviceRpcRequestProtoSchema; | ||
93 | + } else { | ||
94 | + return "syntax =\"proto3\";\n" + | ||
95 | + "package rpc;\n" + | ||
96 | + "\n" + | ||
97 | + "message RpcRequestMsg {\n" + | ||
98 | + " string method = 1;\n" + | ||
99 | + " int32 requestId = 2;\n" + | ||
100 | + " string params = 3;\n" + | ||
101 | + "}"; | ||
102 | + } | ||
103 | + } | ||
104 | + | ||
66 | private Descriptors.Descriptor getDescriptor(String protoSchema, String schemaName) { | 105 | private Descriptors.Descriptor getDescriptor(String protoSchema, String schemaName) { |
67 | try { | 106 | try { |
68 | - ProtoFileElement protoFileElement = getTransportProtoSchema(protoSchema); | ||
69 | - DynamicSchema dynamicSchema = getDynamicSchema(protoFileElement, schemaName); | ||
70 | - String lastMsgName = getMessageTypes(protoFileElement.getTypes()).stream() | ||
71 | - .map(MessageElement::getName).reduce((previous, last) -> last).get(); | ||
72 | - DynamicMessage.Builder builder = dynamicSchema.newMessageBuilder(lastMsgName); | 107 | + DynamicMessage.Builder builder = getDynamicMessageBuilder(protoSchema, schemaName); |
73 | return builder.getDescriptorForType(); | 108 | return builder.getDescriptorForType(); |
74 | } catch (Exception e) { | 109 | } catch (Exception e) { |
75 | log.warn("Failed to get Message Descriptor due to {}", e.getMessage()); | 110 | log.warn("Failed to get Message Descriptor due to {}", e.getMessage()); |
@@ -77,6 +112,14 @@ public class ProtoTransportPayloadConfiguration implements TransportPayloadTypeC | @@ -77,6 +112,14 @@ public class ProtoTransportPayloadConfiguration implements TransportPayloadTypeC | ||
77 | } | 112 | } |
78 | } | 113 | } |
79 | 114 | ||
115 | + public DynamicMessage.Builder getDynamicMessageBuilder(String protoSchema, String schemaName) { | ||
116 | + ProtoFileElement protoFileElement = getTransportProtoSchema(protoSchema); | ||
117 | + DynamicSchema dynamicSchema = getDynamicSchema(protoFileElement, schemaName); | ||
118 | + String lastMsgName = getMessageTypes(protoFileElement.getTypes()).stream() | ||
119 | + .map(MessageElement::getName).reduce((previous, last) -> last).get(); | ||
120 | + return dynamicSchema.newMessageBuilder(lastMsgName); | ||
121 | + } | ||
122 | + | ||
80 | public DynamicSchema getDynamicSchema(ProtoFileElement protoFileElement, String schemaName) { | 123 | public DynamicSchema getDynamicSchema(ProtoFileElement protoFileElement, String schemaName) { |
81 | DynamicSchema.Builder schemaBuilder = DynamicSchema.newBuilder(); | 124 | DynamicSchema.Builder schemaBuilder = DynamicSchema.newBuilder(); |
82 | schemaBuilder.setName(schemaName); | 125 | schemaBuilder.setName(schemaName); |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.event; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.StringUtils; | ||
20 | + | ||
21 | +@Data | ||
22 | +public abstract class DebugEvent implements EventFilter { | ||
23 | + | ||
24 | + private String msgDirectionType; | ||
25 | + private String server; | ||
26 | + private String dataSearch; | ||
27 | + private String metadataSearch; | ||
28 | + private String entityName; | ||
29 | + private String relationType; | ||
30 | + private String entityId; | ||
31 | + private String msgType; | ||
32 | + private boolean isError; | ||
33 | + private String error; | ||
34 | + | ||
35 | + public void setIsError(boolean isError) { | ||
36 | + this.isError = isError; | ||
37 | + } | ||
38 | + | ||
39 | + @Override | ||
40 | + public boolean hasFilterForJsonBody() { | ||
41 | + return !StringUtils.isEmpty(msgDirectionType) || !StringUtils.isEmpty(server) || !StringUtils.isEmpty(dataSearch) || !StringUtils.isEmpty(metadataSearch) | ||
42 | + || !StringUtils.isEmpty(entityName) || !StringUtils.isEmpty(relationType) || !StringUtils.isEmpty(entityId) || !StringUtils.isEmpty(msgType) || !StringUtils.isEmpty(error) || isError; | ||
43 | + } | ||
44 | + | ||
45 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/event/DebugRuleChainEventFilter.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.event; | ||
17 | + | ||
18 | +public class DebugRuleChainEventFilter extends DebugEvent { | ||
19 | + @Override | ||
20 | + public EventType getEventType() { | ||
21 | + return EventType.DEBUG_RULE_CHAIN; | ||
22 | + } | ||
23 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/event/DebugRuleNodeEventFilter.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.event; | ||
17 | + | ||
18 | +public class DebugRuleNodeEventFilter extends DebugEvent { | ||
19 | + @Override | ||
20 | + public EventType getEventType() { | ||
21 | + return EventType.DEBUG_RULE_NODE; | ||
22 | + } | ||
23 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.event; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.StringUtils; | ||
20 | + | ||
21 | +@Data | ||
22 | +public class ErrorEventFilter implements EventFilter { | ||
23 | + private String server; | ||
24 | + private String method; | ||
25 | + private String error; | ||
26 | + | ||
27 | + @Override | ||
28 | + public EventType getEventType() { | ||
29 | + return EventType.ERROR; | ||
30 | + } | ||
31 | + | ||
32 | + @Override | ||
33 | + public boolean hasFilterForJsonBody() { | ||
34 | + return !StringUtils.isEmpty(server) || !StringUtils.isEmpty(method) || !StringUtils.isEmpty(error); | ||
35 | + } | ||
36 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.event; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
20 | +import com.fasterxml.jackson.annotation.JsonSubTypes; | ||
21 | +import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
22 | + | ||
23 | +@JsonTypeInfo( | ||
24 | + use = JsonTypeInfo.Id.NAME, | ||
25 | + include = JsonTypeInfo.As.PROPERTY, | ||
26 | + property = "eventType") | ||
27 | +@JsonSubTypes({ | ||
28 | + @JsonSubTypes.Type(value = DebugRuleNodeEventFilter.class, name = "DEBUG_RULE_NODE"), | ||
29 | + @JsonSubTypes.Type(value = DebugRuleChainEventFilter.class, name = "DEBUG_RULE_CHAIN"), | ||
30 | + @JsonSubTypes.Type(value = ErrorEventFilter.class, name = "ERROR"), | ||
31 | + @JsonSubTypes.Type(value = LifeCycleEventFilter.class, name = "LC_EVENT"), | ||
32 | + @JsonSubTypes.Type(value = StatisticsEventFilter.class, name = "STATS") | ||
33 | +}) | ||
34 | +public interface EventFilter { | ||
35 | + @JsonIgnore | ||
36 | + EventType getEventType(); | ||
37 | + | ||
38 | + boolean hasFilterForJsonBody(); | ||
39 | + | ||
40 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/event/EventType.java
renamed from
ui-ngx/src/app/shared/components/time/quick-time-interval.component.scss
@@ -13,7 +13,8 @@ | @@ -13,7 +13,8 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | +package org.thingsboard.server.common.data.event; | ||
16 | 17 | ||
17 | -:host { | ||
18 | - min-width: 364px; | ||
19 | -} | 18 | +public enum EventType { |
19 | + ERROR, LC_EVENT, STATS, DEBUG_RULE_NODE, DEBUG_RULE_CHAIN | ||
20 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.event; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.StringUtils; | ||
20 | + | ||
21 | +@Data | ||
22 | +public class LifeCycleEventFilter implements EventFilter { | ||
23 | + private String server; | ||
24 | + private String event; | ||
25 | + private String status; | ||
26 | + private String error; | ||
27 | + | ||
28 | + @Override | ||
29 | + public EventType getEventType() { | ||
30 | + return EventType.LC_EVENT; | ||
31 | + } | ||
32 | + | ||
33 | + @Override | ||
34 | + public boolean hasFilterForJsonBody() { | ||
35 | + return !StringUtils.isEmpty(server) || !StringUtils.isEmpty(event) || !StringUtils.isEmpty(status) || !StringUtils.isEmpty(error); | ||
36 | + } | ||
37 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.event; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.StringUtils; | ||
20 | + | ||
21 | +@Data | ||
22 | +public class StatisticsEventFilter implements EventFilter { | ||
23 | + private String server; | ||
24 | + private Integer messagesProcessed; | ||
25 | + private Integer errorsOccurred; | ||
26 | + | ||
27 | + @Override | ||
28 | + public EventType getEventType() { | ||
29 | + return EventType.STATS; | ||
30 | + } | ||
31 | + | ||
32 | + @Override | ||
33 | + public boolean hasFilterForJsonBody() { | ||
34 | + return !StringUtils.isEmpty(server) || (messagesProcessed != null && messagesProcessed > 0) || (errorsOccurred != null && errorsOccurred > 0); | ||
35 | + } | ||
36 | +} |
@@ -15,10 +15,16 @@ | @@ -15,10 +15,16 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.common.data.tenant.profile; | 16 | package org.thingsboard.server.common.data.tenant.profile; |
17 | 17 | ||
18 | +import lombok.AllArgsConstructor; | ||
19 | +import lombok.Builder; | ||
18 | import lombok.Data; | 20 | import lombok.Data; |
21 | +import lombok.NoArgsConstructor; | ||
19 | import org.thingsboard.server.common.data.ApiUsageRecordKey; | 22 | import org.thingsboard.server.common.data.ApiUsageRecordKey; |
20 | import org.thingsboard.server.common.data.TenantProfileType; | 23 | import org.thingsboard.server.common.data.TenantProfileType; |
21 | 24 | ||
25 | +@AllArgsConstructor | ||
26 | +@NoArgsConstructor | ||
27 | +@Builder | ||
22 | @Data | 28 | @Data |
23 | public class DefaultTenantProfileConfiguration implements TenantProfileConfiguration { | 29 | public class DefaultTenantProfileConfiguration implements TenantProfileConfiguration { |
24 | 30 |
@@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.BaseData; | @@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.BaseData; | ||
20 | import org.thingsboard.server.common.data.HasTenantId; | 20 | import org.thingsboard.server.common.data.HasTenantId; |
21 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
22 | import org.thingsboard.server.common.data.id.WidgetTypeId; | 22 | import org.thingsboard.server.common.data.id.WidgetTypeId; |
23 | +import org.thingsboard.server.common.data.validation.NoXss; | ||
23 | 24 | ||
24 | @Data | 25 | @Data |
25 | public class BaseWidgetType extends BaseData<WidgetTypeId> implements HasTenantId { | 26 | public class BaseWidgetType extends BaseData<WidgetTypeId> implements HasTenantId { |
@@ -27,8 +28,11 @@ public class BaseWidgetType extends BaseData<WidgetTypeId> implements HasTenantI | @@ -27,8 +28,11 @@ public class BaseWidgetType extends BaseData<WidgetTypeId> implements HasTenantI | ||
27 | private static final long serialVersionUID = 8388684344603660756L; | 28 | private static final long serialVersionUID = 8388684344603660756L; |
28 | 29 | ||
29 | private TenantId tenantId; | 30 | private TenantId tenantId; |
31 | + @NoXss | ||
30 | private String bundleAlias; | 32 | private String bundleAlias; |
33 | + @NoXss | ||
31 | private String alias; | 34 | private String alias; |
35 | + @NoXss | ||
32 | private String name; | 36 | private String name; |
33 | 37 | ||
34 | public BaseWidgetType() { | 38 | public BaseWidgetType() { |
@@ -15,14 +15,15 @@ | @@ -15,14 +15,15 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.common.data.widget; | 16 | package org.thingsboard.server.common.data.widget; |
17 | 17 | ||
18 | -import com.fasterxml.jackson.databind.JsonNode; | ||
19 | import lombok.Data; | 18 | import lombok.Data; |
20 | import org.thingsboard.server.common.data.id.WidgetTypeId; | 19 | import org.thingsboard.server.common.data.id.WidgetTypeId; |
20 | +import org.thingsboard.server.common.data.validation.NoXss; | ||
21 | 21 | ||
22 | @Data | 22 | @Data |
23 | public class WidgetTypeDetails extends WidgetType { | 23 | public class WidgetTypeDetails extends WidgetType { |
24 | 24 | ||
25 | private String image; | 25 | private String image; |
26 | + @NoXss | ||
26 | private String description; | 27 | private String description; |
27 | 28 | ||
28 | public WidgetTypeDetails() { | 29 | public WidgetTypeDetails() { |
@@ -17,12 +17,15 @@ package org.thingsboard.server.common.data.widget; | @@ -17,12 +17,15 @@ package org.thingsboard.server.common.data.widget; | ||
17 | 17 | ||
18 | import lombok.Data; | 18 | import lombok.Data; |
19 | import org.thingsboard.server.common.data.id.WidgetTypeId; | 19 | import org.thingsboard.server.common.data.id.WidgetTypeId; |
20 | +import org.thingsboard.server.common.data.validation.NoXss; | ||
20 | 21 | ||
21 | @Data | 22 | @Data |
22 | public class WidgetTypeInfo extends BaseWidgetType { | 23 | public class WidgetTypeInfo extends BaseWidgetType { |
23 | 24 | ||
24 | private String image; | 25 | private String image; |
26 | + @NoXss | ||
25 | private String description; | 27 | private String description; |
28 | + @NoXss | ||
26 | private String widgetType; | 29 | private String widgetType; |
27 | 30 | ||
28 | public WidgetTypeInfo() { | 31 | public WidgetTypeInfo() { |
@@ -19,6 +19,7 @@ import org.thingsboard.server.common.data.HasTenantId; | @@ -19,6 +19,7 @@ import org.thingsboard.server.common.data.HasTenantId; | ||
19 | import org.thingsboard.server.common.data.SearchTextBased; | 19 | import org.thingsboard.server.common.data.SearchTextBased; |
20 | import org.thingsboard.server.common.data.id.TenantId; | 20 | import org.thingsboard.server.common.data.id.TenantId; |
21 | import org.thingsboard.server.common.data.id.WidgetsBundleId; | 21 | import org.thingsboard.server.common.data.id.WidgetsBundleId; |
22 | +import org.thingsboard.server.common.data.validation.NoXss; | ||
22 | 23 | ||
23 | import java.util.Arrays; | 24 | import java.util.Arrays; |
24 | 25 | ||
@@ -27,9 +28,12 @@ public class WidgetsBundle extends SearchTextBased<WidgetsBundleId> implements H | @@ -27,9 +28,12 @@ public class WidgetsBundle extends SearchTextBased<WidgetsBundleId> implements H | ||
27 | private static final long serialVersionUID = -7627368878362410489L; | 28 | private static final long serialVersionUID = -7627368878362410489L; |
28 | 29 | ||
29 | private TenantId tenantId; | 30 | private TenantId tenantId; |
31 | + @NoXss | ||
30 | private String alias; | 32 | private String alias; |
33 | + @NoXss | ||
31 | private String title; | 34 | private String title; |
32 | private String image; | 35 | private String image; |
36 | + @NoXss | ||
33 | private String description; | 37 | private String description; |
34 | 38 | ||
35 | public WidgetsBundle() { | 39 | public WidgetsBundle() { |
@@ -113,6 +113,10 @@ | @@ -113,6 +113,10 @@ | ||
113 | <artifactId>protobuf-java</artifactId> | 113 | <artifactId>protobuf-java</artifactId> |
114 | </dependency> | 114 | </dependency> |
115 | <dependency> | 115 | <dependency> |
116 | + <groupId>com.google.protobuf</groupId> | ||
117 | + <artifactId>protobuf-java-util</artifactId> | ||
118 | + </dependency> | ||
119 | + <dependency> | ||
116 | <groupId>org.apache.curator</groupId> | 120 | <groupId>org.apache.curator</groupId> |
117 | <artifactId>curator-recipes</artifactId> | 121 | <artifactId>curator-recipes</artifactId> |
118 | </dependency> | 122 | </dependency> |
@@ -21,22 +21,28 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | @@ -21,22 +21,28 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | ||
21 | import org.thingsboard.server.queue.TbQueueConsumer; | 21 | import org.thingsboard.server.queue.TbQueueConsumer; |
22 | import org.thingsboard.server.queue.TbQueueMsg; | 22 | import org.thingsboard.server.queue.TbQueueMsg; |
23 | 23 | ||
24 | +import javax.annotation.Nonnull; | ||
24 | import java.io.IOException; | 25 | import java.io.IOException; |
25 | import java.util.ArrayList; | 26 | import java.util.ArrayList; |
26 | import java.util.Collections; | 27 | import java.util.Collections; |
27 | import java.util.List; | 28 | import java.util.List; |
29 | +import java.util.Queue; | ||
28 | import java.util.Set; | 30 | import java.util.Set; |
29 | -import java.util.concurrent.locks.Lock; | 31 | +import java.util.concurrent.ConcurrentLinkedQueue; |
32 | +import java.util.concurrent.TimeUnit; | ||
30 | import java.util.concurrent.locks.ReentrantLock; | 33 | import java.util.concurrent.locks.ReentrantLock; |
31 | import java.util.stream.Collectors; | 34 | import java.util.stream.Collectors; |
32 | 35 | ||
36 | +import static java.util.Collections.emptyList; | ||
37 | + | ||
33 | @Slf4j | 38 | @Slf4j |
34 | public abstract class AbstractTbQueueConsumerTemplate<R, T extends TbQueueMsg> implements TbQueueConsumer<T> { | 39 | public abstract class AbstractTbQueueConsumerTemplate<R, T extends TbQueueMsg> implements TbQueueConsumer<T> { |
35 | 40 | ||
36 | private volatile boolean subscribed; | 41 | private volatile boolean subscribed; |
37 | protected volatile boolean stopped = false; | 42 | protected volatile boolean stopped = false; |
38 | protected volatile Set<TopicPartitionInfo> partitions; | 43 | protected volatile Set<TopicPartitionInfo> partitions; |
39 | - protected final Lock consumerLock = new ReentrantLock(); | 44 | + protected final ReentrantLock consumerLock = new ReentrantLock(); //NonfairSync |
45 | + final Queue<Set<TopicPartitionInfo>> subscribeQueue = new ConcurrentLinkedQueue<>(); | ||
40 | 46 | ||
41 | @Getter | 47 | @Getter |
42 | private final String topic; | 48 | private final String topic; |
@@ -47,84 +53,101 @@ public abstract class AbstractTbQueueConsumerTemplate<R, T extends TbQueueMsg> i | @@ -47,84 +53,101 @@ public abstract class AbstractTbQueueConsumerTemplate<R, T extends TbQueueMsg> i | ||
47 | 53 | ||
48 | @Override | 54 | @Override |
49 | public void subscribe() { | 55 | public void subscribe() { |
50 | - consumerLock.lock(); | ||
51 | - try { | ||
52 | - partitions = Collections.singleton(new TopicPartitionInfo(topic, null, null, true)); | ||
53 | - subscribed = false; | ||
54 | - } finally { | ||
55 | - consumerLock.unlock(); | 56 | + log.info("enqueue topic subscribe {} ", topic); |
57 | + if (stopped) { | ||
58 | + log.error("trying subscribe, but consumer stopped for topic {}", topic); | ||
59 | + return; | ||
56 | } | 60 | } |
61 | + subscribeQueue.add(Collections.singleton(new TopicPartitionInfo(topic, null, null, true))); | ||
57 | } | 62 | } |
58 | 63 | ||
59 | @Override | 64 | @Override |
60 | public void subscribe(Set<TopicPartitionInfo> partitions) { | 65 | public void subscribe(Set<TopicPartitionInfo> partitions) { |
66 | + log.info("enqueue topics subscribe {} ", partitions); | ||
67 | + if (stopped) { | ||
68 | + log.error("trying subscribe, but consumer stopped for topic {}", topic); | ||
69 | + return; | ||
70 | + } | ||
71 | + subscribeQueue.add(partitions); | ||
72 | + } | ||
73 | + | ||
74 | + @Override | ||
75 | + public List<T> poll(long durationInMillis) { | ||
76 | + List<R> records; | ||
77 | + long startNanos = System.nanoTime(); | ||
78 | + if (stopped) { | ||
79 | + return errorAndReturnEmpty(); | ||
80 | + } | ||
81 | + if (!subscribed && partitions == null && subscribeQueue.isEmpty()) { | ||
82 | + return sleepAndReturnEmpty(startNanos, durationInMillis); | ||
83 | + } | ||
84 | + | ||
85 | + if (consumerLock.isLocked()) { | ||
86 | + log.error("poll. consumerLock is locked. will wait with no timeout. it looks like a race conditions or deadlock", new RuntimeException("stacktrace")); | ||
87 | + } | ||
88 | + | ||
61 | consumerLock.lock(); | 89 | consumerLock.lock(); |
62 | try { | 90 | try { |
63 | - this.partitions = partitions; | ||
64 | - subscribed = false; | 91 | + while (!subscribeQueue.isEmpty()) { |
92 | + subscribed = false; | ||
93 | + partitions = subscribeQueue.poll(); | ||
94 | + } | ||
95 | + if (!subscribed) { | ||
96 | + List<String> topicNames = partitions.stream().map(TopicPartitionInfo::getFullTopicName).collect(Collectors.toList()); | ||
97 | + doSubscribe(topicNames); | ||
98 | + subscribed = true; | ||
99 | + } | ||
100 | + records = partitions.isEmpty() ? emptyList() : doPoll(durationInMillis); | ||
65 | } finally { | 101 | } finally { |
66 | consumerLock.unlock(); | 102 | consumerLock.unlock(); |
67 | } | 103 | } |
104 | + | ||
105 | + if (records.isEmpty()) { return sleepAndReturnEmpty(startNanos, durationInMillis); } | ||
106 | + | ||
107 | + return decodeRecords(records); | ||
68 | } | 108 | } |
69 | 109 | ||
70 | - @Override | ||
71 | - public List<T> poll(long durationInMillis) { | ||
72 | - if (!subscribed && partitions == null) { | ||
73 | - try { | ||
74 | - Thread.sleep(durationInMillis); | ||
75 | - } catch (InterruptedException e) { | ||
76 | - log.debug("Failed to await subscription", e); | ||
77 | - } | ||
78 | - } else { | ||
79 | - long pollStartTs = System.currentTimeMillis(); | ||
80 | - consumerLock.lock(); | 110 | + @Nonnull |
111 | + List<T> decodeRecords(@Nonnull List<R> records) { | ||
112 | + List<T> result = new ArrayList<>(records.size()); | ||
113 | + records.forEach(record -> { | ||
81 | try { | 114 | try { |
82 | - if (!subscribed) { | ||
83 | - List<String> topicNames = partitions.stream().map(TopicPartitionInfo::getFullTopicName).collect(Collectors.toList()); | ||
84 | - doSubscribe(topicNames); | ||
85 | - subscribed = true; | 115 | + if (record != null) { |
116 | + result.add(decode(record)); | ||
86 | } | 117 | } |
118 | + } catch (IOException e) { | ||
119 | + log.error("Failed decode record: [{}]", record); | ||
120 | + throw new RuntimeException("Failed to decode record: ", e); | ||
121 | + } | ||
122 | + }); | ||
123 | + return result; | ||
124 | + } | ||
87 | 125 | ||
88 | - List<R> records; | ||
89 | - if (partitions.isEmpty()) { | ||
90 | - records = Collections.emptyList(); | ||
91 | - } else { | ||
92 | - records = doPoll(durationInMillis); | ||
93 | - } | ||
94 | - if (!records.isEmpty()) { | ||
95 | - List<T> result = new ArrayList<>(records.size()); | ||
96 | - records.forEach(record -> { | ||
97 | - try { | ||
98 | - if (record != null) { | ||
99 | - result.add(decode(record)); | ||
100 | - } | ||
101 | - } catch (IOException e) { | ||
102 | - log.error("Failed decode record: [{}]", record); | ||
103 | - throw new RuntimeException("Failed to decode record: ", e); | ||
104 | - } | ||
105 | - }); | ||
106 | - return result; | ||
107 | - } else { | ||
108 | - long pollDuration = System.currentTimeMillis() - pollStartTs; | ||
109 | - if (pollDuration < durationInMillis) { | ||
110 | - try { | ||
111 | - Thread.sleep(durationInMillis - pollDuration); | ||
112 | - } catch (InterruptedException e) { | ||
113 | - if (!stopped) { | ||
114 | - log.error("Failed to wait.", e); | ||
115 | - } | ||
116 | - } | ||
117 | - } | 126 | + List<T> errorAndReturnEmpty() { |
127 | + log.error("poll invoked but consumer stopped for topic" + topic, new RuntimeException("stacktrace")); | ||
128 | + return emptyList(); | ||
129 | + } | ||
130 | + | ||
131 | + List<T> sleepAndReturnEmpty(final long startNanos, final long durationInMillis) { | ||
132 | + long durationNanos = TimeUnit.MILLISECONDS.toNanos(durationInMillis); | ||
133 | + long spentNanos = System.nanoTime() - startNanos; | ||
134 | + if (spentNanos < durationNanos) { | ||
135 | + try { | ||
136 | + Thread.sleep(Math.max(TimeUnit.NANOSECONDS.toMillis(durationNanos - spentNanos), 1)); | ||
137 | + } catch (InterruptedException e) { | ||
138 | + if (!stopped) { | ||
139 | + log.error("Failed to wait", e); | ||
118 | } | 140 | } |
119 | - } finally { | ||
120 | - consumerLock.unlock(); | ||
121 | } | 141 | } |
122 | } | 142 | } |
123 | - return Collections.emptyList(); | 143 | + return emptyList(); |
124 | } | 144 | } |
125 | 145 | ||
126 | @Override | 146 | @Override |
127 | public void commit() { | 147 | public void commit() { |
148 | + if (consumerLock.isLocked()) { | ||
149 | + log.error("commit. consumerLock is locked. will wait with no timeout. it looks like a race conditions or deadlock", new RuntimeException("stacktrace")); | ||
150 | + } | ||
128 | consumerLock.lock(); | 151 | consumerLock.lock(); |
129 | try { | 152 | try { |
130 | doCommit(); | 153 | doCommit(); |
@@ -135,6 +158,7 @@ public abstract class AbstractTbQueueConsumerTemplate<R, T extends TbQueueMsg> i | @@ -135,6 +158,7 @@ public abstract class AbstractTbQueueConsumerTemplate<R, T extends TbQueueMsg> i | ||
135 | 158 | ||
136 | @Override | 159 | @Override |
137 | public void unsubscribe() { | 160 | public void unsubscribe() { |
161 | + log.info("unsubscribe topic and stop consumer {}", getTopic()); | ||
138 | stopped = true; | 162 | stopped = true; |
139 | consumerLock.lock(); | 163 | consumerLock.lock(); |
140 | try { | 164 | try { |
@@ -128,9 +128,10 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | @@ -128,9 +128,10 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | ||
128 | log.debug("Ignoring application ready event, ZK client is not started, ZK client state [{}]", client.getState()); | 128 | log.debug("Ignoring application ready event, ZK client is not started, ZK client state [{}]", client.getState()); |
129 | return; | 129 | return; |
130 | } | 130 | } |
131 | + log.info("Going to publish current server..."); | ||
131 | publishCurrentServer(); | 132 | publishCurrentServer(); |
132 | - TransportProtos.ServiceInfo currentService = serviceInfoProvider.getServiceInfo(); | ||
133 | - partitionService.recalculatePartitions(currentService, getOtherServers()); | 133 | + log.info("Going to recalculate partitions..."); |
134 | + recalculatePartitions(); | ||
134 | } | 135 | } |
135 | 136 | ||
136 | public synchronized void publishCurrentServer() { | 137 | public synchronized void publishCurrentServer() { |
@@ -285,11 +286,19 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | @@ -285,11 +286,19 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | ||
285 | case CHILD_ADDED: | 286 | case CHILD_ADDED: |
286 | case CHILD_UPDATED: | 287 | case CHILD_UPDATED: |
287 | case CHILD_REMOVED: | 288 | case CHILD_REMOVED: |
288 | - TransportProtos.ServiceInfo currentService = serviceInfoProvider.getServiceInfo(); | ||
289 | - partitionService.recalculatePartitions(currentService, getOtherServers()); | 289 | + recalculatePartitions(); |
290 | break; | 290 | break; |
291 | default: | 291 | default: |
292 | break; | 292 | break; |
293 | } | 293 | } |
294 | } | 294 | } |
295 | + | ||
296 | + /** | ||
297 | + * A single entry point to recalculate partitions | ||
298 | + * Synchronized to ensure that other servers info is up to date | ||
299 | + * */ | ||
300 | + synchronized void recalculatePartitions() { | ||
301 | + partitionService.recalculatePartitions(serviceInfoProvider.getServiceInfo(), getOtherServers()); | ||
302 | + } | ||
303 | + | ||
295 | } | 304 | } |
@@ -72,8 +72,10 @@ public class TbKafkaConsumerTemplate<T extends TbQueueMsg> extends AbstractTbQue | @@ -72,8 +72,10 @@ public class TbKafkaConsumerTemplate<T extends TbQueueMsg> extends AbstractTbQue | ||
72 | protected void doSubscribe(List<String> topicNames) { | 72 | protected void doSubscribe(List<String> topicNames) { |
73 | if (!topicNames.isEmpty()) { | 73 | if (!topicNames.isEmpty()) { |
74 | topicNames.forEach(admin::createTopicIfNotExists); | 74 | topicNames.forEach(admin::createTopicIfNotExists); |
75 | + log.info("subscribe topics {}", topicNames); | ||
75 | consumer.subscribe(topicNames); | 76 | consumer.subscribe(topicNames); |
76 | } else { | 77 | } else { |
78 | + log.info("unsubscribe due to empty topic list"); | ||
77 | consumer.unsubscribe(); | 79 | consumer.unsubscribe(); |
78 | } | 80 | } |
79 | } | 81 | } |
@@ -102,6 +104,7 @@ public class TbKafkaConsumerTemplate<T extends TbQueueMsg> extends AbstractTbQue | @@ -102,6 +104,7 @@ public class TbKafkaConsumerTemplate<T extends TbQueueMsg> extends AbstractTbQue | ||
102 | 104 | ||
103 | @Override | 105 | @Override |
104 | protected void doUnsubscribe() { | 106 | protected void doUnsubscribe() { |
107 | + log.info("unsubscribe topic and close consumer for topic {}", getTopic()); | ||
105 | if (consumer != null) { | 108 | if (consumer != null) { |
106 | consumer.unsubscribe(); | 109 | consumer.unsubscribe(); |
107 | consumer.close(); | 110 | consumer.close(); |
common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java
@@ -17,6 +17,7 @@ package org.thingsboard.server.transport.coap; | @@ -17,6 +17,7 @@ package org.thingsboard.server.transport.coap; | ||
17 | 17 | ||
18 | import com.google.gson.JsonParseException; | 18 | import com.google.gson.JsonParseException; |
19 | import com.google.protobuf.Descriptors; | 19 | import com.google.protobuf.Descriptors; |
20 | +import com.google.protobuf.DynamicMessage; | ||
20 | import lombok.Data; | 21 | import lombok.Data; |
21 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
22 | import org.eclipse.californium.core.coap.CoAP; | 23 | import org.eclipse.californium.core.coap.CoAP; |
@@ -261,7 +262,8 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | @@ -261,7 +262,8 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | ||
261 | TransportProtos.SessionInfoProto currentAttrSession = tokenToSessionIdMap.get(getTokenFromRequest(request)); | 262 | TransportProtos.SessionInfoProto currentAttrSession = tokenToSessionIdMap.get(getTokenFromRequest(request)); |
262 | if (currentAttrSession == null) { | 263 | if (currentAttrSession == null) { |
263 | attributeSubscriptions.add(sessionId); | 264 | attributeSubscriptions.add(sessionId); |
264 | - registerAsyncCoapSession(exchange, sessionInfo, coapTransportAdaptor, getTokenFromRequest(request)); | 265 | + registerAsyncCoapSession(exchange, sessionInfo, coapTransportAdaptor, |
266 | + transportConfigurationContainer.getRpcRequestDynamicMessageBuilder(), getTokenFromRequest(request)); | ||
265 | transportService.process(sessionInfo, | 267 | transportService.process(sessionInfo, |
266 | TransportProtos.SubscribeToAttributeUpdatesMsg.getDefaultInstance(), new CoapNoOpCallback(exchange)); | 268 | TransportProtos.SubscribeToAttributeUpdatesMsg.getDefaultInstance(), new CoapNoOpCallback(exchange)); |
267 | } | 269 | } |
@@ -281,7 +283,8 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | @@ -281,7 +283,8 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | ||
281 | TransportProtos.SessionInfoProto currentRpcSession = tokenToSessionIdMap.get(getTokenFromRequest(request)); | 283 | TransportProtos.SessionInfoProto currentRpcSession = tokenToSessionIdMap.get(getTokenFromRequest(request)); |
282 | if (currentRpcSession == null) { | 284 | if (currentRpcSession == null) { |
283 | rpcSubscriptions.add(sessionId); | 285 | rpcSubscriptions.add(sessionId); |
284 | - registerAsyncCoapSession(exchange, sessionInfo, coapTransportAdaptor, getTokenFromRequest(request)); | 286 | + registerAsyncCoapSession(exchange, sessionInfo, coapTransportAdaptor, |
287 | + transportConfigurationContainer.getRpcRequestDynamicMessageBuilder(), getTokenFromRequest(request)); | ||
285 | transportService.process(sessionInfo, | 288 | transportService.process(sessionInfo, |
286 | TransportProtos.SubscribeToRPCMsg.getDefaultInstance(), | 289 | TransportProtos.SubscribeToRPCMsg.getDefaultInstance(), |
287 | new CoapNoOpCallback(exchange)); | 290 | new CoapNoOpCallback(exchange)); |
@@ -303,17 +306,19 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | @@ -303,17 +306,19 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | ||
303 | break; | 306 | break; |
304 | case TO_DEVICE_RPC_RESPONSE: | 307 | case TO_DEVICE_RPC_RESPONSE: |
305 | transportService.process(sessionInfo, | 308 | transportService.process(sessionInfo, |
306 | - coapTransportAdaptor.convertToDeviceRpcResponse(sessionId, request), | 309 | + coapTransportAdaptor.convertToDeviceRpcResponse(sessionId, request, transportConfigurationContainer.getRpcResponseMsgDescriptor()), |
307 | new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR)); | 310 | new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR)); |
308 | break; | 311 | break; |
309 | case TO_SERVER_RPC_REQUEST: | 312 | case TO_SERVER_RPC_REQUEST: |
310 | - transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), timeout); | 313 | + transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor, |
314 | + transportConfigurationContainer.getRpcRequestDynamicMessageBuilder()), timeout); | ||
311 | transportService.process(sessionInfo, | 315 | transportService.process(sessionInfo, |
312 | coapTransportAdaptor.convertToServerRpcRequest(sessionId, request), | 316 | coapTransportAdaptor.convertToServerRpcRequest(sessionId, request), |
313 | new CoapNoOpCallback(exchange)); | 317 | new CoapNoOpCallback(exchange)); |
314 | break; | 318 | break; |
315 | case GET_ATTRIBUTES_REQUEST: | 319 | case GET_ATTRIBUTES_REQUEST: |
316 | - transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), timeout); | 320 | + transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor, |
321 | + transportConfigurationContainer.getRpcRequestDynamicMessageBuilder()), timeout); | ||
317 | transportService.process(sessionInfo, | 322 | transportService.process(sessionInfo, |
318 | coapTransportAdaptor.convertToGetAttributes(sessionId, request), | 323 | coapTransportAdaptor.convertToGetAttributes(sessionId, request), |
319 | new CoapNoOpCallback(exchange)); | 324 | new CoapNoOpCallback(exchange)); |
@@ -330,14 +335,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | @@ -330,14 +335,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | ||
330 | return tokenToSessionIdMap.remove(token); | 335 | return tokenToSessionIdMap.remove(token); |
331 | } | 336 | } |
332 | 337 | ||
333 | - private void registerAsyncCoapSession(CoapExchange exchange, TransportProtos.SessionInfoProto sessionInfo, CoapTransportAdaptor coapTransportAdaptor, String token) { | 338 | + private void registerAsyncCoapSession(CoapExchange exchange, TransportProtos.SessionInfoProto sessionInfo, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder, String token) { |
334 | tokenToSessionIdMap.putIfAbsent(token, sessionInfo); | 339 | tokenToSessionIdMap.putIfAbsent(token, sessionInfo); |
335 | - transportService.registerAsyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor)); | 340 | + transportService.registerAsyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor, rpcRequestDynamicMessageBuilder)); |
336 | transportService.process(sessionInfo, getSessionEventMsg(TransportProtos.SessionEvent.OPEN), null); | 341 | transportService.process(sessionInfo, getSessionEventMsg(TransportProtos.SessionEvent.OPEN), null); |
337 | } | 342 | } |
338 | 343 | ||
339 | - private CoapSessionListener getCoapSessionListener(CoapExchange exchange, CoapTransportAdaptor coapTransportAdaptor) { | ||
340 | - return new CoapSessionListener(exchange, coapTransportAdaptor); | 344 | + private CoapSessionListener getCoapSessionListener(CoapExchange exchange, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) { |
345 | + return new CoapSessionListener(exchange, coapTransportAdaptor, rpcRequestDynamicMessageBuilder); | ||
341 | } | 346 | } |
342 | 347 | ||
343 | private String getTokenFromRequest(Request request) { | 348 | private String getTokenFromRequest(Request request) { |
@@ -423,10 +428,12 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | @@ -423,10 +428,12 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | ||
423 | 428 | ||
424 | private final CoapExchange exchange; | 429 | private final CoapExchange exchange; |
425 | private final CoapTransportAdaptor coapTransportAdaptor; | 430 | private final CoapTransportAdaptor coapTransportAdaptor; |
431 | + private final DynamicMessage.Builder rpcRequestDynamicMessageBuilder; | ||
426 | 432 | ||
427 | - CoapSessionListener(CoapExchange exchange, CoapTransportAdaptor coapTransportAdaptor) { | 433 | + CoapSessionListener(CoapExchange exchange, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) { |
428 | this.exchange = exchange; | 434 | this.exchange = exchange; |
429 | this.coapTransportAdaptor = coapTransportAdaptor; | 435 | this.coapTransportAdaptor = coapTransportAdaptor; |
436 | + this.rpcRequestDynamicMessageBuilder = rpcRequestDynamicMessageBuilder; | ||
430 | } | 437 | } |
431 | 438 | ||
432 | @Override | 439 | @Override |
@@ -457,7 +464,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | @@ -457,7 +464,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | ||
457 | @Override | 464 | @Override |
458 | public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg msg) { | 465 | public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg msg) { |
459 | try { | 466 | try { |
460 | - exchange.respond(coapTransportAdaptor.convertToPublish(isConRequest(), msg)); | 467 | + exchange.respond(coapTransportAdaptor.convertToPublish(isConRequest(), msg, rpcRequestDynamicMessageBuilder)); |
461 | } catch (AdaptorException e) { | 468 | } catch (AdaptorException e) { |
462 | log.trace("Failed to reply due to error", e); | 469 | log.trace("Failed to reply due to error", e); |
463 | exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR); | 470 | exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR); |
@@ -545,9 +552,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | @@ -545,9 +552,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | ||
545 | (ProtoTransportPayloadConfiguration) transportPayloadTypeConfiguration; | 552 | (ProtoTransportPayloadConfiguration) transportPayloadTypeConfiguration; |
546 | String deviceTelemetryProtoSchema = protoTransportPayloadConfiguration.getDeviceTelemetryProtoSchema(); | 553 | String deviceTelemetryProtoSchema = protoTransportPayloadConfiguration.getDeviceTelemetryProtoSchema(); |
547 | String deviceAttributesProtoSchema = protoTransportPayloadConfiguration.getDeviceAttributesProtoSchema(); | 554 | String deviceAttributesProtoSchema = protoTransportPayloadConfiguration.getDeviceAttributesProtoSchema(); |
555 | + String deviceRpcRequestProtoSchema = protoTransportPayloadConfiguration.getDeviceRpcRequestProtoSchema(); | ||
556 | + String deviceRpcResponseProtoSchema = protoTransportPayloadConfiguration.getDeviceRpcResponseProtoSchema(); | ||
548 | return new TransportConfigurationContainer(false, | 557 | return new TransportConfigurationContainer(false, |
549 | protoTransportPayloadConfiguration.getTelemetryDynamicMessageDescriptor(deviceTelemetryProtoSchema), | 558 | protoTransportPayloadConfiguration.getTelemetryDynamicMessageDescriptor(deviceTelemetryProtoSchema), |
550 | - protoTransportPayloadConfiguration.getAttributesDynamicMessageDescriptor(deviceAttributesProtoSchema)); | 559 | + protoTransportPayloadConfiguration.getAttributesDynamicMessageDescriptor(deviceAttributesProtoSchema), |
560 | + protoTransportPayloadConfiguration.getRpcResponseDynamicMessageDescriptor(deviceRpcResponseProtoSchema), | ||
561 | + protoTransportPayloadConfiguration.getRpcRequestDynamicMessageBuilder(deviceRpcRequestProtoSchema) | ||
562 | + ); | ||
551 | } | 563 | } |
552 | } else { | 564 | } else { |
553 | throw new AdaptorException("Invalid CoapDeviceTypeConfiguration type: " + coapDeviceTypeConfiguration.getClass().getSimpleName() + "!"); | 565 | throw new AdaptorException("Invalid CoapDeviceTypeConfiguration type: " + coapDeviceTypeConfiguration.getClass().getSimpleName() + "!"); |
@@ -567,11 +579,15 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | @@ -567,11 +579,15 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | ||
567 | private boolean jsonPayload; | 579 | private boolean jsonPayload; |
568 | private Descriptors.Descriptor telemetryMsgDescriptor; | 580 | private Descriptors.Descriptor telemetryMsgDescriptor; |
569 | private Descriptors.Descriptor attributesMsgDescriptor; | 581 | private Descriptors.Descriptor attributesMsgDescriptor; |
582 | + private Descriptors.Descriptor rpcResponseMsgDescriptor; | ||
583 | + private DynamicMessage.Builder rpcRequestDynamicMessageBuilder; | ||
570 | 584 | ||
571 | - public TransportConfigurationContainer(boolean jsonPayload, Descriptors.Descriptor telemetryMsgDescriptor, Descriptors.Descriptor attributesMsgDescriptor) { | 585 | + public TransportConfigurationContainer(boolean jsonPayload, Descriptors.Descriptor telemetryMsgDescriptor, Descriptors.Descriptor attributesMsgDescriptor, Descriptors.Descriptor rpcResponseMsgDescriptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) { |
572 | this.jsonPayload = jsonPayload; | 586 | this.jsonPayload = jsonPayload; |
573 | this.telemetryMsgDescriptor = telemetryMsgDescriptor; | 587 | this.telemetryMsgDescriptor = telemetryMsgDescriptor; |
574 | this.attributesMsgDescriptor = attributesMsgDescriptor; | 588 | this.attributesMsgDescriptor = attributesMsgDescriptor; |
589 | + this.rpcResponseMsgDescriptor = rpcResponseMsgDescriptor; | ||
590 | + this.rpcRequestDynamicMessageBuilder = rpcRequestDynamicMessageBuilder; | ||
575 | } | 591 | } |
576 | 592 | ||
577 | public TransportConfigurationContainer(boolean jsonPayload) { | 593 | public TransportConfigurationContainer(boolean jsonPayload) { |
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | package org.thingsboard.server.transport.coap.adaptors; | 16 | package org.thingsboard.server.transport.coap.adaptors; |
17 | 17 | ||
18 | import com.google.protobuf.Descriptors; | 18 | import com.google.protobuf.Descriptors; |
19 | +import com.google.protobuf.DynamicMessage; | ||
19 | import org.eclipse.californium.core.coap.Request; | 20 | import org.eclipse.californium.core.coap.Request; |
20 | import org.eclipse.californium.core.coap.Response; | 21 | import org.eclipse.californium.core.coap.Response; |
21 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; | 22 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; |
@@ -32,7 +33,7 @@ public interface CoapTransportAdaptor { | @@ -32,7 +33,7 @@ public interface CoapTransportAdaptor { | ||
32 | 33 | ||
33 | TransportProtos.GetAttributeRequestMsg convertToGetAttributes(UUID sessionId, Request inbound) throws AdaptorException; | 34 | TransportProtos.GetAttributeRequestMsg convertToGetAttributes(UUID sessionId, Request inbound) throws AdaptorException; |
34 | 35 | ||
35 | - TransportProtos.ToDeviceRpcResponseMsg convertToDeviceRpcResponse(UUID sessionId, Request inbound) throws AdaptorException; | 36 | + TransportProtos.ToDeviceRpcResponseMsg convertToDeviceRpcResponse(UUID sessionId, Request inbound, Descriptors.Descriptor rpcResponseMsgDescriptor) throws AdaptorException; |
36 | 37 | ||
37 | TransportProtos.ToServerRpcRequestMsg convertToServerRpcRequest(UUID sessionId, Request inbound) throws AdaptorException; | 38 | TransportProtos.ToServerRpcRequestMsg convertToServerRpcRequest(UUID sessionId, Request inbound) throws AdaptorException; |
38 | 39 | ||
@@ -42,7 +43,7 @@ public interface CoapTransportAdaptor { | @@ -42,7 +43,7 @@ public interface CoapTransportAdaptor { | ||
42 | 43 | ||
43 | Response convertToPublish(boolean isConfirmable, TransportProtos.AttributeUpdateNotificationMsg notificationMsg) throws AdaptorException; | 44 | Response convertToPublish(boolean isConfirmable, TransportProtos.AttributeUpdateNotificationMsg notificationMsg) throws AdaptorException; |
44 | 45 | ||
45 | - Response convertToPublish(boolean isConfirmable, TransportProtos.ToDeviceRpcRequestMsg rpcRequest) throws AdaptorException; | 46 | + Response convertToPublish(boolean isConfirmable, TransportProtos.ToDeviceRpcRequestMsg rpcRequest, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) throws AdaptorException; |
46 | 47 | ||
47 | Response convertToPublish(TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException; | 48 | Response convertToPublish(TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException; |
48 | 49 |
@@ -20,6 +20,7 @@ import com.google.gson.JsonObject; | @@ -20,6 +20,7 @@ import com.google.gson.JsonObject; | ||
20 | import com.google.gson.JsonParser; | 20 | import com.google.gson.JsonParser; |
21 | import com.google.gson.JsonSyntaxException; | 21 | import com.google.gson.JsonSyntaxException; |
22 | import com.google.protobuf.Descriptors; | 22 | import com.google.protobuf.Descriptors; |
23 | +import com.google.protobuf.DynamicMessage; | ||
23 | import lombok.extern.slf4j.Slf4j; | 24 | import lombok.extern.slf4j.Slf4j; |
24 | import org.eclipse.californium.core.coap.CoAP; | 25 | import org.eclipse.californium.core.coap.CoAP; |
25 | import org.eclipse.californium.core.coap.Request; | 26 | import org.eclipse.californium.core.coap.Request; |
@@ -64,7 +65,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { | @@ -64,7 +65,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { | ||
64 | } | 65 | } |
65 | 66 | ||
66 | @Override | 67 | @Override |
67 | - public TransportProtos.ToDeviceRpcResponseMsg convertToDeviceRpcResponse(UUID sessionId, Request inbound) throws AdaptorException { | 68 | + public TransportProtos.ToDeviceRpcResponseMsg convertToDeviceRpcResponse(UUID sessionId, Request inbound, Descriptors.Descriptor rpcResponseMsgDescriptor) throws AdaptorException { |
68 | Optional<Integer> requestId = CoapTransportResource.getRequestId(inbound); | 69 | Optional<Integer> requestId = CoapTransportResource.getRequestId(inbound); |
69 | String payload = validatePayload(sessionId, inbound, false); | 70 | String payload = validatePayload(sessionId, inbound, false); |
70 | JsonObject response = new JsonParser().parse(payload).getAsJsonObject(); | 71 | JsonObject response = new JsonParser().parse(payload).getAsJsonObject(); |
@@ -95,7 +96,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { | @@ -95,7 +96,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { | ||
95 | } | 96 | } |
96 | 97 | ||
97 | @Override | 98 | @Override |
98 | - public Response convertToPublish(boolean isConfirmable, TransportProtos.ToDeviceRpcRequestMsg msg) throws AdaptorException { | 99 | + public Response convertToPublish(boolean isConfirmable, TransportProtos.ToDeviceRpcRequestMsg msg, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) throws AdaptorException { |
99 | return getObserveNotification(isConfirmable, JsonConverter.toJson(msg, true)); | 100 | return getObserveNotification(isConfirmable, JsonConverter.toJson(msg, true)); |
100 | } | 101 | } |
101 | 102 |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.transport.coap.adaptors; | 16 | package org.thingsboard.server.transport.coap.adaptors; |
17 | 17 | ||
18 | +import com.google.gson.JsonElement; | ||
18 | import com.google.gson.JsonParser; | 19 | import com.google.gson.JsonParser; |
19 | import com.google.protobuf.Descriptors; | 20 | import com.google.protobuf.Descriptors; |
20 | import com.google.protobuf.DynamicMessage; | 21 | import com.google.protobuf.DynamicMessage; |
@@ -63,16 +64,16 @@ public class ProtoCoapAdaptor implements CoapTransportAdaptor { | @@ -63,16 +64,16 @@ public class ProtoCoapAdaptor implements CoapTransportAdaptor { | ||
63 | } | 64 | } |
64 | 65 | ||
65 | @Override | 66 | @Override |
66 | - public TransportProtos.ToDeviceRpcResponseMsg convertToDeviceRpcResponse(UUID sessionId, Request inbound) throws AdaptorException { | 67 | + public TransportProtos.ToDeviceRpcResponseMsg convertToDeviceRpcResponse(UUID sessionId, Request inbound, Descriptors.Descriptor rpcResponseMsgDescriptor) throws AdaptorException { |
67 | Optional<Integer> requestId = CoapTransportResource.getRequestId(inbound); | 68 | Optional<Integer> requestId = CoapTransportResource.getRequestId(inbound); |
68 | if (requestId.isEmpty()) { | 69 | if (requestId.isEmpty()) { |
69 | throw new AdaptorException("Request id is missing!"); | 70 | throw new AdaptorException("Request id is missing!"); |
70 | } else { | 71 | } else { |
71 | try { | 72 | try { |
72 | - String payload = TransportProtos.ToDeviceRpcResponseMsg.parseFrom(inbound.getPayload()).getPayload(); | ||
73 | - return TransportProtos.ToDeviceRpcResponseMsg.newBuilder().setRequestId(requestId.get()) | ||
74 | - .setPayload(payload).build(); | ||
75 | - } catch (InvalidProtocolBufferException e) { | 73 | + JsonElement response = new JsonParser().parse(dynamicMsgToJson(inbound.getPayload(), rpcResponseMsgDescriptor)); |
74 | + return TransportProtos.ToDeviceRpcResponseMsg.newBuilder().setRequestId(requestId.orElseThrow(() -> new AdaptorException("Request id is missing!"))) | ||
75 | + .setPayload(response.toString()).build(); | ||
76 | + } catch (Exception e) { | ||
76 | throw new AdaptorException(e); | 77 | throw new AdaptorException(e); |
77 | } | 78 | } |
78 | } | 79 | } |
@@ -112,8 +113,8 @@ public class ProtoCoapAdaptor implements CoapTransportAdaptor { | @@ -112,8 +113,8 @@ public class ProtoCoapAdaptor implements CoapTransportAdaptor { | ||
112 | } | 113 | } |
113 | 114 | ||
114 | @Override | 115 | @Override |
115 | - public Response convertToPublish(boolean isConfirmable, TransportProtos.ToDeviceRpcRequestMsg msg) throws AdaptorException { | ||
116 | - return getObserveNotification(isConfirmable, msg.toByteArray()); | 116 | + public Response convertToPublish(boolean isConfirmable, TransportProtos.ToDeviceRpcRequestMsg rpcRequest, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) throws AdaptorException { |
117 | + return getObserveNotification(isConfirmable, ProtoConverter.convertToRpcRequest(rpcRequest, rpcRequestDynamicMessageBuilder)); | ||
117 | } | 118 | } |
118 | 119 | ||
119 | @Override | 120 | @Override |
@@ -35,12 +35,11 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInf | @@ -35,12 +35,11 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInf | ||
35 | import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; | 35 | import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; |
36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; | 36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; |
37 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer; | 37 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer; |
38 | -import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; | ||
39 | import org.thingsboard.server.transport.lwm2m.utils.TypeServer; | 38 | import org.thingsboard.server.transport.lwm2m.utils.TypeServer; |
40 | 39 | ||
41 | import java.io.IOException; | 40 | import java.io.IOException; |
42 | import java.security.GeneralSecurityException; | 41 | import java.security.GeneralSecurityException; |
43 | -import java.util.Arrays; | 42 | +import java.util.Collections; |
44 | import java.util.List; | 43 | import java.util.List; |
45 | import java.util.UUID; | 44 | import java.util.UUID; |
46 | 45 | ||
@@ -70,8 +69,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | @@ -70,8 +69,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | ||
70 | 69 | ||
71 | @Override | 70 | @Override |
72 | public List<SecurityInfo> getAllByEndpoint(String endPoint) { | 71 | public List<SecurityInfo> getAllByEndpoint(String endPoint) { |
73 | - String endPointKey = endPoint; | ||
74 | - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(endPointKey, TypeServer.BOOTSTRAP); | 72 | + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(endPoint, TypeServer.BOOTSTRAP); |
75 | if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { | 73 | if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { |
76 | /** add value to store from BootstrapJson */ | 74 | /** add value to store from BootstrapJson */ |
77 | this.setBootstrapConfigScurityInfo(store); | 75 | this.setBootstrapConfigScurityInfo(store); |
@@ -87,7 +85,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | @@ -87,7 +85,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | ||
87 | } catch (InvalidConfigurationException e) { | 85 | } catch (InvalidConfigurationException e) { |
88 | log.error("", e); | 86 | log.error("", e); |
89 | } | 87 | } |
90 | - return store.getSecurityInfo() == null ? null : Arrays.asList(store.getSecurityInfo()); | 88 | + return store.getSecurityInfo() == null ? null : Collections.singletonList(store.getSecurityInfo()); |
91 | } | 89 | } |
92 | } | 90 | } |
93 | return null; | 91 | return null; |
@@ -166,13 +164,13 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | @@ -166,13 +164,13 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | ||
166 | lwM2MBootstrapConfig.bootstrapServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.bootstrapServer, profileServerBootstrap); | 164 | lwM2MBootstrapConfig.bootstrapServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.bootstrapServer, profileServerBootstrap); |
167 | lwM2MBootstrapConfig.lwm2mServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.lwm2mServer, profileLwm2mServer); | 165 | lwM2MBootstrapConfig.lwm2mServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.lwm2mServer, profileLwm2mServer); |
168 | String logMsg = String.format("%s: getParametersBootstrap: %s Access connect client with bootstrap server.", LOG_LW2M_INFO, store.getEndPoint()); | 166 | String logMsg = String.format("%s: getParametersBootstrap: %s Access connect client with bootstrap server.", LOG_LW2M_INFO, store.getEndPoint()); |
169 | - context.sendParametersOnThingsboard(context.getTelemetryMsgObject(logMsg), LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC, sessionInfo); | 167 | + context.sendParametersOnThingsboardTelemetry(context.getKvLogyToThingsboard(logMsg), sessionInfo); |
170 | return lwM2MBootstrapConfig; | 168 | return lwM2MBootstrapConfig; |
171 | } else { | 169 | } else { |
172 | log.error(" [{}] Different values SecurityMode between of client and profile.", store.getEndPoint()); | 170 | log.error(" [{}] Different values SecurityMode between of client and profile.", store.getEndPoint()); |
173 | log.error("{} getParametersBootstrap: [{}] Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint()); | 171 | log.error("{} getParametersBootstrap: [{}] Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint()); |
174 | String logMsg = String.format("%s: getParametersBootstrap: %s Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint()); | 172 | String logMsg = String.format("%s: getParametersBootstrap: %s Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint()); |
175 | - context.sendParametersOnThingsboard(context.getTelemetryMsgObject(logMsg), LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC, sessionInfo); | 173 | + context.sendParametersOnThingsboardTelemetry(context.getKvLogyToThingsboard(logMsg), sessionInfo); |
176 | return null; | 174 | return null; |
177 | } | 175 | } |
178 | } | 176 | } |
@@ -23,5 +23,5 @@ public class LwM2MBootstrapServers { | @@ -23,5 +23,5 @@ public class LwM2MBootstrapServers { | ||
23 | private Integer lifetime = 300; | 23 | private Integer lifetime = 300; |
24 | private Integer defaultMinPeriod = 1; | 24 | private Integer defaultMinPeriod = 1; |
25 | private boolean notifIfDisabled = true; | 25 | private boolean notifIfDisabled = true; |
26 | - private String binding = "U"; | 26 | + private String binding = "UQ"; |
27 | } | 27 | } |
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mQueuedRequest.java
renamed from
dao/src/test/java/org/thingsboard/server/dao/service/sql/TbResourceServiceSqlTest.java
@@ -13,11 +13,8 @@ | @@ -13,11 +13,8 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.dao.service.sql; | 16 | +package org.thingsboard.server.transport.lwm2m.server; |
17 | 17 | ||
18 | -import org.thingsboard.server.dao.service.BaseTbResourceServiceTest; | ||
19 | -import org.thingsboard.server.dao.service.DaoSqlTest; | ||
20 | - | ||
21 | -@DaoSqlTest | ||
22 | -public class TbResourceServiceSqlTest extends BaseTbResourceServiceTest { | 18 | +public interface LwM2mQueuedRequest { |
19 | + void send(); | ||
23 | } | 20 | } |
@@ -26,7 +26,7 @@ import org.eclipse.leshan.server.registration.RegistrationUpdate; | @@ -26,7 +26,7 @@ import org.eclipse.leshan.server.registration.RegistrationUpdate; | ||
26 | 26 | ||
27 | import java.util.Collection; | 27 | import java.util.Collection; |
28 | 28 | ||
29 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToIdVerFromObjectId; | 29 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer; |
30 | 30 | ||
31 | @Slf4j | 31 | @Slf4j |
32 | public class LwM2mServerListener { | 32 | public class LwM2mServerListener { |
@@ -92,7 +92,7 @@ public class LwM2mServerListener { | @@ -92,7 +92,7 @@ public class LwM2mServerListener { | ||
92 | public void onResponse(Observation observation, Registration registration, ObserveResponse response) { | 92 | public void onResponse(Observation observation, Registration registration, ObserveResponse response) { |
93 | if (registration != null) { | 93 | if (registration != null) { |
94 | try { | 94 | try { |
95 | - service.onObservationResponse(registration, convertToIdVerFromObjectId(observation.getPath().toString(), registration), response); | 95 | + service.onObservationResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(), registration), response); |
96 | } catch (Exception e) { | 96 | } catch (Exception e) { |
97 | log.error("[{}] onResponse", e.toString()); | 97 | log.error("[{}] onResponse", e.toString()); |
98 | 98 | ||
@@ -107,7 +107,7 @@ public class LwM2mServerListener { | @@ -107,7 +107,7 @@ public class LwM2mServerListener { | ||
107 | 107 | ||
108 | @Override | 108 | @Override |
109 | public void newObservation(Observation observation, Registration registration) { | 109 | public void newObservation(Observation observation, Registration registration) { |
110 | -// log.info("Received newObservation from [{}] endpoint [{}] ", observation.getPath(), registration.getEndpoint()); | 110 | + log.info("Received newObservation from [{}] endpoint [{}] ", observation.getPath(), registration.getEndpoint()); |
111 | } | 111 | } |
112 | }; | 112 | }; |
113 | 113 |
@@ -18,6 +18,7 @@ package org.thingsboard.server.transport.lwm2m.server; | @@ -18,6 +18,7 @@ package org.thingsboard.server.transport.lwm2m.server; | ||
18 | import io.netty.util.concurrent.Future; | 18 | import io.netty.util.concurrent.Future; |
19 | import io.netty.util.concurrent.GenericFutureListener; | 19 | import io.netty.util.concurrent.GenericFutureListener; |
20 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
21 | +import org.jetbrains.annotations.NotNull; | ||
21 | import org.thingsboard.server.common.data.Device; | 22 | import org.thingsboard.server.common.data.Device; |
22 | import org.thingsboard.server.common.data.DeviceProfile; | 23 | import org.thingsboard.server.common.data.DeviceProfile; |
23 | import org.thingsboard.server.common.data.ResourceType; | 24 | import org.thingsboard.server.common.data.ResourceType; |
@@ -74,12 +75,12 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s | @@ -74,12 +75,12 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s | ||
74 | 75 | ||
75 | @Override | 76 | @Override |
76 | public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { | 77 | public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { |
77 | - log.info("[{}] toDeviceRpcRequest", toDeviceRequest); | 78 | + this.service.onToDeviceRpcRequest(toDeviceRequest); |
78 | } | 79 | } |
79 | 80 | ||
80 | @Override | 81 | @Override |
81 | public void onToServerRpcResponse(ToServerRpcResponseMsg toServerResponse) { | 82 | public void onToServerRpcResponse(ToServerRpcResponseMsg toServerResponse) { |
82 | - log.info("[{}] toServerRpcResponse", toServerResponse); | 83 | + this.service.onToServerRpcResponse(toServerResponse); |
83 | } | 84 | } |
84 | 85 | ||
85 | @Override | 86 | @Override |
@@ -87,13 +88,15 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s | @@ -87,13 +88,15 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s | ||
87 | log.info("[{}] operationComplete", future); | 88 | log.info("[{}] operationComplete", future); |
88 | } | 89 | } |
89 | 90 | ||
90 | - public void onResourceUpdate(Optional<TransportProtos.ResourceUpdateMsg> resourceUpdateMsgOpt) { | 91 | + @Override |
92 | + public void onResourceUpdate(@NotNull Optional<TransportProtos.ResourceUpdateMsg> resourceUpdateMsgOpt) { | ||
91 | if (ResourceType.LWM2M_MODEL.name().equals(resourceUpdateMsgOpt.get().getResourceType())) { | 93 | if (ResourceType.LWM2M_MODEL.name().equals(resourceUpdateMsgOpt.get().getResourceType())) { |
92 | this.service.onResourceUpdate(resourceUpdateMsgOpt); | 94 | this.service.onResourceUpdate(resourceUpdateMsgOpt); |
93 | } | 95 | } |
94 | } | 96 | } |
95 | 97 | ||
96 | - public void onResourceDelete(Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt) { | 98 | + @Override |
99 | + public void onResourceDelete(@NotNull Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt) { | ||
97 | if (ResourceType.LWM2M_MODEL.name().equals(resourceDeleteMsgOpt.get().getResourceType())) { | 100 | if (ResourceType.LWM2M_MODEL.name().equals(resourceDeleteMsgOpt.get().getResourceType())) { |
98 | this.service.onResourceDelete(resourceDeleteMsgOpt); | 101 | this.service.onResourceDelete(resourceDeleteMsgOpt); |
99 | } | 102 | } |
@@ -30,31 +30,33 @@ package org.thingsboard.server.transport.lwm2m.server; | @@ -30,31 +30,33 @@ package org.thingsboard.server.transport.lwm2m.server; | ||
30 | * limitations under the License. | 30 | * limitations under the License. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | -import com.google.gson.JsonElement; | ||
34 | -import com.google.gson.JsonObject; | ||
35 | import lombok.Getter; | 33 | import lombok.Getter; |
36 | import lombok.extern.slf4j.Slf4j; | 34 | import lombok.extern.slf4j.Slf4j; |
37 | import org.eclipse.leshan.core.model.DDFFileParser; | 35 | import org.eclipse.leshan.core.model.DDFFileParser; |
38 | import org.eclipse.leshan.core.model.DefaultDDFFileValidator; | 36 | import org.eclipse.leshan.core.model.DefaultDDFFileValidator; |
39 | import org.eclipse.leshan.core.model.InvalidDDFFileException; | 37 | import org.eclipse.leshan.core.model.InvalidDDFFileException; |
40 | import org.eclipse.leshan.core.model.ObjectModel; | 38 | import org.eclipse.leshan.core.model.ObjectModel; |
39 | +import org.eclipse.leshan.core.model.ResourceModel; | ||
40 | +import org.eclipse.leshan.core.node.codec.CodecException; | ||
41 | import org.springframework.stereotype.Component; | 41 | import org.springframework.stereotype.Component; |
42 | import org.thingsboard.server.common.transport.TransportContext; | 42 | import org.thingsboard.server.common.transport.TransportContext; |
43 | import org.thingsboard.server.common.transport.TransportResourceCache; | 43 | import org.thingsboard.server.common.transport.TransportResourceCache; |
44 | import org.thingsboard.server.common.transport.TransportService; | 44 | import org.thingsboard.server.common.transport.TransportService; |
45 | import org.thingsboard.server.common.transport.TransportServiceCallback; | 45 | import org.thingsboard.server.common.transport.TransportServiceCallback; |
46 | -import org.thingsboard.server.common.transport.adaptor.AdaptorException; | ||
47 | import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer; | 46 | import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer; |
47 | +import org.thingsboard.server.gen.transport.TransportProtos; | ||
48 | import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; | 48 | import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; |
49 | import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; | 49 | import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; |
50 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | 50 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; |
51 | -import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; | ||
52 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | 51 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
53 | import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor; | 52 | import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor; |
54 | 53 | ||
55 | import java.io.ByteArrayInputStream; | 54 | import java.io.ByteArrayInputStream; |
56 | import java.io.IOException; | 55 | import java.io.IOException; |
56 | +import java.util.ArrayList; | ||
57 | +import java.util.List; | ||
57 | 58 | ||
59 | +import static org.thingsboard.server.gen.transport.TransportProtos.KeyValueType.BOOLEAN_V; | ||
58 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY; | 60 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY; |
59 | 61 | ||
60 | @Slf4j | 62 | @Slf4j |
@@ -91,7 +93,7 @@ public class LwM2mTransportContextServer extends TransportContext { | @@ -91,7 +93,7 @@ public class LwM2mTransportContextServer extends TransportContext { | ||
91 | /** | 93 | /** |
92 | * send to Thingsboard Attribute || Telemetry | 94 | * send to Thingsboard Attribute || Telemetry |
93 | * | 95 | * |
94 | - * @param msg - JsonObject: [{name: value}] | 96 | + * @param msg - JsonObject: [{name: value}] |
95 | * @return - dummy | 97 | * @return - dummy |
96 | */ | 98 | */ |
97 | private <T> TransportServiceCallback<Void> getPubAckCallbackSendAttrTelemetry(final T msg) { | 99 | private <T> TransportServiceCallback<Void> getPubAckCallbackSendAttrTelemetry(final T msg) { |
@@ -108,33 +110,29 @@ public class LwM2mTransportContextServer extends TransportContext { | @@ -108,33 +110,29 @@ public class LwM2mTransportContextServer extends TransportContext { | ||
108 | }; | 110 | }; |
109 | } | 111 | } |
110 | 112 | ||
111 | - public void sendParametersOnThingsboard(JsonElement msg, String topicName, SessionInfoProto sessionInfo) { | ||
112 | - try { | ||
113 | - if (topicName.equals(LwM2mTransportHandler.DEVICE_ATTRIBUTES_TOPIC)) { | ||
114 | - PostAttributeMsg postAttributeMsg = adaptor.convertToPostAttributes(msg); | ||
115 | - TransportServiceCallback call = this.getPubAckCallbackSendAttrTelemetry(postAttributeMsg); | ||
116 | - transportService.process(sessionInfo, postAttributeMsg, this.getPubAckCallbackSendAttrTelemetry(call)); | ||
117 | - } else if (topicName.equals(LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC)) { | ||
118 | - PostTelemetryMsg postTelemetryMsg = adaptor.convertToPostTelemetry(msg); | ||
119 | - TransportServiceCallback call = this.getPubAckCallbackSendAttrTelemetry(postTelemetryMsg); | ||
120 | - transportService.process(sessionInfo, postTelemetryMsg, this.getPubAckCallbackSendAttrTelemetry(call)); | ||
121 | - } | ||
122 | - } catch (AdaptorException e) { | ||
123 | - log.error("[{}] Failed to process publish msg [{}]", topicName, e); | ||
124 | - log.info("[{}] Closing current session due to invalid publish", topicName); | ||
125 | - } | 113 | + public void sendParametersOnThingsboardAttribute(List<TransportProtos.KeyValueProto> result, SessionInfoProto sessionInfo) { |
114 | + PostAttributeMsg.Builder request = PostAttributeMsg.newBuilder(); | ||
115 | + request.addAllKv(result); | ||
116 | + PostAttributeMsg postAttributeMsg = request.build(); | ||
117 | + TransportServiceCallback call = this.getPubAckCallbackSendAttrTelemetry(postAttributeMsg); | ||
118 | + transportService.process(sessionInfo, postAttributeMsg, this.getPubAckCallbackSendAttrTelemetry(call)); | ||
126 | } | 119 | } |
127 | 120 | ||
128 | - public JsonObject getTelemetryMsgObject(String logMsg) { | ||
129 | - JsonObject telemetries = new JsonObject(); | ||
130 | - telemetries.addProperty(LOG_LW2M_TELEMETRY, logMsg); | ||
131 | - return telemetries; | 121 | + public void sendParametersOnThingsboardTelemetry(List<TransportProtos.KeyValueProto> result, SessionInfoProto sessionInfo) { |
122 | + PostTelemetryMsg.Builder request = PostTelemetryMsg.newBuilder(); | ||
123 | + TransportProtos.TsKvListProto.Builder builder = TransportProtos.TsKvListProto.newBuilder(); | ||
124 | + builder.setTs(System.currentTimeMillis()); | ||
125 | + builder.addAllKv(result); | ||
126 | + request.addTsKvList(builder.build()); | ||
127 | + PostTelemetryMsg postTelemetryMsg = request.build(); | ||
128 | + TransportServiceCallback call = this.getPubAckCallbackSendAttrTelemetry(postTelemetryMsg); | ||
129 | + transportService.process(sessionInfo, postTelemetryMsg, this.getPubAckCallbackSendAttrTelemetry(call)); | ||
132 | } | 130 | } |
133 | 131 | ||
134 | /** | 132 | /** |
135 | * @return - sessionInfo after access connect client | 133 | * @return - sessionInfo after access connect client |
136 | */ | 134 | */ |
137 | - public SessionInfoProto getValidateSessionInfo(ValidateDeviceCredentialsResponseMsg msg, long mostSignificantBits, long leastSignificantBits) { | 135 | + public SessionInfoProto getValidateSessionInfo(TransportProtos.ValidateDeviceCredentialsResponseMsg msg, long mostSignificantBits, long leastSignificantBits) { |
138 | return SessionInfoProto.newBuilder() | 136 | return SessionInfoProto.newBuilder() |
139 | .setNodeId(this.getNodeId()) | 137 | .setNodeId(this.getNodeId()) |
140 | .setSessionIdMSB(mostSignificantBits) | 138 | .setSessionIdMSB(mostSignificantBits) |
@@ -159,4 +157,90 @@ public class LwM2mTransportContextServer extends TransportContext { | @@ -159,4 +157,90 @@ public class LwM2mTransportContextServer extends TransportContext { | ||
159 | return null; | 157 | return null; |
160 | } | 158 | } |
161 | } | 159 | } |
160 | + | ||
161 | + /** | ||
162 | + * | ||
163 | + * @param logMsg - info about Logs | ||
164 | + * @return- KeyValueProto for telemetry (Logs) | ||
165 | + */ | ||
166 | + public List <TransportProtos.KeyValueProto> getKvLogyToThingsboard(String logMsg) { | ||
167 | + List <TransportProtos.KeyValueProto> result = new ArrayList<>(); | ||
168 | + result.add(TransportProtos.KeyValueProto.newBuilder() | ||
169 | + .setKey(LOG_LW2M_TELEMETRY) | ||
170 | + .setType(TransportProtos.KeyValueType.STRING_V) | ||
171 | + .setStringV(logMsg).build()); | ||
172 | + return result; | ||
173 | + } | ||
174 | + | ||
175 | + /** | ||
176 | + * @return - KeyValueProto for attribute/telemetry (change value) | ||
177 | + * @throws CodecException - | ||
178 | + */ | ||
179 | + | ||
180 | + public TransportProtos.KeyValueProto getKvAttrTelemetryToThingsboard(ResourceModel.Type resourceType, String resourceName, Object value, boolean isMultiInstances) { | ||
181 | + TransportProtos.KeyValueProto.Builder kvProto = TransportProtos.KeyValueProto.newBuilder().setKey(resourceName); | ||
182 | + if (isMultiInstances) { | ||
183 | + kvProto.setType(TransportProtos.KeyValueType.JSON_V) | ||
184 | + .setJsonV((String) value); | ||
185 | + } | ||
186 | + else { | ||
187 | + switch (resourceType) { | ||
188 | + case BOOLEAN: | ||
189 | + kvProto.setType(BOOLEAN_V).setBoolV((Boolean) value).build(); | ||
190 | + break; | ||
191 | + case STRING: | ||
192 | + case TIME: | ||
193 | + case OPAQUE: | ||
194 | + case OBJLNK: | ||
195 | + kvProto.setType(TransportProtos.KeyValueType.STRING_V).setStringV((String) value); | ||
196 | + break; | ||
197 | + case INTEGER: | ||
198 | + kvProto.setType(TransportProtos.KeyValueType.LONG_V).setLongV((Long) value); | ||
199 | + break; | ||
200 | + case FLOAT: | ||
201 | + kvProto.setType(TransportProtos.KeyValueType.DOUBLE_V).setDoubleV((Double) value); | ||
202 | + } | ||
203 | + } | ||
204 | + return kvProto.build(); | ||
205 | + } | ||
206 | + | ||
207 | + /** | ||
208 | + * | ||
209 | + * @param currentType - | ||
210 | + * @param resourcePath - | ||
211 | + * @return | ||
212 | + */ | ||
213 | + public ResourceModel.Type getResourceModelTypeEqualsKvProtoValueType(ResourceModel.Type currentType, String resourcePath) { | ||
214 | + switch (currentType) { | ||
215 | + case BOOLEAN: | ||
216 | + return ResourceModel.Type.BOOLEAN; | ||
217 | + case STRING: | ||
218 | + case TIME: | ||
219 | + case OPAQUE: | ||
220 | + case OBJLNK: | ||
221 | + return ResourceModel.Type.STRING; | ||
222 | + case INTEGER: | ||
223 | + return ResourceModel.Type.INTEGER; | ||
224 | + case FLOAT: | ||
225 | + return ResourceModel.Type.FLOAT; | ||
226 | + default: | ||
227 | + } | ||
228 | + throw new CodecException("Invalid ResourceModel_Type for resource %s, got %s", resourcePath, currentType); | ||
229 | + } | ||
230 | + | ||
231 | + public Object getValueFromKvProto (TransportProtos.KeyValueProto kv) { | ||
232 | + switch (kv.getType()) { | ||
233 | + case BOOLEAN_V: | ||
234 | + return kv.getBoolV(); | ||
235 | + case LONG_V: | ||
236 | + return kv.getLongV(); | ||
237 | + case DOUBLE_V: | ||
238 | + return kv.getDoubleV(); | ||
239 | + case STRING_V: | ||
240 | + return kv.getStringV(); | ||
241 | + case JSON_V: | ||
242 | + return kv.getJsonV(); | ||
243 | + } | ||
244 | + return null; | ||
245 | + } | ||
162 | } | 246 | } |