Commit 2965e312610424f2fd033f859f774be59e3cafbd
1 parent
9fbd7e5b
Removed cassandra dependencies from services
Showing
24 changed files
with
48 additions
and
108 deletions
... | ... | @@ -15,16 +15,7 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.actors.plugin; |
17 | 17 | |
18 | -import java.io.IOException; | |
19 | -import java.util.*; | |
20 | -import java.util.concurrent.ExecutionException; | |
21 | -import java.util.concurrent.Executor; | |
22 | -import java.util.concurrent.Executors; | |
23 | -import java.util.stream.Collectors; | |
24 | - | |
25 | -import com.datastax.driver.core.ResultSet; | |
26 | -import com.datastax.driver.core.ResultSetFuture; | |
27 | -import com.datastax.driver.core.Row; | |
18 | +import akka.actor.ActorRef; | |
28 | 19 | import com.google.common.base.Function; |
29 | 20 | import com.google.common.util.concurrent.FutureCallback; |
30 | 21 | import com.google.common.util.concurrent.Futures; |
... | ... | @@ -32,18 +23,20 @@ import com.google.common.util.concurrent.ListenableFuture; |
32 | 23 | import lombok.extern.slf4j.Slf4j; |
33 | 24 | import org.thingsboard.server.common.data.DataConstants; |
34 | 25 | import org.thingsboard.server.common.data.Device; |
35 | -import org.thingsboard.server.common.data.id.*; | |
26 | +import org.thingsboard.server.common.data.id.CustomerId; | |
27 | +import org.thingsboard.server.common.data.id.DeviceId; | |
28 | +import org.thingsboard.server.common.data.id.PluginId; | |
29 | +import org.thingsboard.server.common.data.id.TenantId; | |
36 | 30 | import org.thingsboard.server.common.data.kv.AttributeKey; |
37 | 31 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
38 | 32 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
39 | 33 | import org.thingsboard.server.common.data.kv.TsKvQuery; |
40 | -import org.thingsboard.server.common.data.page.TextPageData; | |
41 | 34 | import org.thingsboard.server.common.data.page.TextPageLink; |
42 | 35 | import org.thingsboard.server.common.msg.cluster.ServerAddress; |
43 | 36 | import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg; |
44 | 37 | import org.thingsboard.server.extensions.api.plugins.PluginApiCallSecurityContext; |
45 | -import org.thingsboard.server.extensions.api.plugins.PluginContext; | |
46 | 38 | import org.thingsboard.server.extensions.api.plugins.PluginCallback; |
39 | +import org.thingsboard.server.extensions.api.plugins.PluginContext; | |
47 | 40 | import org.thingsboard.server.extensions.api.plugins.msg.PluginToRuleMsg; |
48 | 41 | import org.thingsboard.server.extensions.api.plugins.msg.TimeoutMsg; |
49 | 42 | import org.thingsboard.server.extensions.api.plugins.msg.ToDeviceRpcRequest; |
... | ... | @@ -52,10 +45,12 @@ import org.thingsboard.server.extensions.api.plugins.rpc.RpcMsg; |
52 | 45 | import org.thingsboard.server.extensions.api.plugins.ws.PluginWebsocketSessionRef; |
53 | 46 | import org.thingsboard.server.extensions.api.plugins.ws.msg.PluginWebsocketMsg; |
54 | 47 | |
55 | -import akka.actor.ActorRef; | |
56 | -import org.w3c.dom.Attr; | |
57 | - | |
58 | 48 | import javax.annotation.Nullable; |
49 | +import java.io.IOException; | |
50 | +import java.util.*; | |
51 | +import java.util.concurrent.Executor; | |
52 | +import java.util.concurrent.Executors; | |
53 | +import java.util.stream.Collectors; | |
59 | 54 | |
60 | 55 | @Slf4j |
61 | 56 | public final class PluginProcessingContext implements PluginContext { | ... | ... |
... | ... | @@ -35,7 +35,6 @@ import org.junit.Assert; |
35 | 35 | import org.junit.Before; |
36 | 36 | import org.junit.Test; |
37 | 37 | |
38 | -import com.datastax.driver.core.utils.UUIDs; | |
39 | 38 | import com.fasterxml.jackson.core.type.TypeReference; |
40 | 39 | |
41 | 40 | public class DashboardControllerTest extends AbstractControllerTest { | ... | ... |
... | ... | @@ -42,7 +42,6 @@ import org.junit.Assert; |
42 | 42 | import org.junit.Before; |
43 | 43 | import org.junit.Test; |
44 | 44 | |
45 | -import com.datastax.driver.core.utils.UUIDs; | |
46 | 45 | import com.fasterxml.jackson.core.type.TypeReference; |
47 | 46 | |
48 | 47 | public class DeviceControllerTest extends AbstractControllerTest { | ... | ... |
... | ... | @@ -15,9 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.attributes; |
17 | 17 | |
18 | -// CASSANDRA ??? | |
19 | -import com.datastax.driver.core.ResultSet; | |
20 | -import com.datastax.driver.core.ResultSetFuture; | |
21 | 18 | import com.google.common.util.concurrent.ListenableFuture; |
22 | 19 | import org.thingsboard.server.common.data.id.EntityId; |
23 | 20 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; | ... | ... |
... | ... | @@ -15,8 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.attributes; |
17 | 17 | |
18 | -// CASSANDRA ??? | |
19 | -import com.datastax.driver.core.ResultSet; | |
20 | 18 | import com.google.common.util.concurrent.ListenableFuture; |
21 | 19 | import org.thingsboard.server.common.data.id.EntityId; |
22 | 20 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; | ... | ... |
... | ... | @@ -15,9 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.attributes; |
17 | 17 | |
18 | -// CASSANDRA ??? | |
19 | -import com.datastax.driver.core.ResultSet; | |
20 | -import com.datastax.driver.core.ResultSetFuture; | |
21 | 18 | import com.google.common.collect.Lists; |
22 | 19 | import com.google.common.util.concurrent.Futures; |
23 | 20 | import com.google.common.util.concurrent.ListenableFuture; | ... | ... |
... | ... | @@ -15,15 +15,12 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.event; |
17 | 17 | |
18 | -// CASSANDRA ??? | |
19 | -import com.datastax.driver.core.utils.UUIDs; | |
20 | 18 | import lombok.extern.slf4j.Slf4j; |
21 | 19 | import org.apache.commons.lang3.StringUtils; |
22 | 20 | import org.springframework.beans.factory.annotation.Autowired; |
23 | 21 | import org.springframework.stereotype.Service; |
24 | 22 | import org.thingsboard.server.common.data.Event; |
25 | 23 | import org.thingsboard.server.common.data.id.EntityId; |
26 | -import org.thingsboard.server.common.data.id.EventId; | |
27 | 24 | import org.thingsboard.server.common.data.id.TenantId; |
28 | 25 | import org.thingsboard.server.common.data.page.TimePageData; |
29 | 26 | import org.thingsboard.server.common.data.page.TimePageLink; |
... | ... | @@ -33,30 +30,16 @@ import org.thingsboard.server.dao.service.DataValidator; |
33 | 30 | import java.util.List; |
34 | 31 | import java.util.Optional; |
35 | 32 | |
36 | -import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; | |
37 | - | |
38 | 33 | @Service |
39 | 34 | @Slf4j |
40 | 35 | public class BaseEventService implements EventService { |
41 | 36 | |
42 | - private final TenantId systemTenantId = new TenantId(NULL_UUID); | |
43 | - | |
44 | 37 | @Autowired |
45 | 38 | public EventDao eventDao; |
46 | 39 | |
47 | 40 | @Override |
48 | 41 | public Event save(Event event) { |
49 | 42 | eventValidator.validate(event); |
50 | - if (event.getTenantId() == null) { | |
51 | - log.trace("Save system event with predefined id {}", systemTenantId); | |
52 | - event.setTenantId(systemTenantId); | |
53 | - } | |
54 | - if (event.getId() == null) { | |
55 | - event.setId(new EventId(UUIDs.timeBased())); | |
56 | - } | |
57 | - if (StringUtils.isEmpty(event.getUid())) { | |
58 | - event.setUid(event.getId().toString()); | |
59 | - } | |
60 | 43 | return eventDao.save(event); |
61 | 44 | } |
62 | 45 | |
... | ... | @@ -66,13 +49,6 @@ public class BaseEventService implements EventService { |
66 | 49 | if (StringUtils.isEmpty(event.getUid())) { |
67 | 50 | throw new DataValidationException("Event uid should be specified!."); |
68 | 51 | } |
69 | - if (event.getTenantId() == null) { | |
70 | - log.trace("Save system event with predefined id {}", systemTenantId); | |
71 | - event.setTenantId(systemTenantId); | |
72 | - } | |
73 | - if (event.getId() == null) { | |
74 | - event.setId(new EventId(UUIDs.timeBased())); | |
75 | - } | |
76 | 52 | Optional<Event> result = eventDao.saveIfNotExists(event); |
77 | 53 | return result.isPresent() ? Optional.of(result.get()) : Optional.empty(); |
78 | 54 | } |
... | ... | @@ -98,13 +74,13 @@ public class BaseEventService implements EventService { |
98 | 74 | @Override |
99 | 75 | public TimePageData<Event> findEvents(TenantId tenantId, EntityId entityId, TimePageLink pageLink) { |
100 | 76 | List<Event> events = eventDao.findEvents(tenantId.getId(), entityId, pageLink); |
101 | - return new TimePageData<Event>(events, pageLink); | |
77 | + return new TimePageData<>(events, pageLink); | |
102 | 78 | } |
103 | 79 | |
104 | 80 | @Override |
105 | 81 | public TimePageData<Event> findEvents(TenantId tenantId, EntityId entityId, String eventType, TimePageLink pageLink) { |
106 | 82 | List<Event> events = eventDao.findEvents(tenantId.getId(), entityId, eventType, pageLink); |
107 | - return new TimePageData<Event>(events, pageLink); | |
83 | + return new TimePageData<>(events, pageLink); | |
108 | 84 | } |
109 | 85 | |
110 | 86 | private DataValidator<Event> eventValidator = | ... | ... |
... | ... | @@ -21,9 +21,12 @@ import com.datastax.driver.core.querybuilder.QueryBuilder; |
21 | 21 | import com.datastax.driver.core.querybuilder.Select; |
22 | 22 | import com.datastax.driver.core.utils.UUIDs; |
23 | 23 | import lombok.extern.slf4j.Slf4j; |
24 | +import org.apache.commons.lang3.StringUtils; | |
24 | 25 | import org.springframework.stereotype.Component; |
25 | 26 | import org.thingsboard.server.common.data.Event; |
26 | 27 | import org.thingsboard.server.common.data.id.EntityId; |
28 | +import org.thingsboard.server.common.data.id.EventId; | |
29 | +import org.thingsboard.server.common.data.id.TenantId; | |
27 | 30 | import org.thingsboard.server.common.data.page.TimePageLink; |
28 | 31 | import org.thingsboard.server.dao.CassandraAbstractSearchTimeDao; |
29 | 32 | import org.thingsboard.server.dao.DaoUtil; |
... | ... | @@ -43,6 +46,8 @@ import static org.thingsboard.server.dao.model.ModelConstants.*; |
43 | 46 | @Slf4j |
44 | 47 | public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventEntity, Event> implements EventDao { |
45 | 48 | |
49 | + private final TenantId systemTenantId = new TenantId(NULL_UUID); | |
50 | + | |
46 | 51 | @Override |
47 | 52 | protected Class<EventEntity> getColumnFamilyClass() { |
48 | 53 | return EventEntity.class; |
... | ... | @@ -56,11 +61,28 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE |
56 | 61 | @Override |
57 | 62 | public Event save(Event event) { |
58 | 63 | log.debug("Save event [{}] ", event); |
64 | + if (event.getTenantId() == null) { | |
65 | + log.trace("Save system event with predefined id {}", systemTenantId); | |
66 | + event.setTenantId(systemTenantId); | |
67 | + } | |
68 | + if (event.getId() == null) { | |
69 | + event.setId(new EventId(UUIDs.timeBased())); | |
70 | + } | |
71 | + if (StringUtils.isEmpty(event.getUid())) { | |
72 | + event.setUid(event.getId().toString()); | |
73 | + } | |
59 | 74 | return save(new EventEntity(event), false).orElse(null); |
60 | 75 | } |
61 | 76 | |
62 | 77 | @Override |
63 | 78 | public Optional<Event> saveIfNotExists(Event event) { |
79 | + if (event.getTenantId() == null) { | |
80 | + log.trace("Save system event with predefined id {}", systemTenantId); | |
81 | + event.setTenantId(systemTenantId); | |
82 | + } | |
83 | + if (event.getId() == null) { | |
84 | + event.setId(new EventId(UUIDs.timeBased())); | |
85 | + } | |
64 | 86 | return save(new EventEntity(event), true); |
65 | 87 | } |
66 | 88 | ... | ... |
... | ... | @@ -15,10 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.timeseries; |
17 | 17 | |
18 | -// CASSANDRA ??? | |
19 | -import com.datastax.driver.core.ResultSet; | |
20 | -import com.datastax.driver.core.ResultSetFuture; | |
21 | -import com.datastax.driver.core.Row; | |
22 | 18 | import com.google.common.collect.Lists; |
23 | 19 | import com.google.common.util.concurrent.Futures; |
24 | 20 | import com.google.common.util.concurrent.ListenableFuture; | ... | ... |
... | ... | @@ -15,9 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.timeseries; |
17 | 17 | |
18 | -// CASSANDRA ??? | |
19 | -import com.datastax.driver.core.ResultSetFuture; | |
20 | -import com.datastax.driver.core.Row; | |
21 | 18 | import com.google.common.util.concurrent.ListenableFuture; |
22 | 19 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
23 | 20 | import org.thingsboard.server.common.data.kv.TsKvQuery; | ... | ... |
... | ... | @@ -15,10 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.timeseries; |
17 | 17 | |
18 | -// CASSANDRA ??? | |
19 | -import com.datastax.driver.core.ResultSet; | |
20 | -import com.datastax.driver.core.ResultSetFuture; | |
21 | -import com.datastax.driver.core.Row; | |
22 | 18 | import com.google.common.util.concurrent.ListenableFuture; |
23 | 19 | import org.thingsboard.server.common.data.id.UUIDBased; |
24 | 20 | import org.thingsboard.server.common.data.kv.TsKvEntry; | ... | ... |
... | ... | @@ -15,7 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.attributes; |
17 | 17 | |
18 | -import com.datastax.driver.core.utils.UUIDs; | |
19 | 18 | import org.thingsboard.server.common.data.DataConstants; |
20 | 19 | import org.thingsboard.server.common.data.id.DeviceId; |
21 | 20 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; | ... | ... |
... | ... | @@ -15,8 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.event; |
17 | 17 | |
18 | -import com.datastax.driver.core.utils.UUIDs; | |
19 | -import org.apache.cassandra.utils.UUIDGen; | |
20 | 18 | import org.junit.Assert; |
21 | 19 | import org.junit.Test; |
22 | 20 | import org.thingsboard.server.common.data.DataConstants; |
... | ... | @@ -34,7 +32,6 @@ import java.io.IOException; |
34 | 32 | import java.time.LocalDateTime; |
35 | 33 | import java.time.Month; |
36 | 34 | import java.time.ZoneOffset; |
37 | -import java.util.List; | |
38 | 35 | import java.util.Optional; |
39 | 36 | |
40 | 37 | public class BaseEventServiceTest extends AbstractServiceTest { | ... | ... |
... | ... | @@ -15,22 +15,17 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.plugin; |
17 | 17 | |
18 | -import java.util.UUID; | |
19 | - | |
20 | 18 | import lombok.extern.slf4j.Slf4j; |
19 | +import org.junit.Assert; | |
20 | +import org.junit.Test; | |
21 | 21 | import org.thingsboard.server.common.data.id.TenantId; |
22 | 22 | import org.thingsboard.server.common.data.page.TextPageData; |
23 | 23 | import org.thingsboard.server.common.data.page.TextPageLink; |
24 | 24 | import org.thingsboard.server.common.data.plugin.PluginMetaData; |
25 | -import org.thingsboard.server.common.data.rule.RuleMetaData; | |
25 | +import org.thingsboard.server.dao.model.ModelConstants; | |
26 | 26 | import org.thingsboard.server.dao.service.AbstractServiceTest; |
27 | -import org.junit.Assert; | |
28 | -import org.junit.Test; | |
29 | -import org.slf4j.Logger; | |
30 | -import org.slf4j.LoggerFactory; | |
31 | 27 | |
32 | -import com.datastax.driver.core.utils.UUIDs; | |
33 | -import org.thingsboard.server.dao.model.ModelConstants; | |
28 | +import java.util.UUID; | |
34 | 29 | |
35 | 30 | @Slf4j |
36 | 31 | public class BasePluginServiceTest extends AbstractServiceTest { | ... | ... |
... | ... | @@ -15,7 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.service; |
17 | 17 | |
18 | -import com.datastax.driver.core.utils.UUIDs; | |
19 | 18 | import com.fasterxml.jackson.databind.JsonNode; |
20 | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
21 | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; | ... | ... |
... | ... | @@ -15,23 +15,21 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.service; |
17 | 17 | |
18 | -import java.util.ArrayList; | |
19 | -import java.util.Collections; | |
20 | -import java.util.List; | |
21 | - | |
22 | 18 | import org.apache.commons.lang3.RandomStringUtils; |
23 | 19 | import org.junit.After; |
20 | +import org.junit.Assert; | |
21 | +import org.junit.Before; | |
22 | +import org.junit.Test; | |
24 | 23 | import org.thingsboard.server.common.data.Customer; |
25 | 24 | import org.thingsboard.server.common.data.Tenant; |
26 | 25 | import org.thingsboard.server.common.data.id.TenantId; |
27 | 26 | import org.thingsboard.server.common.data.page.TextPageData; |
28 | 27 | import org.thingsboard.server.common.data.page.TextPageLink; |
29 | 28 | import org.thingsboard.server.dao.exception.DataValidationException; |
30 | -import org.junit.Assert; | |
31 | -import org.junit.Before; | |
32 | -import org.junit.Test; | |
33 | 29 | |
34 | -import com.datastax.driver.core.utils.UUIDs; | |
30 | +import java.util.ArrayList; | |
31 | +import java.util.Collections; | |
32 | +import java.util.List; | |
35 | 33 | |
36 | 34 | public class CustomerServiceImplTest extends AbstractServiceTest { |
37 | 35 | ... | ... |
... | ... | @@ -15,7 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.service; |
17 | 17 | |
18 | -import com.datastax.driver.core.utils.UUIDs; | |
19 | 18 | import com.hazelcast.core.HazelcastInstance; |
20 | 19 | import org.apache.commons.lang3.RandomStringUtils; |
21 | 20 | import org.junit.After; |
... | ... | @@ -39,10 +38,7 @@ import org.thingsboard.server.dao.device.DeviceService; |
39 | 38 | |
40 | 39 | import java.util.UUID; |
41 | 40 | |
42 | -import static org.mockito.Mockito.mock; | |
43 | -import static org.mockito.Mockito.times; | |
44 | -import static org.mockito.Mockito.verify; | |
45 | -import static org.mockito.Mockito.when; | |
41 | +import static org.mockito.Mockito.*; | |
46 | 42 | |
47 | 43 | @TestPropertySource(properties = {"cache.enabled = true"}) |
48 | 44 | public class DeviceCredentialsCacheTest extends AbstractServiceTest { | ... | ... |
... | ... | @@ -15,7 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.service; |
17 | 17 | |
18 | -import com.datastax.driver.core.utils.UUIDs; | |
19 | 18 | import org.apache.commons.lang3.RandomStringUtils; |
20 | 19 | import org.junit.After; |
21 | 20 | import org.junit.Assert; |
... | ... | @@ -25,8 +24,6 @@ import org.thingsboard.server.common.data.Customer; |
25 | 24 | import org.thingsboard.server.common.data.Device; |
26 | 25 | import org.thingsboard.server.common.data.Tenant; |
27 | 26 | import org.thingsboard.server.common.data.id.CustomerId; |
28 | -import org.thingsboard.server.common.data.id.DeviceCredentialsId; | |
29 | -import org.thingsboard.server.common.data.id.DeviceId; | |
30 | 27 | import org.thingsboard.server.common.data.id.TenantId; |
31 | 28 | import org.thingsboard.server.common.data.page.TextPageData; |
32 | 29 | import org.thingsboard.server.common.data.page.TextPageLink; | ... | ... |
... | ... | @@ -15,7 +15,6 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.service; |
17 | 17 | |
18 | -import com.datastax.driver.core.utils.UUIDs; | |
19 | 18 | import com.fasterxml.jackson.databind.JsonNode; |
20 | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
21 | 20 | import org.junit.After; |
... | ... | @@ -23,7 +22,6 @@ import org.junit.Assert; |
23 | 22 | import org.junit.Before; |
24 | 23 | import org.junit.Test; |
25 | 24 | import org.thingsboard.server.common.data.Tenant; |
26 | -import org.thingsboard.server.common.data.User; | |
27 | 25 | import org.thingsboard.server.common.data.id.TenantId; |
28 | 26 | import org.thingsboard.server.common.data.widget.WidgetType; |
29 | 27 | import org.thingsboard.server.common.data.widget.WidgetsBundle; | ... | ... |
... | ... | @@ -15,21 +15,14 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.timeseries; |
17 | 17 | |
18 | -import com.datastax.driver.core.ResultSet; | |
19 | -import com.datastax.driver.core.ResultSetFuture; | |
20 | -import com.datastax.driver.core.utils.UUIDs; | |
21 | 18 | import lombok.extern.slf4j.Slf4j; |
22 | 19 | import org.junit.Assert; |
20 | +import org.junit.Test; | |
23 | 21 | import org.thingsboard.server.common.data.DataConstants; |
24 | 22 | import org.thingsboard.server.common.data.id.DeviceId; |
25 | -import org.thingsboard.server.dao.service.AbstractServiceTest; | |
26 | -import org.junit.Test; | |
27 | -import org.slf4j.Logger; | |
28 | -import org.slf4j.LoggerFactory; | |
29 | 23 | import org.thingsboard.server.common.data.kv.*; |
24 | +import org.thingsboard.server.dao.service.AbstractServiceTest; | |
30 | 25 | |
31 | -import java.time.LocalDateTime; | |
32 | -import java.time.ZoneOffset; | |
33 | 26 | import java.util.ArrayList; |
34 | 27 | import java.util.Arrays; |
35 | 28 | import java.util.Collections; | ... | ... |