Commit 39591675f9a94c29d58efcc379c41babd7f1851e
1 parent
b03cf28a
Extended Edge controller & service & dao for SQL. Added service test. NoSQL impl - TODO
Showing
25 changed files
with
2016 additions
and
179 deletions
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.controller; | 16 | package org.thingsboard.server.controller; |
17 | 17 | ||
18 | +import com.google.common.util.concurrent.ListenableFuture; | ||
18 | import org.springframework.http.HttpStatus; | 19 | import org.springframework.http.HttpStatus; |
19 | import org.springframework.security.access.prepost.PreAuthorize; | 20 | import org.springframework.security.access.prepost.PreAuthorize; |
20 | import org.springframework.web.bind.annotation.PathVariable; | 21 | import org.springframework.web.bind.annotation.PathVariable; |
@@ -25,14 +26,22 @@ import org.springframework.web.bind.annotation.RequestParam; | @@ -25,14 +26,22 @@ import org.springframework.web.bind.annotation.RequestParam; | ||
25 | import org.springframework.web.bind.annotation.ResponseBody; | 26 | import org.springframework.web.bind.annotation.ResponseBody; |
26 | import org.springframework.web.bind.annotation.ResponseStatus; | 27 | import org.springframework.web.bind.annotation.ResponseStatus; |
27 | import org.springframework.web.bind.annotation.RestController; | 28 | import org.springframework.web.bind.annotation.RestController; |
29 | +import org.thingsboard.server.common.data.Customer; | ||
30 | +import org.thingsboard.server.common.data.Device; | ||
31 | +import org.thingsboard.server.common.data.EntitySubtype; | ||
28 | import org.thingsboard.server.common.data.EntityType; | 32 | import org.thingsboard.server.common.data.EntityType; |
29 | import org.thingsboard.server.common.data.audit.ActionType; | 33 | import org.thingsboard.server.common.data.audit.ActionType; |
34 | +import org.thingsboard.server.common.data.device.DeviceSearchQuery; | ||
30 | import org.thingsboard.server.common.data.edge.Edge; | 35 | import org.thingsboard.server.common.data.edge.Edge; |
36 | +import org.thingsboard.server.common.data.edge.EdgeSearchQuery; | ||
31 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 37 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
38 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
32 | import org.thingsboard.server.common.data.id.EdgeId; | 39 | import org.thingsboard.server.common.data.id.EdgeId; |
33 | import org.thingsboard.server.common.data.id.TenantId; | 40 | import org.thingsboard.server.common.data.id.TenantId; |
34 | import org.thingsboard.server.common.data.page.TextPageData; | 41 | import org.thingsboard.server.common.data.page.TextPageData; |
35 | import org.thingsboard.server.common.data.page.TextPageLink; | 42 | import org.thingsboard.server.common.data.page.TextPageLink; |
43 | +import org.thingsboard.server.dao.exception.IncorrectParameterException; | ||
44 | +import org.thingsboard.server.dao.model.ModelConstants; | ||
36 | import org.thingsboard.server.service.security.model.SecurityUser; | 45 | import org.thingsboard.server.service.security.model.SecurityUser; |
37 | import org.thingsboard.server.service.security.permission.Operation; | 46 | import org.thingsboard.server.service.security.permission.Operation; |
38 | import org.thingsboard.server.service.security.permission.Resource; | 47 | import org.thingsboard.server.service.security.permission.Resource; |
@@ -84,25 +93,6 @@ public class EdgeController extends BaseController { | @@ -84,25 +93,6 @@ public class EdgeController extends BaseController { | ||
84 | } | 93 | } |
85 | } | 94 | } |
86 | 95 | ||
87 | - | ||
88 | - @PreAuthorize("hasAuthority('TENANT_ADMIN')") | ||
89 | - @RequestMapping(value = "/edges", params = {"limit"}, method = RequestMethod.GET) | ||
90 | - @ResponseBody | ||
91 | - public TextPageData<Edge> getEdges( | ||
92 | - @RequestParam int limit, | ||
93 | - @RequestParam(required = false) String textSearch, | ||
94 | - @RequestParam(required = false) String idOffset, | ||
95 | - @RequestParam(required = false) String textOffset) throws ThingsboardException { | ||
96 | - try { | ||
97 | - accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, Operation.READ); | ||
98 | - TenantId tenantId = getCurrentUser().getTenantId(); | ||
99 | - TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset); | ||
100 | - return checkNotNull(edgeService.findTenantEdges(tenantId, pageLink)); | ||
101 | - } catch (Exception e) { | ||
102 | - throw handleException(e); | ||
103 | - } | ||
104 | - } | ||
105 | - | ||
106 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") | 96 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") |
107 | @RequestMapping(value = "/edge/{edgeId}", method = RequestMethod.DELETE) | 97 | @RequestMapping(value = "/edge/{edgeId}", method = RequestMethod.DELETE) |
108 | @ResponseStatus(value = HttpStatus.OK) | 98 | @ResponseStatus(value = HttpStatus.OK) |
@@ -129,35 +119,209 @@ public class EdgeController extends BaseController { | @@ -129,35 +119,209 @@ public class EdgeController extends BaseController { | ||
129 | } | 119 | } |
130 | 120 | ||
131 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") | 121 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") |
122 | + @RequestMapping(value = "/customer/{customerId}/edge/{edgeId}", method = RequestMethod.POST) | ||
123 | + @ResponseBody | ||
124 | + public Edge assignEdgeToCustomer(@PathVariable("customerId") String strCustomerId, | ||
125 | + @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { | ||
126 | + checkParameter("customerId", strCustomerId); | ||
127 | + checkParameter(EDGE_ID, strEdgeId); | ||
128 | + try { | ||
129 | + CustomerId customerId = new CustomerId(toUUID(strCustomerId)); | ||
130 | + Customer customer = checkCustomerId(customerId, Operation.READ); | ||
131 | + | ||
132 | + EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); | ||
133 | + checkEdgeId(edgeId, Operation.ASSIGN_TO_CUSTOMER); | ||
134 | + | ||
135 | + Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(getCurrentUser().getTenantId(), edgeId, customerId)); | ||
136 | + | ||
137 | + logEntityAction(edgeId, savedEdge, | ||
138 | + savedEdge.getCustomerId(), | ||
139 | + ActionType.ASSIGNED_TO_CUSTOMER, null, strEdgeId, strCustomerId, customer.getName()); | ||
140 | + | ||
141 | + return savedEdge; | ||
142 | + } catch (Exception e) { | ||
143 | + logEntityAction(emptyId(EntityType.EDGE), null, | ||
144 | + null, | ||
145 | + ActionType.ASSIGNED_TO_CUSTOMER, e, strEdgeId, strCustomerId); | ||
146 | + throw handleException(e); | ||
147 | + } | ||
148 | + } | ||
149 | + | ||
150 | + @PreAuthorize("hasAuthority('TENANT_ADMIN')") | ||
151 | + @RequestMapping(value = "/customer/edge/{edgeId}", method = RequestMethod.DELETE) | ||
152 | + @ResponseBody | ||
153 | + public Edge unassignEdgeFromCustomer(@PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { | ||
154 | + checkParameter(EDGE_ID, strEdgeId); | ||
155 | + try { | ||
156 | + EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); | ||
157 | + Edge edge = checkEdgeId(edgeId, Operation.UNASSIGN_FROM_CUSTOMER); | ||
158 | + if (edge.getCustomerId() == null || edge.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) { | ||
159 | + throw new IncorrectParameterException("Edge isn't assigned to any customer!"); | ||
160 | + } | ||
161 | + Customer customer = checkCustomerId(edge.getCustomerId(), Operation.READ); | ||
162 | + | ||
163 | + Edge savedEdge = checkNotNull(edgeService.unassignEdgeFromCustomer(getCurrentUser().getTenantId(), edgeId)); | ||
164 | + | ||
165 | + logEntityAction(edgeId, edge, | ||
166 | + edge.getCustomerId(), | ||
167 | + ActionType.UNASSIGNED_FROM_CUSTOMER, null, strEdgeId, customer.getId().toString(), customer.getName()); | ||
168 | + | ||
169 | + return savedEdge; | ||
170 | + } catch (Exception e) { | ||
171 | + logEntityAction(emptyId(EntityType.EDGE), null, | ||
172 | + null, | ||
173 | + ActionType.UNASSIGNED_FROM_CUSTOMER, e, strEdgeId); | ||
174 | + throw handleException(e); | ||
175 | + } | ||
176 | + } | ||
177 | + | ||
178 | + @PreAuthorize("hasAuthority('TENANT_ADMIN')") | ||
179 | + @RequestMapping(value = "/customer/public/edge/{edgeId}", method = RequestMethod.POST) | ||
180 | + @ResponseBody | ||
181 | + public Edge assignEdgeToPublicCustomer(@PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { | ||
182 | + checkParameter(EDGE_ID, strEdgeId); | ||
183 | + try { | ||
184 | + EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); | ||
185 | + Edge edge = checkEdgeId(edgeId, Operation.ASSIGN_TO_CUSTOMER); | ||
186 | + Customer publicCustomer = customerService.findOrCreatePublicCustomer(edge.getTenantId()); | ||
187 | + Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(getCurrentUser().getTenantId(), edgeId, publicCustomer.getId())); | ||
188 | + | ||
189 | + logEntityAction(edgeId, savedEdge, | ||
190 | + savedEdge.getCustomerId(), | ||
191 | + ActionType.ASSIGNED_TO_CUSTOMER, null, strEdgeId, publicCustomer.getId().toString(), publicCustomer.getName()); | ||
192 | + | ||
193 | + return savedEdge; | ||
194 | + } catch (Exception e) { | ||
195 | + logEntityAction(emptyId(EntityType.EDGE), null, | ||
196 | + null, | ||
197 | + ActionType.ASSIGNED_TO_CUSTOMER, e, strEdgeId); | ||
198 | + throw handleException(e); | ||
199 | + } | ||
200 | + } | ||
201 | + | ||
202 | + @PreAuthorize("hasAuthority('TENANT_ADMIN')") | ||
203 | + @RequestMapping(value = "/tenant/edges", params = {"limit"}, method = RequestMethod.GET) | ||
204 | + @ResponseBody | ||
205 | + public TextPageData<Edge> getTenantEdges( | ||
206 | + @RequestParam int limit, | ||
207 | + @RequestParam(required = false) String type, | ||
208 | + @RequestParam(required = false) String textSearch, | ||
209 | + @RequestParam(required = false) String idOffset, | ||
210 | + @RequestParam(required = false) String textOffset) throws ThingsboardException { | ||
211 | + try { | ||
212 | + TenantId tenantId = getCurrentUser().getTenantId(); | ||
213 | + TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset); | ||
214 | + if (type != null && type.trim().length() > 0) { | ||
215 | + return checkNotNull(edgeService.findEdgesByTenantIdAndType(tenantId, type, pageLink)); | ||
216 | + } else { | ||
217 | + return checkNotNull(edgeService.findEdgesByTenantId(tenantId, pageLink)); | ||
218 | + } | ||
219 | + } catch (Exception e) { | ||
220 | + throw handleException(e); | ||
221 | + } | ||
222 | + } | ||
223 | + | ||
224 | + @PreAuthorize("hasAuthority('TENANT_ADMIN')") | ||
225 | + @RequestMapping(value = "/tenant/edges", params = {"edgeName"}, method = RequestMethod.GET) | ||
226 | + @ResponseBody | ||
227 | + public Edge getTenantEdge( | ||
228 | + @RequestParam String edgeName) throws ThingsboardException { | ||
229 | + try { | ||
230 | + TenantId tenantId = getCurrentUser().getTenantId(); | ||
231 | + return checkNotNull(edgeService.findEdgeByTenantIdAndName(tenantId, edgeName)); | ||
232 | + } catch (Exception e) { | ||
233 | + throw handleException(e); | ||
234 | + } | ||
235 | + } | ||
236 | + | ||
237 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | ||
238 | + @RequestMapping(value = "/customer/{customerId}/edges", params = {"limit"}, method = RequestMethod.GET) | ||
239 | + @ResponseBody | ||
240 | + public TextPageData<Edge> getCustomerEdges( | ||
241 | + @PathVariable("customerId") String strCustomerId, | ||
242 | + @RequestParam int limit, | ||
243 | + @RequestParam(required = false) String type, | ||
244 | + @RequestParam(required = false) String textSearch, | ||
245 | + @RequestParam(required = false) String idOffset, | ||
246 | + @RequestParam(required = false) String textOffset) throws ThingsboardException { | ||
247 | + checkParameter("customerId", strCustomerId); | ||
248 | + try { | ||
249 | + TenantId tenantId = getCurrentUser().getTenantId(); | ||
250 | + CustomerId customerId = new CustomerId(toUUID(strCustomerId)); | ||
251 | + checkCustomerId(customerId, Operation.READ); | ||
252 | + TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset); | ||
253 | + if (type != null && type.trim().length() > 0) { | ||
254 | + return checkNotNull(edgeService.findEdgesByTenantIdAndCustomerIdAndType(tenantId, customerId, type, pageLink)); | ||
255 | + } else { | ||
256 | + return checkNotNull(edgeService.findEdgesByTenantIdAndCustomerId(tenantId, customerId, pageLink)); | ||
257 | + } | ||
258 | + } catch (Exception e) { | ||
259 | + throw handleException(e); | ||
260 | + } | ||
261 | + } | ||
262 | + | ||
263 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | ||
132 | @RequestMapping(value = "/edges", params = {"edgeIds"}, method = RequestMethod.GET) | 264 | @RequestMapping(value = "/edges", params = {"edgeIds"}, method = RequestMethod.GET) |
133 | @ResponseBody | 265 | @ResponseBody |
134 | public List<Edge> getEdgesByIds( | 266 | public List<Edge> getEdgesByIds( |
135 | @RequestParam("edgeIds") String[] strEdgeIds) throws ThingsboardException { | 267 | @RequestParam("edgeIds") String[] strEdgeIds) throws ThingsboardException { |
136 | checkArrayParameter("edgeIds", strEdgeIds); | 268 | checkArrayParameter("edgeIds", strEdgeIds); |
137 | try { | 269 | try { |
138 | - accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, Operation.READ); | ||
139 | SecurityUser user = getCurrentUser(); | 270 | SecurityUser user = getCurrentUser(); |
140 | TenantId tenantId = user.getTenantId(); | 271 | TenantId tenantId = user.getTenantId(); |
272 | + CustomerId customerId = user.getCustomerId(); | ||
141 | List<EdgeId> edgeIds = new ArrayList<>(); | 273 | List<EdgeId> edgeIds = new ArrayList<>(); |
142 | for (String strEdgeId : strEdgeIds) { | 274 | for (String strEdgeId : strEdgeIds) { |
143 | edgeIds.add(new EdgeId(toUUID(strEdgeId))); | 275 | edgeIds.add(new EdgeId(toUUID(strEdgeId))); |
144 | } | 276 | } |
145 | - List<Edge> edges = checkNotNull(edgeService.findEdgesByIdsAsync(tenantId, edgeIds).get()); | ||
146 | - return filterEdgesByReadPermission(edges); | 277 | + ListenableFuture<List<Edge>> edges; |
278 | + if (customerId == null || customerId.isNullUid()) { | ||
279 | + edges = edgeService.findEdgesByTenantIdAndIdsAsync(tenantId, edgeIds); | ||
280 | + } else { | ||
281 | + edges = edgeService.findEdgesByTenantIdCustomerIdAndIdsAsync(tenantId, customerId, edgeIds); | ||
282 | + } | ||
283 | + return checkNotNull(edges.get()); | ||
147 | } catch (Exception e) { | 284 | } catch (Exception e) { |
148 | throw handleException(e); | 285 | throw handleException(e); |
149 | } | 286 | } |
150 | } | 287 | } |
151 | 288 | ||
152 | - private List<Edge> filterEdgesByReadPermission(List<Edge> edges) { | ||
153 | - return edges.stream().filter(edge -> { | ||
154 | - try { | ||
155 | - accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, Operation.READ, edge.getId(), edge); | ||
156 | - return true; | ||
157 | - } catch (ThingsboardException e) { | ||
158 | - return false; | ||
159 | - } | ||
160 | - }).collect(Collectors.toList()); | 289 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
290 | + @RequestMapping(value = "/edges", method = RequestMethod.POST) | ||
291 | + @ResponseBody | ||
292 | + public List<Edge> findByQuery(@RequestBody EdgeSearchQuery query) throws ThingsboardException { | ||
293 | + checkNotNull(query); | ||
294 | + checkNotNull(query.getParameters()); | ||
295 | + checkNotNull(query.getEdgeTypes()); | ||
296 | + checkEntityId(query.getParameters().getEntityId(), Operation.READ); | ||
297 | + try { | ||
298 | + List<Edge> edges = checkNotNull(edgeService.findEdgesByQuery(getCurrentUser().getTenantId(), query).get()); | ||
299 | + edges = edges.stream().filter(edge -> { | ||
300 | + try { | ||
301 | + accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, Operation.READ, edge.getId(), edge); | ||
302 | + return true; | ||
303 | + } catch (ThingsboardException e) { | ||
304 | + return false; | ||
305 | + } | ||
306 | + }).collect(Collectors.toList()); | ||
307 | + return edges; | ||
308 | + } catch (Exception e) { | ||
309 | + throw handleException(e); | ||
310 | + } | ||
311 | + } | ||
312 | + | ||
313 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | ||
314 | + @RequestMapping(value = "/edge/types", method = RequestMethod.GET) | ||
315 | + @ResponseBody | ||
316 | + public List<EntitySubtype> getEdgeTypes() throws ThingsboardException { | ||
317 | + try { | ||
318 | + SecurityUser user = getCurrentUser(); | ||
319 | + TenantId tenantId = user.getTenantId(); | ||
320 | + ListenableFuture<List<EntitySubtype>> edgeTypes = edgeService.findEdgeTypesByTenantId(tenantId); | ||
321 | + return checkNotNull(edgeTypes.get()); | ||
322 | + } catch (Exception e) { | ||
323 | + throw handleException(e); | ||
324 | + } | ||
161 | } | 325 | } |
162 | 326 | ||
163 | } | 327 | } |
@@ -29,10 +29,12 @@ import org.thingsboard.server.common.data.Device; | @@ -29,10 +29,12 @@ import org.thingsboard.server.common.data.Device; | ||
29 | import org.thingsboard.server.common.data.EntityView; | 29 | import org.thingsboard.server.common.data.EntityView; |
30 | import org.thingsboard.server.common.data.Tenant; | 30 | import org.thingsboard.server.common.data.Tenant; |
31 | import org.thingsboard.server.common.data.asset.Asset; | 31 | import org.thingsboard.server.common.data.asset.Asset; |
32 | +import org.thingsboard.server.common.data.edge.Edge; | ||
32 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 33 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
33 | import org.thingsboard.server.common.data.id.AssetId; | 34 | import org.thingsboard.server.common.data.id.AssetId; |
34 | import org.thingsboard.server.common.data.id.CustomerId; | 35 | import org.thingsboard.server.common.data.id.CustomerId; |
35 | import org.thingsboard.server.common.data.id.DeviceId; | 36 | import org.thingsboard.server.common.data.id.DeviceId; |
37 | +import org.thingsboard.server.common.data.id.EdgeId; | ||
36 | import org.thingsboard.server.common.data.id.EntityId; | 38 | import org.thingsboard.server.common.data.id.EntityId; |
37 | import org.thingsboard.server.common.data.id.EntityIdFactory; | 39 | import org.thingsboard.server.common.data.id.EntityIdFactory; |
38 | import org.thingsboard.server.common.data.id.EntityViewId; | 40 | import org.thingsboard.server.common.data.id.EntityViewId; |
@@ -46,6 +48,7 @@ import org.thingsboard.server.dao.alarm.AlarmService; | @@ -46,6 +48,7 @@ import org.thingsboard.server.dao.alarm.AlarmService; | ||
46 | import org.thingsboard.server.dao.asset.AssetService; | 48 | import org.thingsboard.server.dao.asset.AssetService; |
47 | import org.thingsboard.server.dao.customer.CustomerService; | 49 | import org.thingsboard.server.dao.customer.CustomerService; |
48 | import org.thingsboard.server.dao.device.DeviceService; | 50 | import org.thingsboard.server.dao.device.DeviceService; |
51 | +import org.thingsboard.server.dao.edge.EdgeService; | ||
49 | import org.thingsboard.server.dao.entityview.EntityViewService; | 52 | import org.thingsboard.server.dao.entityview.EntityViewService; |
50 | import org.thingsboard.server.dao.rule.RuleChainService; | 53 | import org.thingsboard.server.dao.rule.RuleChainService; |
51 | import org.thingsboard.server.dao.tenant.TenantService; | 54 | import org.thingsboard.server.dao.tenant.TenantService; |
@@ -72,6 +75,7 @@ public class AccessValidator { | @@ -72,6 +75,7 @@ public class AccessValidator { | ||
72 | public static final String CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "Customer user is not allowed to perform this operation!"; | 75 | public static final String CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "Customer user is not allowed to perform this operation!"; |
73 | public static final String SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "System administrator is not allowed to perform this operation!"; | 76 | public static final String SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "System administrator is not allowed to perform this operation!"; |
74 | public static final String DEVICE_WITH_REQUESTED_ID_NOT_FOUND = "Device with requested id wasn't found!"; | 77 | public static final String DEVICE_WITH_REQUESTED_ID_NOT_FOUND = "Device with requested id wasn't found!"; |
78 | + public static final String EDGE_WITH_REQUESTED_ID_NOT_FOUND = "Edge with requested id wasn't found!"; | ||
75 | public static final String ENTITY_VIEW_WITH_REQUESTED_ID_NOT_FOUND = "Entity-view with requested id wasn't found!"; | 79 | public static final String ENTITY_VIEW_WITH_REQUESTED_ID_NOT_FOUND = "Entity-view with requested id wasn't found!"; |
76 | 80 | ||
77 | @Autowired | 81 | @Autowired |
@@ -99,6 +103,9 @@ public class AccessValidator { | @@ -99,6 +103,9 @@ public class AccessValidator { | ||
99 | protected EntityViewService entityViewService; | 103 | protected EntityViewService entityViewService; |
100 | 104 | ||
101 | @Autowired | 105 | @Autowired |
106 | + protected EdgeService edgeService; | ||
107 | + | ||
108 | + @Autowired | ||
102 | protected AccessControlService accessControlService; | 109 | protected AccessControlService accessControlService; |
103 | 110 | ||
104 | private ExecutorService executor; | 111 | private ExecutorService executor; |
@@ -174,6 +181,9 @@ public class AccessValidator { | @@ -174,6 +181,9 @@ public class AccessValidator { | ||
174 | case ENTITY_VIEW: | 181 | case ENTITY_VIEW: |
175 | validateEntityView(currentUser, operation, entityId, callback); | 182 | validateEntityView(currentUser, operation, entityId, callback); |
176 | return; | 183 | return; |
184 | + case EDGE: | ||
185 | + validateEdge(currentUser, operation, entityId, callback); | ||
186 | + return; | ||
177 | default: | 187 | default: |
178 | //TODO: add support of other entities | 188 | //TODO: add support of other entities |
179 | throw new IllegalStateException("Not Implemented!"); | 189 | throw new IllegalStateException("Not Implemented!"); |
@@ -327,6 +337,26 @@ public class AccessValidator { | @@ -327,6 +337,26 @@ public class AccessValidator { | ||
327 | } | 337 | } |
328 | } | 338 | } |
329 | 339 | ||
340 | + private void validateEdge(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) { | ||
341 | + if (currentUser.isSystemAdmin()) { | ||
342 | + callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); | ||
343 | + } else { | ||
344 | + ListenableFuture<Edge> edgeFuture = edgeService.findEdgeByIdAsync(currentUser.getTenantId(), new EdgeId(entityId.getId())); | ||
345 | + Futures.addCallback(edgeFuture, getCallback(callback, edge -> { | ||
346 | + if (edge == null) { | ||
347 | + return ValidationResult.entityNotFound(EDGE_WITH_REQUESTED_ID_NOT_FOUND); | ||
348 | + } else { | ||
349 | + try { | ||
350 | + accessControlService.checkPermission(currentUser, Resource.EDGE, operation, entityId, edge); | ||
351 | + } catch (ThingsboardException e) { | ||
352 | + return ValidationResult.accessDenied(e.getMessage()); | ||
353 | + } | ||
354 | + return ValidationResult.ok(edge); | ||
355 | + } | ||
356 | + }), executor); | ||
357 | + } | ||
358 | + } | ||
359 | + | ||
330 | private <T, V> FutureCallback<T> getCallback(FutureCallback<ValidationResult> callback, Function<T, ValidationResult<V>> transformer) { | 360 | private <T, V> FutureCallback<T> getCallback(FutureCallback<ValidationResult> callback, Function<T, ValidationResult<V>> transformer) { |
331 | return new FutureCallback<T>() { | 361 | return new FutureCallback<T>() { |
332 | @Override | 362 | @Override |
@@ -40,6 +40,7 @@ public class CustomerUserPermissions extends AbstractPermissions { | @@ -40,6 +40,7 @@ public class CustomerUserPermissions extends AbstractPermissions { | ||
40 | put(Resource.USER, userPermissionChecker); | 40 | put(Resource.USER, userPermissionChecker); |
41 | put(Resource.WIDGETS_BUNDLE, widgetsPermissionChecker); | 41 | put(Resource.WIDGETS_BUNDLE, widgetsPermissionChecker); |
42 | put(Resource.WIDGET_TYPE, widgetsPermissionChecker); | 42 | put(Resource.WIDGET_TYPE, widgetsPermissionChecker); |
43 | + put(Resource.EDGE, customerEntityPermissionChecker); | ||
43 | } | 44 | } |
44 | 45 | ||
45 | private static final PermissionChecker customerEntityPermissionChecker = | 46 | private static final PermissionChecker customerEntityPermissionChecker = |
@@ -267,6 +267,9 @@ caffeine: | @@ -267,6 +267,9 @@ caffeine: | ||
267 | entityViews: | 267 | entityViews: |
268 | timeToLiveInMinutes: 1440 | 268 | timeToLiveInMinutes: 1440 |
269 | maxSize: 100000 | 269 | maxSize: 100000 |
270 | + edges: | ||
271 | + timeToLiveInMinutes: 1440 | ||
272 | + maxSize: 100000 | ||
270 | claimDevices: | 273 | claimDevices: |
271 | timeToLiveInMinutes: 1 | 274 | timeToLiveInMinutes: 1 |
272 | maxSize: 100000 | 275 | maxSize: 100000 |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | * you may not use this file except in compliance with 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 | 6 | * You may obtain a copy of the License at |
7 | * | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * | 9 | * |
10 | * Unless required by applicable law or agreed to in writing, software | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
@@ -15,39 +15,46 @@ | @@ -15,39 +15,46 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.controller; | 16 | package org.thingsboard.server.controller; |
17 | 17 | ||
18 | +import com.datastax.driver.core.utils.UUIDs; | ||
18 | import com.fasterxml.jackson.core.type.TypeReference; | 19 | import com.fasterxml.jackson.core.type.TypeReference; |
19 | import org.apache.commons.lang3.RandomStringUtils; | 20 | import org.apache.commons.lang3.RandomStringUtils; |
20 | import org.junit.After; | 21 | import org.junit.After; |
21 | import org.junit.Assert; | 22 | import org.junit.Assert; |
22 | import org.junit.Before; | 23 | import org.junit.Before; |
23 | import org.junit.Test; | 24 | import org.junit.Test; |
25 | +import org.thingsboard.server.common.data.Customer; | ||
26 | +import org.thingsboard.server.common.data.EntitySubtype; | ||
24 | import org.thingsboard.server.common.data.Tenant; | 27 | import org.thingsboard.server.common.data.Tenant; |
25 | import org.thingsboard.server.common.data.User; | 28 | import org.thingsboard.server.common.data.User; |
26 | import org.thingsboard.server.common.data.edge.Edge; | 29 | import org.thingsboard.server.common.data.edge.Edge; |
30 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
27 | import org.thingsboard.server.common.data.page.TextPageData; | 31 | import org.thingsboard.server.common.data.page.TextPageData; |
28 | import org.thingsboard.server.common.data.page.TextPageLink; | 32 | import org.thingsboard.server.common.data.page.TextPageLink; |
29 | import org.thingsboard.server.common.data.security.Authority; | 33 | import org.thingsboard.server.common.data.security.Authority; |
34 | +import org.thingsboard.server.dao.model.ModelConstants; | ||
30 | 35 | ||
31 | import java.util.ArrayList; | 36 | import java.util.ArrayList; |
32 | import java.util.Collections; | 37 | import java.util.Collections; |
33 | import java.util.List; | 38 | import java.util.List; |
34 | 39 | ||
35 | import static org.hamcrest.Matchers.containsString; | 40 | import static org.hamcrest.Matchers.containsString; |
36 | -import static org.junit.Assert.assertEquals; | ||
37 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | 41 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
42 | +import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; | ||
38 | 43 | ||
39 | public abstract class BaseEdgeControllerTest extends AbstractControllerTest { | 44 | public abstract class BaseEdgeControllerTest extends AbstractControllerTest { |
40 | 45 | ||
41 | - private IdComparator<Edge> idComparator; | 46 | + private IdComparator<Edge> idComparator = new IdComparator<>(); |
47 | + | ||
42 | private Tenant savedTenant; | 48 | private Tenant savedTenant; |
43 | private User tenantAdmin; | 49 | private User tenantAdmin; |
44 | 50 | ||
45 | @Before | 51 | @Before |
46 | public void beforeTest() throws Exception { | 52 | public void beforeTest() throws Exception { |
47 | loginSysAdmin(); | 53 | loginSysAdmin(); |
48 | - idComparator = new IdComparator<>(); | ||
49 | 54 | ||
50 | - savedTenant = doPost("/api/tenant", getNewTenant("My tenant"), Tenant.class); | 55 | + Tenant tenant = new Tenant(); |
56 | + tenant.setTitle("My tenant"); | ||
57 | + savedTenant = doPost("/api/tenant", tenant, Tenant.class); | ||
51 | Assert.assertNotNull(savedTenant); | 58 | Assert.assertNotNull(savedTenant); |
52 | 59 | ||
53 | tenantAdmin = new User(); | 60 | tenantAdmin = new User(); |
@@ -56,44 +63,88 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest { | @@ -56,44 +63,88 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest { | ||
56 | tenantAdmin.setEmail("tenant2@thingsboard.org"); | 63 | tenantAdmin.setEmail("tenant2@thingsboard.org"); |
57 | tenantAdmin.setFirstName("Joe"); | 64 | tenantAdmin.setFirstName("Joe"); |
58 | tenantAdmin.setLastName("Downs"); | 65 | tenantAdmin.setLastName("Downs"); |
59 | - tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); | ||
60 | 66 | ||
67 | + tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); | ||
61 | } | 68 | } |
62 | 69 | ||
63 | @After | 70 | @After |
64 | public void afterTest() throws Exception { | 71 | public void afterTest() throws Exception { |
65 | loginSysAdmin(); | 72 | loginSysAdmin(); |
73 | + | ||
66 | doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) | 74 | doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) |
67 | .andExpect(status().isOk()); | 75 | .andExpect(status().isOk()); |
68 | } | 76 | } |
69 | 77 | ||
70 | @Test | 78 | @Test |
71 | - public void testFindEdgeById() throws Exception { | ||
72 | - Edge savedEdge = getNewSavedEdge("Test edge"); | ||
73 | - Edge foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class); | ||
74 | - Assert.assertNotNull(foundEdge); | ||
75 | - assertEquals(savedEdge, foundEdge); | ||
76 | - } | ||
77 | - | ||
78 | - @Test | ||
79 | public void testSaveEdge() throws Exception { | 79 | public void testSaveEdge() throws Exception { |
80 | - Edge savedEdge = getNewSavedEdge("Test edge"); | 80 | + Edge edge = new Edge(); |
81 | + edge.setName("My edge"); | ||
82 | + edge.setType("default"); | ||
83 | + Edge savedEdge = doPost("/api/edge", edge, Edge.class); | ||
81 | 84 | ||
82 | Assert.assertNotNull(savedEdge); | 85 | Assert.assertNotNull(savedEdge); |
83 | Assert.assertNotNull(savedEdge.getId()); | 86 | Assert.assertNotNull(savedEdge.getId()); |
84 | Assert.assertTrue(savedEdge.getCreatedTime() > 0); | 87 | Assert.assertTrue(savedEdge.getCreatedTime() > 0); |
85 | - assertEquals(savedTenant.getId(), savedEdge.getTenantId()); | 88 | + Assert.assertEquals(savedTenant.getId(), savedEdge.getTenantId()); |
89 | + Assert.assertNotNull(savedEdge.getCustomerId()); | ||
90 | + Assert.assertEquals(NULL_UUID, savedEdge.getCustomerId().getId()); | ||
91 | + Assert.assertEquals(edge.getName(), savedEdge.getName()); | ||
86 | 92 | ||
87 | - savedEdge.setName("New test edge"); | 93 | + savedEdge.setName("My new edge"); |
88 | doPost("/api/edge", savedEdge, Edge.class); | 94 | doPost("/api/edge", savedEdge, Edge.class); |
95 | + | ||
89 | Edge foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class); | 96 | Edge foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class); |
97 | + Assert.assertEquals(foundEdge.getName(), savedEdge.getName()); | ||
98 | + } | ||
90 | 99 | ||
91 | - assertEquals(foundEdge.getName(), savedEdge.getName()); | 100 | + @Test |
101 | + public void testFindEdgeById() throws Exception { | ||
102 | + Edge edge = new Edge(); | ||
103 | + edge.setName("My edge"); | ||
104 | + edge.setType("default"); | ||
105 | + Edge savedEdge = doPost("/api/edge", edge, Edge.class); | ||
106 | + Edge foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class); | ||
107 | + Assert.assertNotNull(foundEdge); | ||
108 | + Assert.assertEquals(savedEdge, foundEdge); | ||
109 | + } | ||
110 | + | ||
111 | + @Test | ||
112 | + public void testFindEdgeTypesByTenantId() throws Exception { | ||
113 | + List<Edge> edges = new ArrayList<>(); | ||
114 | + for (int i = 0; i < 3; i++) { | ||
115 | + Edge edge = new Edge(); | ||
116 | + edge.setName("My edge B" + i); | ||
117 | + edge.setType("typeB"); | ||
118 | + edges.add(doPost("/api/edge", edge, Edge.class)); | ||
119 | + } | ||
120 | + for (int i = 0; i < 7; i++) { | ||
121 | + Edge edge = new Edge(); | ||
122 | + edge.setName("My edge C" + i); | ||
123 | + edge.setType("typeC"); | ||
124 | + edges.add(doPost("/api/edge", edge, Edge.class)); | ||
125 | + } | ||
126 | + for (int i = 0; i < 9; i++) { | ||
127 | + Edge edge = new Edge(); | ||
128 | + edge.setName("My edge A" + i); | ||
129 | + edge.setType("typeA"); | ||
130 | + edges.add(doPost("/api/edge", edge, Edge.class)); | ||
131 | + } | ||
132 | + List<EntitySubtype> edgeTypes = doGetTyped("/api/edge/types", | ||
133 | + new TypeReference<List<EntitySubtype>>() { | ||
134 | + }); | ||
135 | + | ||
136 | + Assert.assertNotNull(edgeTypes); | ||
137 | + Assert.assertEquals(3, edgeTypes.size()); | ||
138 | + Assert.assertEquals("typeA", edgeTypes.get(0).getType()); | ||
139 | + Assert.assertEquals("typeB", edgeTypes.get(1).getType()); | ||
140 | + Assert.assertEquals("typeC", edgeTypes.get(2).getType()); | ||
92 | } | 141 | } |
93 | 142 | ||
94 | @Test | 143 | @Test |
95 | public void testDeleteEdge() throws Exception { | 144 | public void testDeleteEdge() throws Exception { |
96 | - Edge edge = getNewSavedEdge("Test edge"); | 145 | + Edge edge = new Edge(); |
146 | + edge.setName("My edge"); | ||
147 | + edge.setType("default"); | ||
97 | Edge savedEdge = doPost("/api/edge", edge, Edge.class); | 148 | Edge savedEdge = doPost("/api/edge", edge, Edge.class); |
98 | 149 | ||
99 | doDelete("/api/edge/" + savedEdge.getId().getId().toString()) | 150 | doDelete("/api/edge/" + savedEdge.getId().getId().toString()) |
@@ -104,103 +155,523 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest { | @@ -104,103 +155,523 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest { | ||
104 | } | 155 | } |
105 | 156 | ||
106 | @Test | 157 | @Test |
158 | + public void testSaveEdgeWithEmptyType() throws Exception { | ||
159 | + Edge edge = new Edge(); | ||
160 | + edge.setName("My edge"); | ||
161 | + doPost("/api/edge", edge) | ||
162 | + .andExpect(status().isBadRequest()) | ||
163 | + .andExpect(statusReason(containsString("Edge type should be specified"))); | ||
164 | + } | ||
165 | + | ||
166 | + @Test | ||
107 | public void testSaveEdgeWithEmptyName() throws Exception { | 167 | public void testSaveEdgeWithEmptyName() throws Exception { |
108 | Edge edge = new Edge(); | 168 | Edge edge = new Edge(); |
169 | + edge.setType("default"); | ||
109 | doPost("/api/edge", edge) | 170 | doPost("/api/edge", edge) |
110 | .andExpect(status().isBadRequest()) | 171 | .andExpect(status().isBadRequest()) |
111 | - .andExpect(statusReason(containsString("Edge name should be specified!"))); | 172 | + .andExpect(statusReason(containsString("Edge name should be specified"))); |
173 | + } | ||
174 | + | ||
175 | + @Test | ||
176 | + public void testAssignUnassignEdgeToCustomer() throws Exception { | ||
177 | + Edge edge = new Edge(); | ||
178 | + edge.setName("My edge"); | ||
179 | + edge.setType("default"); | ||
180 | + Edge savedEdge = doPost("/api/edge", edge, Edge.class); | ||
181 | + | ||
182 | + Customer customer = new Customer(); | ||
183 | + customer.setTitle("My customer"); | ||
184 | + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); | ||
185 | + | ||
186 | + Edge assignedEdge = doPost("/api/customer/" + savedCustomer.getId().getId().toString() | ||
187 | + + "/edge/" + savedEdge.getId().getId().toString(), Edge.class); | ||
188 | + Assert.assertEquals(savedCustomer.getId(), assignedEdge.getCustomerId()); | ||
189 | + | ||
190 | + Edge foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class); | ||
191 | + Assert.assertEquals(savedCustomer.getId(), foundEdge.getCustomerId()); | ||
192 | + | ||
193 | + Edge unassignedEdge = | ||
194 | + doDelete("/api/customer/edge/" + savedEdge.getId().getId().toString(), Edge.class); | ||
195 | + Assert.assertEquals(ModelConstants.NULL_UUID, unassignedEdge.getCustomerId().getId()); | ||
196 | + | ||
197 | + foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class); | ||
198 | + Assert.assertEquals(ModelConstants.NULL_UUID, foundEdge.getCustomerId().getId()); | ||
112 | } | 199 | } |
113 | 200 | ||
114 | @Test | 201 | @Test |
115 | - public void testGetEdges() throws Exception { | 202 | + public void testAssignEdgeToNonExistentCustomer() throws Exception { |
203 | + Edge edge = new Edge(); | ||
204 | + edge.setName("My edge"); | ||
205 | + edge.setType("default"); | ||
206 | + Edge savedEdge = doPost("/api/edge", edge, Edge.class); | ||
116 | 207 | ||
208 | + doPost("/api/customer/" + UUIDs.timeBased().toString() | ||
209 | + + "/edge/" + savedEdge.getId().getId().toString()) | ||
210 | + .andExpect(status().isNotFound()); | ||
211 | + } | ||
212 | + | ||
213 | + @Test | ||
214 | + public void testAssignEdgeToCustomerFromDifferentTenant() throws Exception { | ||
215 | + loginSysAdmin(); | ||
216 | + | ||
217 | + Tenant tenant2 = new Tenant(); | ||
218 | + tenant2.setTitle("Different tenant"); | ||
219 | + Tenant savedTenant2 = doPost("/api/tenant", tenant2, Tenant.class); | ||
220 | + Assert.assertNotNull(savedTenant2); | ||
221 | + | ||
222 | + User tenantAdmin2 = new User(); | ||
223 | + tenantAdmin2.setAuthority(Authority.TENANT_ADMIN); | ||
224 | + tenantAdmin2.setTenantId(savedTenant2.getId()); | ||
225 | + tenantAdmin2.setEmail("tenant3@thingsboard.org"); | ||
226 | + tenantAdmin2.setFirstName("Joe"); | ||
227 | + tenantAdmin2.setLastName("Downs"); | ||
228 | + | ||
229 | + tenantAdmin2 = createUserAndLogin(tenantAdmin2, "testPassword1"); | ||
230 | + | ||
231 | + Customer customer = new Customer(); | ||
232 | + customer.setTitle("Different customer"); | ||
233 | + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); | ||
234 | + | ||
235 | + login(tenantAdmin.getEmail(), "testPassword1"); | ||
236 | + | ||
237 | + Edge edge = new Edge(); | ||
238 | + edge.setName("My edge"); | ||
239 | + edge.setType("default"); | ||
240 | + Edge savedEdge = doPost("/api/edge", edge, Edge.class); | ||
241 | + | ||
242 | + doPost("/api/customer/" + savedCustomer.getId().getId().toString() | ||
243 | + + "/edge/" + savedEdge.getId().getId().toString()) | ||
244 | + .andExpect(status().isForbidden()); | ||
245 | + | ||
246 | + loginSysAdmin(); | ||
247 | + | ||
248 | + doDelete("/api/tenant/" + savedTenant2.getId().getId().toString()) | ||
249 | + .andExpect(status().isOk()); | ||
250 | + } | ||
251 | + | ||
252 | + @Test | ||
253 | + public void testFindTenantEdges() throws Exception { | ||
117 | List<Edge> edges = new ArrayList<>(); | 254 | List<Edge> edges = new ArrayList<>(); |
118 | for (int i = 0; i < 178; i++) { | 255 | for (int i = 0; i < 178; i++) { |
119 | - edges.add(getNewSavedEdge("Test edge " + i)); | 256 | + Edge edge = new Edge(); |
257 | + edge.setName("Edge" + i); | ||
258 | + edge.setType("default"); | ||
259 | + edges.add(doPost("/api/edge", edge, Edge.class)); | ||
120 | } | 260 | } |
121 | - List<Edge> loadedEdges = loadListOf(new TextPageLink(23), "/api/edges?"); | 261 | + List<Edge> loadedEdges = new ArrayList<>(); |
262 | + TextPageLink pageLink = new TextPageLink(23); | ||
263 | + TextPageData<Edge> pageData = null; | ||
264 | + do { | ||
265 | + pageData = doGetTypedWithPageLink("/api/tenant/edges?", | ||
266 | + new TypeReference<TextPageData<Edge>>() { | ||
267 | + }, pageLink); | ||
268 | + loadedEdges.addAll(pageData.getData()); | ||
269 | + if (pageData.hasNext()) { | ||
270 | + pageLink = pageData.getNextPageLink(); | ||
271 | + } | ||
272 | + } while (pageData.hasNext()); | ||
122 | 273 | ||
123 | Collections.sort(edges, idComparator); | 274 | Collections.sort(edges, idComparator); |
124 | Collections.sort(loadedEdges, idComparator); | 275 | Collections.sort(loadedEdges, idComparator); |
125 | 276 | ||
126 | - assertEquals(edges, loadedEdges); | 277 | + Assert.assertEquals(edges, loadedEdges); |
127 | } | 278 | } |
128 | 279 | ||
129 | @Test | 280 | @Test |
130 | - public void testGetEdgesByName() throws Exception { | ||
131 | - String name1 = "Entity edge1"; | ||
132 | - List<Edge> namesOfEdge1 = fillListOf(143, name1); | ||
133 | - List<Edge> loadedNamesOfEdge1 = loadListOf(new TextPageLink(15, name1), "/api/edges?"); | ||
134 | - Collections.sort(namesOfEdge1, idComparator); | ||
135 | - Collections.sort(loadedNamesOfEdge1, idComparator); | ||
136 | - assertEquals(namesOfEdge1, loadedNamesOfEdge1); | ||
137 | - | ||
138 | - String name2 = "Entity edge2"; | ||
139 | - List<Edge> namesOfEdge2 = fillListOf(75, name2); | ||
140 | - List<Edge> loadedNamesOfEdge2 = loadListOf(new TextPageLink(4, name2), "/api/edges?"); | ||
141 | - Collections.sort(namesOfEdge2, idComparator); | ||
142 | - Collections.sort(loadedNamesOfEdge2, idComparator); | ||
143 | - assertEquals(namesOfEdge2, loadedNamesOfEdge2); | ||
144 | - | ||
145 | - for (Edge edge : loadedNamesOfEdge1) { | ||
146 | - doDelete("/api/edge/" + edge.getId().getId().toString()).andExpect(status().isOk()); | ||
147 | - } | ||
148 | - TextPageData<Edge> pageData = doGetTypedWithPageLink("/api/edges?", | 281 | + public void testFindTenantEdgesByName() throws Exception { |
282 | + String title1 = "Edge title 1"; | ||
283 | + List<Edge> edgesTitle1 = new ArrayList<>(); | ||
284 | + for (int i = 0; i < 143; i++) { | ||
285 | + Edge edge = new Edge(); | ||
286 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
287 | + String name = title1 + suffix; | ||
288 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
289 | + edge.setName(name); | ||
290 | + edge.setType("default"); | ||
291 | + edgesTitle1.add(doPost("/api/edge", edge, Edge.class)); | ||
292 | + } | ||
293 | + String title2 = "Edge title 2"; | ||
294 | + List<Edge> edgesTitle2 = new ArrayList<>(); | ||
295 | + for (int i = 0; i < 75; i++) { | ||
296 | + Edge edge = new Edge(); | ||
297 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
298 | + String name = title2 + suffix; | ||
299 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
300 | + edge.setName(name); | ||
301 | + edge.setType("default"); | ||
302 | + edgesTitle2.add(doPost("/api/edge", edge, Edge.class)); | ||
303 | + } | ||
304 | + | ||
305 | + List<Edge> loadedEdgesTitle1 = new ArrayList<>(); | ||
306 | + TextPageLink pageLink = new TextPageLink(15, title1); | ||
307 | + TextPageData<Edge> pageData = null; | ||
308 | + do { | ||
309 | + pageData = doGetTypedWithPageLink("/api/tenant/edges?", | ||
310 | + new TypeReference<TextPageData<Edge>>() { | ||
311 | + }, pageLink); | ||
312 | + loadedEdgesTitle1.addAll(pageData.getData()); | ||
313 | + if (pageData.hasNext()) { | ||
314 | + pageLink = pageData.getNextPageLink(); | ||
315 | + } | ||
316 | + } while (pageData.hasNext()); | ||
317 | + | ||
318 | + Collections.sort(edgesTitle1, idComparator); | ||
319 | + Collections.sort(loadedEdgesTitle1, idComparator); | ||
320 | + | ||
321 | + Assert.assertEquals(edgesTitle1, loadedEdgesTitle1); | ||
322 | + | ||
323 | + List<Edge> loadedEdgesTitle2 = new ArrayList<>(); | ||
324 | + pageLink = new TextPageLink(4, title2); | ||
325 | + do { | ||
326 | + pageData = doGetTypedWithPageLink("/api/tenant/edges?", | ||
327 | + new TypeReference<TextPageData<Edge>>() { | ||
328 | + }, pageLink); | ||
329 | + loadedEdgesTitle2.addAll(pageData.getData()); | ||
330 | + if (pageData.hasNext()) { | ||
331 | + pageLink = pageData.getNextPageLink(); | ||
332 | + } | ||
333 | + } while (pageData.hasNext()); | ||
334 | + | ||
335 | + Collections.sort(edgesTitle2, idComparator); | ||
336 | + Collections.sort(loadedEdgesTitle2, idComparator); | ||
337 | + | ||
338 | + Assert.assertEquals(edgesTitle2, loadedEdgesTitle2); | ||
339 | + | ||
340 | + for (Edge edge : loadedEdgesTitle1) { | ||
341 | + doDelete("/api/edge/" + edge.getId().getId().toString()) | ||
342 | + .andExpect(status().isOk()); | ||
343 | + } | ||
344 | + | ||
345 | + pageLink = new TextPageLink(4, title1); | ||
346 | + pageData = doGetTypedWithPageLink("/api/tenant/edges?", | ||
149 | new TypeReference<TextPageData<Edge>>() { | 347 | new TypeReference<TextPageData<Edge>>() { |
150 | - }, new TextPageLink(4, name1)); | 348 | + }, pageLink); |
151 | Assert.assertFalse(pageData.hasNext()); | 349 | Assert.assertFalse(pageData.hasNext()); |
152 | - assertEquals(0, pageData.getData().size()); | 350 | + Assert.assertEquals(0, pageData.getData().size()); |
153 | 351 | ||
154 | - for (Edge edge : loadedNamesOfEdge2) { | ||
155 | - doDelete("/api/edge/" + edge.getId().getId().toString()).andExpect(status().isOk()); | 352 | + for (Edge edge : loadedEdgesTitle2) { |
353 | + doDelete("/api/edge/" + edge.getId().getId().toString()) | ||
354 | + .andExpect(status().isOk()); | ||
156 | } | 355 | } |
157 | - pageData = doGetTypedWithPageLink("/api/edges?", new TypeReference<TextPageData<Edge>>() { | ||
158 | - }, new TextPageLink(4, name2)); | 356 | + |
357 | + pageLink = new TextPageLink(4, title2); | ||
358 | + pageData = doGetTypedWithPageLink("/api/tenant/edges?", | ||
359 | + new TypeReference<TextPageData<Edge>>() { | ||
360 | + }, pageLink); | ||
159 | Assert.assertFalse(pageData.hasNext()); | 361 | Assert.assertFalse(pageData.hasNext()); |
160 | - assertEquals(0, pageData.getData().size()); | 362 | + Assert.assertEquals(0, pageData.getData().size()); |
161 | } | 363 | } |
162 | 364 | ||
163 | - private Edge getNewSavedEdge(String name) throws Exception { | ||
164 | - Edge edge = createEdge(name); | ||
165 | - return doPost("/api/edge", edge, Edge.class); | ||
166 | - } | 365 | + @Test |
366 | + public void testFindTenantEdgesByType() throws Exception { | ||
367 | + String title1 = "Edge title 1"; | ||
368 | + String type1 = "typeA"; | ||
369 | + List<Edge> edgesType1 = new ArrayList<>(); | ||
370 | + for (int i = 0; i < 143; i++) { | ||
371 | + Edge edge = new Edge(); | ||
372 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
373 | + String name = title1 + suffix; | ||
374 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
375 | + edge.setName(name); | ||
376 | + edge.setType(type1); | ||
377 | + edgesType1.add(doPost("/api/edge", edge, Edge.class)); | ||
378 | + } | ||
379 | + String title2 = "Edge title 2"; | ||
380 | + String type2 = "typeB"; | ||
381 | + List<Edge> edgesType2 = new ArrayList<>(); | ||
382 | + for (int i = 0; i < 75; i++) { | ||
383 | + Edge edge = new Edge(); | ||
384 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
385 | + String name = title2 + suffix; | ||
386 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
387 | + edge.setName(name); | ||
388 | + edge.setType(type2); | ||
389 | + edgesType2.add(doPost("/api/edge", edge, Edge.class)); | ||
390 | + } | ||
167 | 391 | ||
168 | - private Edge createEdge(String name) { | ||
169 | - Edge edge = new Edge(); | ||
170 | - edge.setTenantId(savedTenant.getId()); | ||
171 | - edge.setName(name); | ||
172 | - return edge; | 392 | + List<Edge> loadedEdgesType1 = new ArrayList<>(); |
393 | + TextPageLink pageLink = new TextPageLink(15); | ||
394 | + TextPageData<Edge> pageData = null; | ||
395 | + do { | ||
396 | + pageData = doGetTypedWithPageLink("/api/tenant/edges?type={type}&", | ||
397 | + new TypeReference<TextPageData<Edge>>() { | ||
398 | + }, pageLink, type1); | ||
399 | + loadedEdgesType1.addAll(pageData.getData()); | ||
400 | + if (pageData.hasNext()) { | ||
401 | + pageLink = pageData.getNextPageLink(); | ||
402 | + } | ||
403 | + } while (pageData.hasNext()); | ||
404 | + | ||
405 | + Collections.sort(edgesType1, idComparator); | ||
406 | + Collections.sort(loadedEdgesType1, idComparator); | ||
407 | + | ||
408 | + Assert.assertEquals(edgesType1, loadedEdgesType1); | ||
409 | + | ||
410 | + List<Edge> loadedEdgesType2 = new ArrayList<>(); | ||
411 | + pageLink = new TextPageLink(4); | ||
412 | + do { | ||
413 | + pageData = doGetTypedWithPageLink("/api/tenant/edges?type={type}&", | ||
414 | + new TypeReference<TextPageData<Edge>>() { | ||
415 | + }, pageLink, type2); | ||
416 | + loadedEdgesType2.addAll(pageData.getData()); | ||
417 | + if (pageData.hasNext()) { | ||
418 | + pageLink = pageData.getNextPageLink(); | ||
419 | + } | ||
420 | + } while (pageData.hasNext()); | ||
421 | + | ||
422 | + Collections.sort(edgesType2, idComparator); | ||
423 | + Collections.sort(loadedEdgesType2, idComparator); | ||
424 | + | ||
425 | + Assert.assertEquals(edgesType2, loadedEdgesType2); | ||
426 | + | ||
427 | + for (Edge edge : loadedEdgesType1) { | ||
428 | + doDelete("/api/edge/" + edge.getId().getId().toString()) | ||
429 | + .andExpect(status().isOk()); | ||
430 | + } | ||
431 | + | ||
432 | + pageLink = new TextPageLink(4); | ||
433 | + pageData = doGetTypedWithPageLink("/api/tenant/edges?type={type}&", | ||
434 | + new TypeReference<TextPageData<Edge>>() { | ||
435 | + }, pageLink, type1); | ||
436 | + Assert.assertFalse(pageData.hasNext()); | ||
437 | + Assert.assertEquals(0, pageData.getData().size()); | ||
438 | + | ||
439 | + for (Edge edge : loadedEdgesType2) { | ||
440 | + doDelete("/api/edge/" + edge.getId().getId().toString()) | ||
441 | + .andExpect(status().isOk()); | ||
442 | + } | ||
443 | + | ||
444 | + pageLink = new TextPageLink(4); | ||
445 | + pageData = doGetTypedWithPageLink("/api/tenant/edges?type={type}&", | ||
446 | + new TypeReference<TextPageData<Edge>>() { | ||
447 | + }, pageLink, type2); | ||
448 | + Assert.assertFalse(pageData.hasNext()); | ||
449 | + Assert.assertEquals(0, pageData.getData().size()); | ||
173 | } | 450 | } |
174 | 451 | ||
175 | - private Tenant getNewTenant(String title) { | ||
176 | - Tenant tenant = new Tenant(); | ||
177 | - tenant.setTitle(title); | ||
178 | - return tenant; | 452 | + @Test |
453 | + public void testFindCustomerEdges() throws Exception { | ||
454 | + Customer customer = new Customer(); | ||
455 | + customer.setTitle("Test customer"); | ||
456 | + customer = doPost("/api/customer", customer, Customer.class); | ||
457 | + CustomerId customerId = customer.getId(); | ||
458 | + | ||
459 | + List<Edge> edges = new ArrayList<>(); | ||
460 | + for (int i = 0; i < 128; i++) { | ||
461 | + Edge edge = new Edge(); | ||
462 | + edge.setName("Edge" + i); | ||
463 | + edge.setType("default"); | ||
464 | + edge = doPost("/api/edge", edge, Edge.class); | ||
465 | + edges.add(doPost("/api/customer/" + customerId.getId().toString() | ||
466 | + + "/edge/" + edge.getId().getId().toString(), Edge.class)); | ||
467 | + } | ||
468 | + | ||
469 | + List<Edge> loadedEdges = new ArrayList<>(); | ||
470 | + TextPageLink pageLink = new TextPageLink(23); | ||
471 | + TextPageData<Edge> pageData = null; | ||
472 | + do { | ||
473 | + pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/edges?", | ||
474 | + new TypeReference<TextPageData<Edge>>() { | ||
475 | + }, pageLink); | ||
476 | + loadedEdges.addAll(pageData.getData()); | ||
477 | + if (pageData.hasNext()) { | ||
478 | + pageLink = pageData.getNextPageLink(); | ||
479 | + } | ||
480 | + } while (pageData.hasNext()); | ||
481 | + | ||
482 | + Collections.sort(edges, idComparator); | ||
483 | + Collections.sort(loadedEdges, idComparator); | ||
484 | + | ||
485 | + Assert.assertEquals(edges, loadedEdges); | ||
179 | } | 486 | } |
180 | 487 | ||
181 | - private List<Edge> fillListOf(int limit, String partOfName) throws Exception { | ||
182 | - List<Edge> edgeNames = new ArrayList<>(); | ||
183 | - for (int i = 0; i < limit; i++) { | ||
184 | - String fullName = partOfName + ' ' + RandomStringUtils.randomAlphanumeric(15); | ||
185 | - fullName = i % 2 == 0 ? fullName.toLowerCase() : fullName.toUpperCase(); | ||
186 | - Edge edge = getNewSavedEdge(fullName); | ||
187 | - edgeNames.add(doPost("/api/edge", edge, Edge.class)); | 488 | + @Test |
489 | + public void testFindCustomerEdgesByName() throws Exception { | ||
490 | + Customer customer = new Customer(); | ||
491 | + customer.setTitle("Test customer"); | ||
492 | + customer = doPost("/api/customer", customer, Customer.class); | ||
493 | + CustomerId customerId = customer.getId(); | ||
494 | + | ||
495 | + String title1 = "Edge title 1"; | ||
496 | + List<Edge> edgesTitle1 = new ArrayList<>(); | ||
497 | + for (int i = 0; i < 125; i++) { | ||
498 | + Edge edge = new Edge(); | ||
499 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
500 | + String name = title1 + suffix; | ||
501 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
502 | + edge.setName(name); | ||
503 | + edge.setType("default"); | ||
504 | + edge = doPost("/api/edge", edge, Edge.class); | ||
505 | + edgesTitle1.add(doPost("/api/customer/" + customerId.getId().toString() | ||
506 | + + "/edge/" + edge.getId().getId().toString(), Edge.class)); | ||
507 | + } | ||
508 | + String title2 = "Edge title 2"; | ||
509 | + List<Edge> edgesTitle2 = new ArrayList<>(); | ||
510 | + for (int i = 0; i < 143; i++) { | ||
511 | + Edge edge = new Edge(); | ||
512 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
513 | + String name = title2 + suffix; | ||
514 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
515 | + edge.setName(name); | ||
516 | + edge.setType("default"); | ||
517 | + edge = doPost("/api/edge", edge, Edge.class); | ||
518 | + edgesTitle2.add(doPost("/api/customer/" + customerId.getId().toString() | ||
519 | + + "/edge/" + edge.getId().getId().toString(), Edge.class)); | ||
520 | + } | ||
521 | + | ||
522 | + List<Edge> loadedEdgesTitle1 = new ArrayList<>(); | ||
523 | + TextPageLink pageLink = new TextPageLink(15, title1); | ||
524 | + TextPageData<Edge> pageData = null; | ||
525 | + do { | ||
526 | + pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/edges?", | ||
527 | + new TypeReference<TextPageData<Edge>>() { | ||
528 | + }, pageLink); | ||
529 | + loadedEdgesTitle1.addAll(pageData.getData()); | ||
530 | + if (pageData.hasNext()) { | ||
531 | + pageLink = pageData.getNextPageLink(); | ||
532 | + } | ||
533 | + } while (pageData.hasNext()); | ||
534 | + | ||
535 | + Collections.sort(edgesTitle1, idComparator); | ||
536 | + Collections.sort(loadedEdgesTitle1, idComparator); | ||
537 | + | ||
538 | + Assert.assertEquals(edgesTitle1, loadedEdgesTitle1); | ||
539 | + | ||
540 | + List<Edge> loadedEdgesTitle2 = new ArrayList<>(); | ||
541 | + pageLink = new TextPageLink(4, title2); | ||
542 | + do { | ||
543 | + pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/edges?", | ||
544 | + new TypeReference<TextPageData<Edge>>() { | ||
545 | + }, pageLink); | ||
546 | + loadedEdgesTitle2.addAll(pageData.getData()); | ||
547 | + if (pageData.hasNext()) { | ||
548 | + pageLink = pageData.getNextPageLink(); | ||
549 | + } | ||
550 | + } while (pageData.hasNext()); | ||
551 | + | ||
552 | + Collections.sort(edgesTitle2, idComparator); | ||
553 | + Collections.sort(loadedEdgesTitle2, idComparator); | ||
554 | + | ||
555 | + Assert.assertEquals(edgesTitle2, loadedEdgesTitle2); | ||
556 | + | ||
557 | + for (Edge edge : loadedEdgesTitle1) { | ||
558 | + doDelete("/api/customer/edge/" + edge.getId().getId().toString()) | ||
559 | + .andExpect(status().isOk()); | ||
560 | + } | ||
561 | + | ||
562 | + pageLink = new TextPageLink(4, title1); | ||
563 | + pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/edges?", | ||
564 | + new TypeReference<TextPageData<Edge>>() { | ||
565 | + }, pageLink); | ||
566 | + Assert.assertFalse(pageData.hasNext()); | ||
567 | + Assert.assertEquals(0, pageData.getData().size()); | ||
568 | + | ||
569 | + for (Edge edge : loadedEdgesTitle2) { | ||
570 | + doDelete("/api/customer/edge/" + edge.getId().getId().toString()) | ||
571 | + .andExpect(status().isOk()); | ||
188 | } | 572 | } |
189 | - return edgeNames; | 573 | + |
574 | + pageLink = new TextPageLink(4, title2); | ||
575 | + pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/edges?", | ||
576 | + new TypeReference<TextPageData<Edge>>() { | ||
577 | + }, pageLink); | ||
578 | + Assert.assertFalse(pageData.hasNext()); | ||
579 | + Assert.assertEquals(0, pageData.getData().size()); | ||
190 | } | 580 | } |
191 | 581 | ||
192 | - private List<Edge> loadListOf(TextPageLink pageLink, String urlTemplate) throws Exception { | ||
193 | - List<Edge> loadedItems = new ArrayList<>(); | ||
194 | - TextPageData<Edge> pageData; | 582 | + @Test |
583 | + public void testFindCustomerEdgesByType() throws Exception { | ||
584 | + Customer customer = new Customer(); | ||
585 | + customer.setTitle("Test customer"); | ||
586 | + customer = doPost("/api/customer", customer, Customer.class); | ||
587 | + CustomerId customerId = customer.getId(); | ||
588 | + | ||
589 | + String title1 = "Edge title 1"; | ||
590 | + String type1 = "typeC"; | ||
591 | + List<Edge> edgesType1 = new ArrayList<>(); | ||
592 | + for (int i = 0; i < 125; i++) { | ||
593 | + Edge edge = new Edge(); | ||
594 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
595 | + String name = title1 + suffix; | ||
596 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
597 | + edge.setName(name); | ||
598 | + edge.setType(type1); | ||
599 | + edge = doPost("/api/edge", edge, Edge.class); | ||
600 | + edgesType1.add(doPost("/api/customer/" + customerId.getId().toString() | ||
601 | + + "/edge/" + edge.getId().getId().toString(), Edge.class)); | ||
602 | + } | ||
603 | + String title2 = "Edge title 2"; | ||
604 | + String type2 = "typeD"; | ||
605 | + List<Edge> edgesType2 = new ArrayList<>(); | ||
606 | + for (int i = 0; i < 143; i++) { | ||
607 | + Edge edge = new Edge(); | ||
608 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
609 | + String name = title2 + suffix; | ||
610 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
611 | + edge.setName(name); | ||
612 | + edge.setType(type2); | ||
613 | + edge = doPost("/api/edge", edge, Edge.class); | ||
614 | + edgesType2.add(doPost("/api/customer/" + customerId.getId().toString() | ||
615 | + + "/edge/" + edge.getId().getId().toString(), Edge.class)); | ||
616 | + } | ||
617 | + | ||
618 | + List<Edge> loadedEdgesType1 = new ArrayList<>(); | ||
619 | + TextPageLink pageLink = new TextPageLink(15); | ||
620 | + TextPageData<Edge> pageData = null; | ||
621 | + do { | ||
622 | + pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/edges?type={type}&", | ||
623 | + new TypeReference<TextPageData<Edge>>() { | ||
624 | + }, pageLink, type1); | ||
625 | + loadedEdgesType1.addAll(pageData.getData()); | ||
626 | + if (pageData.hasNext()) { | ||
627 | + pageLink = pageData.getNextPageLink(); | ||
628 | + } | ||
629 | + } while (pageData.hasNext()); | ||
630 | + | ||
631 | + Collections.sort(edgesType1, idComparator); | ||
632 | + Collections.sort(loadedEdgesType1, idComparator); | ||
633 | + | ||
634 | + Assert.assertEquals(edgesType1, loadedEdgesType1); | ||
635 | + | ||
636 | + List<Edge> loadedEdgesType2 = new ArrayList<>(); | ||
637 | + pageLink = new TextPageLink(4); | ||
195 | do { | 638 | do { |
196 | - pageData = doGetTypedWithPageLink(urlTemplate, new TypeReference<TextPageData<Edge>>() { | ||
197 | - }, pageLink); | ||
198 | - loadedItems.addAll(pageData.getData()); | 639 | + pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/edges?type={type}&", |
640 | + new TypeReference<TextPageData<Edge>>() { | ||
641 | + }, pageLink, type2); | ||
642 | + loadedEdgesType2.addAll(pageData.getData()); | ||
199 | if (pageData.hasNext()) { | 643 | if (pageData.hasNext()) { |
200 | pageLink = pageData.getNextPageLink(); | 644 | pageLink = pageData.getNextPageLink(); |
201 | } | 645 | } |
202 | } while (pageData.hasNext()); | 646 | } while (pageData.hasNext()); |
203 | 647 | ||
204 | - return loadedItems; | 648 | + Collections.sort(edgesType2, idComparator); |
649 | + Collections.sort(loadedEdgesType2, idComparator); | ||
650 | + | ||
651 | + Assert.assertEquals(edgesType2, loadedEdgesType2); | ||
652 | + | ||
653 | + for (Edge edge : loadedEdgesType1) { | ||
654 | + doDelete("/api/customer/edge/" + edge.getId().getId().toString()) | ||
655 | + .andExpect(status().isOk()); | ||
656 | + } | ||
657 | + | ||
658 | + pageLink = new TextPageLink(4); | ||
659 | + pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/edges?type={type}&", | ||
660 | + new TypeReference<TextPageData<Edge>>() { | ||
661 | + }, pageLink, type1); | ||
662 | + Assert.assertFalse(pageData.hasNext()); | ||
663 | + Assert.assertEquals(0, pageData.getData().size()); | ||
664 | + | ||
665 | + for (Edge edge : loadedEdgesType2) { | ||
666 | + doDelete("/api/customer/edge/" + edge.getId().getId().toString()) | ||
667 | + .andExpect(status().isOk()); | ||
668 | + } | ||
669 | + | ||
670 | + pageLink = new TextPageLink(4); | ||
671 | + pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/edges?type={type}&", | ||
672 | + new TypeReference<TextPageData<Edge>>() { | ||
673 | + }, pageLink, type2); | ||
674 | + Assert.assertFalse(pageData.hasNext()); | ||
675 | + Assert.assertEquals(0, pageData.getData().size()); | ||
205 | } | 676 | } |
206 | } | 677 | } |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | * you may not use this file except in compliance with 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 | 6 | * You may obtain a copy of the License at |
7 | * | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * | 9 | * |
10 | * Unless required by applicable law or agreed to in writing, software | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
@@ -16,7 +16,10 @@ | @@ -16,7 +16,10 @@ | ||
16 | package org.thingsboard.server.dao.edge; | 16 | package org.thingsboard.server.dao.edge; |
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.EntitySubtype; | ||
19 | import org.thingsboard.server.common.data.edge.Edge; | 20 | import org.thingsboard.server.common.data.edge.Edge; |
21 | +import org.thingsboard.server.common.data.edge.EdgeSearchQuery; | ||
22 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
20 | import org.thingsboard.server.common.data.id.EdgeId; | 23 | import org.thingsboard.server.common.data.id.EdgeId; |
21 | import org.thingsboard.server.common.data.id.TenantId; | 24 | import org.thingsboard.server.common.data.id.TenantId; |
22 | import org.thingsboard.server.common.data.page.TextPageData; | 25 | import org.thingsboard.server.common.data.page.TextPageData; |
@@ -26,20 +29,49 @@ import java.util.List; | @@ -26,20 +29,49 @@ import java.util.List; | ||
26 | 29 | ||
27 | public interface EdgeService { | 30 | public interface EdgeService { |
28 | 31 | ||
29 | - Edge saveEdge(Edge edge); | ||
30 | - | ||
31 | Edge findEdgeById(TenantId tenantId, EdgeId edgeId); | 32 | Edge findEdgeById(TenantId tenantId, EdgeId edgeId); |
32 | 33 | ||
33 | ListenableFuture<Edge> findEdgeByIdAsync(TenantId tenantId, EdgeId edgeId); | 34 | ListenableFuture<Edge> findEdgeByIdAsync(TenantId tenantId, EdgeId edgeId); |
34 | 35 | ||
35 | - ListenableFuture<List<Edge>> findEdgesByIdsAsync(TenantId tenantId, List<EdgeId> edgeIds); | 36 | + Edge findEdgeByTenantIdAndName(TenantId tenantId, String name); |
36 | 37 | ||
37 | - List<Edge> findAllEdges(TenantId tenantId); | 38 | + Edge saveEdge(Edge edge); |
38 | 39 | ||
39 | - TextPageData<Edge> findTenantEdges(TenantId tenantId, TextPageLink pageLink); | 40 | + Edge assignEdgeToCustomer(TenantId tenantId, EdgeId edgeId, CustomerId customerId); |
41 | + | ||
42 | + Edge unassignEdgeFromCustomer(TenantId tenantId, EdgeId edgeId); | ||
40 | 43 | ||
41 | void deleteEdge(TenantId tenantId, EdgeId edgeId); | 44 | void deleteEdge(TenantId tenantId, EdgeId edgeId); |
42 | 45 | ||
46 | + TextPageData<Edge> findEdgesByTenantId(TenantId tenantId, TextPageLink pageLink); | ||
47 | + | ||
48 | + TextPageData<Edge> findEdgesByTenantIdAndType(TenantId tenantId, String type, TextPageLink pageLink); | ||
49 | + | ||
50 | + ListenableFuture<List<Edge>> findEdgesByTenantIdAndIdsAsync(TenantId tenantId, List<EdgeId> edgeIds); | ||
51 | + | ||
43 | void deleteEdgesByTenantId(TenantId tenantId); | 52 | void deleteEdgesByTenantId(TenantId tenantId); |
44 | 53 | ||
54 | + TextPageData<Edge> findEdgesByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, TextPageLink pageLink); | ||
55 | + | ||
56 | + TextPageData<Edge> findEdgesByTenantIdAndCustomerIdAndType(TenantId tenantId, CustomerId customerId, String type, TextPageLink pageLink); | ||
57 | + | ||
58 | + ListenableFuture<List<Edge>> findEdgesByTenantIdCustomerIdAndIdsAsync(TenantId tenantId, CustomerId customerId, List<EdgeId> edgeIds); | ||
59 | + | ||
60 | + void unassignCustomerEdges(TenantId tenantId, CustomerId customerId); | ||
61 | + | ||
62 | + ListenableFuture<List<Edge>> findEdgesByQuery(TenantId tenantId, EdgeSearchQuery query); | ||
63 | + | ||
64 | + ListenableFuture<List<EntitySubtype>> findEdgeTypesByTenantId(TenantId tenantId); | ||
65 | + | ||
45 | } | 66 | } |
67 | + | ||
68 | + | ||
69 | + | ||
70 | + | ||
71 | + | ||
72 | + | ||
73 | + | ||
74 | + | ||
75 | + | ||
76 | + | ||
77 | + |
@@ -22,6 +22,7 @@ public class CacheConstants { | @@ -22,6 +22,7 @@ public class CacheConstants { | ||
22 | public static final String SESSIONS_CACHE = "sessions"; | 22 | public static final String SESSIONS_CACHE = "sessions"; |
23 | public static final String ASSET_CACHE = "assets"; | 23 | public static final String ASSET_CACHE = "assets"; |
24 | public static final String ENTITY_VIEW_CACHE = "entityViews"; | 24 | public static final String ENTITY_VIEW_CACHE = "entityViews"; |
25 | + public static final String EDGE_CACHE = "edges"; | ||
25 | public static final String CLAIM_DEVICES_CACHE = "claimDevices"; | 26 | public static final String CLAIM_DEVICES_CACHE = "claimDevices"; |
26 | public static final String SECURITY_SETTINGS_CACHE = "securitySettings"; | 27 | public static final String SECURITY_SETTINGS_CACHE = "securitySettings"; |
27 | } | 28 | } |
@@ -39,6 +39,7 @@ public class Edge extends SearchTextBasedWithAdditionalInfo<EdgeId> implements H | @@ -39,6 +39,7 @@ public class Edge extends SearchTextBasedWithAdditionalInfo<EdgeId> implements H | ||
39 | private TenantId tenantId; | 39 | private TenantId tenantId; |
40 | private CustomerId customerId; | 40 | private CustomerId customerId; |
41 | private String name; | 41 | private String name; |
42 | + private String type; | ||
42 | private transient JsonNode configuration; | 43 | private transient JsonNode configuration; |
43 | private transient JsonNode additionalInfo; | 44 | private transient JsonNode additionalInfo; |
44 | 45 | ||
@@ -54,6 +55,7 @@ public class Edge extends SearchTextBasedWithAdditionalInfo<EdgeId> implements H | @@ -54,6 +55,7 @@ public class Edge extends SearchTextBasedWithAdditionalInfo<EdgeId> implements H | ||
54 | super(edge); | 55 | super(edge); |
55 | this.tenantId = edge.getTenantId(); | 56 | this.tenantId = edge.getTenantId(); |
56 | this.customerId = edge.getCustomerId(); | 57 | this.customerId = edge.getCustomerId(); |
58 | + this.type = edge.getType(); | ||
57 | this.name = edge.getName(); | 59 | this.name = edge.getName(); |
58 | this.configuration = edge.getConfiguration(); | 60 | this.configuration = edge.getConfiguration(); |
59 | this.additionalInfo = edge.getAdditionalInfo(); | 61 | this.additionalInfo = edge.getAdditionalInfo(); |
1 | +/** | ||
2 | + * Copyright © 2016-2019 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.edge; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.EntityType; | ||
20 | +import org.thingsboard.server.common.data.relation.EntityRelation; | ||
21 | +import org.thingsboard.server.common.data.relation.EntityRelationsQuery; | ||
22 | +import org.thingsboard.server.common.data.relation.EntityTypeFilter; | ||
23 | +import org.thingsboard.server.common.data.relation.RelationsSearchParameters; | ||
24 | + | ||
25 | +import java.util.Collections; | ||
26 | +import java.util.List; | ||
27 | + | ||
28 | +@Data | ||
29 | +public class EdgeSearchQuery { | ||
30 | + | ||
31 | + private RelationsSearchParameters parameters; | ||
32 | + private String relationType; | ||
33 | + private List<String> edgeTypes; | ||
34 | + | ||
35 | + public EntityRelationsQuery toEntitySearchQuery() { | ||
36 | + EntityRelationsQuery query = new EntityRelationsQuery(); | ||
37 | + query.setParameters(parameters); | ||
38 | + query.setFilters( | ||
39 | + Collections.singletonList(new EntityTypeFilter(relationType == null ? EntityRelation.CONTAINS_TYPE : relationType, | ||
40 | + Collections.singletonList(EntityType.EDGE)))); | ||
41 | + return query; | ||
42 | + } | ||
43 | +} |
@@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.page.TextPageLink; | @@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.page.TextPageLink; | ||
31 | import org.thingsboard.server.dao.asset.AssetService; | 31 | import org.thingsboard.server.dao.asset.AssetService; |
32 | import org.thingsboard.server.dao.dashboard.DashboardService; | 32 | import org.thingsboard.server.dao.dashboard.DashboardService; |
33 | import org.thingsboard.server.dao.device.DeviceService; | 33 | import org.thingsboard.server.dao.device.DeviceService; |
34 | +import org.thingsboard.server.dao.edge.EdgeService; | ||
34 | import org.thingsboard.server.dao.entity.AbstractEntityService; | 35 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
35 | import org.thingsboard.server.dao.entityview.EntityViewService; | 36 | import org.thingsboard.server.dao.entityview.EntityViewService; |
36 | import org.thingsboard.server.dao.exception.DataValidationException; | 37 | import org.thingsboard.server.dao.exception.DataValidationException; |
@@ -76,6 +77,9 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | @@ -76,6 +77,9 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | ||
76 | @Autowired | 77 | @Autowired |
77 | private DashboardService dashboardService; | 78 | private DashboardService dashboardService; |
78 | 79 | ||
80 | + @Autowired | ||
81 | + private EdgeService edgeService; | ||
82 | + | ||
79 | @Override | 83 | @Override |
80 | public Customer findCustomerById(TenantId tenantId, CustomerId customerId) { | 84 | public Customer findCustomerById(TenantId tenantId, CustomerId customerId) { |
81 | log.trace("Executing findCustomerById [{}]", customerId); | 85 | log.trace("Executing findCustomerById [{}]", customerId); |
@@ -118,6 +122,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | @@ -118,6 +122,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | ||
118 | entityViewService.unassignCustomerEntityViews(customer.getTenantId(), customerId); | 122 | entityViewService.unassignCustomerEntityViews(customer.getTenantId(), customerId); |
119 | assetService.unassignCustomerAssets(customer.getTenantId(), customerId); | 123 | assetService.unassignCustomerAssets(customer.getTenantId(), customerId); |
120 | deviceService.unassignCustomerDevices(customer.getTenantId(), customerId); | 124 | deviceService.unassignCustomerDevices(customer.getTenantId(), customerId); |
125 | + edgeService.unassignCustomerEdges(customer.getTenantId(), customerId); | ||
121 | userService.deleteCustomerUsers(customer.getTenantId(), customerId); | 126 | userService.deleteCustomerUsers(customer.getTenantId(), customerId); |
122 | deleteEntityRelations(tenantId, customerId); | 127 | deleteEntityRelations(tenantId, customerId); |
123 | customerDao.removeById(tenantId, customerId.getId()); | 128 | customerDao.removeById(tenantId, customerId.getId()); |
@@ -15,29 +15,53 @@ | @@ -15,29 +15,53 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.dao.edge; | 16 | package org.thingsboard.server.dao.edge; |
17 | 17 | ||
18 | +import com.google.common.base.Function; | ||
19 | +import com.google.common.util.concurrent.Futures; | ||
18 | import com.google.common.util.concurrent.ListenableFuture; | 20 | import com.google.common.util.concurrent.ListenableFuture; |
19 | import lombok.extern.slf4j.Slf4j; | 21 | import lombok.extern.slf4j.Slf4j; |
20 | import org.springframework.beans.factory.annotation.Autowired; | 22 | import org.springframework.beans.factory.annotation.Autowired; |
23 | +import org.springframework.cache.Cache; | ||
24 | +import org.springframework.cache.CacheManager; | ||
25 | +import org.springframework.cache.annotation.CacheEvict; | ||
26 | +import org.springframework.cache.annotation.Cacheable; | ||
21 | import org.springframework.stereotype.Service; | 27 | import org.springframework.stereotype.Service; |
22 | import org.springframework.util.StringUtils; | 28 | import org.springframework.util.StringUtils; |
29 | +import org.thingsboard.server.common.data.Customer; | ||
30 | +import org.thingsboard.server.common.data.EntitySubtype; | ||
31 | +import org.thingsboard.server.common.data.EntityType; | ||
23 | import org.thingsboard.server.common.data.Tenant; | 32 | import org.thingsboard.server.common.data.Tenant; |
24 | import org.thingsboard.server.common.data.edge.Edge; | 33 | import org.thingsboard.server.common.data.edge.Edge; |
34 | +import org.thingsboard.server.common.data.edge.EdgeSearchQuery; | ||
35 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
25 | import org.thingsboard.server.common.data.id.EdgeId; | 36 | import org.thingsboard.server.common.data.id.EdgeId; |
37 | +import org.thingsboard.server.common.data.id.EntityId; | ||
26 | import org.thingsboard.server.common.data.id.TenantId; | 38 | import org.thingsboard.server.common.data.id.TenantId; |
27 | import org.thingsboard.server.common.data.page.TextPageData; | 39 | import org.thingsboard.server.common.data.page.TextPageData; |
28 | import org.thingsboard.server.common.data.page.TextPageLink; | 40 | import org.thingsboard.server.common.data.page.TextPageLink; |
41 | +import org.thingsboard.server.common.data.relation.EntityRelation; | ||
42 | +import org.thingsboard.server.common.data.relation.EntitySearchDirection; | ||
43 | +import org.thingsboard.server.dao.customer.CustomerDao; | ||
29 | import org.thingsboard.server.dao.entity.AbstractEntityService; | 44 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
30 | import org.thingsboard.server.dao.exception.DataValidationException; | 45 | import org.thingsboard.server.dao.exception.DataValidationException; |
31 | import org.thingsboard.server.dao.service.DataValidator; | 46 | import org.thingsboard.server.dao.service.DataValidator; |
32 | import org.thingsboard.server.dao.service.PaginatedRemover; | 47 | import org.thingsboard.server.dao.service.PaginatedRemover; |
33 | import org.thingsboard.server.dao.tenant.TenantDao; | 48 | import org.thingsboard.server.dao.tenant.TenantDao; |
34 | 49 | ||
50 | +import javax.annotation.Nullable; | ||
51 | +import java.util.ArrayList; | ||
52 | +import java.util.Collections; | ||
53 | +import java.util.Comparator; | ||
35 | import java.util.List; | 54 | import java.util.List; |
55 | +import java.util.Optional; | ||
56 | +import java.util.stream.Collectors; | ||
36 | 57 | ||
58 | +import static org.thingsboard.server.common.data.CacheConstants.EDGE_CACHE; | ||
37 | import static org.thingsboard.server.dao.DaoUtil.toUUIDs; | 59 | import static org.thingsboard.server.dao.DaoUtil.toUUIDs; |
60 | +import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; | ||
38 | import static org.thingsboard.server.dao.service.Validator.validateId; | 61 | import static org.thingsboard.server.dao.service.Validator.validateId; |
39 | import static org.thingsboard.server.dao.service.Validator.validateIds; | 62 | import static org.thingsboard.server.dao.service.Validator.validateIds; |
40 | import static org.thingsboard.server.dao.service.Validator.validatePageLink; | 63 | import static org.thingsboard.server.dao.service.Validator.validatePageLink; |
64 | +import static org.thingsboard.server.dao.service.Validator.validateString; | ||
41 | 65 | ||
42 | @Service | 66 | @Service |
43 | @Slf4j | 67 | @Slf4j |
@@ -45,6 +69,7 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic | @@ -45,6 +69,7 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic | ||
45 | 69 | ||
46 | public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; | 70 | public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
47 | public static final String INCORRECT_PAGE_LINK = "Incorrect page link "; | 71 | public static final String INCORRECT_PAGE_LINK = "Incorrect page link "; |
72 | + public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; | ||
48 | public static final String INCORRECT_EDGE_ID = "Incorrect edgeId "; | 73 | public static final String INCORRECT_EDGE_ID = "Incorrect edgeId "; |
49 | 74 | ||
50 | @Autowired | 75 | @Autowired |
@@ -53,12 +78,11 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic | @@ -53,12 +78,11 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic | ||
53 | @Autowired | 78 | @Autowired |
54 | private TenantDao tenantDao; | 79 | private TenantDao tenantDao; |
55 | 80 | ||
56 | - @Override | ||
57 | - public Edge saveEdge(Edge edge) { | ||
58 | - log.trace("Executing saveEdge [{}]", edge); | ||
59 | - edgeValidator.validate(edge, Edge::getTenantId); | ||
60 | - return edgeDao.save(edge.getTenantId(), edge); | ||
61 | - } | 81 | + @Autowired |
82 | + private CustomerDao customerDao; | ||
83 | + | ||
84 | + @Autowired | ||
85 | + private CacheManager cacheManager; | ||
62 | 86 | ||
63 | @Override | 87 | @Override |
64 | public Edge findEdgeById(TenantId tenantId, EdgeId edgeId) { | 88 | public Edge findEdgeById(TenantId tenantId, EdgeId edgeId) { |
@@ -69,73 +93,222 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic | @@ -69,73 +93,222 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic | ||
69 | 93 | ||
70 | @Override | 94 | @Override |
71 | public ListenableFuture<Edge> findEdgeByIdAsync(TenantId tenantId, EdgeId edgeId) { | 95 | public ListenableFuture<Edge> findEdgeByIdAsync(TenantId tenantId, EdgeId edgeId) { |
72 | - log.trace("Executing findEdgeByIdAsync [{}]", edgeId); | 96 | + log.trace("Executing findEdgeById [{}]", edgeId); |
73 | validateId(edgeId, INCORRECT_EDGE_ID + edgeId); | 97 | validateId(edgeId, INCORRECT_EDGE_ID + edgeId); |
74 | return edgeDao.findByIdAsync(tenantId, edgeId.getId()); | 98 | return edgeDao.findByIdAsync(tenantId, edgeId.getId()); |
75 | } | 99 | } |
76 | 100 | ||
101 | + @Cacheable(cacheNames = EDGE_CACHE, key = "{#tenantId, #name}") | ||
77 | @Override | 102 | @Override |
78 | - public ListenableFuture<List<Edge>> findEdgesByIdsAsync(TenantId tenantId, List<EdgeId> edgeIds) { | ||
79 | - log.trace("Executing findEdgesByIdsAsync, tenantId [{}], edgeIds [{}]", tenantId, edgeIds); | 103 | + public Edge findEdgeByTenantIdAndName(TenantId tenantId, String name) { |
104 | + log.trace("Executing findEdgeByTenantIdAndName [{}][{}]", tenantId, name); | ||
80 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | 105 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); |
81 | - validateIds(edgeIds, "Incorrect edgeIds " + edgeIds); | ||
82 | - return edgeDao.findEdgesByTenantIdAndIdsAsync(tenantId.getId(), toUUIDs(edgeIds)); | 106 | + Optional<Edge> edgeOpt = edgeDao.findEdgeByTenantIdAndName(tenantId.getId(), name); |
107 | + return edgeOpt.orElse(null); | ||
83 | } | 108 | } |
84 | 109 | ||
110 | + @CacheEvict(cacheNames = EDGE_CACHE, key = "{#edge.tenantId, #edge.name}") | ||
85 | @Override | 111 | @Override |
86 | - public List<Edge> findAllEdges(TenantId tenantId) { | ||
87 | - log.trace("Executing findAllEdges"); | ||
88 | - return edgeDao.find(tenantId); | 112 | + public Edge saveEdge(Edge edge) { |
113 | + log.trace("Executing saveEdge [{}]", edge); | ||
114 | + edgeValidator.validate(edge, Edge::getTenantId); | ||
115 | + return edgeDao.save(edge.getTenantId(), edge); | ||
89 | } | 116 | } |
90 | 117 | ||
91 | @Override | 118 | @Override |
92 | - public TextPageData<Edge> findTenantEdges(TenantId tenantId, TextPageLink pageLink) { | ||
93 | - log.trace("Executing findTenantEdges, tenantId [{}], pageLink [{}]", tenantId, pageLink); | ||
94 | - validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
95 | - validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); | ||
96 | - List<Edge> edges = edgeDao.findByTenantIdAndPageLink(tenantId.getId(), pageLink); | ||
97 | - return new TextPageData<>(edges, pageLink); | 119 | + public Edge assignEdgeToCustomer(TenantId tenantId, EdgeId edgeId, CustomerId customerId) { |
120 | + Edge edge = findEdgeById(tenantId, edgeId); | ||
121 | + edge.setCustomerId(customerId); | ||
122 | + return saveEdge(edge); | ||
123 | + } | ||
124 | + | ||
125 | + @Override | ||
126 | + public Edge unassignEdgeFromCustomer(TenantId tenantId, EdgeId edgeId) { | ||
127 | + Edge edge = findEdgeById(tenantId, edgeId); | ||
128 | + edge.setCustomerId(null); | ||
129 | + return saveEdge(edge); | ||
98 | } | 130 | } |
99 | 131 | ||
100 | @Override | 132 | @Override |
101 | public void deleteEdge(TenantId tenantId, EdgeId edgeId) { | 133 | public void deleteEdge(TenantId tenantId, EdgeId edgeId) { |
102 | log.trace("Executing deleteEdge [{}]", edgeId); | 134 | log.trace("Executing deleteEdge [{}]", edgeId); |
103 | validateId(edgeId, INCORRECT_EDGE_ID + edgeId); | 135 | validateId(edgeId, INCORRECT_EDGE_ID + edgeId); |
136 | + | ||
137 | + Edge edge = edgeDao.findById(tenantId, edgeId.getId()); | ||
138 | + | ||
104 | deleteEntityRelations(tenantId, edgeId); | 139 | deleteEntityRelations(tenantId, edgeId); |
140 | + | ||
141 | + List<Object> list = new ArrayList<>(); | ||
142 | + list.add(edge.getTenantId()); | ||
143 | + list.add(edge.getName()); | ||
144 | + Cache cache = cacheManager.getCache(EDGE_CACHE); | ||
145 | + cache.evict(list); | ||
146 | + | ||
105 | edgeDao.removeById(tenantId, edgeId.getId()); | 147 | edgeDao.removeById(tenantId, edgeId.getId()); |
106 | } | 148 | } |
107 | 149 | ||
108 | @Override | 150 | @Override |
151 | + public TextPageData<Edge> findEdgesByTenantId(TenantId tenantId, TextPageLink pageLink) { | ||
152 | + log.trace("Executing findEdgesByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink); | ||
153 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
154 | + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); | ||
155 | + List<Edge> edges = edgeDao.findEdgesByTenantId(tenantId.getId(), pageLink); | ||
156 | + return new TextPageData<>(edges, pageLink); | ||
157 | + } | ||
158 | + | ||
159 | + @Override | ||
160 | + public TextPageData<Edge> findEdgesByTenantIdAndType(TenantId tenantId, String type, TextPageLink pageLink) { | ||
161 | + log.trace("Executing findEdgesByTenantIdAndType, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink); | ||
162 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
163 | + validateString(type, "Incorrect type " + type); | ||
164 | + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); | ||
165 | + List<Edge> edges = edgeDao.findEdgesByTenantIdAndType(tenantId.getId(), type, pageLink); | ||
166 | + return new TextPageData<>(edges, pageLink); | ||
167 | + } | ||
168 | + | ||
169 | + @Override | ||
170 | + public ListenableFuture<List<Edge>> findEdgesByTenantIdAndIdsAsync(TenantId tenantId, List<EdgeId> edgeIds) { | ||
171 | + log.trace("Executing findEdgesByTenantIdAndIdsAsync, tenantId [{}], edgeIds [{}]", tenantId, edgeIds); | ||
172 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
173 | + validateIds(edgeIds, "Incorrect edgeIds " + edgeIds); | ||
174 | + return edgeDao.findEdgesByTenantIdAndIdsAsync(tenantId.getId(), toUUIDs(edgeIds)); | ||
175 | + } | ||
176 | + | ||
177 | + | ||
178 | + @Override | ||
109 | public void deleteEdgesByTenantId(TenantId tenantId) { | 179 | public void deleteEdgesByTenantId(TenantId tenantId) { |
110 | log.trace("Executing deleteEdgesByTenantId, tenantId [{}]", tenantId); | 180 | log.trace("Executing deleteEdgesByTenantId, tenantId [{}]", tenantId); |
111 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | 181 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); |
112 | tenantEdgesRemover.removeEntities(tenantId, tenantId); | 182 | tenantEdgesRemover.removeEntities(tenantId, tenantId); |
113 | } | 183 | } |
114 | 184 | ||
185 | + @Override | ||
186 | + public TextPageData<Edge> findEdgesByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, TextPageLink pageLink) { | ||
187 | + log.trace("Executing findEdgesByTenantIdAndCustomerId, tenantId [{}], customerId [{}], pageLink [{}]", tenantId, customerId, pageLink); | ||
188 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
189 | + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); | ||
190 | + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); | ||
191 | + List<Edge> edges = edgeDao.findEdgesByTenantIdAndCustomerId(tenantId.getId(), customerId.getId(), pageLink); | ||
192 | + return new TextPageData<>(edges, pageLink); | ||
193 | + } | ||
194 | + | ||
195 | + @Override | ||
196 | + public TextPageData<Edge> findEdgesByTenantIdAndCustomerIdAndType(TenantId tenantId, CustomerId customerId, String type, TextPageLink pageLink) { | ||
197 | + log.trace("Executing findEdgesByTenantIdAndCustomerIdAndType, tenantId [{}], customerId [{}], type [{}], pageLink [{}]", tenantId, customerId, type, pageLink); | ||
198 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
199 | + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); | ||
200 | + validateString(type, "Incorrect type " + type); | ||
201 | + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); | ||
202 | + List<Edge> edges = edgeDao.findEdgesByTenantIdAndCustomerIdAndType(tenantId.getId(), customerId.getId(), type, pageLink); | ||
203 | + return new TextPageData<>(edges, pageLink); | ||
204 | + } | ||
205 | + | ||
206 | + @Override | ||
207 | + public ListenableFuture<List<Edge>> findEdgesByTenantIdCustomerIdAndIdsAsync(TenantId tenantId, CustomerId customerId, List<EdgeId> edgeIds) { | ||
208 | + log.trace("Executing findEdgesByTenantIdCustomerIdAndIdsAsync, tenantId [{}], customerId [{}], edgeIds [{}]", tenantId, customerId, edgeIds); | ||
209 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
210 | + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); | ||
211 | + validateIds(edgeIds, "Incorrect edgeIds " + edgeIds); | ||
212 | + return edgeDao.findEdgesByTenantIdCustomerIdAndIdsAsync(tenantId.getId(), | ||
213 | + customerId.getId(), toUUIDs(edgeIds)); | ||
214 | + } | ||
215 | + | ||
216 | + @Override | ||
217 | + public void unassignCustomerEdges(TenantId tenantId, CustomerId customerId) { | ||
218 | + log.trace("Executing unassignCustomerEdges, tenantId [{}], customerId [{}]", tenantId, customerId); | ||
219 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
220 | + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); | ||
221 | + customerEdgeUnasigner.removeEntities(tenantId, customerId); | ||
222 | + } | ||
223 | + | ||
224 | + @Override | ||
225 | + public ListenableFuture<List<Edge>> findEdgesByQuery(TenantId tenantId, EdgeSearchQuery query) { | ||
226 | + ListenableFuture<List<EntityRelation>> relations = relationService.findByQuery(tenantId, query.toEntitySearchQuery()); | ||
227 | + ListenableFuture<List<Edge>> edges = Futures.transformAsync(relations, r -> { | ||
228 | + EntitySearchDirection direction = query.toEntitySearchQuery().getParameters().getDirection(); | ||
229 | + List<ListenableFuture<Edge>> futures = new ArrayList<>(); | ||
230 | + for (EntityRelation relation : r) { | ||
231 | + EntityId entityId = direction == EntitySearchDirection.FROM ? relation.getTo() : relation.getFrom(); | ||
232 | + if (entityId.getEntityType() == EntityType.EDGE) { | ||
233 | + futures.add(findEdgeByIdAsync(tenantId, new EdgeId(entityId.getId()))); | ||
234 | + } | ||
235 | + } | ||
236 | + return Futures.successfulAsList(futures); | ||
237 | + }); | ||
238 | + | ||
239 | + edges = Futures.transform(edges, new Function<List<Edge>, List<Edge>>() { | ||
240 | + @Nullable | ||
241 | + @Override | ||
242 | + public List<Edge> apply(@Nullable List<Edge> edgeList) { | ||
243 | + return edgeList == null ? Collections.emptyList() : edgeList.stream().filter(edge -> query.getEdgeTypes().contains(edge.getType())).collect(Collectors.toList()); | ||
244 | + } | ||
245 | + }); | ||
246 | + | ||
247 | + return edges; | ||
248 | + } | ||
249 | + | ||
250 | + @Override | ||
251 | + public ListenableFuture<List<EntitySubtype>> findEdgeTypesByTenantId(TenantId tenantId) { | ||
252 | + log.trace("Executing findEdgeTypesByTenantId, tenantId [{}]", tenantId); | ||
253 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
254 | + ListenableFuture<List<EntitySubtype>> tenantEdgeTypes = edgeDao.findTenantEdgeTypesAsync(tenantId.getId()); | ||
255 | + return Futures.transform(tenantEdgeTypes, | ||
256 | + edgeTypes -> { | ||
257 | + edgeTypes.sort(Comparator.comparing(EntitySubtype::getType)); | ||
258 | + return edgeTypes; | ||
259 | + }); | ||
260 | + } | ||
261 | + | ||
115 | private DataValidator<Edge> edgeValidator = | 262 | private DataValidator<Edge> edgeValidator = |
116 | new DataValidator<Edge>() { | 263 | new DataValidator<Edge>() { |
117 | 264 | ||
118 | @Override | 265 | @Override |
119 | protected void validateCreate(TenantId tenantId, Edge edge) { | 266 | protected void validateCreate(TenantId tenantId, Edge edge) { |
267 | + edgeDao.findEdgeByTenantIdAndName(edge.getTenantId().getId(), edge.getName()).ifPresent( | ||
268 | + d -> { | ||
269 | + throw new DataValidationException("Edge with such name already exists!"); | ||
270 | + } | ||
271 | + ); | ||
120 | } | 272 | } |
121 | 273 | ||
122 | @Override | 274 | @Override |
123 | protected void validateUpdate(TenantId tenantId, Edge edge) { | 275 | protected void validateUpdate(TenantId tenantId, Edge edge) { |
276 | + edgeDao.findEdgeByTenantIdAndName(edge.getTenantId().getId(), edge.getName()).ifPresent( | ||
277 | + e -> { | ||
278 | + if (!e.getUuidId().equals(edge.getUuidId())) { | ||
279 | + throw new DataValidationException("Edge with such name already exists!"); | ||
280 | + } | ||
281 | + } | ||
282 | + ); | ||
124 | } | 283 | } |
125 | 284 | ||
126 | @Override | 285 | @Override |
127 | protected void validateDataImpl(TenantId tenantId, Edge edge) { | 286 | protected void validateDataImpl(TenantId tenantId, Edge edge) { |
287 | + if (StringUtils.isEmpty(edge.getType())) { | ||
288 | + throw new DataValidationException("Edge type should be specified!"); | ||
289 | + } | ||
128 | if (StringUtils.isEmpty(edge.getName())) { | 290 | if (StringUtils.isEmpty(edge.getName())) { |
129 | throw new DataValidationException("Edge name should be specified!"); | 291 | throw new DataValidationException("Edge name should be specified!"); |
130 | } | 292 | } |
131 | - if (edge.getTenantId() == null || edge.getTenantId().isNullUid()) { | 293 | + if (edge.getTenantId() == null) { |
132 | throw new DataValidationException("Edge should be assigned to tenant!"); | 294 | throw new DataValidationException("Edge should be assigned to tenant!"); |
133 | } else { | 295 | } else { |
134 | - Tenant tenant = tenantDao.findById(tenantId, edge.getTenantId().getId()); | 296 | + Tenant tenant = tenantDao.findById(edge.getTenantId(), edge.getTenantId().getId()); |
135 | if (tenant == null) { | 297 | if (tenant == null) { |
136 | throw new DataValidationException("Edge is referencing to non-existent tenant!"); | 298 | throw new DataValidationException("Edge is referencing to non-existent tenant!"); |
137 | } | 299 | } |
138 | } | 300 | } |
301 | + if (edge.getCustomerId() == null) { | ||
302 | + edge.setCustomerId(new CustomerId(NULL_UUID)); | ||
303 | + } else if (!edge.getCustomerId().getId().equals(NULL_UUID)) { | ||
304 | + Customer customer = customerDao.findById(edge.getTenantId(), edge.getCustomerId().getId()); | ||
305 | + if (customer == null) { | ||
306 | + throw new DataValidationException("Can't assign edge to non-existent customer!"); | ||
307 | + } | ||
308 | + if (!customer.getTenantId().getId().equals(edge.getTenantId().getId())) { | ||
309 | + throw new DataValidationException("Can't assign edge to customer from different tenant!"); | ||
310 | + } | ||
311 | + } | ||
139 | } | 312 | } |
140 | }; | 313 | }; |
141 | 314 | ||
@@ -144,13 +317,26 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic | @@ -144,13 +317,26 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic | ||
144 | 317 | ||
145 | @Override | 318 | @Override |
146 | protected List<Edge> findEntities(TenantId tenantId, TenantId id, TextPageLink pageLink) { | 319 | protected List<Edge> findEntities(TenantId tenantId, TenantId id, TextPageLink pageLink) { |
147 | - return edgeDao.findByTenantIdAndPageLink(id.getId(), pageLink); | 320 | + return edgeDao.findEdgesByTenantId(id.getId(), pageLink); |
148 | } | 321 | } |
149 | 322 | ||
150 | @Override | 323 | @Override |
151 | protected void removeEntity(TenantId tenantId, Edge entity) { | 324 | protected void removeEntity(TenantId tenantId, Edge entity) { |
152 | - deleteEdge(tenantId, new EdgeId(entity.getId().getId())); | 325 | + deleteEdge(tenantId, new EdgeId(entity.getUuidId())); |
153 | } | 326 | } |
154 | }; | 327 | }; |
155 | 328 | ||
329 | + private PaginatedRemover<CustomerId, Edge> customerEdgeUnasigner = new PaginatedRemover<CustomerId, Edge>() { | ||
330 | + | ||
331 | + @Override | ||
332 | + protected List<Edge> findEntities(TenantId tenantId, CustomerId id, TextPageLink pageLink) { | ||
333 | + return edgeDao.findEdgesByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink); | ||
334 | + } | ||
335 | + | ||
336 | + @Override | ||
337 | + protected void removeEntity(TenantId tenantId, Edge entity) { | ||
338 | + unassignEdgeFromCustomer(tenantId, new EdgeId(entity.getUuidId())); | ||
339 | + } | ||
340 | + }; | ||
341 | + | ||
156 | } | 342 | } |
@@ -15,29 +15,21 @@ | @@ -15,29 +15,21 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.dao.edge; | 16 | package org.thingsboard.server.dao.edge; |
17 | 17 | ||
18 | -import com.datastax.driver.core.querybuilder.Select; | ||
19 | import com.google.common.util.concurrent.ListenableFuture; | 18 | import com.google.common.util.concurrent.ListenableFuture; |
20 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
21 | import org.springframework.stereotype.Component; | 20 | import org.springframework.stereotype.Component; |
21 | +import org.thingsboard.server.common.data.EntitySubtype; | ||
22 | import org.thingsboard.server.common.data.edge.Edge; | 22 | import org.thingsboard.server.common.data.edge.Edge; |
23 | -import org.thingsboard.server.common.data.id.TenantId; | ||
24 | import org.thingsboard.server.common.data.page.TextPageLink; | 23 | import org.thingsboard.server.common.data.page.TextPageLink; |
25 | -import org.thingsboard.server.dao.DaoUtil; | ||
26 | import org.thingsboard.server.dao.model.nosql.EdgeEntity; | 24 | import org.thingsboard.server.dao.model.nosql.EdgeEntity; |
27 | import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao; | 25 | import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao; |
28 | import org.thingsboard.server.dao.util.NoSqlDao; | 26 | import org.thingsboard.server.dao.util.NoSqlDao; |
29 | 27 | ||
30 | -import java.util.Collections; | ||
31 | import java.util.List; | 28 | import java.util.List; |
29 | +import java.util.Optional; | ||
32 | import java.util.UUID; | 30 | import java.util.UUID; |
33 | 31 | ||
34 | -import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; | ||
35 | -import static com.datastax.driver.core.querybuilder.QueryBuilder.in; | ||
36 | -import static com.datastax.driver.core.querybuilder.QueryBuilder.select; | ||
37 | -import static org.thingsboard.server.dao.model.ModelConstants.EDGE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME; | ||
38 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_COLUMN_FAMILY_NAME; | 32 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_COLUMN_FAMILY_NAME; |
39 | -import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TENANT_ID_PROPERTY; | ||
40 | -import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY; | ||
41 | 33 | ||
42 | @Component | 34 | @Component |
43 | @Slf4j | 35 | @Slf4j |
@@ -54,24 +46,44 @@ public class CassandraEdgeDao extends CassandraAbstractSearchTextDao<EdgeEntity, | @@ -54,24 +46,44 @@ public class CassandraEdgeDao extends CassandraAbstractSearchTextDao<EdgeEntity, | ||
54 | return EDGE_COLUMN_FAMILY_NAME; | 46 | return EDGE_COLUMN_FAMILY_NAME; |
55 | } | 47 | } |
56 | 48 | ||
49 | + | ||
57 | @Override | 50 | @Override |
58 | - public List<Edge> findByTenantIdAndPageLink(UUID tenantId, TextPageLink pageLink) { | ||
59 | - log.debug("Try to find edges by tenantId [{}] and pageLink [{}]", tenantId, pageLink); | ||
60 | - List<EdgeEntity> edgeEntities = findPageWithTextSearch(new TenantId(tenantId), EDGE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, | ||
61 | - Collections.singletonList(eq(EDGE_TENANT_ID_PROPERTY, tenantId)), pageLink); | 51 | + public List<Edge> findEdgesByTenantId(UUID tenantId, TextPageLink pageLink) { |
52 | + return null; | ||
53 | + } | ||
62 | 54 | ||
63 | - log.trace("Found edges [{}] by tenantId [{}] and pageLink [{}]", edgeEntities, tenantId, pageLink); | ||
64 | - return DaoUtil.convertDataList(edgeEntities); | 55 | + @Override |
56 | + public List<Edge> findEdgesByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink) { | ||
57 | + return null; | ||
65 | } | 58 | } |
66 | 59 | ||
67 | @Override | 60 | @Override |
68 | public ListenableFuture<List<Edge>> findEdgesByTenantIdAndIdsAsync(UUID tenantId, List<UUID> edgeIds) { | 61 | public ListenableFuture<List<Edge>> findEdgesByTenantIdAndIdsAsync(UUID tenantId, List<UUID> edgeIds) { |
69 | - log.debug("Try to find edges by tenantId [{}] and edge Ids [{}]", tenantId, edgeIds); | ||
70 | - Select select = select().from(getColumnFamilyName()); | ||
71 | - Select.Where query = select.where(); | ||
72 | - query.and(eq(EDGE_TENANT_ID_PROPERTY, tenantId)); | ||
73 | - query.and(in(ID_PROPERTY, edgeIds)); | ||
74 | - return findListByStatementAsync(new TenantId(tenantId), query); | 62 | + return null; |
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + public List<Edge> findEdgesByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) { | ||
67 | + return null; | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + public List<Edge> findEdgesByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink) { | ||
72 | + return null; | ||
75 | } | 73 | } |
76 | 74 | ||
75 | + @Override | ||
76 | + public ListenableFuture<List<Edge>> findEdgesByTenantIdCustomerIdAndIdsAsync(UUID tenantId, UUID customerId, List<UUID> edgeIds) { | ||
77 | + return null; | ||
78 | + } | ||
79 | + | ||
80 | + @Override | ||
81 | + public Optional<Edge> findEdgeByTenantIdAndName(UUID tenantId, String name) { | ||
82 | + return Optional.empty(); | ||
83 | + } | ||
84 | + | ||
85 | + @Override | ||
86 | + public ListenableFuture<List<EntitySubtype>> findTenantEdgeTypesAsync(UUID tenantId) { | ||
87 | + return null; | ||
88 | + } | ||
77 | } | 89 | } |
@@ -16,11 +16,14 @@ | @@ -16,11 +16,14 @@ | ||
16 | package org.thingsboard.server.dao.edge; | 16 | package org.thingsboard.server.dao.edge; |
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.EntitySubtype; | ||
19 | import org.thingsboard.server.common.data.edge.Edge; | 20 | import org.thingsboard.server.common.data.edge.Edge; |
21 | +import org.thingsboard.server.common.data.id.TenantId; | ||
20 | import org.thingsboard.server.common.data.page.TextPageLink; | 22 | import org.thingsboard.server.common.data.page.TextPageLink; |
21 | import org.thingsboard.server.dao.Dao; | 23 | import org.thingsboard.server.dao.Dao; |
22 | 24 | ||
23 | import java.util.List; | 25 | import java.util.List; |
26 | +import java.util.Optional; | ||
24 | import java.util.UUID; | 27 | import java.util.UUID; |
25 | 28 | ||
26 | /** | 29 | /** |
@@ -30,16 +33,34 @@ import java.util.UUID; | @@ -30,16 +33,34 @@ import java.util.UUID; | ||
30 | public interface EdgeDao extends Dao<Edge> { | 33 | public interface EdgeDao extends Dao<Edge> { |
31 | 34 | ||
32 | /** | 35 | /** |
36 | + * Save or update edge object | ||
37 | + * | ||
38 | + * @param edge the edge object | ||
39 | + * @return saved edge object | ||
40 | + */ | ||
41 | + Edge save(TenantId tenantId, Edge edge); | ||
42 | + | ||
43 | + /** | ||
33 | * Find edges by tenantId and page link. | 44 | * Find edges by tenantId and page link. |
34 | * | 45 | * |
35 | * @param tenantId the tenantId | 46 | * @param tenantId the tenantId |
36 | * @param pageLink the page link | 47 | * @param pageLink the page link |
37 | * @return the list of edge objects | 48 | * @return the list of edge objects |
38 | */ | 49 | */ |
39 | - List<Edge> findByTenantIdAndPageLink(UUID tenantId, TextPageLink pageLink); | 50 | + List<Edge> findEdgesByTenantId(UUID tenantId, TextPageLink pageLink); |
51 | + | ||
52 | + /** | ||
53 | + * Find edges by tenantId, type and page link. | ||
54 | + * | ||
55 | + * @param tenantId the tenantId | ||
56 | + * @param type the type | ||
57 | + * @param pageLink the page link | ||
58 | + * @return the list of edge objects | ||
59 | + */ | ||
60 | + List<Edge> findEdgesByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink); | ||
40 | 61 | ||
41 | /** | 62 | /** |
42 | - * Find edges by tenantId and edge Ids. | 63 | + * Find edges by tenantId and edges Ids. |
43 | * | 64 | * |
44 | * @param tenantId the tenantId | 65 | * @param tenantId the tenantId |
45 | * @param edgeIds the edge Ids | 66 | * @param edgeIds the edge Ids |
@@ -47,5 +68,53 @@ public interface EdgeDao extends Dao<Edge> { | @@ -47,5 +68,53 @@ public interface EdgeDao extends Dao<Edge> { | ||
47 | */ | 68 | */ |
48 | ListenableFuture<List<Edge>> findEdgesByTenantIdAndIdsAsync(UUID tenantId, List<UUID> edgeIds); | 69 | ListenableFuture<List<Edge>> findEdgesByTenantIdAndIdsAsync(UUID tenantId, List<UUID> edgeIds); |
49 | 70 | ||
71 | + /** | ||
72 | + * Find edges by tenantId, customerId and page link. | ||
73 | + * | ||
74 | + * @param tenantId the tenantId | ||
75 | + * @param customerId the customerId | ||
76 | + * @param pageLink the page link | ||
77 | + * @return the list of edge objects | ||
78 | + */ | ||
79 | + List<Edge> findEdgesByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink); | ||
80 | + | ||
81 | + /** | ||
82 | + * Find edges by tenantId, customerId, type and page link. | ||
83 | + * | ||
84 | + * @param tenantId the tenantId | ||
85 | + * @param customerId the customerId | ||
86 | + * @param type the type | ||
87 | + * @param pageLink the page link | ||
88 | + * @return the list of edge objects | ||
89 | + */ | ||
90 | + List<Edge> findEdgesByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink); | ||
91 | + | ||
92 | + | ||
93 | + /** | ||
94 | + * Find edges by tenantId, customerId and edges Ids. | ||
95 | + * | ||
96 | + * @param tenantId the tenantId | ||
97 | + * @param customerId the customerId | ||
98 | + * @param edgeIds the edge Ids | ||
99 | + * @return the list of edge objects | ||
100 | + */ | ||
101 | + ListenableFuture<List<Edge>> findEdgesByTenantIdCustomerIdAndIdsAsync(UUID tenantId, UUID customerId, List<UUID> edgeIds); | ||
102 | + | ||
103 | + /** | ||
104 | + * Find edges by tenantId and edge name. | ||
105 | + * | ||
106 | + * @param tenantId the tenantId | ||
107 | + * @param name the edge name | ||
108 | + * @return the optional edge object | ||
109 | + */ | ||
110 | + Optional<Edge> findEdgeByTenantIdAndName(UUID tenantId, String name); | ||
111 | + | ||
112 | + /** | ||
113 | + * Find tenants edge types. | ||
114 | + * | ||
115 | + * @return the list of tenant edge type objects | ||
116 | + */ | ||
117 | + ListenableFuture<List<EntitySubtype>> findTenantEdgeTypesAsync(UUID tenantId); | ||
118 | + | ||
50 | 119 | ||
51 | } | 120 | } |
@@ -354,6 +354,7 @@ public class ModelConstants { | @@ -354,6 +354,7 @@ public class ModelConstants { | ||
354 | public static final String EDGE_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; | 354 | public static final String EDGE_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; |
355 | public static final String EDGE_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY; | 355 | public static final String EDGE_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY; |
356 | public static final String EDGE_NAME_PROPERTY = "name"; | 356 | public static final String EDGE_NAME_PROPERTY = "name"; |
357 | + public static final String EDGE_TYPE_PROPERTY = "type"; | ||
357 | public static final String EDGE_CONFIGURATION_PROPERTY = "configuration"; | 358 | public static final String EDGE_CONFIGURATION_PROPERTY = "configuration"; |
358 | public static final String EDGE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; | 359 | public static final String EDGE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; |
359 | 360 |
@@ -37,6 +37,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CONFIGURATION | @@ -37,6 +37,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CONFIGURATION | ||
37 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CUSTOMER_ID_PROPERTY; | 37 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CUSTOMER_ID_PROPERTY; |
38 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_NAME_PROPERTY; | 38 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_NAME_PROPERTY; |
39 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TENANT_ID_PROPERTY; | 39 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TENANT_ID_PROPERTY; |
40 | +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TYPE_PROPERTY; | ||
40 | import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY; | 41 | import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY; |
41 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; | 42 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; |
42 | 43 | ||
@@ -56,6 +57,9 @@ public class EdgeEntity implements SearchTextEntity<Edge> { | @@ -56,6 +57,9 @@ public class EdgeEntity implements SearchTextEntity<Edge> { | ||
56 | @Column(name = EDGE_CUSTOMER_ID_PROPERTY) | 57 | @Column(name = EDGE_CUSTOMER_ID_PROPERTY) |
57 | private UUID customerId; | 58 | private UUID customerId; |
58 | 59 | ||
60 | + @Column(name = EDGE_TYPE_PROPERTY) | ||
61 | + private String type; | ||
62 | + | ||
59 | @Column(name = EDGE_NAME_PROPERTY) | 63 | @Column(name = EDGE_NAME_PROPERTY) |
60 | private String name; | 64 | private String name; |
61 | 65 | ||
@@ -79,6 +83,7 @@ public class EdgeEntity implements SearchTextEntity<Edge> { | @@ -79,6 +83,7 @@ public class EdgeEntity implements SearchTextEntity<Edge> { | ||
79 | if (edge.getTenantId() != null) { | 83 | if (edge.getTenantId() != null) { |
80 | this.tenantId = edge.getTenantId().getId(); | 84 | this.tenantId = edge.getTenantId().getId(); |
81 | } | 85 | } |
86 | + this.type = edge.getType(); | ||
82 | this.name = edge.getName(); | 87 | this.name = edge.getName(); |
83 | this.configuration = edge.getConfiguration(); | 88 | this.configuration = edge.getConfiguration(); |
84 | this.additionalInfo = edge.getAdditionalInfo(); | 89 | this.additionalInfo = edge.getAdditionalInfo(); |
@@ -99,6 +104,7 @@ public class EdgeEntity implements SearchTextEntity<Edge> { | @@ -99,6 +104,7 @@ public class EdgeEntity implements SearchTextEntity<Edge> { | ||
99 | if (customerId != null) { | 104 | if (customerId != null) { |
100 | edge.setCustomerId(new CustomerId(customerId)); | 105 | edge.setCustomerId(new CustomerId(customerId)); |
101 | } | 106 | } |
107 | + edge.setType(type); | ||
102 | edge.setName(name); | 108 | edge.setName(name); |
103 | edge.setConfiguration(configuration); | 109 | edge.setConfiguration(configuration); |
104 | edge.setAdditionalInfo(additionalInfo); | 110 | edge.setAdditionalInfo(additionalInfo); |
@@ -40,6 +40,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.EDGE_COLUMN_FAMILY | @@ -40,6 +40,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.EDGE_COLUMN_FAMILY | ||
40 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CUSTOMER_ID_PROPERTY; | 40 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CUSTOMER_ID_PROPERTY; |
41 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_NAME_PROPERTY; | 41 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_NAME_PROPERTY; |
42 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TENANT_ID_PROPERTY; | 42 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TENANT_ID_PROPERTY; |
43 | +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TYPE_PROPERTY; | ||
43 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; | 44 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; |
44 | 45 | ||
45 | @Data | 46 | @Data |
@@ -55,6 +56,9 @@ public class EdgeEntity extends BaseSqlEntity<Edge> implements SearchTextEntity< | @@ -55,6 +56,9 @@ public class EdgeEntity extends BaseSqlEntity<Edge> implements SearchTextEntity< | ||
55 | @Column(name = EDGE_CUSTOMER_ID_PROPERTY) | 56 | @Column(name = EDGE_CUSTOMER_ID_PROPERTY) |
56 | private String customerId; | 57 | private String customerId; |
57 | 58 | ||
59 | + @Column(name = EDGE_TYPE_PROPERTY) | ||
60 | + private String type; | ||
61 | + | ||
58 | @Column(name = EDGE_NAME_PROPERTY) | 62 | @Column(name = EDGE_NAME_PROPERTY) |
59 | private String name; | 63 | private String name; |
60 | 64 | ||
@@ -80,6 +84,10 @@ public class EdgeEntity extends BaseSqlEntity<Edge> implements SearchTextEntity< | @@ -80,6 +84,10 @@ public class EdgeEntity extends BaseSqlEntity<Edge> implements SearchTextEntity< | ||
80 | if (edge.getTenantId() != null) { | 84 | if (edge.getTenantId() != null) { |
81 | this.tenantId = UUIDConverter.fromTimeUUID(edge.getTenantId().getId()); | 85 | this.tenantId = UUIDConverter.fromTimeUUID(edge.getTenantId().getId()); |
82 | } | 86 | } |
87 | + if (edge.getCustomerId() != null) { | ||
88 | + this.customerId = UUIDConverter.fromTimeUUID(edge.getCustomerId().getId()); | ||
89 | + } | ||
90 | + this.type = edge.getType(); | ||
83 | this.name = edge.getName(); | 91 | this.name = edge.getName(); |
84 | this.configuration = edge.getConfiguration(); | 92 | this.configuration = edge.getConfiguration(); |
85 | this.additionalInfo = edge.getAdditionalInfo(); | 93 | this.additionalInfo = edge.getAdditionalInfo(); |
@@ -109,6 +117,7 @@ public class EdgeEntity extends BaseSqlEntity<Edge> implements SearchTextEntity< | @@ -109,6 +117,7 @@ public class EdgeEntity extends BaseSqlEntity<Edge> implements SearchTextEntity< | ||
109 | if (customerId != null) { | 117 | if (customerId != null) { |
110 | edge.setCustomerId(new CustomerId(UUIDConverter.fromString(customerId))); | 118 | edge.setCustomerId(new CustomerId(UUIDConverter.fromString(customerId))); |
111 | } | 119 | } |
120 | + edge.setType(type); | ||
112 | edge.setName(name); | 121 | edge.setName(name); |
113 | edge.setConfiguration(configuration); | 122 | edge.setConfiguration(configuration); |
114 | edge.setAdditionalInfo(additionalInfo); | 123 | edge.setAdditionalInfo(additionalInfo); |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | * you may not use this file except in compliance with 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 | 6 | * You may obtain a copy of the License at |
7 | * | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * | 9 | * |
10 | * Unless required by applicable law or agreed to in writing, software | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
@@ -27,13 +27,52 @@ import java.util.List; | @@ -27,13 +27,52 @@ import java.util.List; | ||
27 | @SqlDao | 27 | @SqlDao |
28 | public interface EdgeRepository extends CrudRepository<EdgeEntity, String> { | 28 | public interface EdgeRepository extends CrudRepository<EdgeEntity, String> { |
29 | 29 | ||
30 | - @Query("SELECT a FROM EdgeEntity a WHERE a.tenantId = :tenantId " + | ||
31 | - "AND LOWER(a.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " + | ||
32 | - "AND a.id > :idOffset ORDER BY a.id") | ||
33 | - List<EdgeEntity> findByTenantIdAndPageLink(@Param("tenantId") String tenantId, | ||
34 | - @Param("textSearch") String textSearch, | ||
35 | - @Param("idOffset") String idOffset, | ||
36 | - Pageable pageable); | 30 | + @Query("SELECT d FROM EdgeEntity d WHERE d.tenantId = :tenantId " + |
31 | + "AND d.customerId = :customerId " + | ||
32 | + "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:searchText, '%')) " + | ||
33 | + "AND d.id > :idOffset ORDER BY d.id") | ||
34 | + List<EdgeEntity> findByTenantIdAndCustomerId(@Param("tenantId") String tenantId, | ||
35 | + @Param("customerId") String customerId, | ||
36 | + @Param("searchText") String searchText, | ||
37 | + @Param("idOffset") String idOffset, | ||
38 | + Pageable pageable); | ||
39 | + | ||
40 | + @Query("SELECT d FROM EdgeEntity d WHERE d.tenantId = :tenantId " + | ||
41 | + "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " + | ||
42 | + "AND d.id > :idOffset ORDER BY d.id") | ||
43 | + List<EdgeEntity> findByTenantId(@Param("tenantId") String tenantId, | ||
44 | + @Param("textSearch") String textSearch, | ||
45 | + @Param("idOffset") String idOffset, | ||
46 | + Pageable pageable); | ||
47 | + | ||
48 | + @Query("SELECT d FROM EdgeEntity d WHERE d.tenantId = :tenantId " + | ||
49 | + "AND d.type = :type " + | ||
50 | + "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " + | ||
51 | + "AND d.id > :idOffset ORDER BY d.id") | ||
52 | + List<EdgeEntity> findByTenantIdAndType(@Param("tenantId") String tenantId, | ||
53 | + @Param("type") String type, | ||
54 | + @Param("textSearch") String textSearch, | ||
55 | + @Param("idOffset") String idOffset, | ||
56 | + Pageable pageable); | ||
57 | + | ||
58 | + @Query("SELECT d FROM EdgeEntity d WHERE d.tenantId = :tenantId " + | ||
59 | + "AND d.customerId = :customerId " + | ||
60 | + "AND d.type = :type " + | ||
61 | + "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " + | ||
62 | + "AND d.id > :idOffset ORDER BY d.id") | ||
63 | + List<EdgeEntity> findByTenantIdAndCustomerIdAndType(@Param("tenantId") String tenantId, | ||
64 | + @Param("customerId") String customerId, | ||
65 | + @Param("type") String type, | ||
66 | + @Param("textSearch") String textSearch, | ||
67 | + @Param("idOffset") String idOffset, | ||
68 | + Pageable pageable); | ||
69 | + | ||
70 | + @Query("SELECT DISTINCT d.type FROM EdgeEntity d WHERE d.tenantId = :tenantId") | ||
71 | + List<String> findTenantEdgeTypes(@Param("tenantId") String tenantId); | ||
72 | + | ||
73 | + EdgeEntity findByTenantIdAndName(String tenantId, String name); | ||
74 | + | ||
75 | + List<EdgeEntity> findEdgesByTenantIdAndCustomerIdAndIdIn(String tenantId, String customerId, List<String> edgeIds); | ||
37 | 76 | ||
38 | List<EdgeEntity> findEdgesByTenantIdAndIdIn(String tenantId, List<String> edgeIds); | 77 | List<EdgeEntity> findEdgesByTenantIdAndIdIn(String tenantId, List<String> edgeIds); |
39 | 78 |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | * you may not use this file except in compliance with 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 | 6 | * You may obtain a copy of the License at |
7 | * | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * | 9 | * |
10 | * Unless required by applicable law or agreed to in writing, software | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
@@ -20,8 +20,11 @@ import org.springframework.beans.factory.annotation.Autowired; | @@ -20,8 +20,11 @@ import org.springframework.beans.factory.annotation.Autowired; | ||
20 | import org.springframework.data.domain.PageRequest; | 20 | import org.springframework.data.domain.PageRequest; |
21 | import org.springframework.data.repository.CrudRepository; | 21 | import org.springframework.data.repository.CrudRepository; |
22 | import org.springframework.stereotype.Component; | 22 | import org.springframework.stereotype.Component; |
23 | +import org.thingsboard.server.common.data.EntitySubtype; | ||
24 | +import org.thingsboard.server.common.data.EntityType; | ||
23 | import org.thingsboard.server.common.data.UUIDConverter; | 25 | import org.thingsboard.server.common.data.UUIDConverter; |
24 | import org.thingsboard.server.common.data.edge.Edge; | 26 | import org.thingsboard.server.common.data.edge.Edge; |
27 | +import org.thingsboard.server.common.data.id.TenantId; | ||
25 | import org.thingsboard.server.common.data.page.TextPageLink; | 28 | import org.thingsboard.server.common.data.page.TextPageLink; |
26 | import org.thingsboard.server.dao.DaoUtil; | 29 | import org.thingsboard.server.dao.DaoUtil; |
27 | import org.thingsboard.server.dao.edge.EdgeDao; | 30 | import org.thingsboard.server.dao.edge.EdgeDao; |
@@ -29,8 +32,11 @@ import org.thingsboard.server.dao.model.sql.EdgeEntity; | @@ -29,8 +32,11 @@ import org.thingsboard.server.dao.model.sql.EdgeEntity; | ||
29 | import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; | 32 | import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; |
30 | import org.thingsboard.server.dao.util.SqlDao; | 33 | import org.thingsboard.server.dao.util.SqlDao; |
31 | 34 | ||
35 | +import java.util.ArrayList; | ||
36 | +import java.util.Collections; | ||
32 | import java.util.List; | 37 | import java.util.List; |
33 | import java.util.Objects; | 38 | import java.util.Objects; |
39 | +import java.util.Optional; | ||
34 | import java.util.UUID; | 40 | import java.util.UUID; |
35 | 41 | ||
36 | import static org.thingsboard.server.common.data.UUIDConverter.fromTimeUUID; | 42 | import static org.thingsboard.server.common.data.UUIDConverter.fromTimeUUID; |
@@ -45,9 +51,19 @@ public class JpaEdgeDao extends JpaAbstractSearchTextDao<EdgeEntity, Edge> imple | @@ -45,9 +51,19 @@ public class JpaEdgeDao extends JpaAbstractSearchTextDao<EdgeEntity, Edge> imple | ||
45 | private EdgeRepository edgeRepository; | 51 | private EdgeRepository edgeRepository; |
46 | 52 | ||
47 | @Override | 53 | @Override |
48 | - public List<Edge> findByTenantIdAndPageLink(UUID tenantId, TextPageLink pageLink) { | ||
49 | - return DaoUtil.convertDataList(edgeRepository | ||
50 | - .findByTenantIdAndPageLink( | 54 | + protected Class<EdgeEntity> getEntityClass() { |
55 | + return EdgeEntity.class; | ||
56 | + } | ||
57 | + | ||
58 | + @Override | ||
59 | + protected CrudRepository<EdgeEntity, String> getCrudRepository() { | ||
60 | + return edgeRepository; | ||
61 | + } | ||
62 | + | ||
63 | + @Override | ||
64 | + public List<Edge> findEdgesByTenantId(UUID tenantId, TextPageLink pageLink) { | ||
65 | + return DaoUtil.convertDataList( | ||
66 | + edgeRepository.findByTenantId( | ||
51 | fromTimeUUID(tenantId), | 67 | fromTimeUUID(tenantId), |
52 | Objects.toString(pageLink.getTextSearch(), ""), | 68 | Objects.toString(pageLink.getTextSearch(), ""), |
53 | pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()), | 69 | pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()), |
@@ -60,13 +76,65 @@ public class JpaEdgeDao extends JpaAbstractSearchTextDao<EdgeEntity, Edge> imple | @@ -60,13 +76,65 @@ public class JpaEdgeDao extends JpaAbstractSearchTextDao<EdgeEntity, Edge> imple | ||
60 | } | 76 | } |
61 | 77 | ||
62 | @Override | 78 | @Override |
63 | - protected Class<EdgeEntity> getEntityClass() { | ||
64 | - return EdgeEntity.class; | 79 | + public List<Edge> findEdgesByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) { |
80 | + return DaoUtil.convertDataList( | ||
81 | + edgeRepository.findByTenantIdAndCustomerId( | ||
82 | + fromTimeUUID(tenantId), | ||
83 | + fromTimeUUID(customerId), | ||
84 | + Objects.toString(pageLink.getTextSearch(), ""), | ||
85 | + pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()), | ||
86 | + new PageRequest(0, pageLink.getLimit()))); | ||
65 | } | 87 | } |
66 | 88 | ||
67 | @Override | 89 | @Override |
68 | - protected CrudRepository<EdgeEntity, String> getCrudRepository() { | ||
69 | - return edgeRepository; | 90 | + public ListenableFuture<List<Edge>> findEdgesByTenantIdCustomerIdAndIdsAsync(UUID tenantId, UUID customerId, List<UUID> edgeIds) { |
91 | + return service.submit(() -> DaoUtil.convertDataList( | ||
92 | + edgeRepository.findEdgesByTenantIdAndCustomerIdAndIdIn(fromTimeUUID(tenantId), fromTimeUUID(customerId), fromTimeUUIDs(edgeIds)))); | ||
93 | + } | ||
94 | + | ||
95 | + @Override | ||
96 | + public Optional<Edge> findEdgeByTenantIdAndName(UUID tenantId, String name) { | ||
97 | + Edge edge = DaoUtil.getData(edgeRepository.findByTenantIdAndName(fromTimeUUID(tenantId), name)); | ||
98 | + return Optional.ofNullable(edge); | ||
99 | + } | ||
100 | + | ||
101 | + @Override | ||
102 | + public List<Edge> findEdgesByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink) { | ||
103 | + return DaoUtil.convertDataList( | ||
104 | + edgeRepository.findByTenantIdAndType( | ||
105 | + fromTimeUUID(tenantId), | ||
106 | + type, | ||
107 | + Objects.toString(pageLink.getTextSearch(), ""), | ||
108 | + pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()), | ||
109 | + new PageRequest(0, pageLink.getLimit()))); | ||
110 | + } | ||
111 | + | ||
112 | + @Override | ||
113 | + public List<Edge> findEdgesByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink) { | ||
114 | + return DaoUtil.convertDataList( | ||
115 | + edgeRepository.findByTenantIdAndCustomerIdAndType( | ||
116 | + fromTimeUUID(tenantId), | ||
117 | + fromTimeUUID(customerId), | ||
118 | + type, | ||
119 | + Objects.toString(pageLink.getTextSearch(), ""), | ||
120 | + pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()), | ||
121 | + new PageRequest(0, pageLink.getLimit()))); | ||
122 | + } | ||
123 | + | ||
124 | + @Override | ||
125 | + public ListenableFuture<List<EntitySubtype>> findTenantEdgeTypesAsync(UUID tenantId) { | ||
126 | + return service.submit(() -> convertTenantEdgeTypesToDto(tenantId, edgeRepository.findTenantEdgeTypes(fromTimeUUID(tenantId)))); | ||
127 | + } | ||
128 | + | ||
129 | + private List<EntitySubtype> convertTenantEdgeTypesToDto(UUID tenantId, List<String> types) { | ||
130 | + List<EntitySubtype> list = Collections.emptyList(); | ||
131 | + if (types != null && !types.isEmpty()) { | ||
132 | + list = new ArrayList<>(); | ||
133 | + for (String type : types) { | ||
134 | + list.add(new EntitySubtype(new TenantId(tenantId), EntityType.EDGE, type)); | ||
135 | + } | ||
136 | + } | ||
137 | + return list; | ||
70 | } | 138 | } |
71 | 139 | ||
72 | } | 140 | } |
@@ -29,6 +29,7 @@ import org.thingsboard.server.dao.asset.AssetService; | @@ -29,6 +29,7 @@ import org.thingsboard.server.dao.asset.AssetService; | ||
29 | import org.thingsboard.server.dao.customer.CustomerService; | 29 | import org.thingsboard.server.dao.customer.CustomerService; |
30 | import org.thingsboard.server.dao.dashboard.DashboardService; | 30 | import org.thingsboard.server.dao.dashboard.DashboardService; |
31 | import org.thingsboard.server.dao.device.DeviceService; | 31 | import org.thingsboard.server.dao.device.DeviceService; |
32 | +import org.thingsboard.server.dao.edge.EdgeService; | ||
32 | import org.thingsboard.server.dao.entity.AbstractEntityService; | 33 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
33 | import org.thingsboard.server.dao.entityview.EntityViewService; | 34 | import org.thingsboard.server.dao.entityview.EntityViewService; |
34 | import org.thingsboard.server.dao.exception.DataValidationException; | 35 | import org.thingsboard.server.dao.exception.DataValidationException; |
@@ -77,6 +78,9 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | @@ -77,6 +78,9 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | ||
77 | @Autowired | 78 | @Autowired |
78 | private RuleChainService ruleChainService; | 79 | private RuleChainService ruleChainService; |
79 | 80 | ||
81 | + @Autowired | ||
82 | + private EdgeService edgeService; | ||
83 | + | ||
80 | @Override | 84 | @Override |
81 | public Tenant findTenantById(TenantId tenantId) { | 85 | public Tenant findTenantById(TenantId tenantId) { |
82 | log.trace("Executing findTenantById [{}]", tenantId); | 86 | log.trace("Executing findTenantById [{}]", tenantId); |
@@ -109,6 +113,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | @@ -109,6 +113,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | ||
109 | entityViewService.deleteEntityViewsByTenantId(tenantId); | 113 | entityViewService.deleteEntityViewsByTenantId(tenantId); |
110 | assetService.deleteAssetsByTenantId(tenantId); | 114 | assetService.deleteAssetsByTenantId(tenantId); |
111 | deviceService.deleteDevicesByTenantId(tenantId); | 115 | deviceService.deleteDevicesByTenantId(tenantId); |
116 | + edgeService.deleteEdgesByTenantId(tenantId); | ||
112 | userService.deleteTenantAdmins(tenantId); | 117 | userService.deleteTenantAdmins(tenantId); |
113 | ruleChainService.deleteRuleChainsByTenantId(tenantId); | 118 | ruleChainService.deleteRuleChainsByTenantId(tenantId); |
114 | tenantDao.removeById(tenantId, tenantId.getId()); | 119 | tenantDao.removeById(tenantId, tenantId.getId()); |
@@ -254,6 +254,7 @@ CREATE TABLE IF NOT EXISTS edge ( | @@ -254,6 +254,7 @@ CREATE TABLE IF NOT EXISTS edge ( | ||
254 | additional_info varchar, | 254 | additional_info varchar, |
255 | customer_id varchar(31), | 255 | customer_id varchar(31), |
256 | configuration varchar(10000000), | 256 | configuration varchar(10000000), |
257 | + type varchar(255), | ||
257 | name varchar(255), | 258 | name varchar(255), |
258 | search_text varchar(255), | 259 | search_text varchar(255), |
259 | tenant_id varchar(31) | 260 | tenant_id varchar(31) |
@@ -45,6 +45,7 @@ import org.thingsboard.server.dao.customer.CustomerService; | @@ -45,6 +45,7 @@ import org.thingsboard.server.dao.customer.CustomerService; | ||
45 | import org.thingsboard.server.dao.dashboard.DashboardService; | 45 | import org.thingsboard.server.dao.dashboard.DashboardService; |
46 | import org.thingsboard.server.dao.device.DeviceCredentialsService; | 46 | import org.thingsboard.server.dao.device.DeviceCredentialsService; |
47 | import org.thingsboard.server.dao.device.DeviceService; | 47 | import org.thingsboard.server.dao.device.DeviceService; |
48 | +import org.thingsboard.server.dao.edge.EdgeService; | ||
48 | import org.thingsboard.server.dao.entityview.EntityViewService; | 49 | import org.thingsboard.server.dao.entityview.EntityViewService; |
49 | import org.thingsboard.server.dao.event.EventService; | 50 | import org.thingsboard.server.dao.event.EventService; |
50 | import org.thingsboard.server.dao.relation.RelationService; | 51 | import org.thingsboard.server.dao.relation.RelationService; |
@@ -122,6 +123,9 @@ public abstract class AbstractServiceTest { | @@ -122,6 +123,9 @@ public abstract class AbstractServiceTest { | ||
122 | protected RuleChainService ruleChainService; | 123 | protected RuleChainService ruleChainService; |
123 | 124 | ||
124 | @Autowired | 125 | @Autowired |
126 | + protected EdgeService edgeService; | ||
127 | + | ||
128 | + @Autowired | ||
125 | private ComponentDescriptorService componentDescriptorService; | 129 | private ComponentDescriptorService componentDescriptorService; |
126 | 130 | ||
127 | class IdComparator<D extends BaseData<? extends UUIDBased>> implements Comparator<D> { | 131 | class IdComparator<D extends BaseData<? extends UUIDBased>> implements Comparator<D> { |
1 | +/** | ||
2 | + * Copyright © 2016-2019 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.service; | ||
17 | + | ||
18 | +import com.datastax.driver.core.utils.UUIDs; | ||
19 | +import org.apache.commons.lang3.RandomStringUtils; | ||
20 | +import org.junit.After; | ||
21 | +import org.junit.Assert; | ||
22 | +import org.junit.Before; | ||
23 | +import org.junit.Test; | ||
24 | +import org.thingsboard.server.common.data.Customer; | ||
25 | +import org.thingsboard.server.common.data.EntitySubtype; | ||
26 | +import org.thingsboard.server.common.data.Tenant; | ||
27 | +import org.thingsboard.server.common.data.edge.Edge; | ||
28 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
29 | +import org.thingsboard.server.common.data.id.TenantId; | ||
30 | +import org.thingsboard.server.common.data.page.TextPageData; | ||
31 | +import org.thingsboard.server.common.data.page.TextPageLink; | ||
32 | +import org.thingsboard.server.dao.exception.DataValidationException; | ||
33 | + | ||
34 | +import java.util.ArrayList; | ||
35 | +import java.util.Collections; | ||
36 | +import java.util.List; | ||
37 | + | ||
38 | +import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; | ||
39 | + | ||
40 | +public abstract class BaseEdgeServiceTest extends AbstractServiceTest { | ||
41 | + | ||
42 | + private IdComparator<Edge> idComparator = new IdComparator<>(); | ||
43 | + | ||
44 | + private TenantId tenantId; | ||
45 | + | ||
46 | + @Before | ||
47 | + public void before() { | ||
48 | + Tenant tenant = new Tenant(); | ||
49 | + tenant.setTitle("My tenant"); | ||
50 | + Tenant savedTenant = tenantService.saveTenant(tenant); | ||
51 | + Assert.assertNotNull(savedTenant); | ||
52 | + tenantId = savedTenant.getId(); | ||
53 | + } | ||
54 | + | ||
55 | + @After | ||
56 | + public void after() { | ||
57 | + tenantService.deleteTenant(tenantId); | ||
58 | + } | ||
59 | + | ||
60 | + @Test | ||
61 | + public void testSaveEdge() { | ||
62 | + Edge edge = new Edge(); | ||
63 | + edge.setTenantId(tenantId); | ||
64 | + edge.setName("My edge"); | ||
65 | + edge.setType("default"); | ||
66 | + Edge savedEdge = edgeService.saveEdge(edge); | ||
67 | + | ||
68 | + Assert.assertNotNull(savedEdge); | ||
69 | + Assert.assertNotNull(savedEdge.getId()); | ||
70 | + Assert.assertTrue(savedEdge.getCreatedTime() > 0); | ||
71 | + Assert.assertEquals(edge.getTenantId(), savedEdge.getTenantId()); | ||
72 | + Assert.assertNotNull(savedEdge.getCustomerId()); | ||
73 | + Assert.assertEquals(NULL_UUID, savedEdge.getCustomerId().getId()); | ||
74 | + Assert.assertEquals(edge.getName(), savedEdge.getName()); | ||
75 | + | ||
76 | + savedEdge.setName("My new edge"); | ||
77 | + | ||
78 | + edgeService.saveEdge(savedEdge); | ||
79 | + Edge foundEdge = edgeService.findEdgeById(tenantId, savedEdge.getId()); | ||
80 | + Assert.assertEquals(foundEdge.getName(), savedEdge.getName()); | ||
81 | + | ||
82 | + edgeService.deleteEdge(tenantId, savedEdge.getId()); | ||
83 | + } | ||
84 | + | ||
85 | + @Test(expected = DataValidationException.class) | ||
86 | + public void testSaveEdgeWithEmptyName() { | ||
87 | + Edge edge = new Edge(); | ||
88 | + edge.setType("default"); | ||
89 | + edge.setTenantId(tenantId); | ||
90 | + edgeService.saveEdge(edge); | ||
91 | + } | ||
92 | + | ||
93 | + @Test(expected = DataValidationException.class) | ||
94 | + public void testSaveEdgeWithEmptyTenant() { | ||
95 | + Edge edge = new Edge(); | ||
96 | + edge.setName("My edge"); | ||
97 | + edge.setType("default"); | ||
98 | + edgeService.saveEdge(edge); | ||
99 | + } | ||
100 | + | ||
101 | + @Test(expected = DataValidationException.class) | ||
102 | + public void testSaveEdgeWithInvalidTenant() { | ||
103 | + Edge edge = new Edge(); | ||
104 | + edge.setName("My edge"); | ||
105 | + edge.setType("default"); | ||
106 | + edge.setTenantId(new TenantId(UUIDs.timeBased())); | ||
107 | + edgeService.saveEdge(edge); | ||
108 | + } | ||
109 | + | ||
110 | + @Test(expected = DataValidationException.class) | ||
111 | + public void testAssignEdgeToNonExistentCustomer() { | ||
112 | + Edge edge = new Edge(); | ||
113 | + edge.setName("My edge"); | ||
114 | + edge.setType("default"); | ||
115 | + edge.setTenantId(tenantId); | ||
116 | + edge = edgeService.saveEdge(edge); | ||
117 | + try { | ||
118 | + edgeService.assignEdgeToCustomer(tenantId, edge.getId(), new CustomerId(UUIDs.timeBased())); | ||
119 | + } finally { | ||
120 | + edgeService.deleteEdge(tenantId, edge.getId()); | ||
121 | + } | ||
122 | + } | ||
123 | + | ||
124 | + @Test(expected = DataValidationException.class) | ||
125 | + public void testAssignEdgeToCustomerFromDifferentTenant() { | ||
126 | + Edge edge = new Edge(); | ||
127 | + edge.setName("My edge"); | ||
128 | + edge.setType("default"); | ||
129 | + edge.setTenantId(tenantId); | ||
130 | + edge = edgeService.saveEdge(edge); | ||
131 | + Tenant tenant = new Tenant(); | ||
132 | + tenant.setTitle("Test different tenant"); | ||
133 | + tenant = tenantService.saveTenant(tenant); | ||
134 | + Customer customer = new Customer(); | ||
135 | + customer.setTenantId(tenant.getId()); | ||
136 | + customer.setTitle("Test different customer"); | ||
137 | + customer = customerService.saveCustomer(customer); | ||
138 | + try { | ||
139 | + edgeService.assignEdgeToCustomer(tenantId, edge.getId(), customer.getId()); | ||
140 | + } finally { | ||
141 | + edgeService.deleteEdge(tenantId, edge.getId()); | ||
142 | + tenantService.deleteTenant(tenant.getId()); | ||
143 | + } | ||
144 | + } | ||
145 | + | ||
146 | + @Test | ||
147 | + public void testFindEdgeById() { | ||
148 | + Edge edge = new Edge(); | ||
149 | + edge.setTenantId(tenantId); | ||
150 | + edge.setName("My edge"); | ||
151 | + edge.setType("default"); | ||
152 | + Edge savedEdge = edgeService.saveEdge(edge); | ||
153 | + Edge foundEdge = edgeService.findEdgeById(tenantId, savedEdge.getId()); | ||
154 | + Assert.assertNotNull(foundEdge); | ||
155 | + Assert.assertEquals(savedEdge, foundEdge); | ||
156 | + edgeService.deleteEdge(tenantId, savedEdge.getId()); | ||
157 | + } | ||
158 | + | ||
159 | + @Test | ||
160 | + public void testFindEdgeTypesByTenantId() throws Exception { | ||
161 | + List<Edge> edges = new ArrayList<>(); | ||
162 | + try { | ||
163 | + for (int i = 0; i < 3; i++) { | ||
164 | + Edge edge = new Edge(); | ||
165 | + edge.setTenantId(tenantId); | ||
166 | + edge.setName("My edge B" + i); | ||
167 | + edge.setType("typeB"); | ||
168 | + edges.add(edgeService.saveEdge(edge)); | ||
169 | + } | ||
170 | + for (int i = 0; i < 7; i++) { | ||
171 | + Edge edge = new Edge(); | ||
172 | + edge.setTenantId(tenantId); | ||
173 | + edge.setName("My edge C" + i); | ||
174 | + edge.setType("typeC"); | ||
175 | + edges.add(edgeService.saveEdge(edge)); | ||
176 | + } | ||
177 | + for (int i = 0; i < 9; i++) { | ||
178 | + Edge edge = new Edge(); | ||
179 | + edge.setTenantId(tenantId); | ||
180 | + edge.setName("My edge A" + i); | ||
181 | + edge.setType("typeA"); | ||
182 | + edges.add(edgeService.saveEdge(edge)); | ||
183 | + } | ||
184 | + List<EntitySubtype> edgeTypes = edgeService.findEdgeTypesByTenantId(tenantId).get(); | ||
185 | + Assert.assertNotNull(edgeTypes); | ||
186 | + Assert.assertEquals(3, edgeTypes.size()); | ||
187 | + Assert.assertEquals("typeA", edgeTypes.get(0).getType()); | ||
188 | + Assert.assertEquals("typeB", edgeTypes.get(1).getType()); | ||
189 | + Assert.assertEquals("typeC", edgeTypes.get(2).getType()); | ||
190 | + } finally { | ||
191 | + edges.forEach((edge) -> { | ||
192 | + edgeService.deleteEdge(tenantId, edge.getId()); | ||
193 | + }); | ||
194 | + } | ||
195 | + } | ||
196 | + | ||
197 | + @Test | ||
198 | + public void testDeleteEdge() { | ||
199 | + Edge edge = new Edge(); | ||
200 | + edge.setTenantId(tenantId); | ||
201 | + edge.setName("My edge"); | ||
202 | + edge.setType("default"); | ||
203 | + Edge savedEdge = edgeService.saveEdge(edge); | ||
204 | + Edge foundEdge = edgeService.findEdgeById(tenantId, savedEdge.getId()); | ||
205 | + Assert.assertNotNull(foundEdge); | ||
206 | + edgeService.deleteEdge(tenantId, savedEdge.getId()); | ||
207 | + foundEdge = edgeService.findEdgeById(tenantId, savedEdge.getId()); | ||
208 | + Assert.assertNull(foundEdge); | ||
209 | + } | ||
210 | + | ||
211 | + @Test | ||
212 | + public void testFindEdgesByTenantId() { | ||
213 | + Tenant tenant = new Tenant(); | ||
214 | + tenant.setTitle("Test tenant"); | ||
215 | + tenant = tenantService.saveTenant(tenant); | ||
216 | + | ||
217 | + TenantId tenantId = tenant.getId(); | ||
218 | + | ||
219 | + List<Edge> edges = new ArrayList<>(); | ||
220 | + for (int i = 0; i < 178; i++) { | ||
221 | + Edge edge = new Edge(); | ||
222 | + edge.setTenantId(tenantId); | ||
223 | + edge.setName("Edge" + i); | ||
224 | + edge.setType("default"); | ||
225 | + edges.add(edgeService.saveEdge(edge)); | ||
226 | + } | ||
227 | + | ||
228 | + List<Edge> loadedEdges = new ArrayList<>(); | ||
229 | + TextPageLink pageLink = new TextPageLink(23); | ||
230 | + TextPageData<Edge> pageData = null; | ||
231 | + do { | ||
232 | + pageData = edgeService.findEdgesByTenantId(tenantId, pageLink); | ||
233 | + loadedEdges.addAll(pageData.getData()); | ||
234 | + if (pageData.hasNext()) { | ||
235 | + pageLink = pageData.getNextPageLink(); | ||
236 | + } | ||
237 | + } while (pageData.hasNext()); | ||
238 | + | ||
239 | + Collections.sort(edges, idComparator); | ||
240 | + Collections.sort(loadedEdges, idComparator); | ||
241 | + | ||
242 | + Assert.assertEquals(edges, loadedEdges); | ||
243 | + | ||
244 | + edgeService.deleteEdgesByTenantId(tenantId); | ||
245 | + | ||
246 | + pageLink = new TextPageLink(33); | ||
247 | + pageData = edgeService.findEdgesByTenantId(tenantId, pageLink); | ||
248 | + Assert.assertFalse(pageData.hasNext()); | ||
249 | + Assert.assertTrue(pageData.getData().isEmpty()); | ||
250 | + | ||
251 | + tenantService.deleteTenant(tenantId); | ||
252 | + } | ||
253 | + | ||
254 | + @Test | ||
255 | + public void testFindEdgesByTenantIdAndName() { | ||
256 | + String title1 = "Edge title 1"; | ||
257 | + List<Edge> edgesTitle1 = new ArrayList<>(); | ||
258 | + for (int i = 0; i < 143; i++) { | ||
259 | + Edge edge = new Edge(); | ||
260 | + edge.setTenantId(tenantId); | ||
261 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
262 | + String name = title1 + suffix; | ||
263 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
264 | + edge.setName(name); | ||
265 | + edge.setType("default"); | ||
266 | + edgesTitle1.add(edgeService.saveEdge(edge)); | ||
267 | + } | ||
268 | + String title2 = "Edge title 2"; | ||
269 | + List<Edge> edgesTitle2 = new ArrayList<>(); | ||
270 | + for (int i = 0; i < 175; i++) { | ||
271 | + Edge edge = new Edge(); | ||
272 | + edge.setTenantId(tenantId); | ||
273 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
274 | + String name = title2 + suffix; | ||
275 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
276 | + edge.setName(name); | ||
277 | + edge.setType("default"); | ||
278 | + edgesTitle2.add(edgeService.saveEdge(edge)); | ||
279 | + } | ||
280 | + | ||
281 | + List<Edge> loadedEdgesTitle1 = new ArrayList<>(); | ||
282 | + TextPageLink pageLink = new TextPageLink(15, title1); | ||
283 | + TextPageData<Edge> pageData = null; | ||
284 | + do { | ||
285 | + pageData = edgeService.findEdgesByTenantId(tenantId, pageLink); | ||
286 | + loadedEdgesTitle1.addAll(pageData.getData()); | ||
287 | + if (pageData.hasNext()) { | ||
288 | + pageLink = pageData.getNextPageLink(); | ||
289 | + } | ||
290 | + } while (pageData.hasNext()); | ||
291 | + | ||
292 | + Collections.sort(edgesTitle1, idComparator); | ||
293 | + Collections.sort(loadedEdgesTitle1, idComparator); | ||
294 | + | ||
295 | + Assert.assertEquals(edgesTitle1, loadedEdgesTitle1); | ||
296 | + | ||
297 | + List<Edge> loadedEdgesTitle2 = new ArrayList<>(); | ||
298 | + pageLink = new TextPageLink(4, title2); | ||
299 | + do { | ||
300 | + pageData = edgeService.findEdgesByTenantId(tenantId, pageLink); | ||
301 | + loadedEdgesTitle2.addAll(pageData.getData()); | ||
302 | + if (pageData.hasNext()) { | ||
303 | + pageLink = pageData.getNextPageLink(); | ||
304 | + } | ||
305 | + } while (pageData.hasNext()); | ||
306 | + | ||
307 | + Collections.sort(edgesTitle2, idComparator); | ||
308 | + Collections.sort(loadedEdgesTitle2, idComparator); | ||
309 | + | ||
310 | + Assert.assertEquals(edgesTitle2, loadedEdgesTitle2); | ||
311 | + | ||
312 | + for (Edge edge : loadedEdgesTitle1) { | ||
313 | + edgeService.deleteEdge(tenantId, edge.getId()); | ||
314 | + } | ||
315 | + | ||
316 | + pageLink = new TextPageLink(4, title1); | ||
317 | + pageData = edgeService.findEdgesByTenantId(tenantId, pageLink); | ||
318 | + Assert.assertFalse(pageData.hasNext()); | ||
319 | + Assert.assertEquals(0, pageData.getData().size()); | ||
320 | + | ||
321 | + for (Edge edge : loadedEdgesTitle2) { | ||
322 | + edgeService.deleteEdge(tenantId, edge.getId()); | ||
323 | + } | ||
324 | + | ||
325 | + pageLink = new TextPageLink(4, title2); | ||
326 | + pageData = edgeService.findEdgesByTenantId(tenantId, pageLink); | ||
327 | + Assert.assertFalse(pageData.hasNext()); | ||
328 | + Assert.assertEquals(0, pageData.getData().size()); | ||
329 | + } | ||
330 | + | ||
331 | + @Test | ||
332 | + public void testFindEdgesByTenantIdAndType() { | ||
333 | + String title1 = "Edge title 1"; | ||
334 | + String type1 = "typeA"; | ||
335 | + List<Edge> edgesType1 = new ArrayList<>(); | ||
336 | + for (int i = 0; i < 143; i++) { | ||
337 | + Edge edge = new Edge(); | ||
338 | + edge.setTenantId(tenantId); | ||
339 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
340 | + String name = title1 + suffix; | ||
341 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
342 | + edge.setName(name); | ||
343 | + edge.setType(type1); | ||
344 | + edgesType1.add(edgeService.saveEdge(edge)); | ||
345 | + } | ||
346 | + String title2 = "Edge title 2"; | ||
347 | + String type2 = "typeB"; | ||
348 | + List<Edge> edgesType2 = new ArrayList<>(); | ||
349 | + for (int i = 0; i < 175; i++) { | ||
350 | + Edge edge = new Edge(); | ||
351 | + edge.setTenantId(tenantId); | ||
352 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
353 | + String name = title2 + suffix; | ||
354 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
355 | + edge.setName(name); | ||
356 | + edge.setType(type2); | ||
357 | + edgesType2.add(edgeService.saveEdge(edge)); | ||
358 | + } | ||
359 | + | ||
360 | + List<Edge> loadedEdgesType1 = new ArrayList<>(); | ||
361 | + TextPageLink pageLink = new TextPageLink(15); | ||
362 | + TextPageData<Edge> pageData = null; | ||
363 | + do { | ||
364 | + pageData = edgeService.findEdgesByTenantIdAndType(tenantId, type1, pageLink); | ||
365 | + loadedEdgesType1.addAll(pageData.getData()); | ||
366 | + if (pageData.hasNext()) { | ||
367 | + pageLink = pageData.getNextPageLink(); | ||
368 | + } | ||
369 | + } while (pageData.hasNext()); | ||
370 | + | ||
371 | + Collections.sort(edgesType1, idComparator); | ||
372 | + Collections.sort(loadedEdgesType1, idComparator); | ||
373 | + | ||
374 | + Assert.assertEquals(edgesType1, loadedEdgesType1); | ||
375 | + | ||
376 | + List<Edge> loadedEdgesType2 = new ArrayList<>(); | ||
377 | + pageLink = new TextPageLink(4); | ||
378 | + do { | ||
379 | + pageData = edgeService.findEdgesByTenantIdAndType(tenantId, type2, pageLink); | ||
380 | + loadedEdgesType2.addAll(pageData.getData()); | ||
381 | + if (pageData.hasNext()) { | ||
382 | + pageLink = pageData.getNextPageLink(); | ||
383 | + } | ||
384 | + } while (pageData.hasNext()); | ||
385 | + | ||
386 | + Collections.sort(edgesType2, idComparator); | ||
387 | + Collections.sort(loadedEdgesType2, idComparator); | ||
388 | + | ||
389 | + Assert.assertEquals(edgesType2, loadedEdgesType2); | ||
390 | + | ||
391 | + for (Edge edge : loadedEdgesType1) { | ||
392 | + edgeService.deleteEdge(tenantId, edge.getId()); | ||
393 | + } | ||
394 | + | ||
395 | + pageLink = new TextPageLink(4); | ||
396 | + pageData = edgeService.findEdgesByTenantIdAndType(tenantId, type1, pageLink); | ||
397 | + Assert.assertFalse(pageData.hasNext()); | ||
398 | + Assert.assertEquals(0, pageData.getData().size()); | ||
399 | + | ||
400 | + for (Edge edge : loadedEdgesType2) { | ||
401 | + edgeService.deleteEdge(tenantId, edge.getId()); | ||
402 | + } | ||
403 | + | ||
404 | + pageLink = new TextPageLink(4); | ||
405 | + pageData = edgeService.findEdgesByTenantIdAndType(tenantId, type2, pageLink); | ||
406 | + Assert.assertFalse(pageData.hasNext()); | ||
407 | + Assert.assertEquals(0, pageData.getData().size()); | ||
408 | + } | ||
409 | + | ||
410 | + @Test | ||
411 | + public void testFindEdgesByTenantIdAndCustomerId() { | ||
412 | + Tenant tenant = new Tenant(); | ||
413 | + tenant.setTitle("Test tenant"); | ||
414 | + tenant = tenantService.saveTenant(tenant); | ||
415 | + | ||
416 | + TenantId tenantId = tenant.getId(); | ||
417 | + | ||
418 | + Customer customer = new Customer(); | ||
419 | + customer.setTitle("Test customer"); | ||
420 | + customer.setTenantId(tenantId); | ||
421 | + customer = customerService.saveCustomer(customer); | ||
422 | + CustomerId customerId = customer.getId(); | ||
423 | + | ||
424 | + List<Edge> edges = new ArrayList<>(); | ||
425 | + for (int i = 0; i < 278; i++) { | ||
426 | + Edge edge = new Edge(); | ||
427 | + edge.setTenantId(tenantId); | ||
428 | + edge.setName("Edge" + i); | ||
429 | + edge.setType("default"); | ||
430 | + edge = edgeService.saveEdge(edge); | ||
431 | + edges.add(edgeService.assignEdgeToCustomer(tenantId, edge.getId(), customerId)); | ||
432 | + } | ||
433 | + | ||
434 | + List<Edge> loadedEdges = new ArrayList<>(); | ||
435 | + TextPageLink pageLink = new TextPageLink(23); | ||
436 | + TextPageData<Edge> pageData = null; | ||
437 | + do { | ||
438 | + pageData = edgeService.findEdgesByTenantIdAndCustomerId(tenantId, customerId, pageLink); | ||
439 | + loadedEdges.addAll(pageData.getData()); | ||
440 | + if (pageData.hasNext()) { | ||
441 | + pageLink = pageData.getNextPageLink(); | ||
442 | + } | ||
443 | + } while (pageData.hasNext()); | ||
444 | + | ||
445 | + Collections.sort(edges, idComparator); | ||
446 | + Collections.sort(loadedEdges, idComparator); | ||
447 | + | ||
448 | + Assert.assertEquals(edges, loadedEdges); | ||
449 | + | ||
450 | + edgeService.unassignCustomerEdges(tenantId, customerId); | ||
451 | + | ||
452 | + pageLink = new TextPageLink(33); | ||
453 | + pageData = edgeService.findEdgesByTenantIdAndCustomerId(tenantId, customerId, pageLink); | ||
454 | + Assert.assertFalse(pageData.hasNext()); | ||
455 | + Assert.assertTrue(pageData.getData().isEmpty()); | ||
456 | + | ||
457 | + tenantService.deleteTenant(tenantId); | ||
458 | + } | ||
459 | + | ||
460 | + @Test | ||
461 | + public void testFindEdgesByTenantIdCustomerIdAndName() { | ||
462 | + | ||
463 | + Customer customer = new Customer(); | ||
464 | + customer.setTitle("Test customer"); | ||
465 | + customer.setTenantId(tenantId); | ||
466 | + customer = customerService.saveCustomer(customer); | ||
467 | + CustomerId customerId = customer.getId(); | ||
468 | + | ||
469 | + String title1 = "Edge title 1"; | ||
470 | + List<Edge> edgesTitle1 = new ArrayList<>(); | ||
471 | + for (int i = 0; i < 175; i++) { | ||
472 | + Edge edge = new Edge(); | ||
473 | + edge.setTenantId(tenantId); | ||
474 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
475 | + String name = title1 + suffix; | ||
476 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
477 | + edge.setName(name); | ||
478 | + edge.setType("default"); | ||
479 | + edge = edgeService.saveEdge(edge); | ||
480 | + edgesTitle1.add(edgeService.assignEdgeToCustomer(tenantId, edge.getId(), customerId)); | ||
481 | + } | ||
482 | + String title2 = "Edge title 2"; | ||
483 | + List<Edge> edgesTitle2 = new ArrayList<>(); | ||
484 | + for (int i = 0; i < 143; i++) { | ||
485 | + Edge edge = new Edge(); | ||
486 | + edge.setTenantId(tenantId); | ||
487 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
488 | + String name = title2 + suffix; | ||
489 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
490 | + edge.setName(name); | ||
491 | + edge.setType("default"); | ||
492 | + edge = edgeService.saveEdge(edge); | ||
493 | + edgesTitle2.add(edgeService.assignEdgeToCustomer(tenantId, edge.getId(), customerId)); | ||
494 | + } | ||
495 | + | ||
496 | + List<Edge> loadedEdgesTitle1 = new ArrayList<>(); | ||
497 | + TextPageLink pageLink = new TextPageLink(15, title1); | ||
498 | + TextPageData<Edge> pageData = null; | ||
499 | + do { | ||
500 | + pageData = edgeService.findEdgesByTenantIdAndCustomerId(tenantId, customerId, pageLink); | ||
501 | + loadedEdgesTitle1.addAll(pageData.getData()); | ||
502 | + if (pageData.hasNext()) { | ||
503 | + pageLink = pageData.getNextPageLink(); | ||
504 | + } | ||
505 | + } while (pageData.hasNext()); | ||
506 | + | ||
507 | + Collections.sort(edgesTitle1, idComparator); | ||
508 | + Collections.sort(loadedEdgesTitle1, idComparator); | ||
509 | + | ||
510 | + Assert.assertEquals(edgesTitle1, loadedEdgesTitle1); | ||
511 | + | ||
512 | + List<Edge> loadedEdgesTitle2 = new ArrayList<>(); | ||
513 | + pageLink = new TextPageLink(4, title2); | ||
514 | + do { | ||
515 | + pageData = edgeService.findEdgesByTenantIdAndCustomerId(tenantId, customerId, pageLink); | ||
516 | + loadedEdgesTitle2.addAll(pageData.getData()); | ||
517 | + if (pageData.hasNext()) { | ||
518 | + pageLink = pageData.getNextPageLink(); | ||
519 | + } | ||
520 | + } while (pageData.hasNext()); | ||
521 | + | ||
522 | + Collections.sort(edgesTitle2, idComparator); | ||
523 | + Collections.sort(loadedEdgesTitle2, idComparator); | ||
524 | + | ||
525 | + Assert.assertEquals(edgesTitle2, loadedEdgesTitle2); | ||
526 | + | ||
527 | + for (Edge edge : loadedEdgesTitle1) { | ||
528 | + edgeService.deleteEdge(tenantId, edge.getId()); | ||
529 | + } | ||
530 | + | ||
531 | + pageLink = new TextPageLink(4, title1); | ||
532 | + pageData = edgeService.findEdgesByTenantIdAndCustomerId(tenantId, customerId, pageLink); | ||
533 | + Assert.assertFalse(pageData.hasNext()); | ||
534 | + Assert.assertEquals(0, pageData.getData().size()); | ||
535 | + | ||
536 | + for (Edge edge : loadedEdgesTitle2) { | ||
537 | + edgeService.deleteEdge(tenantId, edge.getId()); | ||
538 | + } | ||
539 | + | ||
540 | + pageLink = new TextPageLink(4, title2); | ||
541 | + pageData = edgeService.findEdgesByTenantIdAndCustomerId(tenantId, customerId, pageLink); | ||
542 | + Assert.assertFalse(pageData.hasNext()); | ||
543 | + Assert.assertEquals(0, pageData.getData().size()); | ||
544 | + customerService.deleteCustomer(tenantId, customerId); | ||
545 | + } | ||
546 | + | ||
547 | + @Test | ||
548 | + public void testFindEdgesByTenantIdCustomerIdAndType() { | ||
549 | + | ||
550 | + Customer customer = new Customer(); | ||
551 | + customer.setTitle("Test customer"); | ||
552 | + customer.setTenantId(tenantId); | ||
553 | + customer = customerService.saveCustomer(customer); | ||
554 | + CustomerId customerId = customer.getId(); | ||
555 | + | ||
556 | + String title1 = "Edge title 1"; | ||
557 | + String type1 = "typeC"; | ||
558 | + List<Edge> edgesType1 = new ArrayList<>(); | ||
559 | + for (int i = 0; i < 175; i++) { | ||
560 | + Edge edge = new Edge(); | ||
561 | + edge.setTenantId(tenantId); | ||
562 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
563 | + String name = title1 + suffix; | ||
564 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
565 | + edge.setName(name); | ||
566 | + edge.setType(type1); | ||
567 | + edge = edgeService.saveEdge(edge); | ||
568 | + edgesType1.add(edgeService.assignEdgeToCustomer(tenantId, edge.getId(), customerId)); | ||
569 | + } | ||
570 | + String title2 = "Edge title 2"; | ||
571 | + String type2 = "typeD"; | ||
572 | + List<Edge> edgesType2 = new ArrayList<>(); | ||
573 | + for (int i = 0; i < 143; i++) { | ||
574 | + Edge edge = new Edge(); | ||
575 | + edge.setTenantId(tenantId); | ||
576 | + String suffix = RandomStringUtils.randomAlphanumeric(15); | ||
577 | + String name = title2 + suffix; | ||
578 | + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); | ||
579 | + edge.setName(name); | ||
580 | + edge.setType(type2); | ||
581 | + edge = edgeService.saveEdge(edge); | ||
582 | + edgesType2.add(edgeService.assignEdgeToCustomer(tenantId, edge.getId(), customerId)); | ||
583 | + } | ||
584 | + | ||
585 | + List<Edge> loadedEdgesType1 = new ArrayList<>(); | ||
586 | + TextPageLink pageLink = new TextPageLink(15); | ||
587 | + TextPageData<Edge> pageData = null; | ||
588 | + do { | ||
589 | + pageData = edgeService.findEdgesByTenantIdAndCustomerIdAndType(tenantId, customerId, type1, pageLink); | ||
590 | + loadedEdgesType1.addAll(pageData.getData()); | ||
591 | + if (pageData.hasNext()) { | ||
592 | + pageLink = pageData.getNextPageLink(); | ||
593 | + } | ||
594 | + } while (pageData.hasNext()); | ||
595 | + | ||
596 | + Collections.sort(edgesType1, idComparator); | ||
597 | + Collections.sort(loadedEdgesType1, idComparator); | ||
598 | + | ||
599 | + Assert.assertEquals(edgesType1, loadedEdgesType1); | ||
600 | + | ||
601 | + List<Edge> loadedEdgesType2 = new ArrayList<>(); | ||
602 | + pageLink = new TextPageLink(4); | ||
603 | + do { | ||
604 | + pageData = edgeService.findEdgesByTenantIdAndCustomerIdAndType(tenantId, customerId, type2, pageLink); | ||
605 | + loadedEdgesType2.addAll(pageData.getData()); | ||
606 | + if (pageData.hasNext()) { | ||
607 | + pageLink = pageData.getNextPageLink(); | ||
608 | + } | ||
609 | + } while (pageData.hasNext()); | ||
610 | + | ||
611 | + Collections.sort(edgesType2, idComparator); | ||
612 | + Collections.sort(loadedEdgesType2, idComparator); | ||
613 | + | ||
614 | + Assert.assertEquals(edgesType2, loadedEdgesType2); | ||
615 | + | ||
616 | + for (Edge edge : loadedEdgesType1) { | ||
617 | + edgeService.deleteEdge(tenantId, edge.getId()); | ||
618 | + } | ||
619 | + | ||
620 | + pageLink = new TextPageLink(4); | ||
621 | + pageData = edgeService.findEdgesByTenantIdAndCustomerIdAndType(tenantId, customerId, type1, pageLink); | ||
622 | + Assert.assertFalse(pageData.hasNext()); | ||
623 | + Assert.assertEquals(0, pageData.getData().size()); | ||
624 | + | ||
625 | + for (Edge edge : loadedEdgesType2) { | ||
626 | + edgeService.deleteEdge(tenantId, edge.getId()); | ||
627 | + } | ||
628 | + | ||
629 | + pageLink = new TextPageLink(4); | ||
630 | + pageData = edgeService.findEdgesByTenantIdAndCustomerIdAndType(tenantId, customerId, type2, pageLink); | ||
631 | + Assert.assertFalse(pageData.hasNext()); | ||
632 | + Assert.assertEquals(0, pageData.getData().size()); | ||
633 | + customerService.deleteCustomer(tenantId, customerId); | ||
634 | + } | ||
635 | + | ||
636 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2019 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.service.nosql; | ||
17 | + | ||
18 | +import org.thingsboard.server.dao.service.BaseEdgeServiceTest; | ||
19 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | ||
20 | + | ||
21 | +@DaoNoSqlTest | ||
22 | +public class EdgeServiceNoSqlTest extends BaseEdgeServiceTest { | ||
23 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2019 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.service.sql; | ||
17 | + | ||
18 | +import org.thingsboard.server.dao.service.BaseEdgeServiceTest; | ||
19 | +import org.thingsboard.server.dao.service.DaoSqlTest; | ||
20 | + | ||
21 | +@DaoSqlTest | ||
22 | +public class EdgeServiceSqlTest extends BaseEdgeServiceTest { | ||
23 | +} |
@@ -30,6 +30,9 @@ caffeine.specs.entityViews.maxSize=100000 | @@ -30,6 +30,9 @@ caffeine.specs.entityViews.maxSize=100000 | ||
30 | caffeine.specs.claimDevices.timeToLiveInMinutes=1440 | 30 | caffeine.specs.claimDevices.timeToLiveInMinutes=1440 |
31 | caffeine.specs.claimDevices.maxSize=100000 | 31 | caffeine.specs.claimDevices.maxSize=100000 |
32 | 32 | ||
33 | +caffeine.specs.edges.timeToLiveInMinutes=1440 | ||
34 | +caffeine.specs.edges.maxSize=100000 | ||
35 | + | ||
33 | redis.connection.host=localhost | 36 | redis.connection.host=localhost |
34 | redis.connection.port=6379 | 37 | redis.connection.port=6379 |
35 | redis.connection.db=0 | 38 | redis.connection.db=0 |