Refactor: strategy creation, hide implementation details from clients
This commit is contained in:
parent
07b8140b77
commit
a5c06ec70d
@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
@ -46,10 +47,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
|
||||
import org.thingsboard.server.common.transport.activity.ActivityReportCallback;
|
||||
import org.thingsboard.server.common.transport.activity.ActivityState;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.AllEventsActivityStrategy;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.FirstAndLastEventActivityStrategy;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.FirstEventActivityStrategy;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.LastEventActivityStrategy;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyType;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||
import org.thingsboard.server.queue.TbQueueCallback;
|
||||
import org.thingsboard.server.queue.TbQueueProducer;
|
||||
@ -181,33 +179,32 @@ public class IntegrationActivityManagerTest {
|
||||
verify(integrationServiceMock).onActivity(key);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideTestParamsForCreateNewState")
|
||||
void givenDifferentReportingStrategies_whenCreatingNewState_thenShouldCreateEmptyStateWithCorrectStrategy(
|
||||
String reportingStrategyName, ActivityStrategy reportingStrategy
|
||||
) {
|
||||
@Test
|
||||
void givenKey_whenCreatingNewState_thenShouldCorrectlyCreateNewEmptyState() {
|
||||
// GIVEN
|
||||
var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID);
|
||||
when(integrationServiceMock.createNewState(key)).thenCallRealMethod();
|
||||
ReflectionTestUtils.setField(integrationServiceMock, "reportingStrategyName", reportingStrategyName);
|
||||
|
||||
ActivityState<Void> expectedState = new ActivityState<>();
|
||||
expectedState.setStrategy(reportingStrategy);
|
||||
|
||||
// WHEN
|
||||
ActivityState<Void> actualState = integrationServiceMock.createNewState(key);
|
||||
ActivityState<Void> actualNewState = integrationServiceMock.createNewState(key);
|
||||
|
||||
// THEN
|
||||
assertThat(actualState).isEqualTo(expectedState);
|
||||
ActivityState<Void> expectedNewState = new ActivityState<>();
|
||||
assertThat(actualNewState).isEqualTo(expectedNewState);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> provideTestParamsForCreateNewState() {
|
||||
return Stream.of(
|
||||
Arguments.of("ALL", new AllEventsActivityStrategy()),
|
||||
Arguments.of("FIRST", new FirstEventActivityStrategy()),
|
||||
Arguments.of("LAST", new LastEventActivityStrategy()),
|
||||
Arguments.of("FIRST_AND_LAST", new FirstAndLastEventActivityStrategy())
|
||||
);
|
||||
@ParameterizedTest
|
||||
@EnumSource(ActivityStrategyType.class)
|
||||
void givenDifferentReportingStrategies_whenGettingStrategy_thenShouldReturnCorrectStrategy(ActivityStrategyType reportingStrategyType) {
|
||||
// GIVEN
|
||||
doCallRealMethod().when(integrationServiceMock).getStrategy();
|
||||
ReflectionTestUtils.setField(integrationServiceMock, "reportingStrategyType", reportingStrategyType);
|
||||
|
||||
// WHEN
|
||||
ActivityStrategy actualStrategy = integrationServiceMock.getStrategy();
|
||||
|
||||
// THEN
|
||||
assertThat(actualStrategy).isEqualTo(reportingStrategyType.toStrategy());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -215,12 +212,8 @@ public class IntegrationActivityManagerTest {
|
||||
// GIVEN
|
||||
var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID);
|
||||
|
||||
ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy());
|
||||
|
||||
ActivityState<Void> state = new ActivityState<>();
|
||||
state.setLastRecordedTime(123L);
|
||||
state.setLastReportedTime(312L);
|
||||
state.setStrategy(strategySpy);
|
||||
ActivityState<Void> stateSpy = spy(state);
|
||||
|
||||
when(integrationServiceMock.updateState(key, state)).thenCallRealMethod();
|
||||
@ -231,7 +224,6 @@ public class IntegrationActivityManagerTest {
|
||||
// THEN
|
||||
assertThat(updatedState).isSameAs(state);
|
||||
verifyNoInteractions(stateSpy);
|
||||
verifyNoInteractions(strategySpy);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
||||
@ -30,9 +30,11 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.transport.activity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.thingsboard.server.common.data.StringUtils;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy;
|
||||
import org.thingsboard.server.queue.scheduler.SchedulerComponent;
|
||||
|
||||
import java.util.Map;
|
||||
@ -45,7 +47,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@Slf4j
|
||||
public abstract class AbstractActivityManager<Key, Metadata> implements ActivityManager<Key> {
|
||||
|
||||
private final ConcurrentMap<Key, ActivityState<Metadata>> states = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<Key, ActivityStateWrapper> states = new ConcurrentHashMap<>();
|
||||
|
||||
@Autowired
|
||||
protected SchedulerComponent scheduler;
|
||||
@ -53,6 +55,15 @@ public abstract class AbstractActivityManager<Key, Metadata> implements Activity
|
||||
protected String name;
|
||||
private boolean initialized;
|
||||
|
||||
@Data
|
||||
private class ActivityStateWrapper {
|
||||
|
||||
private volatile ActivityState<Metadata> state;
|
||||
private volatile long lastReportedTime;
|
||||
private volatile ActivityStrategy strategy;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void init(String name, long reportingPeriodMillis) {
|
||||
if (!initialized) {
|
||||
@ -70,6 +81,8 @@ public abstract class AbstractActivityManager<Key, Metadata> implements Activity
|
||||
|
||||
protected abstract ActivityState<Metadata> createNewState(Key key);
|
||||
|
||||
protected abstract ActivityStrategy getStrategy();
|
||||
|
||||
protected abstract ActivityState<Metadata> updateState(Key key, ActivityState<Metadata> state);
|
||||
|
||||
protected abstract boolean hasExpired(long lastRecordedTime);
|
||||
@ -92,27 +105,31 @@ public abstract class AbstractActivityManager<Key, Metadata> implements Activity
|
||||
|
||||
long newLastRecordedTime = System.currentTimeMillis();
|
||||
var shouldReport = new AtomicBoolean(false);
|
||||
var activityState = states.compute(key, (__, state) -> {
|
||||
if (state == null) {
|
||||
var activityStateWrapper = states.compute(key, (__, stateWrapper) -> {
|
||||
if (stateWrapper == null) {
|
||||
var newState = createNewState(key);
|
||||
if (newState == null) {
|
||||
return null;
|
||||
}
|
||||
state = newState;
|
||||
stateWrapper = new ActivityStateWrapper();
|
||||
stateWrapper.setState(newState);
|
||||
stateWrapper.setStrategy(getStrategy());
|
||||
}
|
||||
var state = stateWrapper.getState();
|
||||
if (state.getLastRecordedTime() < newLastRecordedTime) {
|
||||
state.setLastRecordedTime(newLastRecordedTime);
|
||||
}
|
||||
shouldReport.set(state.getStrategy().onActivity());
|
||||
return state;
|
||||
shouldReport.set(stateWrapper.getStrategy().onActivity());
|
||||
return stateWrapper;
|
||||
});
|
||||
|
||||
if (activityState == null) {
|
||||
if (activityStateWrapper == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var activityState = activityStateWrapper.getState();
|
||||
long lastRecordedTime = activityState.getLastRecordedTime();
|
||||
long lastReportedTime = activityState.getLastReportedTime();
|
||||
long lastReportedTime = activityStateWrapper.getLastReportedTime();
|
||||
if (shouldReport.get() && lastReportedTime < lastRecordedTime) {
|
||||
log.debug("[{}] Going to report first activity event for key: [{}].", name, key);
|
||||
reportActivity(key, activityState.getMetadata(), lastRecordedTime, new ActivityReportCallback<>() {
|
||||
@ -131,18 +148,19 @@ public abstract class AbstractActivityManager<Key, Metadata> implements Activity
|
||||
|
||||
@Override
|
||||
public long getLastRecordedTime(Key key) {
|
||||
ActivityState<Metadata> state = states.get(key);
|
||||
return state == null ? 0L : state.getLastRecordedTime();
|
||||
ActivityStateWrapper stateWrapper = states.get(key);
|
||||
return stateWrapper == null ? 0L : stateWrapper.getState().getLastRecordedTime();
|
||||
}
|
||||
|
||||
private void onReportingPeriodEnd() {
|
||||
log.debug("[{}] Going to end reporting period.", name);
|
||||
for (Map.Entry<Key, ActivityState<Metadata>> entry : states.entrySet()) {
|
||||
for (Map.Entry<Key, ActivityStateWrapper> entry : states.entrySet()) {
|
||||
var key = entry.getKey();
|
||||
var currentState = entry.getValue();
|
||||
var stateWrapper = entry.getValue();
|
||||
var currentState = stateWrapper.getState();
|
||||
|
||||
long lastRecordedTime = currentState.getLastRecordedTime();
|
||||
long lastReportedTime = currentState.getLastReportedTime();
|
||||
long lastReportedTime = stateWrapper.getLastReportedTime();
|
||||
var metadata = currentState.getMetadata();
|
||||
|
||||
boolean hasExpired;
|
||||
@ -151,10 +169,9 @@ public abstract class AbstractActivityManager<Key, Metadata> implements Activity
|
||||
var updatedState = updateState(key, currentState);
|
||||
if (updatedState != null) {
|
||||
lastRecordedTime = updatedState.getLastRecordedTime();
|
||||
lastReportedTime = updatedState.getLastReportedTime();
|
||||
metadata = updatedState.getMetadata();
|
||||
hasExpired = hasExpired(lastRecordedTime);
|
||||
shouldReport = updatedState.getStrategy().onReportingPeriodEnd();
|
||||
shouldReport = stateWrapper.getStrategy().onReportingPeriodEnd();
|
||||
} else {
|
||||
states.remove(key);
|
||||
hasExpired = false;
|
||||
@ -185,9 +202,9 @@ public abstract class AbstractActivityManager<Key, Metadata> implements Activity
|
||||
}
|
||||
|
||||
private void updateLastReportedTime(Key key, long newLastReportedTime) {
|
||||
states.computeIfPresent(key, (__, state) -> {
|
||||
state.setLastReportedTime(Math.max(state.getLastReportedTime(), newLastReportedTime));
|
||||
return state;
|
||||
states.computeIfPresent(key, (__, stateWrapper) -> {
|
||||
stateWrapper.setLastReportedTime(Math.max(stateWrapper.getLastReportedTime(), newLastReportedTime));
|
||||
return stateWrapper;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -31,14 +31,11 @@
|
||||
package org.thingsboard.server.common.transport.activity;
|
||||
|
||||
import lombok.Data;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy;
|
||||
|
||||
@Data
|
||||
public class ActivityState<Metadata> {
|
||||
|
||||
private volatile long lastRecordedTime;
|
||||
private volatile long lastReportedTime;
|
||||
private volatile ActivityStrategy strategy;
|
||||
private volatile Metadata metadata;
|
||||
|
||||
}
|
||||
|
||||
@ -28,17 +28,35 @@
|
||||
* DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS,
|
||||
* OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART.
|
||||
*/
|
||||
package org.thingsboard.server.common.transport.service;
|
||||
package org.thingsboard.server.common.transport.activity.strategy;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.thingsboard.server.common.transport.activity.ActivityState;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||
public enum ActivityStrategyType {
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class TransportActivityState extends ActivityState {
|
||||
ALL {
|
||||
@Override
|
||||
public ActivityStrategy toStrategy() {
|
||||
return AllEventsActivityStrategy.getInstance();
|
||||
}
|
||||
},
|
||||
FIRST {
|
||||
@Override
|
||||
public ActivityStrategy toStrategy() {
|
||||
return new FirstEventActivityStrategy();
|
||||
}
|
||||
},
|
||||
LAST {
|
||||
@Override
|
||||
public ActivityStrategy toStrategy() {
|
||||
return LastEventActivityStrategy.getInstance();
|
||||
}
|
||||
},
|
||||
FIRST_AND_LAST {
|
||||
@Override
|
||||
public ActivityStrategy toStrategy() {
|
||||
return new FirstAndLastEventActivityStrategy();
|
||||
}
|
||||
};
|
||||
|
||||
private volatile TransportProtos.SessionInfoProto sessionInfoProto;
|
||||
public abstract ActivityStrategy toStrategy();
|
||||
|
||||
}
|
||||
@ -30,10 +30,16 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.transport.activity.strategy;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
public final class AllEventsActivityStrategy implements ActivityStrategy {
|
||||
|
||||
@EqualsAndHashCode
|
||||
public class AllEventsActivityStrategy implements ActivityStrategy {
|
||||
private static final AllEventsActivityStrategy INSTANCE = new AllEventsActivityStrategy();
|
||||
|
||||
private AllEventsActivityStrategy() {
|
||||
}
|
||||
|
||||
public static AllEventsActivityStrategy getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActivity() {
|
||||
|
||||
@ -33,7 +33,7 @@ package org.thingsboard.server.common.transport.activity.strategy;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode
|
||||
public class FirstAndLastEventActivityStrategy implements ActivityStrategy {
|
||||
public final class FirstAndLastEventActivityStrategy implements ActivityStrategy {
|
||||
|
||||
private boolean firstEventReceived;
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ package org.thingsboard.server.common.transport.activity.strategy;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode
|
||||
public class FirstEventActivityStrategy implements ActivityStrategy {
|
||||
public final class FirstEventActivityStrategy implements ActivityStrategy {
|
||||
|
||||
private boolean firstEventReceived;
|
||||
|
||||
|
||||
@ -30,10 +30,16 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.transport.activity.strategy;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
public final class LastEventActivityStrategy implements ActivityStrategy {
|
||||
|
||||
@EqualsAndHashCode
|
||||
public class LastEventActivityStrategy implements ActivityStrategy {
|
||||
private static final LastEventActivityStrategy INSTANCE = new LastEventActivityStrategy();
|
||||
|
||||
private LastEventActivityStrategy() {
|
||||
}
|
||||
|
||||
public static LastEventActivityStrategy getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActivity() {
|
||||
|
||||
@ -74,7 +74,8 @@ import org.thingsboard.server.common.transport.TransportTenantProfileCache;
|
||||
import org.thingsboard.server.common.transport.activity.AbstractActivityManager;
|
||||
import org.thingsboard.server.common.transport.activity.ActivityReportCallback;
|
||||
import org.thingsboard.server.common.transport.activity.ActivityState;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyFactory;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyType;
|
||||
import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse;
|
||||
import org.thingsboard.server.common.transport.auth.TransportDeviceInfo;
|
||||
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
|
||||
@ -158,7 +159,7 @@ public class DefaultTransportService extends AbstractActivityManager<UUID, Trans
|
||||
@Value("${transport.sessions.report_timeout}")
|
||||
private long sessionReportTimeout;
|
||||
@Value("${transport.activity.reporting_strategy:LAST}")
|
||||
private String reportingStrategyName;
|
||||
private ActivityStrategyType reportingStrategyType;
|
||||
@Value("${transport.client_side_rpc.timeout:60000}")
|
||||
private long clientSideRpcTimeout;
|
||||
@Value("${queue.transport.poll_interval}")
|
||||
@ -796,10 +797,14 @@ public class DefaultTransportService extends AbstractActivityManager<UUID, Trans
|
||||
}
|
||||
ActivityState<TransportProtos.SessionInfoProto> state = new ActivityState<>();
|
||||
state.setMetadata(session.getSessionInfo());
|
||||
state.setStrategy(ActivityStrategyFactory.createStrategy(reportingStrategyName));
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActivityStrategy getStrategy() {
|
||||
return reportingStrategyType.toStrategy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActivityState<TransportProtos.SessionInfoProto> updateState(UUID sessionId, ActivityState<TransportProtos.SessionInfoProto> state) {
|
||||
SessionMetaData session = sessions.get(sessionId);
|
||||
|
||||
@ -1,70 +0,0 @@
|
||||
/**
|
||||
* ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL
|
||||
*
|
||||
* Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved.
|
||||
*
|
||||
* NOTICE: All information contained herein is, and remains
|
||||
* the property of ThingsBoard, Inc. and its suppliers,
|
||||
* if any. The intellectual and technical concepts contained
|
||||
* herein are proprietary to ThingsBoard, Inc.
|
||||
* and its suppliers and may be covered by U.S. and Foreign Patents,
|
||||
* patents in process, and are protected by trade secret or copyright law.
|
||||
*
|
||||
* Dissemination of this information or reproduction of this material is strictly forbidden
|
||||
* unless prior written permission is obtained from COMPANY.
|
||||
*
|
||||
* Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees,
|
||||
* managers or contractors who have executed Confidentiality and Non-disclosure agreements
|
||||
* explicitly covering such access.
|
||||
*
|
||||
* The copyright notice above does not evidence any actual or intended publication
|
||||
* or disclosure of this source code, which includes
|
||||
* information that is confidential and/or proprietary, and is a trade secret, of COMPANY.
|
||||
* ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE,
|
||||
* OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT
|
||||
* THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED,
|
||||
* AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES.
|
||||
* THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION
|
||||
* DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS,
|
||||
* OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART.
|
||||
*/
|
||||
package org.thingsboard.server.common.transport.activity.strategy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class ActivityStrategyFactoryTest {
|
||||
|
||||
@Test
|
||||
public void testCreateAllEventsStrategy() {
|
||||
ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("ALL");
|
||||
assertInstanceOf(AllEventsActivityStrategy.class, strategy, "Should return an instance of AllEventsActivityStrategy.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFirstEventStrategy() {
|
||||
ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("FIRST");
|
||||
assertInstanceOf(FirstEventActivityStrategy.class, strategy, "Should return an instance of FirstEventActivityStrategy.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateLastEventStrategy() {
|
||||
ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("LAST");
|
||||
assertInstanceOf(LastEventActivityStrategy.class, strategy, "Should return an instance of LastEventActivityStrategy.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFirstAndLastEventStrategy() {
|
||||
ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("FIRST_AND_LAST");
|
||||
assertInstanceOf(FirstAndLastEventActivityStrategy.class, strategy, "Should return an instance of FirstAndLastEventActivityStrategy.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateUnknownStrategy() {
|
||||
assertThrows(IllegalArgumentException.class, () -> ActivityStrategyFactory.createStrategy("UNKNOWN"),
|
||||
"Should throw IllegalArgumentException for unknown strategy names.");
|
||||
}
|
||||
|
||||
}
|
||||
@ -30,29 +30,30 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.transport.activity.strategy;
|
||||
|
||||
public final class ActivityStrategyFactory {
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
private static final String ALL_EVENTS_STRATEGY_NAME = "ALL";
|
||||
private static final String FIRST_EVENT_STRATEGY_NAME = "FIRST";
|
||||
private static final String LAST_EVENT_STRATEGY_NAME = "LAST";
|
||||
private static final String FIRST_AND_LAST_STRATEGY_NAME = "FIRST_AND_LAST";
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
private ActivityStrategyFactory() {
|
||||
public class ActivityStrategyTypeTest {
|
||||
|
||||
@Test
|
||||
public void testCreateAllEventsStrategy() {
|
||||
assertThat(ActivityStrategyType.ALL.toStrategy()).isEqualTo(AllEventsActivityStrategy.getInstance());
|
||||
}
|
||||
|
||||
public static ActivityStrategy createStrategy(String strategyName) {
|
||||
switch (strategyName) {
|
||||
case ALL_EVENTS_STRATEGY_NAME:
|
||||
return new AllEventsActivityStrategy();
|
||||
case FIRST_EVENT_STRATEGY_NAME:
|
||||
return new FirstEventActivityStrategy();
|
||||
case LAST_EVENT_STRATEGY_NAME:
|
||||
return new LastEventActivityStrategy();
|
||||
case FIRST_AND_LAST_STRATEGY_NAME:
|
||||
return new FirstAndLastEventActivityStrategy();
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown activity strategy name: [" + strategyName + ".");
|
||||
}
|
||||
@Test
|
||||
public void testCreateFirstEventStrategy() {
|
||||
assertThat(ActivityStrategyType.FIRST.toStrategy()).isEqualTo(new FirstEventActivityStrategy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateLastEventStrategy() {
|
||||
assertThat(ActivityStrategyType.LAST.toStrategy()).isEqualTo(LastEventActivityStrategy.getInstance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFirstAndLastEventStrategy() {
|
||||
assertThat(ActivityStrategyType.FIRST_AND_LAST.toStrategy()).isEqualTo(new FirstAndLastEventActivityStrategy());
|
||||
}
|
||||
|
||||
}
|
||||
@ -41,7 +41,7 @@ public class AllEventsActivityStrategyTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
strategy = new AllEventsActivityStrategy();
|
||||
strategy = AllEventsActivityStrategy.getInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -42,7 +42,7 @@ public class LastEventActivityStrategyTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
strategy = new LastEventActivityStrategy();
|
||||
strategy = LastEventActivityStrategy.getInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -35,6 +35,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
@ -45,10 +46,7 @@ import org.thingsboard.server.common.transport.TransportServiceCallback;
|
||||
import org.thingsboard.server.common.transport.activity.ActivityReportCallback;
|
||||
import org.thingsboard.server.common.transport.activity.ActivityState;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.AllEventsActivityStrategy;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.FirstAndLastEventActivityStrategy;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.FirstEventActivityStrategy;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.LastEventActivityStrategy;
|
||||
import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyType;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||
|
||||
import java.util.UUID;
|
||||
@ -60,9 +58,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.doCallRealMethod;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED;
|
||||
import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EXPIRED_NOTIFICATION_PROTO;
|
||||
@ -195,25 +191,18 @@ public class TransportActivityManagerTest {
|
||||
verify(transportServiceMock).onActivity(SESSION_ID);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideTestParamsForCreateNewState")
|
||||
void givenDifferentReportingStrategies_whenCreatingNewState_thenShouldCreateEmptyStateWithCorrectStrategy(
|
||||
String reportingStrategyName, ActivityStrategy reportingStrategy
|
||||
) {
|
||||
@Test
|
||||
void givenKey_whenCreatingNewState_thenShouldCorrectlyCreateNewEmptyState() {
|
||||
// GIVEN
|
||||
TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder()
|
||||
.setSessionIdMSB(SESSION_ID.getMostSignificantBits())
|
||||
.setSessionIdLSB(SESSION_ID.getLeastSignificantBits())
|
||||
.build();
|
||||
SessionMsgListener listenerMock = mock(SessionMsgListener.class);
|
||||
sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock));
|
||||
|
||||
ReflectionTestUtils.setField(transportServiceMock, "reportingStrategyName", reportingStrategyName);
|
||||
sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, null));
|
||||
|
||||
when(transportServiceMock.createNewState(SESSION_ID)).thenCallRealMethod();
|
||||
|
||||
ActivityState<TransportProtos.SessionInfoProto> expectedState = new ActivityState<>();
|
||||
expectedState.setStrategy(reportingStrategy);
|
||||
expectedState.setMetadata(sessionInfo);
|
||||
|
||||
// WHEN
|
||||
@ -223,13 +212,18 @@ public class TransportActivityManagerTest {
|
||||
assertThat(actualState).isEqualTo(expectedState);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> provideTestParamsForCreateNewState() {
|
||||
return Stream.of(
|
||||
Arguments.of("ALL", new AllEventsActivityStrategy()),
|
||||
Arguments.of("FIRST", new FirstEventActivityStrategy()),
|
||||
Arguments.of("LAST", new LastEventActivityStrategy()),
|
||||
Arguments.of("FIRST_AND_LAST", new FirstAndLastEventActivityStrategy())
|
||||
);
|
||||
@ParameterizedTest
|
||||
@EnumSource(ActivityStrategyType.class)
|
||||
void givenDifferentReportingStrategies_whenGettingStrategy_thenShouldReturnCorrectStrategy(ActivityStrategyType reportingStrategyType) {
|
||||
// GIVEN
|
||||
doCallRealMethod().when(transportServiceMock).getStrategy();
|
||||
ReflectionTestUtils.setField(transportServiceMock, "reportingStrategyType", reportingStrategyType);
|
||||
|
||||
// WHEN
|
||||
ActivityStrategy actualStrategy = transportServiceMock.getStrategy();
|
||||
|
||||
// THEN
|
||||
assertThat(actualStrategy).isEqualTo(reportingStrategyType.toStrategy());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -242,9 +236,7 @@ public class TransportActivityManagerTest {
|
||||
|
||||
ActivityState<TransportProtos.SessionInfoProto> state = new ActivityState<>();
|
||||
state.setLastRecordedTime(123L);
|
||||
state.setLastReportedTime(312L);
|
||||
state.setMetadata(sessionInfo);
|
||||
state.setStrategy(new FirstEventActivityStrategy());
|
||||
|
||||
when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod();
|
||||
|
||||
@ -266,14 +258,10 @@ public class TransportActivityManagerTest {
|
||||
sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock));
|
||||
|
||||
long lastRecordedTime = 123L;
|
||||
long lastReportedTime = 312L;
|
||||
ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy());
|
||||
|
||||
ActivityState<TransportProtos.SessionInfoProto> state = new ActivityState<>();
|
||||
state.setLastRecordedTime(lastRecordedTime);
|
||||
state.setLastReportedTime(lastReportedTime);
|
||||
state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance());
|
||||
state.setStrategy(strategySpy);
|
||||
|
||||
when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod();
|
||||
|
||||
@ -283,10 +271,7 @@ public class TransportActivityManagerTest {
|
||||
// THEN
|
||||
assertThat(updatedState).isSameAs(state);
|
||||
assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime);
|
||||
assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime);
|
||||
assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo);
|
||||
assertThat(updatedState.getStrategy()).isEqualTo(strategySpy);
|
||||
verifyNoInteractions(strategySpy);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -303,14 +288,10 @@ public class TransportActivityManagerTest {
|
||||
sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock));
|
||||
|
||||
long lastRecordedTime = 123L;
|
||||
long lastReportedTime = 312L;
|
||||
ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy());
|
||||
|
||||
ActivityState<TransportProtos.SessionInfoProto> state = new ActivityState<>();
|
||||
state.setLastRecordedTime(lastRecordedTime);
|
||||
state.setLastReportedTime(lastReportedTime);
|
||||
state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance());
|
||||
state.setStrategy(strategySpy);
|
||||
|
||||
when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod();
|
||||
|
||||
@ -320,10 +301,7 @@ public class TransportActivityManagerTest {
|
||||
// THEN
|
||||
assertThat(updatedState).isSameAs(state);
|
||||
assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime);
|
||||
assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime);
|
||||
assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo);
|
||||
assertThat(updatedState.getStrategy()).isEqualTo(strategySpy);
|
||||
verifyNoInteractions(strategySpy);
|
||||
|
||||
verify(transportServiceMock, never()).getLastRecordedTime(gwSessionId);
|
||||
}
|
||||
@ -349,14 +327,10 @@ public class TransportActivityManagerTest {
|
||||
sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock));
|
||||
|
||||
long lastRecordedTime = 123L;
|
||||
long lastReportedTime = 312L;
|
||||
ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy());
|
||||
|
||||
ActivityState<TransportProtos.SessionInfoProto> state = new ActivityState<>();
|
||||
state.setLastRecordedTime(lastRecordedTime);
|
||||
state.setLastReportedTime(lastReportedTime);
|
||||
state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance());
|
||||
state.setStrategy(strategySpy);
|
||||
|
||||
when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod();
|
||||
|
||||
@ -366,10 +340,7 @@ public class TransportActivityManagerTest {
|
||||
// THEN
|
||||
assertThat(updatedState).isSameAs(state);
|
||||
assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime);
|
||||
assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime);
|
||||
assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo);
|
||||
assertThat(updatedState.getStrategy()).isEqualTo(strategySpy);
|
||||
verifyNoInteractions(strategySpy);
|
||||
|
||||
verify(transportServiceMock, never()).getLastRecordedTime(gwSessionId);
|
||||
}
|
||||
@ -400,14 +371,10 @@ public class TransportActivityManagerTest {
|
||||
sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock));
|
||||
|
||||
long lastRecordedTime = 123L;
|
||||
long lastReportedTime = 312L;
|
||||
ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy());
|
||||
|
||||
ActivityState<TransportProtos.SessionInfoProto> state = new ActivityState<>();
|
||||
state.setLastRecordedTime(lastRecordedTime);
|
||||
state.setLastReportedTime(lastReportedTime);
|
||||
state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance());
|
||||
state.setStrategy(strategySpy);
|
||||
|
||||
when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod();
|
||||
|
||||
@ -417,10 +384,7 @@ public class TransportActivityManagerTest {
|
||||
// THEN
|
||||
assertThat(updatedState).isSameAs(state);
|
||||
assertThat(updatedState.getLastRecordedTime()).isEqualTo(gwLastRecordedTime);
|
||||
assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime);
|
||||
assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo);
|
||||
assertThat(updatedState.getStrategy()).isEqualTo(strategySpy);
|
||||
verifyNoInteractions(strategySpy);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -449,14 +413,10 @@ public class TransportActivityManagerTest {
|
||||
sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock));
|
||||
|
||||
long lastRecordedTime = 123L;
|
||||
long lastReportedTime = 312L;
|
||||
ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy());
|
||||
|
||||
ActivityState<TransportProtos.SessionInfoProto> state = new ActivityState<>();
|
||||
state.setLastRecordedTime(lastRecordedTime);
|
||||
state.setLastReportedTime(lastReportedTime);
|
||||
state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance());
|
||||
state.setStrategy(strategySpy);
|
||||
|
||||
when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod();
|
||||
|
||||
@ -466,10 +426,7 @@ public class TransportActivityManagerTest {
|
||||
// THEN
|
||||
assertThat(updatedState).isSameAs(state);
|
||||
assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime);
|
||||
assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime);
|
||||
assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo);
|
||||
assertThat(updatedState.getStrategy()).isEqualTo(strategySpy);
|
||||
verifyNoInteractions(strategySpy);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user