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 | 15 | */ |
16 | 16 | package org.thingsboard.server.controller; |
17 | 17 | |
18 | +import com.google.common.util.concurrent.ListenableFuture; | |
18 | 19 | import org.springframework.http.HttpStatus; |
19 | 20 | import org.springframework.security.access.prepost.PreAuthorize; |
20 | 21 | import org.springframework.web.bind.annotation.PathVariable; |
... | ... | @@ -25,14 +26,22 @@ import org.springframework.web.bind.annotation.RequestParam; |
25 | 26 | import org.springframework.web.bind.annotation.ResponseBody; |
26 | 27 | import org.springframework.web.bind.annotation.ResponseStatus; |
27 | 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 | 32 | import org.thingsboard.server.common.data.EntityType; |
29 | 33 | import org.thingsboard.server.common.data.audit.ActionType; |
34 | +import org.thingsboard.server.common.data.device.DeviceSearchQuery; | |
30 | 35 | import org.thingsboard.server.common.data.edge.Edge; |
36 | +import org.thingsboard.server.common.data.edge.EdgeSearchQuery; | |
31 | 37 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
38 | +import org.thingsboard.server.common.data.id.CustomerId; | |
32 | 39 | import org.thingsboard.server.common.data.id.EdgeId; |
33 | 40 | import org.thingsboard.server.common.data.id.TenantId; |
34 | 41 | import org.thingsboard.server.common.data.page.TextPageData; |
35 | 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 | 45 | import org.thingsboard.server.service.security.model.SecurityUser; |
37 | 46 | import org.thingsboard.server.service.security.permission.Operation; |
38 | 47 | import org.thingsboard.server.service.security.permission.Resource; |
... | ... | @@ -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 | 96 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") |
107 | 97 | @RequestMapping(value = "/edge/{edgeId}", method = RequestMethod.DELETE) |
108 | 98 | @ResponseStatus(value = HttpStatus.OK) |
... | ... | @@ -129,35 +119,209 @@ public class EdgeController extends BaseController { |
129 | 119 | } |
130 | 120 | |
131 | 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 | 264 | @RequestMapping(value = "/edges", params = {"edgeIds"}, method = RequestMethod.GET) |
133 | 265 | @ResponseBody |
134 | 266 | public List<Edge> getEdgesByIds( |
135 | 267 | @RequestParam("edgeIds") String[] strEdgeIds) throws ThingsboardException { |
136 | 268 | checkArrayParameter("edgeIds", strEdgeIds); |
137 | 269 | try { |
138 | - accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, Operation.READ); | |
139 | 270 | SecurityUser user = getCurrentUser(); |
140 | 271 | TenantId tenantId = user.getTenantId(); |
272 | + CustomerId customerId = user.getCustomerId(); | |
141 | 273 | List<EdgeId> edgeIds = new ArrayList<>(); |
142 | 274 | for (String strEdgeId : strEdgeIds) { |
143 | 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 | 284 | } catch (Exception e) { |
148 | 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 | 29 | import org.thingsboard.server.common.data.EntityView; |
30 | 30 | import org.thingsboard.server.common.data.Tenant; |
31 | 31 | import org.thingsboard.server.common.data.asset.Asset; |
32 | +import org.thingsboard.server.common.data.edge.Edge; | |
32 | 33 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
33 | 34 | import org.thingsboard.server.common.data.id.AssetId; |
34 | 35 | import org.thingsboard.server.common.data.id.CustomerId; |
35 | 36 | import org.thingsboard.server.common.data.id.DeviceId; |
37 | +import org.thingsboard.server.common.data.id.EdgeId; | |
36 | 38 | import org.thingsboard.server.common.data.id.EntityId; |
37 | 39 | import org.thingsboard.server.common.data.id.EntityIdFactory; |
38 | 40 | import org.thingsboard.server.common.data.id.EntityViewId; |
... | ... | @@ -46,6 +48,7 @@ import org.thingsboard.server.dao.alarm.AlarmService; |
46 | 48 | import org.thingsboard.server.dao.asset.AssetService; |
47 | 49 | import org.thingsboard.server.dao.customer.CustomerService; |
48 | 50 | import org.thingsboard.server.dao.device.DeviceService; |
51 | +import org.thingsboard.server.dao.edge.EdgeService; | |
49 | 52 | import org.thingsboard.server.dao.entityview.EntityViewService; |
50 | 53 | import org.thingsboard.server.dao.rule.RuleChainService; |
51 | 54 | import org.thingsboard.server.dao.tenant.TenantService; |
... | ... | @@ -72,6 +75,7 @@ public class AccessValidator { |
72 | 75 | public static final String CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "Customer user is not allowed to perform this operation!"; |
73 | 76 | public static final String SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "System administrator is not allowed to perform this operation!"; |
74 | 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 | 79 | public static final String ENTITY_VIEW_WITH_REQUESTED_ID_NOT_FOUND = "Entity-view with requested id wasn't found!"; |
76 | 80 | |
77 | 81 | @Autowired |
... | ... | @@ -99,6 +103,9 @@ public class AccessValidator { |
99 | 103 | protected EntityViewService entityViewService; |
100 | 104 | |
101 | 105 | @Autowired |
106 | + protected EdgeService edgeService; | |
107 | + | |
108 | + @Autowired | |
102 | 109 | protected AccessControlService accessControlService; |
103 | 110 | |
104 | 111 | private ExecutorService executor; |
... | ... | @@ -174,6 +181,9 @@ public class AccessValidator { |
174 | 181 | case ENTITY_VIEW: |
175 | 182 | validateEntityView(currentUser, operation, entityId, callback); |
176 | 183 | return; |
184 | + case EDGE: | |
185 | + validateEdge(currentUser, operation, entityId, callback); | |
186 | + return; | |
177 | 187 | default: |
178 | 188 | //TODO: add support of other entities |
179 | 189 | throw new IllegalStateException("Not Implemented!"); |
... | ... | @@ -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 | 360 | private <T, V> FutureCallback<T> getCallback(FutureCallback<ValidationResult> callback, Function<T, ValidationResult<V>> transformer) { |
331 | 361 | return new FutureCallback<T>() { |
332 | 362 | @Override | ... | ... |
... | ... | @@ -40,6 +40,7 @@ public class CustomerUserPermissions extends AbstractPermissions { |
40 | 40 | put(Resource.USER, userPermissionChecker); |
41 | 41 | put(Resource.WIDGETS_BUNDLE, widgetsPermissionChecker); |
42 | 42 | put(Resource.WIDGET_TYPE, widgetsPermissionChecker); |
43 | + put(Resource.EDGE, customerEntityPermissionChecker); | |
43 | 44 | } |
44 | 45 | |
45 | 46 | private static final PermissionChecker customerEntityPermissionChecker = | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 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 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
... | ... | @@ -15,39 +15,46 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.controller; |
17 | 17 | |
18 | +import com.datastax.driver.core.utils.UUIDs; | |
18 | 19 | import com.fasterxml.jackson.core.type.TypeReference; |
19 | 20 | import org.apache.commons.lang3.RandomStringUtils; |
20 | 21 | import org.junit.After; |
21 | 22 | import org.junit.Assert; |
22 | 23 | import org.junit.Before; |
23 | 24 | import org.junit.Test; |
25 | +import org.thingsboard.server.common.data.Customer; | |
26 | +import org.thingsboard.server.common.data.EntitySubtype; | |
24 | 27 | import org.thingsboard.server.common.data.Tenant; |
25 | 28 | import org.thingsboard.server.common.data.User; |
26 | 29 | import org.thingsboard.server.common.data.edge.Edge; |
30 | +import org.thingsboard.server.common.data.id.CustomerId; | |
27 | 31 | import org.thingsboard.server.common.data.page.TextPageData; |
28 | 32 | import org.thingsboard.server.common.data.page.TextPageLink; |
29 | 33 | import org.thingsboard.server.common.data.security.Authority; |
34 | +import org.thingsboard.server.dao.model.ModelConstants; | |
30 | 35 | |
31 | 36 | import java.util.ArrayList; |
32 | 37 | import java.util.Collections; |
33 | 38 | import java.util.List; |
34 | 39 | |
35 | 40 | import static org.hamcrest.Matchers.containsString; |
36 | -import static org.junit.Assert.assertEquals; | |
37 | 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 | 44 | public abstract class BaseEdgeControllerTest extends AbstractControllerTest { |
40 | 45 | |
41 | - private IdComparator<Edge> idComparator; | |
46 | + private IdComparator<Edge> idComparator = new IdComparator<>(); | |
47 | + | |
42 | 48 | private Tenant savedTenant; |
43 | 49 | private User tenantAdmin; |
44 | 50 | |
45 | 51 | @Before |
46 | 52 | public void beforeTest() throws Exception { |
47 | 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 | 58 | Assert.assertNotNull(savedTenant); |
52 | 59 | |
53 | 60 | tenantAdmin = new User(); |
... | ... | @@ -56,44 +63,88 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest { |
56 | 63 | tenantAdmin.setEmail("tenant2@thingsboard.org"); |
57 | 64 | tenantAdmin.setFirstName("Joe"); |
58 | 65 | tenantAdmin.setLastName("Downs"); |
59 | - tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); | |
60 | 66 | |
67 | + tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); | |
61 | 68 | } |
62 | 69 | |
63 | 70 | @After |
64 | 71 | public void afterTest() throws Exception { |
65 | 72 | loginSysAdmin(); |
73 | + | |
66 | 74 | doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) |
67 | 75 | .andExpect(status().isOk()); |
68 | 76 | } |
69 | 77 | |
70 | 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 | 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 | 85 | Assert.assertNotNull(savedEdge); |
83 | 86 | Assert.assertNotNull(savedEdge.getId()); |
84 | 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 | 94 | doPost("/api/edge", savedEdge, Edge.class); |
95 | + | |
89 | 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 | 143 | @Test |
95 | 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 | 148 | Edge savedEdge = doPost("/api/edge", edge, Edge.class); |
98 | 149 | |
99 | 150 | doDelete("/api/edge/" + savedEdge.getId().getId().toString()) |
... | ... | @@ -104,103 +155,523 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest { |
104 | 155 | } |
105 | 156 | |
106 | 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 | 167 | public void testSaveEdgeWithEmptyName() throws Exception { |
108 | 168 | Edge edge = new Edge(); |
169 | + edge.setType("default"); | |
109 | 170 | doPost("/api/edge", edge) |
110 | 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 | 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 | 254 | List<Edge> edges = new ArrayList<>(); |
118 | 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 | 274 | Collections.sort(edges, idComparator); |
124 | 275 | Collections.sort(loadedEdges, idComparator); |
125 | 276 | |
126 | - assertEquals(edges, loadedEdges); | |
277 | + Assert.assertEquals(edges, loadedEdges); | |
127 | 278 | } |
128 | 279 | |
129 | 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 | 347 | new TypeReference<TextPageData<Edge>>() { |
150 | - }, new TextPageLink(4, name1)); | |
348 | + }, pageLink); | |
151 | 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 | 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 | 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 | 643 | if (pageData.hasNext()) { |
200 | 644 | pageLink = pageData.getNextPageLink(); |
201 | 645 | } |
202 | 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 | 5 | * you may not use this file except in compliance with the License. |
6 | 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 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
... | ... | @@ -16,7 +16,10 @@ |
16 | 16 | package org.thingsboard.server.dao.edge; |
17 | 17 | |
18 | 18 | import com.google.common.util.concurrent.ListenableFuture; |
19 | +import org.thingsboard.server.common.data.EntitySubtype; | |
19 | 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 | 23 | import org.thingsboard.server.common.data.id.EdgeId; |
21 | 24 | import org.thingsboard.server.common.data.id.TenantId; |
22 | 25 | import org.thingsboard.server.common.data.page.TextPageData; |
... | ... | @@ -26,20 +29,49 @@ import java.util.List; |
26 | 29 | |
27 | 30 | public interface EdgeService { |
28 | 31 | |
29 | - Edge saveEdge(Edge edge); | |
30 | - | |
31 | 32 | Edge findEdgeById(TenantId tenantId, EdgeId edgeId); |
32 | 33 | |
33 | 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 | 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 | 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 | + | |
\ No newline at end of file | ... | ... |
... | ... | @@ -22,6 +22,7 @@ public class CacheConstants { |
22 | 22 | public static final String SESSIONS_CACHE = "sessions"; |
23 | 23 | public static final String ASSET_CACHE = "assets"; |
24 | 24 | public static final String ENTITY_VIEW_CACHE = "entityViews"; |
25 | + public static final String EDGE_CACHE = "edges"; | |
25 | 26 | public static final String CLAIM_DEVICES_CACHE = "claimDevices"; |
26 | 27 | public static final String SECURITY_SETTINGS_CACHE = "securitySettings"; |
27 | 28 | } | ... | ... |
... | ... | @@ -39,6 +39,7 @@ public class Edge extends SearchTextBasedWithAdditionalInfo<EdgeId> implements H |
39 | 39 | private TenantId tenantId; |
40 | 40 | private CustomerId customerId; |
41 | 41 | private String name; |
42 | + private String type; | |
42 | 43 | private transient JsonNode configuration; |
43 | 44 | private transient JsonNode additionalInfo; |
44 | 45 | |
... | ... | @@ -54,6 +55,7 @@ public class Edge extends SearchTextBasedWithAdditionalInfo<EdgeId> implements H |
54 | 55 | super(edge); |
55 | 56 | this.tenantId = edge.getTenantId(); |
56 | 57 | this.customerId = edge.getCustomerId(); |
58 | + this.type = edge.getType(); | |
57 | 59 | this.name = edge.getName(); |
58 | 60 | this.configuration = edge.getConfiguration(); |
59 | 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 | 31 | import org.thingsboard.server.dao.asset.AssetService; |
32 | 32 | import org.thingsboard.server.dao.dashboard.DashboardService; |
33 | 33 | import org.thingsboard.server.dao.device.DeviceService; |
34 | +import org.thingsboard.server.dao.edge.EdgeService; | |
34 | 35 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
35 | 36 | import org.thingsboard.server.dao.entityview.EntityViewService; |
36 | 37 | import org.thingsboard.server.dao.exception.DataValidationException; |
... | ... | @@ -76,6 +77,9 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom |
76 | 77 | @Autowired |
77 | 78 | private DashboardService dashboardService; |
78 | 79 | |
80 | + @Autowired | |
81 | + private EdgeService edgeService; | |
82 | + | |
79 | 83 | @Override |
80 | 84 | public Customer findCustomerById(TenantId tenantId, CustomerId customerId) { |
81 | 85 | log.trace("Executing findCustomerById [{}]", customerId); |
... | ... | @@ -118,6 +122,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom |
118 | 122 | entityViewService.unassignCustomerEntityViews(customer.getTenantId(), customerId); |
119 | 123 | assetService.unassignCustomerAssets(customer.getTenantId(), customerId); |
120 | 124 | deviceService.unassignCustomerDevices(customer.getTenantId(), customerId); |
125 | + edgeService.unassignCustomerEdges(customer.getTenantId(), customerId); | |
121 | 126 | userService.deleteCustomerUsers(customer.getTenantId(), customerId); |
122 | 127 | deleteEntityRelations(tenantId, customerId); |
123 | 128 | customerDao.removeById(tenantId, customerId.getId()); | ... | ... |
... | ... | @@ -15,29 +15,53 @@ |
15 | 15 | */ |
16 | 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 | 20 | import com.google.common.util.concurrent.ListenableFuture; |
19 | 21 | import lombok.extern.slf4j.Slf4j; |
20 | 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 | 27 | import org.springframework.stereotype.Service; |
22 | 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 | 32 | import org.thingsboard.server.common.data.Tenant; |
24 | 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 | 36 | import org.thingsboard.server.common.data.id.EdgeId; |
37 | +import org.thingsboard.server.common.data.id.EntityId; | |
26 | 38 | import org.thingsboard.server.common.data.id.TenantId; |
27 | 39 | import org.thingsboard.server.common.data.page.TextPageData; |
28 | 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 | 44 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
30 | 45 | import org.thingsboard.server.dao.exception.DataValidationException; |
31 | 46 | import org.thingsboard.server.dao.service.DataValidator; |
32 | 47 | import org.thingsboard.server.dao.service.PaginatedRemover; |
33 | 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 | 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 | 59 | import static org.thingsboard.server.dao.DaoUtil.toUUIDs; |
60 | +import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; | |
38 | 61 | import static org.thingsboard.server.dao.service.Validator.validateId; |
39 | 62 | import static org.thingsboard.server.dao.service.Validator.validateIds; |
40 | 63 | import static org.thingsboard.server.dao.service.Validator.validatePageLink; |
64 | +import static org.thingsboard.server.dao.service.Validator.validateString; | |
41 | 65 | |
42 | 66 | @Service |
43 | 67 | @Slf4j |
... | ... | @@ -45,6 +69,7 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic |
45 | 69 | |
46 | 70 | public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
47 | 71 | public static final String INCORRECT_PAGE_LINK = "Incorrect page link "; |
72 | + public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; | |
48 | 73 | public static final String INCORRECT_EDGE_ID = "Incorrect edgeId "; |
49 | 74 | |
50 | 75 | @Autowired |
... | ... | @@ -53,12 +78,11 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic |
53 | 78 | @Autowired |
54 | 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 | 87 | @Override |
64 | 88 | public Edge findEdgeById(TenantId tenantId, EdgeId edgeId) { |
... | ... | @@ -69,73 +93,222 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic |
69 | 93 | |
70 | 94 | @Override |
71 | 95 | public ListenableFuture<Edge> findEdgeByIdAsync(TenantId tenantId, EdgeId edgeId) { |
72 | - log.trace("Executing findEdgeByIdAsync [{}]", edgeId); | |
96 | + log.trace("Executing findEdgeById [{}]", edgeId); | |
73 | 97 | validateId(edgeId, INCORRECT_EDGE_ID + edgeId); |
74 | 98 | return edgeDao.findByIdAsync(tenantId, edgeId.getId()); |
75 | 99 | } |
76 | 100 | |
101 | + @Cacheable(cacheNames = EDGE_CACHE, key = "{#tenantId, #name}") | |
77 | 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 | 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 | 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 | 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 | 132 | @Override |
101 | 133 | public void deleteEdge(TenantId tenantId, EdgeId edgeId) { |
102 | 134 | log.trace("Executing deleteEdge [{}]", edgeId); |
103 | 135 | validateId(edgeId, INCORRECT_EDGE_ID + edgeId); |
136 | + | |
137 | + Edge edge = edgeDao.findById(tenantId, edgeId.getId()); | |
138 | + | |
104 | 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 | 147 | edgeDao.removeById(tenantId, edgeId.getId()); |
106 | 148 | } |
107 | 149 | |
108 | 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 | 179 | public void deleteEdgesByTenantId(TenantId tenantId) { |
110 | 180 | log.trace("Executing deleteEdgesByTenantId, tenantId [{}]", tenantId); |
111 | 181 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); |
112 | 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 | 262 | private DataValidator<Edge> edgeValidator = |
116 | 263 | new DataValidator<Edge>() { |
117 | 264 | |
118 | 265 | @Override |
119 | 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 | 274 | @Override |
123 | 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 | 285 | @Override |
127 | 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 | 290 | if (StringUtils.isEmpty(edge.getName())) { |
129 | 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 | 294 | throw new DataValidationException("Edge should be assigned to tenant!"); |
133 | 295 | } else { |
134 | - Tenant tenant = tenantDao.findById(tenantId, edge.getTenantId().getId()); | |
296 | + Tenant tenant = tenantDao.findById(edge.getTenantId(), edge.getTenantId().getId()); | |
135 | 297 | if (tenant == null) { |
136 | 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 | 317 | |
145 | 318 | @Override |
146 | 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 | 323 | @Override |
151 | 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 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.edge; |
17 | 17 | |
18 | -import com.datastax.driver.core.querybuilder.Select; | |
19 | 18 | import com.google.common.util.concurrent.ListenableFuture; |
20 | 19 | import lombok.extern.slf4j.Slf4j; |
21 | 20 | import org.springframework.stereotype.Component; |
21 | +import org.thingsboard.server.common.data.EntitySubtype; | |
22 | 22 | import org.thingsboard.server.common.data.edge.Edge; |
23 | -import org.thingsboard.server.common.data.id.TenantId; | |
24 | 23 | import org.thingsboard.server.common.data.page.TextPageLink; |
25 | -import org.thingsboard.server.dao.DaoUtil; | |
26 | 24 | import org.thingsboard.server.dao.model.nosql.EdgeEntity; |
27 | 25 | import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao; |
28 | 26 | import org.thingsboard.server.dao.util.NoSqlDao; |
29 | 27 | |
30 | -import java.util.Collections; | |
31 | 28 | import java.util.List; |
29 | +import java.util.Optional; | |
32 | 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 | 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 | 34 | @Component |
43 | 35 | @Slf4j |
... | ... | @@ -54,24 +46,44 @@ public class CassandraEdgeDao extends CassandraAbstractSearchTextDao<EdgeEntity, |
54 | 46 | return EDGE_COLUMN_FAMILY_NAME; |
55 | 47 | } |
56 | 48 | |
49 | + | |
57 | 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 | 60 | @Override |
68 | 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 | 16 | package org.thingsboard.server.dao.edge; |
17 | 17 | |
18 | 18 | import com.google.common.util.concurrent.ListenableFuture; |
19 | +import org.thingsboard.server.common.data.EntitySubtype; | |
19 | 20 | import org.thingsboard.server.common.data.edge.Edge; |
21 | +import org.thingsboard.server.common.data.id.TenantId; | |
20 | 22 | import org.thingsboard.server.common.data.page.TextPageLink; |
21 | 23 | import org.thingsboard.server.dao.Dao; |
22 | 24 | |
23 | 25 | import java.util.List; |
26 | +import java.util.Optional; | |
24 | 27 | import java.util.UUID; |
25 | 28 | |
26 | 29 | /** |
... | ... | @@ -30,16 +33,34 @@ import java.util.UUID; |
30 | 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 | 44 | * Find edges by tenantId and page link. |
34 | 45 | * |
35 | 46 | * @param tenantId the tenantId |
36 | 47 | * @param pageLink the page link |
37 | 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 | 65 | * @param tenantId the tenantId |
45 | 66 | * @param edgeIds the edge Ids |
... | ... | @@ -47,5 +68,53 @@ public interface EdgeDao extends Dao<Edge> { |
47 | 68 | */ |
48 | 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 | 354 | public static final String EDGE_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; |
355 | 355 | public static final String EDGE_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY; |
356 | 356 | public static final String EDGE_NAME_PROPERTY = "name"; |
357 | + public static final String EDGE_TYPE_PROPERTY = "type"; | |
357 | 358 | public static final String EDGE_CONFIGURATION_PROPERTY = "configuration"; |
358 | 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 | 37 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CUSTOMER_ID_PROPERTY; |
38 | 38 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_NAME_PROPERTY; |
39 | 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 | 41 | import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY; |
41 | 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 | 57 | @Column(name = EDGE_CUSTOMER_ID_PROPERTY) |
57 | 58 | private UUID customerId; |
58 | 59 | |
60 | + @Column(name = EDGE_TYPE_PROPERTY) | |
61 | + private String type; | |
62 | + | |
59 | 63 | @Column(name = EDGE_NAME_PROPERTY) |
60 | 64 | private String name; |
61 | 65 | |
... | ... | @@ -79,6 +83,7 @@ public class EdgeEntity implements SearchTextEntity<Edge> { |
79 | 83 | if (edge.getTenantId() != null) { |
80 | 84 | this.tenantId = edge.getTenantId().getId(); |
81 | 85 | } |
86 | + this.type = edge.getType(); | |
82 | 87 | this.name = edge.getName(); |
83 | 88 | this.configuration = edge.getConfiguration(); |
84 | 89 | this.additionalInfo = edge.getAdditionalInfo(); |
... | ... | @@ -99,6 +104,7 @@ public class EdgeEntity implements SearchTextEntity<Edge> { |
99 | 104 | if (customerId != null) { |
100 | 105 | edge.setCustomerId(new CustomerId(customerId)); |
101 | 106 | } |
107 | + edge.setType(type); | |
102 | 108 | edge.setName(name); |
103 | 109 | edge.setConfiguration(configuration); |
104 | 110 | edge.setAdditionalInfo(additionalInfo); | ... | ... |
... | ... | @@ -40,6 +40,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.EDGE_COLUMN_FAMILY |
40 | 40 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CUSTOMER_ID_PROPERTY; |
41 | 41 | import static org.thingsboard.server.dao.model.ModelConstants.EDGE_NAME_PROPERTY; |
42 | 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 | 44 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; |
44 | 45 | |
45 | 46 | @Data |
... | ... | @@ -55,6 +56,9 @@ public class EdgeEntity extends BaseSqlEntity<Edge> implements SearchTextEntity< |
55 | 56 | @Column(name = EDGE_CUSTOMER_ID_PROPERTY) |
56 | 57 | private String customerId; |
57 | 58 | |
59 | + @Column(name = EDGE_TYPE_PROPERTY) | |
60 | + private String type; | |
61 | + | |
58 | 62 | @Column(name = EDGE_NAME_PROPERTY) |
59 | 63 | private String name; |
60 | 64 | |
... | ... | @@ -80,6 +84,10 @@ public class EdgeEntity extends BaseSqlEntity<Edge> implements SearchTextEntity< |
80 | 84 | if (edge.getTenantId() != null) { |
81 | 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 | 91 | this.name = edge.getName(); |
84 | 92 | this.configuration = edge.getConfiguration(); |
85 | 93 | this.additionalInfo = edge.getAdditionalInfo(); |
... | ... | @@ -109,6 +117,7 @@ public class EdgeEntity extends BaseSqlEntity<Edge> implements SearchTextEntity< |
109 | 117 | if (customerId != null) { |
110 | 118 | edge.setCustomerId(new CustomerId(UUIDConverter.fromString(customerId))); |
111 | 119 | } |
120 | + edge.setType(type); | |
112 | 121 | edge.setName(name); |
113 | 122 | edge.setConfiguration(configuration); |
114 | 123 | edge.setAdditionalInfo(additionalInfo); | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 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 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
... | ... | @@ -27,13 +27,52 @@ import java.util.List; |
27 | 27 | @SqlDao |
28 | 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 | 77 | List<EdgeEntity> findEdgesByTenantIdAndIdIn(String tenantId, List<String> edgeIds); |
39 | 78 | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 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 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
... | ... | @@ -20,8 +20,11 @@ import org.springframework.beans.factory.annotation.Autowired; |
20 | 20 | import org.springframework.data.domain.PageRequest; |
21 | 21 | import org.springframework.data.repository.CrudRepository; |
22 | 22 | import org.springframework.stereotype.Component; |
23 | +import org.thingsboard.server.common.data.EntitySubtype; | |
24 | +import org.thingsboard.server.common.data.EntityType; | |
23 | 25 | import org.thingsboard.server.common.data.UUIDConverter; |
24 | 26 | import org.thingsboard.server.common.data.edge.Edge; |
27 | +import org.thingsboard.server.common.data.id.TenantId; | |
25 | 28 | import org.thingsboard.server.common.data.page.TextPageLink; |
26 | 29 | import org.thingsboard.server.dao.DaoUtil; |
27 | 30 | import org.thingsboard.server.dao.edge.EdgeDao; |
... | ... | @@ -29,8 +32,11 @@ import org.thingsboard.server.dao.model.sql.EdgeEntity; |
29 | 32 | import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; |
30 | 33 | import org.thingsboard.server.dao.util.SqlDao; |
31 | 34 | |
35 | +import java.util.ArrayList; | |
36 | +import java.util.Collections; | |
32 | 37 | import java.util.List; |
33 | 38 | import java.util.Objects; |
39 | +import java.util.Optional; | |
34 | 40 | import java.util.UUID; |
35 | 41 | |
36 | 42 | import static org.thingsboard.server.common.data.UUIDConverter.fromTimeUUID; |
... | ... | @@ -45,9 +51,19 @@ public class JpaEdgeDao extends JpaAbstractSearchTextDao<EdgeEntity, Edge> imple |
45 | 51 | private EdgeRepository edgeRepository; |
46 | 52 | |
47 | 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 | 67 | fromTimeUUID(tenantId), |
52 | 68 | Objects.toString(pageLink.getTextSearch(), ""), |
53 | 69 | pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()), |
... | ... | @@ -60,13 +76,65 @@ public class JpaEdgeDao extends JpaAbstractSearchTextDao<EdgeEntity, Edge> imple |
60 | 76 | } |
61 | 77 | |
62 | 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 | 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 | 29 | import org.thingsboard.server.dao.customer.CustomerService; |
30 | 30 | import org.thingsboard.server.dao.dashboard.DashboardService; |
31 | 31 | import org.thingsboard.server.dao.device.DeviceService; |
32 | +import org.thingsboard.server.dao.edge.EdgeService; | |
32 | 33 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
33 | 34 | import org.thingsboard.server.dao.entityview.EntityViewService; |
34 | 35 | import org.thingsboard.server.dao.exception.DataValidationException; |
... | ... | @@ -77,6 +78,9 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe |
77 | 78 | @Autowired |
78 | 79 | private RuleChainService ruleChainService; |
79 | 80 | |
81 | + @Autowired | |
82 | + private EdgeService edgeService; | |
83 | + | |
80 | 84 | @Override |
81 | 85 | public Tenant findTenantById(TenantId tenantId) { |
82 | 86 | log.trace("Executing findTenantById [{}]", tenantId); |
... | ... | @@ -109,6 +113,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe |
109 | 113 | entityViewService.deleteEntityViewsByTenantId(tenantId); |
110 | 114 | assetService.deleteAssetsByTenantId(tenantId); |
111 | 115 | deviceService.deleteDevicesByTenantId(tenantId); |
116 | + edgeService.deleteEdgesByTenantId(tenantId); | |
112 | 117 | userService.deleteTenantAdmins(tenantId); |
113 | 118 | ruleChainService.deleteRuleChainsByTenantId(tenantId); |
114 | 119 | tenantDao.removeById(tenantId, tenantId.getId()); | ... | ... |
... | ... | @@ -45,6 +45,7 @@ import org.thingsboard.server.dao.customer.CustomerService; |
45 | 45 | import org.thingsboard.server.dao.dashboard.DashboardService; |
46 | 46 | import org.thingsboard.server.dao.device.DeviceCredentialsService; |
47 | 47 | import org.thingsboard.server.dao.device.DeviceService; |
48 | +import org.thingsboard.server.dao.edge.EdgeService; | |
48 | 49 | import org.thingsboard.server.dao.entityview.EntityViewService; |
49 | 50 | import org.thingsboard.server.dao.event.EventService; |
50 | 51 | import org.thingsboard.server.dao.relation.RelationService; |
... | ... | @@ -122,6 +123,9 @@ public abstract class AbstractServiceTest { |
122 | 123 | protected RuleChainService ruleChainService; |
123 | 124 | |
124 | 125 | @Autowired |
126 | + protected EdgeService edgeService; | |
127 | + | |
128 | + @Autowired | |
125 | 129 | private ComponentDescriptorService componentDescriptorService; |
126 | 130 | |
127 | 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 | 30 | caffeine.specs.claimDevices.timeToLiveInMinutes=1440 |
31 | 31 | caffeine.specs.claimDevices.maxSize=100000 |
32 | 32 | |
33 | +caffeine.specs.edges.timeToLiveInMinutes=1440 | |
34 | +caffeine.specs.edges.maxSize=100000 | |
35 | + | |
33 | 36 | redis.connection.host=localhost |
34 | 37 | redis.connection.port=6379 |
35 | 38 | redis.connection.db=0 | ... | ... |