diff --git a/pom.xml b/pom.xml index c0e56990dd..7f5395d7f5 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,7 @@ Copyright 2014-2015 CyberVision, Inc. 4.0.2.RELEASE 3.2.5.RELEASE Fowler-RELEASE + 1.1.2.RELEASE 2.8.1 1.2.0 4.3.11.Final @@ -804,6 +805,11 @@ Copyright 2014-2015 CyberVision, Inc. pom import + + org.springframework.retry + spring-retry + ${spring.retry.version} + com.couchbase.client java-client diff --git a/server/common/dao/pom.xml b/server/common/dao/pom.xml index 2eb6e659fd..7c93240e0a 100644 --- a/server/common/dao/pom.xml +++ b/server/common/dao/pom.xml @@ -83,6 +83,10 @@ org.springframework spring-aop + + org.springframework.retry + spring-retry + org.aspectj aspectjrt diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/EndpointService.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/EndpointService.java index 6db63c3f11..cb3b523497 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/EndpointService.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/EndpointService.java @@ -30,6 +30,9 @@ import org.kaaproject.kaa.common.dto.PageLinkDto; import org.kaaproject.kaa.common.dto.TopicListEntryDto; import org.kaaproject.kaa.common.dto.UpdateNotificationDto; +import org.kaaproject.kaa.server.common.dao.exception.KaaOptimisticLockingFailureException; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; /** * The interface Endpoint service. @@ -196,14 +199,17 @@ public interface EndpointService { * @param endpointUserId the endpoint user id * @param endpointAccessToken the endpoint access token * @return the endpoint profile dto - */ - EndpointProfileDto attachEndpointToUser(String endpointUserId, String endpointAccessToken); + */ + + @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 100), value = {KaaOptimisticLockingFailureException.class}) + EndpointProfileDto attachEndpointToUser(String endpointUserId, String endpointAccessToken) throws KaaOptimisticLockingFailureException; /** * Detach endpoint profile from user. * * @param detachEndpoint the detach endpoint */ + @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 100), value = {KaaOptimisticLockingFailureException.class}) void detachEndpointFromUser(EndpointProfileDto detachEndpoint); /** diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/lock/KaaOptimisticLockingFailureException.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/exception/KaaOptimisticLockingFailureException.java similarity index 88% rename from server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/lock/KaaOptimisticLockingFailureException.java rename to server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/exception/KaaOptimisticLockingFailureException.java index f39a81302f..a90566dd37 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/lock/KaaOptimisticLockingFailureException.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/exception/KaaOptimisticLockingFailureException.java @@ -13,13 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.kaaproject.kaa.server.common.dao.lock; + +package org.kaaproject.kaa.server.common.dao.exception; import org.springframework.dao.OptimisticLockingFailureException; public class KaaOptimisticLockingFailureException extends OptimisticLockingFailureException { - private static final long serialVersionUID = -6616568718875823310L; + private static final long serialVersionUID = 1985741897367919195L; public KaaOptimisticLockingFailureException(String msg, Throwable cause) { super(msg, cause); diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/impl/EndpointUserDao.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/impl/EndpointUserDao.java index f02c09004a..552eb47040 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/impl/EndpointUserDao.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/impl/EndpointUserDao.java @@ -70,4 +70,5 @@ public interface EndpointUserDao extends Dao * @return true, if successful */ boolean checkAccessToken(String externalUid, String tenantId, String accessToken); + } diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointConfiguration.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointConfiguration.java index 3e7ba30d4d..49836c9006 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointConfiguration.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointConfiguration.java @@ -16,7 +16,8 @@ package org.kaaproject.kaa.server.common.dao.model; import org.kaaproject.kaa.common.dto.EndpointConfigurationDto; +import org.kaaproject.kaa.common.dto.HasVersion; -public interface EndpointConfiguration extends ToDto{ +public interface EndpointConfiguration extends ToDto, HasVersion { } diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointNotification.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointNotification.java index 15d982d84e..8e6cc02cb9 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointNotification.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointNotification.java @@ -16,7 +16,8 @@ package org.kaaproject.kaa.server.common.dao.model; import org.kaaproject.kaa.common.dto.EndpointNotificationDto; +import org.kaaproject.kaa.common.dto.HasVersion; -public interface EndpointNotification extends ToDto{ +public interface EndpointNotification extends ToDto, HasVersion { } diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointProfile.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointProfile.java index 6a03d29f2c..93f75af94c 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointProfile.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointProfile.java @@ -18,8 +18,9 @@ import java.util.List; import org.kaaproject.kaa.common.dto.EndpointProfileDto; +import org.kaaproject.kaa.common.dto.HasVersion; -public interface EndpointProfile extends ToDto{ +public interface EndpointProfile extends ToDto, HasVersion { byte[] getEndpointKey(); diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointUser.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointUser.java index 3be88342fd..010ba2cac4 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointUser.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointUser.java @@ -18,8 +18,9 @@ import java.util.List; import org.kaaproject.kaa.common.dto.EndpointUserDto; +import org.kaaproject.kaa.common.dto.HasVersion; -public interface EndpointUser extends ToDto{ +public interface EndpointUser extends ToDto, HasVersion { List getEndpointIds(); diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointUserConfiguration.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointUserConfiguration.java index 0b56fdf80c..8e807b12c1 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointUserConfiguration.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/EndpointUserConfiguration.java @@ -16,8 +16,9 @@ package org.kaaproject.kaa.server.common.dao.model; import org.kaaproject.kaa.common.dto.EndpointUserConfigurationDto; +import org.kaaproject.kaa.common.dto.HasVersion; -public interface EndpointUserConfiguration extends ToDto { +public interface EndpointUserConfiguration extends ToDto, HasVersion { String getUserId(); diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/Notification.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/Notification.java index 0d19f19106..a4920695ff 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/Notification.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/Notification.java @@ -15,8 +15,9 @@ */ package org.kaaproject.kaa.server.common.dao.model; +import org.kaaproject.kaa.common.dto.HasVersion; import org.kaaproject.kaa.common.dto.NotificationDto; -public interface Notification extends ToDto{ +public interface Notification extends ToDto, HasVersion { } diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/TopicListEntry.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/TopicListEntry.java index 11093a982a..3c9c338cc1 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/TopicListEntry.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/model/TopicListEntry.java @@ -15,11 +15,12 @@ */ package org.kaaproject.kaa.server.common.dao.model; +import org.kaaproject.kaa.common.dto.HasVersion; import org.kaaproject.kaa.common.dto.TopicListEntryDto; import java.util.List; -public interface TopicListEntry extends ToDto { +public interface TopicListEntry extends ToDto, HasVersion { List getTopicIds(); } diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/service/EndpointServiceImpl.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/service/EndpointServiceImpl.java index 4bfcec887d..4ade5a7f21 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/service/EndpointServiceImpl.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/service/EndpointServiceImpl.java @@ -28,6 +28,7 @@ import static org.kaaproject.kaa.server.common.dao.service.Validator.validateString; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.apache.commons.lang.StringUtils; @@ -54,23 +55,19 @@ import org.kaaproject.kaa.server.common.dao.ServerProfileService; import org.kaaproject.kaa.server.common.dao.exception.DatabaseProcessingException; import org.kaaproject.kaa.server.common.dao.exception.IncorrectParameterException; -import org.kaaproject.kaa.server.common.dao.impl.ConfigurationDao; +import org.kaaproject.kaa.server.common.dao.exception.KaaOptimisticLockingFailureException; import org.kaaproject.kaa.server.common.dao.impl.EndpointConfigurationDao; import org.kaaproject.kaa.server.common.dao.impl.EndpointGroupDao; import org.kaaproject.kaa.server.common.dao.impl.EndpointProfileDao; import org.kaaproject.kaa.server.common.dao.impl.EndpointUserDao; -import org.kaaproject.kaa.server.common.dao.impl.ProfileFilterDao; import org.kaaproject.kaa.server.common.dao.impl.TopicDao; import org.kaaproject.kaa.server.common.dao.impl.TopicListEntryDao; -import org.kaaproject.kaa.server.common.dao.lock.KaaOptimisticLockingFailureException; import org.kaaproject.kaa.server.common.dao.model.EndpointConfiguration; import org.kaaproject.kaa.server.common.dao.model.EndpointProfile; import org.kaaproject.kaa.server.common.dao.model.EndpointUser; import org.kaaproject.kaa.server.common.dao.model.TopicListEntry; -import org.kaaproject.kaa.server.common.dao.model.sql.Configuration; import org.kaaproject.kaa.server.common.dao.model.sql.EndpointGroup; import org.kaaproject.kaa.server.common.dao.model.sql.ModelUtils; -import org.kaaproject.kaa.server.common.dao.model.sql.ProfileFilter; import org.kaaproject.kaa.server.common.dao.model.sql.Topic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,12 +84,6 @@ public class EndpointServiceImpl implements EndpointService { @Autowired private EndpointGroupDao endpointGroupDao; @Autowired - private ConfigurationDao configurationDao; - @Autowired - private ProfileFilterDao profileFilterDao; - @Autowired - private ProfileFilterDao verifierDao; - @Autowired private HistoryService historyService; @Autowired private ServerProfileService serverProfileService; @@ -282,7 +273,6 @@ public void removeEndpointProfileByAppId(String appId) { @Override public EndpointProfileDto saveEndpointProfile(EndpointProfileDto endpointProfileDto) throws KaaOptimisticLockingFailureException { - EndpointProfileDto profileDto = null; validateObject(endpointProfileDto, "Can't save endpoint profile object. Invalid endpoint profile object " + endpointProfileDto); byte[] keyHash = endpointProfileDto.getEndpointKeyHash(); validateHash(keyHash, "Incorrect key hash for endpoint profile."); @@ -293,15 +283,27 @@ public EndpointProfileDto saveEndpointProfile(EndpointProfileDto endpointProfile endpointProfileDto.setServerProfileVersion(serverProfileSchemaDto.getVersion()); endpointProfileDto.setServerProfileBody(schemaDto.getDefaultRecord()); } + EndpointProfileDto dto; if (isBlank(endpointProfileDto.getId())) { - EndpointProfile storedProfile = endpointProfileDao.findEndpointIdByKeyHash(keyHash); - if (storedProfile != null) { - endpointProfileDto.setId(storedProfile.getId()); - LOG.debug("Register new endpoint profile."); + EndpointProfile storedProfile = endpointProfileDao.findByKeyHash(keyHash); + if (storedProfile == null) { + dto = getDto(endpointProfileDao.save(endpointProfileDto)); + } else { + if (Arrays.equals(storedProfile.getEndpointKey(), endpointProfileDto.getEndpointKey())) { + LOG.debug("Got register profile for already existing profile {}. Will overwrite existing profile!", keyHash); + endpointProfileDto.setId(storedProfile.getId()); + endpointProfileDto.setVersion(storedProfile.getVersion()); + dto = getDto(endpointProfileDao.save(endpointProfileDto)); + } else { + LOG.warn("Endpoint profile with key hash {} already exists.", keyHash); + throw new DatabaseProcessingException("Can't save endpoint profile with existing key hash."); + } } + } else { + LOG.debug("Update endpoint profile with id [{}]", endpointProfileDto.getId()); + dto = getDto(endpointProfileDao.save(endpointProfileDto)); } - profileDto = getDto(endpointProfileDao.save(endpointProfileDto)); - return profileDto; + return dto; } @Override @@ -322,14 +324,14 @@ public EndpointProfileDto attachEndpointToUser(String userExternalId, String ten endpointUser.setEndpointIds(endpointIds); } endpointIds.add(profile.getId()); - endpointUserDao.save(endpointUser); + endpointUser = endpointUserDao.save(endpointUser); profile.setEndpointUserId(endpointUser.getId()); LOG.trace("Save endpoint user {} and endpoint profile {}", endpointUser, profile); return saveEndpointProfile(profile); } - - @Override - public EndpointProfileDto attachEndpointToUser(String endpointUserId, String endpointAccessToken) { + + @Override + public EndpointProfileDto attachEndpointToUser(String endpointUserId, String endpointAccessToken) throws KaaOptimisticLockingFailureException { LOG.info("Try to attach endpoint with access token {} to user with {}", endpointAccessToken, endpointUserId); validateString(endpointUserId, "Incorrect endpointUserId " + endpointUserId); EndpointUser endpointUser = endpointUserDao.findById(endpointUserId); @@ -339,14 +341,18 @@ public EndpointProfileDto attachEndpointToUser(String endpointUserId, String end LOG.trace("[{}] Found endpoint profile by with access token {} ", endpointAccessToken, endpoint); if (endpoint != null) { if (endpoint.getEndpointUserId() == null || endpointUserId.equals(endpoint.getEndpointUserId())) { + LOG.debug("Attach endpoint profile with id {} to endpoint user with id {} ", endpoint.getId(), endpointUser.getId()); List endpointIds = endpointUser.getEndpointIds(); + if (endpointIds != null && endpointIds.contains(endpoint.getId())) { + LOG.warn("Endpoint is already assigned to current user {}. Unassign it first!.", endpoint.getEndpointUserId()); + throw new DatabaseProcessingException("Endpoint is already assigned to current user."); + } if (endpointIds == null) { endpointIds = new ArrayList<>(); endpointUser.setEndpointIds(endpointIds); } - LOG.debug("Attach endpoint profile with id {} to endpoint user with id {} ", endpoint.getId(), endpointUser.getId()); endpointIds.add(endpoint.getId()); - endpointUserDao.save(endpointUser); + endpointUser = endpointUserDao.save(endpointUser); endpoint.setEndpointUserId(endpointUser.getId()); endpoint = endpointProfileDao.save(endpoint); return getDto(endpoint); @@ -371,8 +377,11 @@ public void detachEndpointFromUser(EndpointProfileDto detachEndpoint) { EndpointUser endpointUser = endpointUserDao.findById(endpointUserId); if (endpointUser != null) { List endpointIds = endpointUser.getEndpointIds(); - if (endpointIds != null) { + if (endpointIds != null && endpointIds.contains(detachEndpoint.getId())) { endpointIds.remove(detachEndpoint.getId()); + } else { + LOG.warn("Endpoint is not assigned to current user {}!", endpointUserId); + throw new DatabaseProcessingException("Endpoint is not assigned to current user."); } endpointUserDao.save(endpointUser); detachEndpoint.setEndpointUserId(null); diff --git a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/service/NotificationServiceImpl.java b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/service/NotificationServiceImpl.java index d168544278..352bd10149 100644 --- a/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/service/NotificationServiceImpl.java +++ b/server/common/dao/src/main/java/org/kaaproject/kaa/server/common/dao/service/NotificationServiceImpl.java @@ -126,7 +126,7 @@ public UpdateNotificationDto saveNotification(NotificationDto d if (isNotBlank(schemaId) && isNotBlank(topicId)) { NotificationSchema schema = notificationSchemaDao.findById(schemaId); if (schema != null) { - dto.setVersion(schema.getVersion()); + dto.setNfVersion(schema.getVersion()); dto.setApplicationId(schema.getApplicationId()); dto.setType(schema.getType()); } else { @@ -290,7 +290,7 @@ public UpdateNotificationDto saveUnicastNotification(En notificationDto.setSecNum(-1); NotificationSchema schema = notificationSchemaDao.findById(schemaId); if (schema != null) { - notificationDto.setVersion(schema.getVersion()); + notificationDto.setNfVersion(schema.getVersion()); notificationDto.setApplicationId(schema.getApplicationId()); notificationDto.setType(schema.getType()); try { diff --git a/server/common/dao/src/main/resources/common-dao-context.xml b/server/common/dao/src/main/resources/common-dao-context.xml index e86ab1340d..33c07acb72 100644 --- a/server/common/dao/src/main/resources/common-dao-context.xml +++ b/server/common/dao/src/main/resources/common-dao-context.xml @@ -29,7 +29,9 @@ http://www.springframework.org/schema/util/spring-util-3.0.xsd"> - + + + diff --git a/server/common/dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/EndpointServiceImplTest.java b/server/common/dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/EndpointServiceImplTest.java index 374dd3f514..e0fe582b64 100644 --- a/server/common/dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/EndpointServiceImplTest.java +++ b/server/common/dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/EndpointServiceImplTest.java @@ -18,7 +18,14 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import org.junit.Assert; import org.junit.Ignore; @@ -35,11 +42,17 @@ import org.kaaproject.kaa.common.dto.TopicDto; import org.kaaproject.kaa.common.dto.TopicListEntryDto; import org.kaaproject.kaa.common.dto.TopicTypeDto; -import org.kaaproject.kaa.server.common.dao.exception.IncorrectParameterException; import org.kaaproject.kaa.server.common.dao.AbstractTest; +import org.kaaproject.kaa.server.common.dao.exception.IncorrectParameterException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Ignore("This test should be extended and initialized with proper context in each NoSQL submodule") public class EndpointServiceImplTest extends AbstractTest { + + private static final Logger LOG = LoggerFactory.getLogger(EndpointServiceImplTest.class); + + private ExecutorService executorService = Executors.newFixedThreadPool(10); private static final String INCORRECT_ID = "incorrect id"; private static final String DEFAULT_LIMIT = "1"; @@ -200,6 +213,7 @@ public void generateEndpointUserAccessTokenTest() { Assert.assertEquals(generatedAccessToken, endpointUser.getAccessToken()); } + @Test public void findTopicListEntryByHashTest() { ApplicationDto applicationDto = generateApplicationDto(); @@ -212,4 +226,98 @@ public void findTopicListEntryByHashTest() { TopicListEntryDto foundTopicListEntry = endpointService.findTopicListEntryByHash(hash); Assert.assertEquals(topicListEntryDto, foundTopicListEntry); } + + @Test + public void attchEndpointToUserTest() { + TenantDto tenantDto = generateTenantDto(); + EndpointUserDto endpointUserDto = generateEndpointUserDto(tenantDto.getId()); + String endpointGroupId = "124"; + EndpointProfileDto endpointProfileDto = generateEndpointProfileWithGroupIdDto(endpointGroupId); + String accessToken = "1111"; + endpointProfileDto.setAccessToken(accessToken); + endpointService.saveEndpointProfile(endpointProfileDto); + endpointService.attachEndpointToUser(endpointUserDto.getId(), accessToken); + endpointUserDto = endpointService.findEndpointUserById(endpointUserDto.getId()); + List endpointIds = endpointUserDto.getEndpointIds(); + Assert.assertNotNull(endpointIds); + Assert.assertEquals(1, endpointIds.size()); + Assert.assertEquals(endpointProfileDto.getId(), endpointIds.get(0)); + } + + @Test + @Ignore + public void multiThreadAttachDetachEndpointToUserTest() throws InterruptedException, ExecutionException { + TenantDto tenantDto = generateTenantDto(); + EndpointUserDto endpointUserDto = generateEndpointUserDto(tenantDto.getId()); + String endpointGroupId = "124"; + List accessTokens = new ArrayList<>(); + List endpointIds = new ArrayList(); + for (int i = 0; i < 100; i++) { + EndpointProfileDto endpointProfileDto = generateEndpointProfileWithGroupIdDto(endpointGroupId); + String accessToken = "" + i; + endpointProfileDto.setAccessToken(accessToken); + endpointService.saveEndpointProfile(endpointProfileDto); + accessTokens.add(accessToken); + endpointIds.add(endpointProfileDto.getId()); + } + List> list = new ArrayList<>(); + final String endpointUserId = endpointUserDto.getId(); + for (int i = 0; i < accessTokens.size(); i++) { + final String accessToken = accessTokens.get(i); + list.add(executorService.submit(new Callable() { + @Override + public EndpointProfileDto call() { + EndpointProfileDto ep = null; + try { + ep = endpointService.attachEndpointToUser(endpointUserId, accessToken); + } catch (Throwable t) { + LOG.error("Error: " + t.getClass() + ": " + t.getMessage() + ". accessToken = " + accessToken); + throw t; + } + return ep; + } + })); + } + + Iterator> iterator = list.iterator(); + List attachedProfiles = new ArrayList<>(); + while (iterator.hasNext()) { + Future f = iterator.next(); + attachedProfiles.add(f.get()); + iterator.remove(); + } + endpointUserDto = endpointService.findEndpointUserById(endpointUserId); + List attachedEndpointIds = endpointUserDto.getEndpointIds(); + Assert.assertNotNull(attachedEndpointIds); + Collections.sort(endpointIds); + Collections.sort(attachedEndpointIds); + Assert.assertEquals(endpointIds, attachedEndpointIds); + + List> detachFutureList = new ArrayList<>(); + for (int i = 0; i < attachedProfiles.size(); i++) { + final EndpointProfileDto attachedProfile = attachedProfiles.get(i); + detachFutureList.add(executorService.submit(new Callable() { + @Override + public Void call() { + try { + endpointService.detachEndpointFromUser(attachedProfile); + } catch (Throwable t) { + LOG.error("Error: " + t.getMessage(), t); + throw t; + } + return null; + } + })); + } + Iterator> detachIterator = detachFutureList.iterator(); + while (detachIterator.hasNext()) { + Future f = detachIterator.next(); + while (!f.isDone()) { + } + detachIterator.remove(); + } + endpointUserDto = endpointService.findEndpointUserById(endpointUserId); + attachedEndpointIds = endpointUserDto.getEndpointIds(); + Assert.assertTrue(attachedEndpointIds == null || attachedEndpointIds.isEmpty()); + } } diff --git a/server/common/dao/src/test/resources/common-dao-test-context.xml b/server/common/dao/src/test/resources/common-dao-test-context.xml index 605403a021..8cb952b333 100644 --- a/server/common/dao/src/test/resources/common-dao-test-context.xml +++ b/server/common/dao/src/test/resources/common-dao-test-context.xml @@ -34,6 +34,8 @@ http://www.springframework.org/schema/util/spring-util-3.0.xsd"> + + diff --git a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointConfigurationDto.java b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointConfigurationDto.java index 6b04718976..1ef3e561ae 100644 --- a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointConfigurationDto.java +++ b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointConfigurationDto.java @@ -21,12 +21,13 @@ import static org.kaaproject.kaa.common.dto.Util.getArrayCopy; -public class EndpointConfigurationDto implements Serializable { +public class EndpointConfigurationDto implements HasVersion, Serializable { private static final long serialVersionUID = 5662111748223086520L; private byte[] configurationHash; private byte[] configuration; + private Long version; public byte[] getConfigurationHash() { return configurationHash; @@ -75,4 +76,14 @@ public String toString() { ", configuration=" + Arrays.toString(configuration) + '}'; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } } diff --git a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointNotificationDto.java b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointNotificationDto.java index afa7e79890..d4e33029a4 100644 --- a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointNotificationDto.java +++ b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointNotificationDto.java @@ -23,13 +23,14 @@ import static org.kaaproject.kaa.common.dto.Util.getArrayCopy; -public class EndpointNotificationDto implements HasId, Serializable { +public class EndpointNotificationDto implements HasId, HasVersion, Serializable { private static final long serialVersionUID = -5548269571722364843L; private String id; private byte[] endpointKeyHash; private NotificationDto notificationDto; + private Long version; public String getId() { return id; @@ -54,6 +55,16 @@ public byte[] getEndpointKeyHash() { public void setEndpointKeyHash(byte[] endpointKeyHash) { this.endpointKeyHash = getArrayCopy(endpointKeyHash); } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public boolean equals(Object o) { diff --git a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointProfileDto.java b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointProfileDto.java index 61248aec80..cd84348ef2 100644 --- a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointProfileDto.java +++ b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointProfileDto.java @@ -24,7 +24,10 @@ import java.util.Collections; import java.util.List; -public class EndpointProfileDto implements HasId, Serializable { +import static org.kaaproject.kaa.common.dto.Util.getArrayCopy; + +public class EndpointProfileDto implements HasId, HasVersion, Serializable { + private static final List EMPTY_GROUP_STATE = Collections.unmodifiableList(new ArrayList<>()); @@ -56,7 +59,8 @@ public class EndpointProfileDto implements HasId, Serializable { private List ecfVersionStates; private String serverHash; private String sdkToken; - + private Long version; + @Override public String getId() { return id; @@ -270,6 +274,16 @@ public String getSdkToken() { public void setSdkToken(String sdkToken) { this.sdkToken = sdkToken; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public boolean equals(Object o) { diff --git a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointUserConfigurationDto.java b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointUserConfigurationDto.java index 707e13bcb3..e4ce6c098b 100644 --- a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointUserConfigurationDto.java +++ b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointUserConfigurationDto.java @@ -17,7 +17,7 @@ import java.io.Serializable; -public class EndpointUserConfigurationDto implements Serializable { +public class EndpointUserConfigurationDto implements HasVersion, Serializable { private static final long serialVersionUID = -1463982688020241482L; @@ -25,6 +25,7 @@ public class EndpointUserConfigurationDto implements Serializable { private String appToken; private Integer schemaVersion; private String body; + private Long version; public String getUserId() { return userId; @@ -57,6 +58,16 @@ public String getBody() { public void setBody(String body) { this.body = body; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public boolean equals(Object o) { diff --git a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointUserDto.java b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointUserDto.java index a0f46e5f24..73d1999baa 100644 --- a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointUserDto.java +++ b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/EndpointUserDto.java @@ -18,7 +18,7 @@ import java.io.Serializable; import java.util.List; -public class EndpointUserDto implements HasId, Serializable{ +public class EndpointUserDto implements HasId, HasVersion, Serializable{ private static final long serialVersionUID = 8228053998621647905L; private String id; @@ -27,6 +27,7 @@ public class EndpointUserDto implements HasId, Serializable{ private String username; private String accessToken; private List endpointIds; + private Long version; @Override public String getId() { @@ -77,6 +78,16 @@ public List getEndpointIds() { public void setEndpointIds(List endpointIds) { this.endpointIds = endpointIds; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public int hashCode() { diff --git a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/HasVersion.java b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/HasVersion.java new file mode 100644 index 0000000000..6e47974f29 --- /dev/null +++ b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/HasVersion.java @@ -0,0 +1,38 @@ +/* + * Copyright 2014-2016 CyberVision, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This interface is marker which indicate that object has Long version. + */ +package org.kaaproject.kaa.common.dto; + +public interface HasVersion { + + /** + * This method return long version + * + * @return long version + */ + Long getVersion(); + + /** + * This is method set long version + * + * @param version long version + */ + void setVersion(Long version); + +} diff --git a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/NotificationDto.java b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/NotificationDto.java index db8b4a97a0..47bb3b65e4 100644 --- a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/NotificationDto.java +++ b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/NotificationDto.java @@ -20,7 +20,7 @@ import java.util.Arrays; import java.util.Date; -public class NotificationDto implements Serializable, HasId { +public class NotificationDto implements HasId, HasVersion, Serializable { private static final long serialVersionUID = -4470699717187588732L; @@ -28,13 +28,14 @@ public class NotificationDto implements Serializable, HasId { private String applicationId; private String schemaId; private String topicId; - private int version; + private int nfVersion; private Date lastTimeModify; private NotificationTypeDto type; private byte[] body; private Date expiredAt; private int secNum = -1; - + private Long version; + public String getId() { return id; } @@ -67,12 +68,12 @@ public void setTopicId(String topicId) { this.topicId = topicId; } - public int getVersion() { - return version; + public int getNfVersion() { + return nfVersion; } - public void setVersion(int version) { - this.version = version; + public void setNfVersion(int nfVersion) { + this.nfVersion = nfVersion; } public Date getLastTimeModify() { @@ -115,6 +116,16 @@ public void setSecNum(int secNum) { this.secNum = secNum; } + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -129,7 +140,7 @@ public boolean equals(Object o) { if (secNum != that.secNum) { return false; } - if (version != that.version) { + if (nfVersion != that.nfVersion) { return false; } if (applicationId != null ? !applicationId.equals(that.applicationId) : that.applicationId != null) { @@ -162,7 +173,7 @@ public int hashCode() { int result = applicationId != null ? applicationId.hashCode() : 0; result = 31 * result + (schemaId != null ? schemaId.hashCode() : 0); result = 31 * result + (topicId != null ? topicId.hashCode() : 0); - result = 31 * result + version; + result = 31 * result + nfVersion; result = 31 * result + (lastTimeModify != null ? lastTimeModify.hashCode() : 0); result = 31 * result + (type != null ? type.hashCode() : 0); result = 31 * result + (body != null ? Arrays.hashCode(body) : 0); @@ -178,7 +189,7 @@ public String toString() { ", applicationId='" + applicationId + '\'' + ", schemaId='" + schemaId + '\'' + ", topicId='" + topicId + '\'' + - ", version=" + version + + ", nfVersion=" + nfVersion + ", lastTimeModify=" + lastTimeModify + ", type=" + type + ", body=" + Arrays.toString(body) + diff --git a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/TopicListEntryDto.java b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/TopicListEntryDto.java index 1efba44438..0cd2c1a488 100644 --- a/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/TopicListEntryDto.java +++ b/server/common/dto/src/main/java/org/kaaproject/kaa/common/dto/TopicListEntryDto.java @@ -20,7 +20,7 @@ import java.util.Arrays; import java.util.List; -public final class TopicListEntryDto implements Serializable { +public final class TopicListEntryDto implements HasVersion, Serializable { private static final long serialVersionUID = 2771583997490244417L; @@ -30,6 +30,8 @@ public final class TopicListEntryDto implements Serializable { private List topics; + private Long version; + public TopicListEntryDto(int simpleHash, byte[] hash, List topics) { this.simpleHash = simpleHash; this.hash = hash; @@ -60,6 +62,16 @@ public void setTopics(List topics) { this.topics = topics; } + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/AbstractCassandraDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/AbstractCassandraDao.java index 83d08dd855..3d9312a74d 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/AbstractCassandraDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/AbstractCassandraDao.java @@ -16,26 +16,40 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao; +import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; +import static com.datastax.driver.core.querybuilder.QueryBuilder.select; +import static com.datastax.driver.core.querybuilder.QueryBuilder.set; +import static com.datastax.driver.core.querybuilder.QueryBuilder.update; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.kaaproject.kaa.common.dto.HasVersion; +import org.kaaproject.kaa.server.common.dao.exception.KaaOptimisticLockingFailureException; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.client.CassandraClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; + import com.datastax.driver.core.BatchStatement; import com.datastax.driver.core.ConsistencyLevel; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Session; import com.datastax.driver.core.Statement; import com.datastax.driver.core.UserType; +import com.datastax.driver.core.querybuilder.Assignment; +import com.datastax.driver.core.querybuilder.Clause; import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; +import com.datastax.driver.core.querybuilder.Update; +import com.datastax.driver.core.querybuilder.Update.Assignments; import com.datastax.driver.mapping.Mapper; import com.datastax.driver.mapping.Result; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.client.CassandraClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -public abstract class AbstractCassandraDao { +public abstract class AbstractCassandraDao { private static final Logger LOG = LoggerFactory.getLogger(AbstractCassandraDao.class); private static final String KAA = "kaa"; @@ -114,22 +128,47 @@ protected Statement getSaveQuery(T dto) { return mapper.saveQuery(dto); } - public T save(T dto) { - LOG.debug("Save entity {}", dto); - Statement saveStatement = getSaveQuery(dto); - saveStatement.setConsistencyLevel(getWriteConsistencyLevel()); - execute(saveStatement); - return dto; + public T save(T entity) { + if (entity.getVersion() == null) { + entity.setVersion(0l); + LOG.debug("Save entity {}", entity); + Statement saveStatement = getSaveQuery(entity); + saveStatement.setConsistencyLevel(getWriteConsistencyLevel()); + execute(saveStatement); + return entity; + } else { + LOG.debug("Update entity {}", entity); + return updateLocked(entity); + } } - protected boolean wasApplied(ResultSet resultSet) { - boolean result = false; - if (resultSet != null) { - if (resultSet.wasApplied()) { - result = true; + protected abstract T updateLocked(T entity); + + protected T updateLockedImpl(Long version, Assignment[] assignments, Clause... whereClauses) { + version = (version == null) ? 0l : version; + Assignments assigns = update(getColumnFamilyName()).onlyIf(eq(OPT_LOCK, version)).with(set(OPT_LOCK, version + 1)); + for (Assignment assignment : assignments) { + assigns = assigns.and(assignment); + } + Update.Where query = assigns.where(whereClauses[0]); + if (whereClauses.length > 1) { + for (int i = 1; i < whereClauses.length; i++) { + query = query.and(whereClauses[i]); + } + } + ResultSet res = execute(query); + if (!res.wasApplied()) { + LOG.error("[{}] Can't update entity with version {}. Entity already changed!", getColumnFamilyClass(), version); + throw new KaaOptimisticLockingFailureException("Can't update entity with version " + version + ". Entity already changed!"); + } else { + Select.Where where = select().from(getColumnFamilyName()).where(whereClauses[0]); + if (whereClauses.length > 1) { + for (int i = 1; i < whereClauses.length; i++) { + where = where.and(whereClauses[i]); + } } + return findOneByStatement(where); } - return result; } protected void executeBatch(BatchStatement batch) { diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointConfigurationCassandraDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointConfigurationCassandraDao.java index b6a8d6dc8e..714b983387 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointConfigurationCassandraDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointConfigurationCassandraDao.java @@ -16,6 +16,17 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao; +import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; +import static com.datastax.driver.core.querybuilder.QueryBuilder.set; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getByteBuffer; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getBytes; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ENDPOINT_CONFIGURATION_COLUMN_FAMILY_NAME; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ENDPOINT_CONFIGURATION_CONF_HASH_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ENDPOINT_CONFIGURATION_CONF_ID_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ENDPOINT_CONFIGURATION_CONF_PROPERTY; + +import java.nio.ByteBuffer; + import org.kaaproject.kaa.common.dto.EndpointConfigurationDto; import org.kaaproject.kaa.server.common.dao.impl.EndpointConfigurationDao; import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEndpointConfiguration; @@ -23,11 +34,7 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Repository; -import java.nio.ByteBuffer; - -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getByteBuffer; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getBytes; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ENDPOINT_CONFIGURATION_COLUMN_FAMILY_NAME; +import com.datastax.driver.core.querybuilder.Assignment; @Repository(value = "endpointConfigurationDao") public class EndpointConfigurationCassandraDao extends AbstractCassandraDao implements EndpointConfigurationDao { @@ -43,6 +50,16 @@ protected Class getColumnFamilyClass() { protected String getColumnFamilyName() { return ENDPOINT_CONFIGURATION_COLUMN_FAMILY_NAME; } + + @Override + protected CassandraEndpointConfiguration updateLocked( + CassandraEndpointConfiguration entity) { + return updateLockedImpl(entity.getVersion(), + new Assignment[]{set(ENDPOINT_CONFIGURATION_CONF_PROPERTY, entity.getConfiguration()), + set(ENDPOINT_CONFIGURATION_CONF_ID_PROPERTY, entity.getId())}, + eq(ENDPOINT_CONFIGURATION_CONF_HASH_PROPERTY, getByteBuffer(getBytes(entity.getConfigurationHash()))) + ); + } @Override public CassandraEndpointConfiguration findByHash(final byte[] hash) { @@ -80,4 +97,6 @@ public void removeById(ByteBuffer key) { removeByHash(getBytes(key)); } } + + } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointNotificationCassandraDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointNotificationCassandraDao.java index d790cf9ebe..069139cebc 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointNotificationCassandraDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointNotificationCassandraDao.java @@ -16,9 +16,27 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao; -import com.datastax.driver.core.Statement; -import com.datastax.driver.core.querybuilder.QueryBuilder; -import com.datastax.driver.core.querybuilder.Select; +import static com.datastax.driver.core.querybuilder.QueryBuilder.delete; +import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; +import static com.datastax.driver.core.querybuilder.QueryBuilder.select; +import static com.datastax.driver.core.querybuilder.QueryBuilder.set; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getByteBuffer; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_APPLICATION_ID_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_BODY_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_COLUMN_FAMILY_NAME; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_ENDPOINT_KEY_HASH_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_EXPIRED_AT_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_ID_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_LAST_MOD_TIME_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_NOTIFICATION_TYPE_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_SCHEMA_ID_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_SEQ_NUM_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_TOPIC_ID_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_VERSION_PROPERTY; + +import java.util.Collections; +import java.util.List; + import org.kaaproject.kaa.common.dto.EndpointNotificationDto; import org.kaaproject.kaa.server.common.dao.impl.EndpointNotificationDao; import org.kaaproject.kaa.server.common.nosql.cassandra.dao.filter.CassandraEPByAppIdDao; @@ -28,16 +46,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; -import java.util.Collections; -import java.util.List; - -import static com.datastax.driver.core.querybuilder.QueryBuilder.delete; -import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; -import static com.datastax.driver.core.querybuilder.QueryBuilder.select; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getByteBuffer; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_COLUMN_FAMILY_NAME; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_ENDPOINT_KEY_HASH_PROPERTY; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ET_NF_LAST_MOD_TIME_PROPERTY; +import com.datastax.driver.core.Statement; +import com.datastax.driver.core.querybuilder.Assignment; +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; @Repository(value = "unicastNotificationDao") public class EndpointNotificationCassandraDao extends AbstractCassandraDao implements EndpointNotificationDao { @@ -57,6 +69,27 @@ protected String getColumnFamilyName() { return ET_NF_COLUMN_FAMILY_NAME; } + @Override + protected CassandraEndpointNotification updateLocked( + CassandraEndpointNotification entity) { + return updateLockedImpl( + entity.getVersion(), + new Assignment[] { + set(ET_NF_ID_PROPERTY, entity.getId()), + set(ET_NF_SEQ_NUM_PROPERTY, entity.getSeqNum()), + set(ET_NF_NOTIFICATION_TYPE_PROPERTY, entity.getType().name()), + set(ET_NF_APPLICATION_ID_PROPERTY, + entity.getApplicationId()), + set(ET_NF_SCHEMA_ID_PROPERTY, entity.getSchemaId()), + set(ET_NF_VERSION_PROPERTY, entity.getNfVersion()), + set(ET_NF_BODY_PROPERTY, entity.getBody()), + set(ET_NF_EXPIRED_AT_PROPERTY, entity.getExpiredAt()), + set(ET_NF_TOPIC_ID_PROPERTY, entity.getTopicId()) }, + eq(ET_NF_ENDPOINT_KEY_HASH_PROPERTY, + entity.getEndpointKeyHash()), + eq(ET_NF_LAST_MOD_TIME_PROPERTY, entity.getLastModifyTime())); + } + @Override public List findNotificationsByKeyHash(byte[] keyHash) { LOG.debug("Try to find endpoint notifications by endpoint key hash {}", keyHash); @@ -113,4 +146,5 @@ public void removeById(String id) { execute(delete); LOG.debug("[{}] Execute query {}:", id, delete); } + } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointProfileCassandraDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointProfileCassandraDao.java index 2df9150247..d2898aa518 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointProfileCassandraDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointProfileCassandraDao.java @@ -16,61 +16,11 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao; -import com.datastax.driver.core.BoundStatement; -import com.datastax.driver.core.ConsistencyLevel; -import com.datastax.driver.core.PreparedStatement; -import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.Row; -import com.datastax.driver.core.Statement; -import com.datastax.driver.core.UserType; -import com.datastax.driver.core.querybuilder.QueryBuilder; -import com.google.common.base.Predicates; -import com.google.common.collect.Sets; -import org.apache.commons.codec.binary.Base64; -import org.kaaproject.kaa.common.dto.EndpointProfileBodyDto; -import org.kaaproject.kaa.common.dto.EndpointProfileDto; -import org.kaaproject.kaa.common.dto.EndpointProfilesBodyDto; -import org.kaaproject.kaa.common.dto.EndpointProfilesPageDto; -import org.kaaproject.kaa.common.dto.PageLinkDto; -import org.kaaproject.kaa.server.common.dao.DaoConstants; -import org.kaaproject.kaa.server.common.dao.exception.DatabaseProcessingException; -import org.kaaproject.kaa.server.common.dao.impl.EndpointProfileDao; -import org.kaaproject.kaa.server.common.dao.lock.KaaOptimisticLockingFailureException; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.filter.CassandraEPByAccessTokenDao; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.filter.CassandraEPByAppIdDao; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.filter.CassandraEPByEndpointGroupIdDao; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.filter.CassandraEPBySdkTokenDao; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEPByAccessToken; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEPByAppId; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEPByEndpointGroupId; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEPBySdkToken; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEndpointProfile; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEndpointUser; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.type.CassandraEndpointGroupState; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.type.CassandraEventClassFamilyVersionState; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Repository; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - import static com.datastax.driver.core.querybuilder.QueryBuilder.delete; import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; import static com.datastax.driver.core.querybuilder.QueryBuilder.in; import static com.datastax.driver.core.querybuilder.QueryBuilder.select; import static com.datastax.driver.core.querybuilder.QueryBuilder.set; -import static org.apache.commons.lang.StringUtils.isBlank; -import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.dao.impl.DaoUtil.getDto; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.convertKeyHashToString; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.convertStringToKeyHash; @@ -92,41 +42,85 @@ import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_BY_SDK_TOKEN_SDK_TOKEN_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_COLUMN_FAMILY_NAME; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_CONFIGURATION_VERSION_PROPERTY; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_GROUP_STATE_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_CONFIG_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_ECF_VERSION_STATE_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_ENDPOINT_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_EP_KEY_HASH_PROPERTY; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SEQUENCE_NUMBER_PROPERTY; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SIMPLE_TOPIC_HASH_PROPERTY; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_TOPIC_HASH_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_EP_KEY_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_GROUP_STATE_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_LOG_SCHEMA_VERSION_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_NOTIFICATION_VERSION_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_PROFILE_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_PROFILE_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_PROFILE_VERSION_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SDK_TOKEN_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SEQUENCE_NUMBER_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SERVER_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SERVER_PROFILE_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SERVER_PROFILE_VERSION_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SIMPLE_TOPIC_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SUBSCRIPTIONS_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SYSTEM_NOTIFICATION_VERSION_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_TOPIC_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_CONFIG_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_NOTIFICATION_VERSION_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EVENT_CLASS_FAMILY_VERSION_STATE_ECF_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EVENT_CLASS_FAMILY_VERSION_STATE_ECF_VERSION_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EVENT_CLASS_FAMILY_VERSION_STATE_USER_TYPE_NAME; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.VERSION_PROPERTY; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.apache.commons.codec.binary.Base64; +import org.kaaproject.kaa.common.dto.EndpointProfileBodyDto; +import org.kaaproject.kaa.common.dto.EndpointProfileDto; +import org.kaaproject.kaa.common.dto.EndpointProfilesBodyDto; +import org.kaaproject.kaa.common.dto.EndpointProfilesPageDto; +import org.kaaproject.kaa.common.dto.PageLinkDto; +import org.kaaproject.kaa.server.common.dao.DaoConstants; +import org.kaaproject.kaa.server.common.dao.exception.DatabaseProcessingException; +import org.kaaproject.kaa.server.common.dao.exception.KaaOptimisticLockingFailureException; +import org.kaaproject.kaa.server.common.dao.impl.EndpointProfileDao; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.filter.CassandraEPByAccessTokenDao; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.filter.CassandraEPByAppIdDao; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.filter.CassandraEPByEndpointGroupIdDao; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.filter.CassandraEPBySdkTokenDao; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEPByAccessToken; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEPByAppId; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEPByEndpointGroupId; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEPBySdkToken; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEndpointProfile; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEndpointUser; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.type.CassandraEndpointGroupState; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.type.CassandraEventClassFamilyVersionState; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import com.datastax.driver.core.ConsistencyLevel; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Statement; +import com.datastax.driver.core.UDTValue; +import com.datastax.driver.core.UserType; +import com.datastax.driver.core.querybuilder.Assignment; +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.google.common.base.Predicates; +import com.google.common.collect.Sets; + @Repository(value = "endpointProfileDao") public class EndpointProfileCassandraDao extends AbstractCassandraDao implements EndpointProfileDao { private static final Logger LOG = LoggerFactory.getLogger(EndpointProfileCassandraDao.class); - private static final String UPDATE_PROFILE = "UPDATE kaa.ep_profile SET ecf_ver_state=?, cf_hash=?, topic_hash=?, simple_topic_hash=?, group_state=?, " + - "srv_pf_ver=?, sys_nf_ver=?, seq_num=?, nf_ver=?, pf_ver=?, ucf_hash=?, server_hash=?, user_id=?, user_nf_ver=?, cf_ver=?, access_token=?, " + - " pf=?, srv_pf=?, subscs=?, opt_lock=? WHERE ep_key_hash=? "; - - private static final String IF_CONDITION = "IF opt_lock = "; - - private ConcurrentHashMap statements = new ConcurrentHashMap<>(); @Autowired private CassandraEPByAppIdDao cassandraEPByAppIdDao; @@ -151,16 +145,63 @@ protected String getColumnFamilyName() { @Override public CassandraEndpointProfile save(EndpointProfileDto dto) { - if (isBlank(dto.getId())) { - return save(new CassandraEndpointProfile(dto)); + CassandraEndpointProfile endpointProfile = new CassandraEndpointProfile(dto); + return save(endpointProfile); + } + + @Override + public CassandraEndpointProfile save(CassandraEndpointProfile endpointProfile) { + if (endpointProfile.getVersion() == null) { + return saveProfile(endpointProfile); } else { - return update(new CassandraEndpointProfile(dto)); + return updateProfile(endpointProfile); } } - + @Override - public CassandraEndpointProfile save(CassandraEndpointProfile profile) { + protected CassandraEndpointProfile updateLocked( + CassandraEndpointProfile entity) { + return updateLockedImpl( + entity.getVersion(), + new Assignment[] {set(EP_ECF_VERSION_STATE_PROPERTY, convertEventStateToUDT(entity.getEcfVersionStates())), + set(EP_CONFIG_HASH_PROPERTY, entity.getConfigurationHash()), + set(EP_GROUP_STATE_PROPERTY, convertGroupStateToUDT(entity.getGroupStates())), + set(EP_SEQUENCE_NUMBER_PROPERTY, entity.getSequenceNumber()), + set(EP_SERVER_PROFILE_VERSION_PROPERTY, entity.getServerProfileVersion()), + set(EP_SYSTEM_NOTIFICATION_VERSION_PROPERTY, entity.getSystemNfVersion()), + set(EP_NOTIFICATION_VERSION_PROPERTY, entity.getNotificationVersion()), + set(EP_PROFILE_VERSION_PROPERTY, entity.getProfileVersion()), + set(EP_USER_CONFIG_HASH_PROPERTY, entity.getUserConfigurationHash()), + set(EP_SERVER_HASH_PROPERTY, entity.getServerHash()), + set(EP_USER_ID_PROPERTY, entity.getEndpointUserId()), + set(EP_USER_NOTIFICATION_VERSION_PROPERTY, entity.getUserNfVersion()), + set(EP_CONFIGURATION_VERSION_PROPERTY, entity.getConfigurationVersion()), + set(EP_ACCESS_TOKEN_PROPERTY, entity.getAccessToken()), + set(EP_PROFILE_PROPERTY, entity.getProfile()), + set(EP_SERVER_PROFILE_PROPERTY, entity.getServerProfile()), + set(EP_SUBSCRIPTIONS_PROPERTY, entity.getSubscriptions()), + set(EP_LOG_SCHEMA_VERSION_PROPERTY, entity.getLogSchemaVersion()), + set(EP_APP_ID_PROPERTY, entity.getApplicationId()), + set(EP_EP_KEY_PROPERTY, entity.getEndpointProfileKey()), + set(EP_PROFILE_HASH_PROPERTY, entity.getProfileHash()), + set(EP_TOPIC_HASH_PROPERTY, entity.getTopicHash()), + set(EP_SIMPLE_TOPIC_HASH_PROPERTY, entity.getSimpleTopicHash()), + set(EP_SDK_TOKEN_PROPERTY, entity.getSdkToken()), + set(EP_ENDPOINT_ID_PROPERTY, entity.getId())}, + + eq(EP_EP_KEY_HASH_PROPERTY, entity.getEndpointKeyHash()) + + ); + } + + private CassandraEndpointProfile saveProfile(CassandraEndpointProfile profile) { + CassandraEndpointProfile storedProfile = findByKeyHash(getBytes(profile.getEndpointKeyHash())); profile.setId(convertKeyHashToString(profile.getEndpointKeyHash())); + if (storedProfile != null) { + LOG.error("[{}] Profile is already exists. Can't save endpoint profile.", profile.getId()); + throw new DatabaseProcessingException("Profile is already exists. Can't save endpoint profile."); + } + profile.setVersion(0l); LOG.debug("Saving endpoint profile with id {}", profile.getId()); ByteBuffer epKeyHash = profile.getEndpointKeyHash(); List statementList = new ArrayList<>(); @@ -181,59 +222,23 @@ public CassandraEndpointProfile save(CassandraEndpointProfile profile) { return profile; } - private BoundStatement prepareStatement(String q, CassandraEndpointProfile pf) { - StringBuilder sb = new StringBuilder(q); - sb.append(IF_CONDITION).append(pf.getVersion()).append(";"); - String query = sb.toString(); - LOG.info("Get version {}", pf.getVersion()); - LOG.debug("Prepared query {}", query); - PreparedStatement ps = statements.get(query); - if (ps == null) { - ps = getSession().prepare(query); - statements.put(query, ps); - } - BoundStatement bs = ps.bind(); - bs.setList(EP_ECF_VERSION_STATE_PROPERTY, convertEventStateToUDT(pf.getEcfVersionStates())); - bs.setBytes(EP_CONFIG_HASH_PROPERTY, pf.getConfigurationHash()); - bs.setBytes(EP_TOPIC_HASH_PROPERTY, pf.getTopicHash()); - bs.setInt(EP_SIMPLE_TOPIC_HASH_PROPERTY, pf.getSimpleTopicHash()); - bs.setList(EP_GROUP_STATE_PROPERTY, convertGroupStateToUDT(pf.getGroupStates())); - bs.setInt(EP_SEQUENCE_NUMBER_PROPERTY, pf.getSequenceNumber()); - bs.setInt(EP_SERVER_PROFILE_VERSION_PROPERTY, pf.getServerProfileVersion()); - bs.setInt(EP_SYSTEM_NOTIFICATION_VERSION_PROPERTY, pf.getSystemNfVersion()); - bs.setInt(EP_NOTIFICATION_VERSION_PROPERTY, pf.getNotificationVersion()); - bs.setInt(EP_PROFILE_VERSION_PROPERTY, pf.getProfileVersion()); - bs.setBytes(EP_USER_CONFIG_HASH_PROPERTY, pf.getUserConfigurationHash()); - bs.setString(EP_SERVER_HASH_PROPERTY, pf.getServerHash()); - bs.setString(EP_USER_ID_PROPERTY, pf.getEndpointUserId()); - bs.setInt(EP_USER_NOTIFICATION_VERSION_PROPERTY, pf.getUserNfVersion()); - bs.setInt(EP_CONFIGURATION_VERSION_PROPERTY, pf.getConfigurationVersion()); - bs.setString(EP_ACCESS_TOKEN_PROPERTY, pf.getAccessToken()); - bs.setString(EP_PROFILE_PROPERTY, pf.getProfile()); - bs.setString(EP_SERVER_PROFILE_PROPERTY, pf.getServerProfile()); - bs.setList(EP_SUBSCRIPTIONS_PROPERTY, pf.getSubscriptions()); - bs.setBytes(EP_EP_KEY_HASH_PROPERTY, pf.getEndpointKeyHash()); - bs.setLong(OPT_LOCK, pf.getVersion() + 1); - return bs; - } - - private CassandraEndpointProfile update(CassandraEndpointProfile profile) { + private CassandraEndpointProfile updateProfile(CassandraEndpointProfile profile) { LOG.debug("Updating endpoint profile with id {}", profile.getId()); ByteBuffer epKeyHash = profile.getEndpointKeyHash(); byte[] keyHash = getBytes(epKeyHash); CassandraEndpointProfile storedProfile = findByKeyHash(keyHash); if (storedProfile != null) { + profile = super.save(profile); List statementList = new ArrayList<>(); - BoundStatement bs = prepareStatement(UPDATE_PROFILE, profile); - if (wasApplied(execute(bs))) { - Set oldEndpointGroupIds = getEndpointProfilesGroupIdSet(storedProfile); - Set newEndpointGroupIds = getEndpointProfilesGroupIdSet(profile); - Set removeEndpointGroupIds = Sets.filter(oldEndpointGroupIds, Predicates.not(Predicates.in(newEndpointGroupIds))); - Set addEndpointGroupIds = Sets.filter(newEndpointGroupIds, Predicates.not(Predicates.in(oldEndpointGroupIds))); - if (addEndpointGroupIds != null) { - for (String id : addEndpointGroupIds) { - statementList.add(cassandraEPByEndpointGroupIdDao.getSaveQuery(new CassandraEPByEndpointGroupId(id, epKeyHash))); - } + + Set oldEndpointGroupIds = getEndpointProfilesGroupIdSet(storedProfile); + Set newEndpointGroupIds = getEndpointProfilesGroupIdSet(profile); + + Set removeEndpointGroupIds = Sets.filter(oldEndpointGroupIds, Predicates.not(Predicates.in(newEndpointGroupIds))); + Set addEndpointGroupIds = Sets.filter(newEndpointGroupIds, Predicates.not(Predicates.in(oldEndpointGroupIds))); + if (addEndpointGroupIds != null) { + for (String id : addEndpointGroupIds) { + statementList.add(cassandraEPByEndpointGroupIdDao.getSaveQuery(new CassandraEPByEndpointGroupId(id, epKeyHash))); } if (removeEndpointGroupIds != null) { for (String id : removeEndpointGroupIds) { @@ -247,6 +252,15 @@ private CassandraEndpointProfile update(CassandraEndpointProfile profile) { LOG.error("[{}] Can't update endpoint profile with version {}. Endpoint profile already changed!", profile.getId(), profile.getVersion()); throw new KaaOptimisticLockingFailureException("Can't update endpoint profile with version . Endpoint profile already changed!"); } + + String accessToken = profile.getAccessToken(); + if (storedProfile.getAccessToken() != null && !storedProfile.getAccessToken().equals(accessToken)) { + cassandraEPByAccessTokenDao.removeById(storedProfile.getAccessToken()); + } + if (accessToken != null) { + statementList.add(cassandraEPByAccessTokenDao.getSaveQuery(new CassandraEPByAccessToken(accessToken, epKeyHash))); + } + executeBatch(statementList.toArray(new Statement[statementList.size()])); LOG.debug("[{}] Endpoint profile updated", profile.getId()); } else { LOG.error("[{}] Stored profile is null. Can't update endpoint profile.", profile.getId()); @@ -480,29 +494,31 @@ public CassandraEndpointProfile updateServerProfile(byte[] keyHash, int version, execute(update, ConsistencyLevel.ALL); return findById(key); } - - private List convertGroupStateToUDT(List cfGroupState) { - List utList = null; + + private List convertGroupStateToUDT(List cfGroupState) { + List utList = null; if (cfGroupState != null && !cfGroupState.isEmpty()) { UserType ut = getUserType(ENDPOINT_GROUP_STATE_USER_TYPE_NAME); utList = new ArrayList<>(); for (CassandraEndpointGroupState state : cfGroupState) { - ut.newValue().setString(ENDPOINT_GROUP_STATE_ENDPOINT_GROUP_ID_PROPERTY, state.getEndpointGroupId()) + UDTValue udtValue = ut.newValue().setString(ENDPOINT_GROUP_STATE_ENDPOINT_GROUP_ID_PROPERTY, state.getEndpointGroupId()) .setString(ENDPOINT_GROUP_STATE_PROFILE_FILTER_ID_PROPERTY, state.getProfileFilterId()) .setString(ENDPOINT_GROUP_STATE_CONFIGURATION_ID_PROPERTY, state.getConfigurationId()); + utList.add(udtValue); } } return utList; } - private List convertEventStateToUDT(List eventStates) { - List utList = null; + private List convertEventStateToUDT(List eventStates) { + List utList = null; if (eventStates != null && !eventStates.isEmpty()) { UserType ut = getUserType(EVENT_CLASS_FAMILY_VERSION_STATE_USER_TYPE_NAME); utList = new ArrayList<>(); for (CassandraEventClassFamilyVersionState state : eventStates) { - ut.newValue().setString(EVENT_CLASS_FAMILY_VERSION_STATE_ECF_ID_PROPERTY, state.getEcfId()) + UDTValue udtValue = ut.newValue().setString(EVENT_CLASS_FAMILY_VERSION_STATE_ECF_ID_PROPERTY, state.getEcfId()) .setInt(EVENT_CLASS_FAMILY_VERSION_STATE_ECF_VERSION_PROPERTY, state.getVersion()); + utList.add(udtValue); } } return utList; @@ -579,4 +595,6 @@ public void setEndpointUserDao(EndpointUserCassandraDao endpointUserDao) { this.endpointUserDao = endpointUserDao; } + + } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointUserCassandraDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointUserCassandraDao.java index 005637529a..291d4e89e1 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointUserCassandraDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointUserCassandraDao.java @@ -22,8 +22,10 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.set; import static com.datastax.driver.core.querybuilder.QueryBuilder.update; import static org.apache.commons.lang.StringUtils.isBlank; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_ACCESS_TOKEN_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_EXTERNAL_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_TENANT_ID_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_USERNAME_PROPERTY; import java.util.UUID; @@ -34,6 +36,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.datastax.driver.core.querybuilder.Assignment; import com.datastax.driver.core.querybuilder.Select.Where; import com.datastax.driver.core.querybuilder.Update; @@ -55,10 +58,21 @@ protected String getColumnFamilyName() { public CassandraEndpointUser save(CassandraEndpointUser user) { if (isBlank(user.getId())) { user.generateId(); - } + } LOG.trace("Save endpoint user {}", user); return super.save(user); } + + @Override + protected CassandraEndpointUser updateLocked(CassandraEndpointUser endpointUser) { + return updateLockedImpl(endpointUser.getVersion(), + new Assignment[]{set(EP_USER_USERNAME_PROPERTY, endpointUser.getUsername()), + set(EP_USER_ACCESS_TOKEN_PROPERTY, endpointUser.getAccessToken()), + set(CassandraModelConstants.EP_USER_ENDPOINT_IDS_PROPERTY, endpointUser.getEndpointIds())}, + eq(EP_USER_EXTERNAL_ID_PROPERTY, endpointUser.getExternalId()), + eq(EP_USER_TENANT_ID_PROPERTY, endpointUser.getTenantId()) + ); + } @Override public CassandraEndpointUser save(EndpointUserDto dto) { @@ -119,4 +133,5 @@ public CassandraEndpointUser findById(String id) { LOG.trace("Found endpoint user {} by id {}", endpointUser, id); return endpointUser; } + } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointUserConfigurationCassandraDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointUserConfigurationCassandraDao.java index c091c9519e..b4e6b9b354 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointUserConfigurationCassandraDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointUserConfigurationCassandraDao.java @@ -15,25 +15,29 @@ */ package org.kaaproject.kaa.server.common.nosql.cassandra.dao; -import com.datastax.driver.core.querybuilder.Select; -import org.kaaproject.kaa.common.dto.EndpointUserConfigurationDto; -import org.kaaproject.kaa.server.common.dao.impl.EndpointUserConfigurationDao; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEndpointUserConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Repository; - -import java.util.Arrays; -import java.util.List; - import static com.datastax.driver.core.querybuilder.QueryBuilder.delete; import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; import static com.datastax.driver.core.querybuilder.QueryBuilder.select; +import static com.datastax.driver.core.querybuilder.QueryBuilder.set; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_CONF_APP_TOKEN_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_CONF_BODY_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_CONF_COLUMN_FAMILY_NAME; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_CONF_USER_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_CONF_VERSION_PROPERTY; +import java.util.Arrays; +import java.util.List; + +import org.kaaproject.kaa.common.dto.EndpointUserConfigurationDto; +import org.kaaproject.kaa.server.common.dao.impl.EndpointUserConfigurationDao; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEndpointUserConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Repository; + +import com.datastax.driver.core.querybuilder.Assignment; +import com.datastax.driver.core.querybuilder.Select; + @Repository public class EndpointUserConfigurationCassandraDao extends AbstractCassandraDao implements EndpointUserConfigurationDao { @@ -48,6 +52,17 @@ protected Class getColumnFamilyClass() { protected String getColumnFamilyName() { return EP_USER_CONF_COLUMN_FAMILY_NAME; } + + @Override + protected CassandraEndpointUserConfiguration updateLocked( + CassandraEndpointUserConfiguration entity) { + return updateLockedImpl(entity.getVersion(), + new Assignment[]{set(EP_USER_CONF_BODY_PROPERTY, entity.getBody())}, + eq(EP_USER_CONF_USER_ID_PROPERTY, entity.getUserId()), + eq(EP_USER_CONF_APP_TOKEN_PROPERTY, entity.getAppToken()), + eq(EP_USER_CONF_VERSION_PROPERTY, entity.getSchemaVersion()) + ); + } @Override public CassandraEndpointUserConfiguration save(EndpointUserConfigurationDto dto) { @@ -96,4 +111,6 @@ public void removeByUserIdAndAppTokenAndSchemaVersion(String userId, String appT .and(eq(EP_USER_CONF_VERSION_PROPERTY, schemaVersion))); LOG.debug("Removed user specific configuration by user id {}, application token {} and schema version {}", userId, appToken, schemaVersion); } + + } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/NotificationCassandraDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/NotificationCassandraDao.java index 90bc102573..2ce8d8c5d7 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/NotificationCassandraDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/NotificationCassandraDao.java @@ -16,31 +16,39 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao; -import com.datastax.driver.core.querybuilder.Delete; -import com.datastax.driver.core.querybuilder.QueryBuilder; -import com.datastax.driver.core.querybuilder.Select.Where; -import org.kaaproject.kaa.common.dto.NotificationDto; -import org.kaaproject.kaa.common.dto.NotificationTypeDto; -import org.kaaproject.kaa.server.common.dao.impl.NotificationDao; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraNotification; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Repository; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import static com.datastax.driver.core.querybuilder.QueryBuilder.delete; import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; import static com.datastax.driver.core.querybuilder.QueryBuilder.select; +import static com.datastax.driver.core.querybuilder.QueryBuilder.set; import static org.apache.commons.lang.StringUtils.isBlank; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.NF_APPLICATION_ID_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.NF_BODY_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.NF_COLUMN_FAMILY_NAME; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.NF_EXPIRED_AT_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.NF_LAST_MOD_TIME_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.NF_NOTIFICATION_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.NF_NOTIFICATION_TYPE_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.NF_SCHEMA_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.NF_SEQ_NUM_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.NF_TOPIC_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.NF_VERSION_PROPERTY; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.kaaproject.kaa.common.dto.NotificationDto; +import org.kaaproject.kaa.common.dto.NotificationTypeDto; +import org.kaaproject.kaa.server.common.dao.impl.NotificationDao; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraNotification; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Repository; + +import com.datastax.driver.core.querybuilder.Assignment; +import com.datastax.driver.core.querybuilder.Delete; +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select.Where; @Repository public class NotificationCassandraDao extends AbstractCassandraDao implements NotificationDao { @@ -56,6 +64,24 @@ protected Class getColumnFamilyClass() { protected String getColumnFamilyName() { return NF_COLUMN_FAMILY_NAME; } + + @Override + protected CassandraNotification updateLocked( + CassandraNotification entity) { + return updateLockedImpl( + entity.getVersion(), + new Assignment[] { + set(NF_NOTIFICATION_ID_PROPERTY, entity.getId()), + set(NF_APPLICATION_ID_PROPERTY, entity.getApplicationId()), + set(NF_SCHEMA_ID_PROPERTY, entity.getSchemaId()), + set(NF_LAST_MOD_TIME_PROPERTY, entity.getLastModifyTime()), + set(NF_BODY_PROPERTY, entity.getBody()), + set(NF_EXPIRED_AT_PROPERTY, entity.getExpiredAt())}, + eq(NF_TOPIC_ID_PROPERTY, entity.getTopicId()), + eq(NF_NOTIFICATION_TYPE_PROPERTY, entity.getType().name()), + eq(NF_VERSION_PROPERTY, entity.getNfVersion()), + eq(NF_SEQ_NUM_PROPERTY, entity.getSeqNum())); + } @Override public CassandraNotification findById(String id) { @@ -63,7 +89,7 @@ public CassandraNotification findById(String id) { CassandraNotification nf = new CassandraNotification(id); Where query = select().from(getColumnFamilyName()).where(eq(NF_TOPIC_ID_PROPERTY, nf.getTopicId())) .and(eq(NF_NOTIFICATION_TYPE_PROPERTY, nf.getType().name())) - .and(eq(NF_VERSION_PROPERTY, nf.getVersion())) + .and(eq(NF_VERSION_PROPERTY, nf.getNfVersion())) .and(eq(NF_SEQ_NUM_PROPERTY, nf.getSeqNum())); LOG.trace("Execute query {}", query); nf = findOneByStatement(query); @@ -77,7 +103,7 @@ public void removeById(String id) { CassandraNotification nf = new CassandraNotification(id); Delete.Where deleteQuery = delete().from(getColumnFamilyName()).where(eq(NF_TOPIC_ID_PROPERTY, nf.getTopicId())) .and(eq(NF_NOTIFICATION_TYPE_PROPERTY, nf.getType().name())) - .and(eq(NF_VERSION_PROPERTY, nf.getVersion())) + .and(eq(NF_VERSION_PROPERTY, nf.getNfVersion())) .and(eq(NF_SEQ_NUM_PROPERTY, nf.getSeqNum())); LOG.trace("Remove notification by id {}", deleteQuery); execute(deleteQuery); @@ -149,4 +175,5 @@ private String[] getStringTypes(NotificationTypeDto[] typeArray) { } return types; } + } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/TopicListEntryCassandraDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/TopicListEntryCassandraDao.java index 516854b7e1..50dbfe6a8d 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/TopicListEntryCassandraDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/TopicListEntryCassandraDao.java @@ -24,9 +24,16 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Repository; +import com.datastax.driver.core.querybuilder.Assignment; + import java.nio.ByteBuffer; +import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; +import static com.datastax.driver.core.querybuilder.QueryBuilder.set; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getByteBuffer; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.TOPIC_LIST_ENTRY_HASH_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.TOPIC_LIST_ENTRY_SIMPLE_HASH_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.TOPIC_LIST_ENTRY_TOPIC_IDS_PROPERTY; @Repository(value = "topicListEntryDao") public class TopicListEntryCassandraDao extends AbstractCassandraDao implements TopicListEntryDao { @@ -60,4 +67,14 @@ public void removeByHash(byte[] hash) { LOG.debug("Remove topic list entry by hash [{}] ", hash); getMapper().delete(getByteBuffer(hash)); } + + @Override + protected CassandraTopicListEntry updateLocked(CassandraTopicListEntry entity) { + return updateLockedImpl( + entity.getVersion(), + new Assignment[] { + set(TOPIC_LIST_ENTRY_SIMPLE_HASH_PROPERTY, entity.getSimpleHash()), + set(TOPIC_LIST_ENTRY_TOPIC_IDS_PROPERTY, entity.getTopicIds())}, + eq(TOPIC_LIST_ENTRY_HASH_PROPERTY, entity.getHash())); + } } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByAccessTokenDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByAccessTokenDao.java index 9a64e96fa1..16e2a5a7b1 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByAccessTokenDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByAccessTokenDao.java @@ -48,4 +48,10 @@ public ByteBuffer findEPIdByAccessToken(String accessToken) { } return endpointKeyHash; } + + @Override + protected CassandraEPByAccessToken updateLocked( + CassandraEPByAccessToken entity) { + throw new UnsupportedOperationException("Not implemented!"); + } } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByAppIdDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByAppIdDao.java index e3f03a58b9..ab137d587f 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByAppIdDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByAppIdDao.java @@ -94,4 +94,9 @@ public ByteBuffer[] findEPByAppId(PageLinkDto pageLink, String appId) { List filter = findListByStatement(queryStatement); return getEndpointKeyHash(filter); } + + @Override + protected CassandraEPByAppId updateLocked(CassandraEPByAppId entity) { + throw new UnsupportedOperationException("Not implemented!"); + } } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByEndpointGroupIdDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByEndpointGroupIdDao.java index 173f9af63b..8b6edef67f 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByEndpointGroupIdDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPByEndpointGroupIdDao.java @@ -82,4 +82,10 @@ public ByteBuffer[] findEPByEndpointGroupId(PageLinkDto pageLink) { List filter = findListByStatement(queryStatement); return getEndpointKeyHash(filter); } + + @Override + protected CassandraEPByEndpointGroupId updateLocked( + CassandraEPByEndpointGroupId entity) { + throw new UnsupportedOperationException("Not implemented!"); + } } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPBySdkTokenDao.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPBySdkTokenDao.java index efdbf65438..d16004da23 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPBySdkTokenDao.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/filter/CassandraEPBySdkTokenDao.java @@ -76,4 +76,9 @@ public ByteBuffer[] getEPIdsBySdkToken(String sdkToken) { return result; } + + @Override + protected CassandraEPBySdkToken updateLocked(CassandraEPBySdkToken entity) { + throw new UnsupportedOperationException("Not implemented!"); + } } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByAccessToken.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByAccessToken.java index ffb715fd68..96525aec1d 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByAccessToken.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByAccessToken.java @@ -16,6 +16,8 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao.model; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; + import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; @@ -24,8 +26,10 @@ import java.io.Serializable; import java.nio.ByteBuffer; +import org.kaaproject.kaa.common.dto.HasVersion; + @Table(name = CassandraModelConstants.EP_BY_ACCESS_TOKEN_COLUMN_FAMILY_NAME) -public class CassandraEPByAccessToken implements Serializable { +public class CassandraEPByAccessToken implements HasVersion, Serializable { @Transient private static final long serialVersionUID = -8826203709978813176L; @@ -35,6 +39,9 @@ public class CassandraEPByAccessToken implements Serializable { private String accessToken; @Column(name = CassandraModelConstants.EP_BY_ACCESS_TOKEN_ENDPOINT_KEY_HASH_PROPERTY) private ByteBuffer endpointKeyHash; + + @Column(name = OPT_LOCK) + private Long version; public CassandraEPByAccessToken() { } @@ -59,6 +66,16 @@ public ByteBuffer getEndpointKeyHash() { public void setEndpointKeyHash(ByteBuffer endpointKeyHash) { this.endpointKeyHash = endpointKeyHash; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public boolean equals(Object o) { diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByAppId.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByAppId.java index ebab7cd0af..84b9a74769 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByAppId.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByAppId.java @@ -16,6 +16,8 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao.model; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; + import com.datastax.driver.mapping.annotations.ClusteringColumn; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; @@ -25,8 +27,10 @@ import java.io.Serializable; import java.nio.ByteBuffer; +import org.kaaproject.kaa.common.dto.HasVersion; + @Table(name = CassandraModelConstants.EP_BY_APP_ID_COLUMN_FAMILY_NAME) -public class CassandraEPByAppId implements Serializable { +public class CassandraEPByAppId implements HasVersion, Serializable { @Transient private static final long serialVersionUID = 4620788066149588088L; @@ -37,6 +41,9 @@ public class CassandraEPByAppId implements Serializable { @ClusteringColumn @Column(name = CassandraModelConstants.EP_BY_APP_ID_ENDPOINT_KEY_HASH_PROPERTY) private ByteBuffer endpointKeyHash; + + @Column(name = OPT_LOCK) + private Long version; public CassandraEPByAppId() { } @@ -61,6 +68,16 @@ public ByteBuffer getEndpointKeyHash() { public void setEndpointKeyHash(ByteBuffer endpointKeyHash) { this.endpointKeyHash = endpointKeyHash; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public boolean equals(Object o) { diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByEndpointGroupId.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByEndpointGroupId.java index 00d5a42e27..a479622c09 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByEndpointGroupId.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPByEndpointGroupId.java @@ -16,6 +16,8 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao.model; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; + import com.datastax.driver.mapping.annotations.ClusteringColumn; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; @@ -25,8 +27,10 @@ import java.io.Serializable; import java.nio.ByteBuffer; +import org.kaaproject.kaa.common.dto.HasVersion; + @Table(name = CassandraModelConstants.EP_BY_ENDPOINT_GROUP_ID_COLUMN_FAMILY_NAME) -public class CassandraEPByEndpointGroupId implements Serializable { +public class CassandraEPByEndpointGroupId implements HasVersion, Serializable { @Transient private static final long serialVersionUID = 4892433114353644609L; @@ -37,6 +41,9 @@ public class CassandraEPByEndpointGroupId implements Serializable { @ClusteringColumn @Column(name = CassandraModelConstants.EP_BY_ENDPOINT_GROUP_ID_ENDPOINT_KEY_HASH_PROPERTY) private ByteBuffer endpointKeyHash; + + @Column(name = OPT_LOCK) + private Long version; public CassandraEPByEndpointGroupId() { } @@ -61,6 +68,16 @@ public ByteBuffer getEndpointKeyHash() { public void setEndpointKeyHash(ByteBuffer endpointKeyHash) { this.endpointKeyHash = endpointKeyHash; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public int hashCode() { diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPBySdkToken.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPBySdkToken.java index ea23e566ca..3d9eadf0ae 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPBySdkToken.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEPBySdkToken.java @@ -16,6 +16,7 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao.model; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_BY_SDK_TOKEN_COLUMN_FAMILY_NAME; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_BY_SDK_TOKEN_ENDPOINT_KEY_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_BY_SDK_TOKEN_SDK_TOKEN_PROPERTY; @@ -23,6 +24,8 @@ import java.io.Serializable; import java.nio.ByteBuffer; +import org.kaaproject.kaa.common.dto.HasVersion; + import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; @@ -34,7 +37,7 @@ * @since v0.8.0 */ @Table(name = EP_BY_SDK_TOKEN_COLUMN_FAMILY_NAME) -public class CassandraEPBySdkToken implements Serializable { +public class CassandraEPBySdkToken implements HasVersion, Serializable { @Transient private static final long serialVersionUID = 3580976363337794171L; @@ -45,6 +48,9 @@ public class CassandraEPBySdkToken implements Serializable { @Column(name = EP_BY_SDK_TOKEN_ENDPOINT_KEY_HASH_PROPERTY) private ByteBuffer endpointKeyHash; + + @Column(name = OPT_LOCK) + private Long version; public CassandraEPBySdkToken() { } @@ -70,6 +76,16 @@ public void setEndpointKeyHash(ByteBuffer endpointKeyHash) { this.endpointKeyHash = endpointKeyHash; } + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } + @Override public int hashCode() { final int prime = 31; diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointConfiguration.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointConfiguration.java index c263b452ea..362d13fced 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointConfiguration.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointConfiguration.java @@ -20,17 +20,17 @@ import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; import com.datastax.driver.mapping.annotations.Transient; + import org.kaaproject.kaa.common.dto.EndpointConfigurationDto; import org.kaaproject.kaa.server.common.dao.model.EndpointConfiguration; import java.io.Serializable; import java.nio.ByteBuffer; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getByteBuffer; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getBytes; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.*; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ENDPOINT_CONFIGURATION_CONF_HASH_PROPERTY; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.ENDPOINT_CONFIGURATION_CONF_PROPERTY; @Table(name = ENDPOINT_CONFIGURATION_COLUMN_FAMILY_NAME) @@ -46,6 +46,9 @@ public final class CassandraEndpointConfiguration implements EndpointConfigurati private ByteBuffer configuration; @Column(name = ENDPOINT_CONFIGURATION_CONF_ID_PROPERTY) private String id; + + @Column(name = OPT_LOCK) + private Long version; public CassandraEndpointConfiguration() { } @@ -53,6 +56,7 @@ public CassandraEndpointConfiguration() { public CassandraEndpointConfiguration(EndpointConfigurationDto dto) { this.configuration = getByteBuffer(dto.getConfiguration()); this.configurationHash = getByteBuffer(dto.getConfigurationHash()); + this.version = dto.getVersion(); } public ByteBuffer getConfigurationHash() { @@ -78,6 +82,16 @@ public String getId() { public void setId(String id) { this.id = id; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public boolean equals(Object o) { @@ -116,6 +130,7 @@ public EndpointConfigurationDto toDto() { EndpointConfigurationDto dto = new EndpointConfigurationDto(); dto.setConfiguration(getBytes(configuration)); dto.setConfigurationHash(getBytes(configurationHash)); + dto.setVersion(version); return dto; } } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointNotification.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointNotification.java index 4914d12eb1..3337b11baa 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointNotification.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointNotification.java @@ -24,6 +24,7 @@ import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; import com.datastax.driver.mapping.annotations.Transient; + import org.kaaproject.kaa.common.dto.EndpointNotificationDto; import org.kaaproject.kaa.common.dto.NotificationDto; import org.kaaproject.kaa.common.dto.NotificationTypeDto; @@ -33,6 +34,7 @@ import java.nio.ByteBuffer; import java.util.Date; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getByteBuffer; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getBytes; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.parseId; @@ -58,7 +60,7 @@ public final class CassandraEndpointNotification implements EndpointNotification @Column(name = CassandraModelConstants.ET_NF_SCHEMA_ID_PROPERTY) private String schemaId; @Column(name = CassandraModelConstants.ET_NF_VERSION_PROPERTY) - private int version; + private int nfVersion; @ClusteringColumn @Column(name = CassandraModelConstants.ET_NF_LAST_MOD_TIME_PROPERTY) private Date lastModifyTime; @@ -68,6 +70,10 @@ public final class CassandraEndpointNotification implements EndpointNotification private Date expiredAt; @Column(name = CassandraModelConstants.ET_NF_TOPIC_ID_PROPERTY) private String topicId; + + @Column(name = OPT_LOCK) + private Long version; + public CassandraEndpointNotification() { } @@ -84,7 +90,7 @@ public CassandraEndpointNotification(EndpointNotificationDto dto) { this.type = notificationDto.getType(); this.applicationId = notificationDto.getApplicationId(); this.schemaId = notificationDto.getSchemaId(); - this.version = notificationDto.getVersion(); + this.nfVersion = notificationDto.getNfVersion(); this.lastModifyTime = notificationDto.getLastTimeModify(); this.body = getByteBuffer(notificationDto.getBody()); this.expiredAt = notificationDto.getExpiredAt(); @@ -92,6 +98,7 @@ public CassandraEndpointNotification(EndpointNotificationDto dto) { } this.id = dto.getId() != null ? dto.getId() : generateId(); + this.version = dto.getVersion(); } @@ -161,12 +168,12 @@ public void setSchemaId(String schemaId) { this.schemaId = schemaId; } - public int getVersion() { - return version; + public int getNfVersion() { + return nfVersion; } - public void setVersion(int version) { - this.version = version; + public void setNfVersion(int nfVersion) { + this.nfVersion = nfVersion; } public Date getLastModifyTime() { @@ -200,6 +207,16 @@ public String getTopicId() { public void setTopicId(String topicId) { this.topicId = topicId; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public boolean equals(Object o) { @@ -208,7 +225,7 @@ public boolean equals(Object o) { CassandraEndpointNotification that = (CassandraEndpointNotification) o; - if (version != that.version) return false; + if (nfVersion != that.nfVersion) return false; if (applicationId != null ? !applicationId.equals(that.applicationId) : that.applicationId != null) return false; if (body != null ? !body.equals(that.body) : that.body != null) return false; @@ -233,7 +250,7 @@ public int hashCode() { result = 31 * result + (type != null ? type.hashCode() : 0); result = 31 * result + (applicationId != null ? applicationId.hashCode() : 0); result = 31 * result + (schemaId != null ? schemaId.hashCode() : 0); - result = 31 * result + version; + result = 31 * result + nfVersion; result = 31 * result + (lastModifyTime != null ? lastModifyTime.hashCode() : 0); result = 31 * result + (body != null ? body.hashCode() : 0); result = 31 * result + (expiredAt != null ? expiredAt.hashCode() : 0); @@ -249,7 +266,7 @@ public String toString() { ", type=" + type + ", applicationId='" + applicationId + '\'' + ", schemaId='" + schemaId + '\'' + - ", version=" + version + + ", nfVersion=" + nfVersion + ", lastModifyTime=" + lastModifyTime + ", body=" + body + ", expiredAt=" + expiredAt + @@ -266,12 +283,13 @@ public EndpointNotificationDto toDto() { notificationDto.setType(type); notificationDto.setApplicationId(applicationId); notificationDto.setSchemaId(schemaId); - notificationDto.setVersion(version); + notificationDto.setNfVersion(nfVersion); notificationDto.setLastTimeModify(lastModifyTime); notificationDto.setBody(getBytes(body)); notificationDto.setExpiredAt(expiredAt); notificationDto.setTopicId(topicId); dto.setNotificationDto(notificationDto); + dto.setVersion(version); return dto; } } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointProfile.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointProfile.java index 9792ef8da5..d3013ae27c 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointProfile.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointProfile.java @@ -16,22 +16,6 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao.model; -import com.datastax.driver.mapping.annotations.Column; -import com.datastax.driver.mapping.annotations.FrozenValue; -import com.datastax.driver.mapping.annotations.PartitionKey; -import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; -import org.kaaproject.kaa.common.dto.EndpointProfileDto; -import org.kaaproject.kaa.common.dto.EventClassFamilyVersionStateDto; -import org.kaaproject.kaa.server.common.dao.impl.DaoUtil; -import org.kaaproject.kaa.server.common.dao.model.EndpointProfile; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.type.CassandraEndpointGroupState; -import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.type.CassandraEventClassFamilyVersionState; - -import java.io.Serializable; -import java.nio.ByteBuffer; -import java.util.List; - import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.convertDtoToModelList; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.convertECFVersionDtoToModelList; @@ -41,15 +25,13 @@ import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_APP_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_COLUMN_FAMILY_NAME; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_CONFIGURATION_VERSION_PROPERTY; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_GROUP_STATE_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_CONFIG_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_ECF_VERSION_STATE_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_ENDPOINT_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_EP_KEY_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_EP_KEY_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_GROUP_STATE_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_LOG_SCHEMA_VERSION_PROPERTY; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SIMPLE_TOPIC_HASH_PROPERTY; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_TOPIC_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_NOTIFICATION_VERSION_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_PROFILE_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_PROFILE_PROPERTY; @@ -57,14 +39,33 @@ import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SDK_TOKEN_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SEQUENCE_NUMBER_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SERVER_HASH_PROPERTY; -import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SERVER_PROFILE_VERSION_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SERVER_PROFILE_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SERVER_PROFILE_VERSION_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SIMPLE_TOPIC_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SUBSCRIPTIONS_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_SYSTEM_NOTIFICATION_VERSION_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_TOPIC_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_CONFIG_HASH_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_NOTIFICATION_VERSION_PROPERTY; +import java.io.Serializable; +import java.nio.ByteBuffer; +import java.util.List; + +import org.kaaproject.kaa.common.dto.EndpointProfileDto; +import org.kaaproject.kaa.common.dto.EventClassFamilyVersionStateDto; +import org.kaaproject.kaa.server.common.dao.impl.DaoUtil; +import org.kaaproject.kaa.server.common.dao.model.EndpointProfile; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.type.CassandraEndpointGroupState; +import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.type.CassandraEventClassFamilyVersionState; + +import com.datastax.driver.mapping.annotations.Column; +import com.datastax.driver.mapping.annotations.FrozenValue; +import com.datastax.driver.mapping.annotations.PartitionKey; +import com.datastax.driver.mapping.annotations.Table; +import com.datastax.driver.mapping.annotations.Transient; + @Table(name = EP_COLUMN_FAMILY_NAME) public final class CassandraEndpointProfile implements EndpointProfile, Serializable { @@ -125,9 +126,9 @@ public final class CassandraEndpointProfile implements EndpointProfile, Serializ @Column(name = EP_SDK_TOKEN_PROPERTY) private String sdkToken; @Column(name = EP_SERVER_PROFILE_PROPERTY) - private String serverProfile; + private String serverProfile; @Column(name = OPT_LOCK) - private long version; + private Long version; public CassandraEndpointProfile() { } @@ -159,6 +160,7 @@ public CassandraEndpointProfile(EndpointProfileDto dto) { this.serverHash = dto.getServerHash(); this.sdkToken = dto.getSdkToken(); this.serverProfile = dto.getServerProfileBody(); + this.version = dto.getVersion(); } public void setId(String id) { @@ -376,12 +378,14 @@ public void setSdkToken(String sdkToken) { public void setApplicationId(String applicationId) { this.applicationId = applicationId; } - - public long getVersion() { + + @Override + public Long getVersion() { return version; } - public void setVersion(long version) { + @Override + public void setVersion(Long version) { this.version = version; } @@ -513,6 +517,7 @@ public EndpointProfileDto toDto() { dto.setServerHash(serverHash); dto.setSdkToken(sdkToken); dto.setServerProfileBody(serverProfile); + dto.setVersion(version); return dto; } } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointUser.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointUser.java index 6637e75496..c041168b97 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointUser.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointUser.java @@ -16,17 +16,8 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao.model; -import com.datastax.driver.mapping.annotations.Column; -import com.datastax.driver.mapping.annotations.PartitionKey; -import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; -import org.kaaproject.kaa.common.dto.EndpointUserDto; -import org.kaaproject.kaa.server.common.dao.model.EndpointUser; - -import java.io.Serializable; -import java.util.List; - import static org.apache.commons.lang.StringUtils.isBlank; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.parseId; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_ACCESS_TOKEN_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_COLUMN_FAMILY_NAME; @@ -37,6 +28,17 @@ import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_USER_ID_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.KEY_DELIMITER; +import java.io.Serializable; +import java.util.List; + +import org.kaaproject.kaa.common.dto.EndpointUserDto; +import org.kaaproject.kaa.server.common.dao.model.EndpointUser; + +import com.datastax.driver.mapping.annotations.Column; +import com.datastax.driver.mapping.annotations.PartitionKey; +import com.datastax.driver.mapping.annotations.Table; +import com.datastax.driver.mapping.annotations.Transient; + @Table(name = EP_USER_COLUMN_FAMILY_NAME) public final class CassandraEndpointUser implements EndpointUser, Serializable { @@ -59,6 +61,9 @@ public final class CassandraEndpointUser implements EndpointUser, Serializable { private String accessToken; @Column(name = EP_USER_ENDPOINT_IDS_PROPERTY) private List endpointIds; + + @Column(name = OPT_LOCK) + private Long version; public CassandraEndpointUser() { } @@ -78,6 +83,7 @@ public CassandraEndpointUser(EndpointUserDto dto) { this.tenantId = dto.getTenantId(); this.accessToken = dto.getAccessToken(); this.endpointIds = dto.getEndpointIds(); + this.version = dto.getVersion(); } public String getId() { @@ -127,6 +133,16 @@ public List getEndpointIds() { public void setEndpointIds(List endpointIds) { this.endpointIds = endpointIds; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public int hashCode() { @@ -181,6 +197,7 @@ public EndpointUserDto toDto() { dto.setTenantId(tenantId); dto.setAccessToken(accessToken); dto.setEndpointIds(endpointIds); + dto.setVersion(version); return dto; } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointUserConfiguration.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointUserConfiguration.java index c03f9bab9b..2c7e58a731 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointUserConfiguration.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraEndpointUserConfiguration.java @@ -20,11 +20,13 @@ import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; import com.datastax.driver.mapping.annotations.Transient; + import org.kaaproject.kaa.common.dto.EndpointUserConfigurationDto; import org.kaaproject.kaa.server.common.dao.model.EndpointUserConfiguration; import java.io.Serializable; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_CONF_APP_TOKEN_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_CONF_BODY_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.EP_USER_CONF_COLUMN_FAMILY_NAME; @@ -48,6 +50,9 @@ public class CassandraEndpointUserConfiguration implements EndpointUserConfigura private Integer schemaVersion; @Column(name = EP_USER_CONF_BODY_PROPERTY) private String body; + + @Column(name = OPT_LOCK) + private Long version; public CassandraEndpointUserConfiguration() { } @@ -57,6 +62,7 @@ public CassandraEndpointUserConfiguration(EndpointUserConfigurationDto dto) { this.appToken = dto.getAppToken(); this.schemaVersion = dto.getSchemaVersion(); this.body = dto.getBody(); + this.version = dto.getVersion(); } @Override @@ -96,6 +102,16 @@ public String getBody() { public void setBody(String body) { this.body = body; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public EndpointUserConfigurationDto toDto() { @@ -104,6 +120,7 @@ public EndpointUserConfigurationDto toDto() { dto.setBody(body); dto.setSchemaVersion(schemaVersion); dto.setUserId(userId); + dto.setVersion(version); return dto; } } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraModelConstants.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraModelConstants.java index 84ca910149..925d7f249e 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraModelConstants.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraModelConstants.java @@ -32,7 +32,6 @@ public class CassandraModelConstants { public static final String SEQ_NUM_PROPERTY = "seq_num"; public static final String BODY_PROPERTY = "body"; public static final String EXPIRED_AT_PROPERTY = "expired_at"; - public static final String VERSION_PROPERTY = "version"; public static final String LAST_MOD_TIME_PROPERTY = "last_mod_time"; public static final String SCHEMA_ID_PROPERTY = "schema_id"; public static final String TOPIC_ID_PROPERTY = "topic_id"; @@ -50,7 +49,7 @@ public class CassandraModelConstants { public static final String ET_NF_SEQ_NUM_PROPERTY = SEQ_NUM_PROPERTY; public static final String ET_NF_BODY_PROPERTY = BODY_PROPERTY; public static final String ET_NF_EXPIRED_AT_PROPERTY = EXPIRED_AT_PROPERTY; - public static final String ET_NF_VERSION_PROPERTY = VERSION_PROPERTY; + public static final String ET_NF_VERSION_PROPERTY = "ep_nf_version"; public static final String ET_NF_LAST_MOD_TIME_PROPERTY = LAST_MOD_TIME_PROPERTY; public static final String ET_NF_SCHEMA_ID_PROPERTY = SCHEMA_ID_PROPERTY; public static final String ET_NF_TOPIC_ID_PROPERTY = TOPIC_ID_PROPERTY; @@ -63,7 +62,7 @@ public class CassandraModelConstants { public static final String NF_APPLICATION_ID_PROPERTY = APPLICATION_ID_PROPERTY; public static final String NF_NOTIFICATION_ID_PROPERTY = NOTIFICATION_ID_PROPERTY; public static final String NF_SCHEMA_ID_PROPERTY = SCHEMA_ID_PROPERTY; - public static final String NF_VERSION_PROPERTY = VERSION_PROPERTY; + public static final String NF_VERSION_PROPERTY = "nf_version"; public static final String NF_LAST_MOD_TIME_PROPERTY = LAST_MOD_TIME_PROPERTY; public static final String NF_NOTIFICATION_TYPE_PROPERTY = NOTIFICATION_TYPE_PROPERTY; public static final String NF_BODY_PROPERTY = BODY_PROPERTY; @@ -168,7 +167,7 @@ public class CassandraModelConstants { public static final String EP_USER_CONF_COLUMN_FAMILY_NAME = "user_conf"; public static final String EP_USER_CONF_USER_ID_PROPERTY = "user_id"; public static final String EP_USER_CONF_APP_TOKEN_PROPERTY = "app_token"; - public static final String EP_USER_CONF_VERSION_PROPERTY = VERSION_PROPERTY; + public static final String EP_USER_CONF_VERSION_PROPERTY = "schema_version"; public static final String EP_USER_CONF_BODY_PROPERTY = BODY_PROPERTY; /** diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraNotification.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraNotification.java index f2caa110c8..b2e1435a78 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraNotification.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraNotification.java @@ -23,6 +23,7 @@ import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; import com.datastax.driver.mapping.annotations.Transient; + import org.kaaproject.kaa.common.dto.NotificationDto; import org.kaaproject.kaa.common.dto.NotificationTypeDto; import org.kaaproject.kaa.server.common.dao.model.Notification; @@ -32,6 +33,7 @@ import java.util.Date; import static org.apache.commons.lang.StringUtils.isBlank; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getByteBuffer; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getBytes; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.parseId; @@ -75,7 +77,7 @@ public final class CassandraNotification implements Notification, Serializable { @ClusteringColumn(value = 0) @Column(name = NF_VERSION_PROPERTY) - private int version; + private int nfVersion; @ClusteringColumn(value = 1) @Column(name = NF_SEQ_NUM_PROPERTY) private int seqNum; @@ -86,6 +88,9 @@ public final class CassandraNotification implements Notification, Serializable { private ByteBuffer body; @Column(name = NF_EXPIRED_AT_PROPERTY) private Date expiredAt; + + @Column(name = OPT_LOCK) + private Long version; public CassandraNotification() { } @@ -95,7 +100,7 @@ public CassandraNotification(String id) { if (columns != null && columns.length == COMPOSITE_ID_SIZE) { this.topicId = columns[0]; this.type = NotificationTypeDto.valueOf(columns[1]); - this.version = Integer.valueOf(columns[2]); + this.nfVersion = Integer.valueOf(columns[2]); this.seqNum = Integer.valueOf(columns[3]); } } @@ -105,7 +110,7 @@ public CassandraNotification(NotificationDto dto) { this.schemaId = dto.getSchemaId(); this.topicId = dto.getTopicId(); this.type = dto.getType(); - this.version = dto.getVersion(); + this.nfVersion = dto.getNfVersion(); this.seqNum = dto.getSecNum(); this.lastModifyTime = dto.getLastTimeModify(); this.body = getByteBuffer(dto.getBody()); @@ -115,6 +120,7 @@ public CassandraNotification(NotificationDto dto) { if (isBlank(id)) { generateId(); } + this.version = dto.getVersion(); } public String getTopicId() { @@ -157,12 +163,12 @@ public void setSchemaId(String schemaId) { this.schemaId = schemaId; } - public int getVersion() { - return version; + public int getNfVersion() { + return nfVersion; } - public void setVersion(int version) { - this.version = version; + public void setNfVersion(int nfVersion) { + this.nfVersion = nfVersion; } public int getSeqNum() { @@ -196,6 +202,16 @@ public Date getExpiredAt() { public void setExpiredAt(Date expiredAt) { this.expiredAt = expiredAt; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public boolean equals(Object o) { @@ -205,7 +221,7 @@ public boolean equals(Object o) { CassandraNotification that = (CassandraNotification) o; if (seqNum != that.seqNum) return false; - if (version != that.version) return false; + if (nfVersion != that.nfVersion) return false; if (applicationId != null ? !applicationId.equals(that.applicationId) : that.applicationId != null) return false; if (body != null ? !body.equals(that.body) : that.body != null) return false; @@ -228,7 +244,7 @@ public String toString() { ", id='" + id + '\'' + ", applicationId='" + applicationId + '\'' + ", schemaId='" + schemaId + '\'' + - ", version=" + version + + ", nfVersion=" + nfVersion + ", seqNum=" + seqNum + ", lastModifyTime=" + lastModifyTime + ", body=" + body + @@ -243,7 +259,7 @@ public int hashCode() { result = 31 * result + (id != null ? id.hashCode() : 0); result = 31 * result + (applicationId != null ? applicationId.hashCode() : 0); result = 31 * result + (schemaId != null ? schemaId.hashCode() : 0); - result = 31 * result + version; + result = 31 * result + nfVersion; result = 31 * result + seqNum; result = 31 * result + (lastModifyTime != null ? lastModifyTime.hashCode() : 0); result = 31 * result + (body != null ? body.hashCode() : 0); @@ -259,11 +275,12 @@ public NotificationDto toDto() { dto.setSchemaId(schemaId); dto.setTopicId(topicId); dto.setLastTimeModify(lastModifyTime); - dto.setVersion(version); + dto.setNfVersion(nfVersion); dto.setType(type); dto.setBody(body != null ? getBytes(body) : null); dto.setExpiredAt(expiredAt); dto.setSecNum(seqNum); + dto.setVersion(version); return dto; } @@ -278,7 +295,7 @@ public void generateId() { StringBuilder builder = new StringBuilder(); builder.append(topicId) .append(KEY_DELIMITER).append(type) - .append(KEY_DELIMITER).append(version) + .append(KEY_DELIMITER).append(nfVersion) .append(KEY_DELIMITER).append(seqNum); id = builder.toString(); } diff --git a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraTopicListEntry.java b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraTopicListEntry.java index fab36cf2f5..a8458b299d 100644 --- a/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraTopicListEntry.java +++ b/server/common/nosql/cassandra-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/model/CassandraTopicListEntry.java @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.List; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getByteBuffer; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.CassandraDaoUtil.getBytes; import static org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraModelConstants.TOPIC_LIST_ENTRY_COLUMN_FAMILY_NAME; @@ -47,6 +48,9 @@ public final class CassandraTopicListEntry implements TopicListEntry, Serializab private int simpleHash; @Column(name = CassandraModelConstants.TOPIC_LIST_ENTRY_TOPIC_IDS_PROPERTY) private List topicIds; + + @Column(name = OPT_LOCK) + private Long version; public CassandraTopicListEntry() { } @@ -60,6 +64,7 @@ public CassandraTopicListEntry(TopicListEntryDto dto) { topicIds.add(topic.getId()); } } + this.version = dto.getVersion(); } public ByteBuffer getHash() { @@ -122,6 +127,18 @@ public TopicListEntryDto toDto() { topicDto.setId(topicId); topicDtos.add(topicDto); } - return new TopicListEntryDto(simpleHash, getBytes(hash), topicDtos); + TopicListEntryDto dto = new TopicListEntryDto(simpleHash, getBytes(hash), topicDtos); + dto.setVersion(version); + return dto; + } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; } } diff --git a/server/common/nosql/cassandra-dao/src/main/resources/cassandra.cql b/server/common/nosql/cassandra-dao/src/main/resources/cassandra.cql index 34a9d04618..b4b1d1f722 100644 --- a/server/common/nosql/cassandra-dao/src/main/resources/cassandra.cql +++ b/server/common/nosql/cassandra-dao/src/main/resources/cassandra.cql @@ -19,11 +19,12 @@ CREATE TABLE IF NOT EXISTS kaa.ep_nfs ( nf_type text, app_id text, schema_id text, - version int, + ep_nf_version int, last_mod_time timestamp, body blob, expired_at timestamp, topic_id text, + opt_lock bigint, PRIMARY KEY (ep_key_hash, last_mod_time) ) WITH CLUSTERING ORDER BY (last_mod_time DESC); @@ -34,17 +35,19 @@ CREATE TABLE IF NOT EXISTS kaa.notification ( app_id text, schema_id text, last_mod_time timestamp, - version int, + nf_version int, body blob, expired_at timestamp, seq_num int, - PRIMARY KEY((topic_id, nf_type), version, seq_num) -) WITH CLUSTERING ORDER BY (version DESC, seq_num DESC); + opt_lock bigint, + PRIMARY KEY((topic_id, nf_type), nf_version, seq_num) +) WITH CLUSTERING ORDER BY (nf_version DESC, seq_num DESC); CREATE TABLE IF NOT EXISTS kaa.ep_conf ( cf_hash blob PRIMARY KEY, cf blob, - cf_id text + cf_id text, + opt_lock bigint ); CREATE TABLE IF NOT EXISTS kaa.ep_user ( @@ -54,6 +57,7 @@ CREATE TABLE IF NOT EXISTS kaa.ep_user ( tenant_id text, access_token text, ep_ids list , + opt_lock bigint, PRIMARY KEY (ext_id, tenant_id) ); @@ -89,36 +93,42 @@ CREATE TABLE IF NOT EXISTS kaa.ep_profile ( CREATE TABLE IF NOT EXISTS kaa.app_eps ( app_id text, - ep_key_hash blob, + ep_key_hash blob, + opt_lock bigint, PRIMARY KEY (app_id, ep_key_hash) ); CREATE TABLE IF NOT EXISTS kaa.access_token_eps ( access_token text PRIMARY KEY , - ep_key_hash blob + ep_key_hash blob, + opt_lock bigint ); CREATE TABLE IF NOT EXISTS kaa.endpoint_group_id_eps ( ep_group_id text , ep_key_hash blob, + opt_lock bigint, PRIMARY KEY (ep_group_id, ep_key_hash) ); CREATE TABLE IF NOT EXISTS kaa.sdk_token_eps ( sdk_token text PRIMARY KEY, - ep_key_hash blob + ep_key_hash blob, + opt_lock bigint ); CREATE TABLE IF NOT EXISTS kaa.user_conf ( user_id text, app_token text, - version int, + schema_version int, body text, - PRIMARY KEY (user_id, app_token, version) + opt_lock bigint, + PRIMARY KEY (user_id, app_token, schema_version) ); CREATE TABLE IF NOT EXISTS kaa.tl_entry ( tl_entry_hash blob PRIMARY KEY, tl_entry_simple_hash int, - tl_entry_topic_ids list + tl_entry_topic_ids list, + opt_lock bigint ); diff --git a/server/common/nosql/cassandra-dao/src/main/resources/common-dao-cassandra-context.xml b/server/common/nosql/cassandra-dao/src/main/resources/common-dao-cassandra-context.xml index 40e31eef03..53548bed03 100644 --- a/server/common/nosql/cassandra-dao/src/main/resources/common-dao-cassandra-context.xml +++ b/server/common/nosql/cassandra-dao/src/main/resources/common-dao-cassandra-context.xml @@ -27,7 +27,7 @@ - + diff --git a/server/common/nosql/cassandra-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/AbstractCassandraTest.java b/server/common/nosql/cassandra-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/AbstractCassandraTest.java index e577347f8a..c8d1a5553b 100644 --- a/server/common/nosql/cassandra-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/AbstractCassandraTest.java +++ b/server/common/nosql/cassandra-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/AbstractCassandraTest.java @@ -91,7 +91,7 @@ protected List generateNotifications(String topicId, String app notification.setSecNum(i); notification.setBody(UUID.randomUUID().toString().getBytes()); notification.setLastTimeModify(new Date(System.currentTimeMillis())); - notification.setVersion(1); + notification.setNfVersion(1); notification.setExpiredAt(new Date(System.currentTimeMillis() + 7 * 24 * 3600 * 1000)); notifications.add(notificationDao.save(notification).toDto()); } @@ -145,11 +145,11 @@ protected EndpointProfileDto generateEndpointProfile(String appId, String sdkTok return endpointProfileDao.save(new CassandraEndpointProfile(profileDto)).toDto(); } - protected EndpointProfileDto generateEndpointProfileForTestUpdate(String id, List cfGroupState) { + protected EndpointProfileDto generateEndpointProfileForTestUpdate(String id, byte[] keyHash, List cfGroupState) { EndpointProfileDto profileDto = new EndpointProfileDto(); profileDto.setId(id); + profileDto.setEndpointKeyHash(keyHash); profileDto.setApplicationId(generateStringId()); - profileDto.setEndpointKeyHash("TEST_KEY_HASH".getBytes()); profileDto.setAccessToken(generateStringId()); profileDto.setGroupState(cfGroupState); profileDto.setSdkToken(UUID.randomUUID().toString()); diff --git a/server/common/nosql/cassandra-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointProfileCassandraDaoTest.java b/server/common/nosql/cassandra-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointProfileCassandraDaoTest.java index 071aecbc9e..c9b5c70364 100644 --- a/server/common/nosql/cassandra-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointProfileCassandraDaoTest.java +++ b/server/common/nosql/cassandra-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/cassandra/dao/EndpointProfileCassandraDaoTest.java @@ -16,6 +16,15 @@ package org.kaaproject.kaa.server.common.nosql.cassandra.dao; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,7 +36,7 @@ import org.kaaproject.kaa.common.dto.EndpointProfilesPageDto; import org.kaaproject.kaa.common.dto.EndpointUserDto; import org.kaaproject.kaa.common.dto.PageLinkDto; -import org.kaaproject.kaa.server.common.dao.lock.KaaOptimisticLockingFailureException; +import org.kaaproject.kaa.server.common.dao.exception.KaaOptimisticLockingFailureException; import org.kaaproject.kaa.server.common.dao.model.EndpointProfile; import org.kaaproject.kaa.server.common.nosql.cassandra.dao.model.CassandraEndpointProfile; import org.slf4j.Logger; @@ -36,16 +45,6 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; - @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "/cassandra-client-test-context.xml") @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @@ -141,12 +140,14 @@ public void testUpdate() throws Exception { cfGroupStateSave.add(new EndpointGroupStateDto("111", null, null)); cfGroupStateSave.add(new EndpointGroupStateDto("222", null, null)); cfGroupStateSave.add(new EndpointGroupStateDto("333", null, null)); - EndpointProfileDto endpointProfileSave = generateEndpointProfileForTestUpdate(null, cfGroupStateSave); - endpointProfileDao.save(endpointProfileSave); + byte[] keyHash = generateBytes(); + EndpointProfileDto endpointProfileSave = generateEndpointProfileForTestUpdate(null, keyHash, cfGroupStateSave); + EndpointProfile saved = endpointProfileDao.save(endpointProfileSave); cfGroupStateUpdate.add(new EndpointGroupStateDto("111", null, null)); cfGroupStateUpdate.add(new EndpointGroupStateDto("444", null, null)); - EndpointProfileDto endpointProfileUpdate = generateEndpointProfileForTestUpdate(endpointProfileId, cfGroupStateUpdate); - endpointProfileDao.save(endpointProfileUpdate); + EndpointProfileDto endpointProfileUpdate = generateEndpointProfileForTestUpdate(endpointProfileId, keyHash, cfGroupStateUpdate); + endpointProfileUpdate.setVersion(saved.getVersion()); + saved = endpointProfileDao.save(endpointProfileUpdate); String limit = "10"; String offset = "0"; String[] endpointGroupId = {"111", "444", "222", "333"}; diff --git a/server/common/nosql/cassandra-dao/src/test/resources/cassandra-dao-test-context.xml b/server/common/nosql/cassandra-dao/src/test/resources/cassandra-dao-test-context.xml index ef05ebbb90..8a6163e355 100644 --- a/server/common/nosql/cassandra-dao/src/test/resources/cassandra-dao-test-context.xml +++ b/server/common/nosql/cassandra-dao/src/test/resources/cassandra-dao-test-context.xml @@ -32,6 +32,9 @@ http://www.springframework.org/schema/util/spring-util-3.0.xsd"> + + + diff --git a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/AbstractMongoDao.java b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/AbstractMongoDao.java index e6be7af9bf..94426ef7fa 100644 --- a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/AbstractMongoDao.java +++ b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/AbstractMongoDao.java @@ -16,18 +16,22 @@ package org.kaaproject.kaa.server.common.nosql.mongo.dao; -import com.mongodb.DBCollection; +import java.util.List; + +import org.kaaproject.kaa.common.dto.HasVersion; +import org.kaaproject.kaa.server.common.dao.exception.KaaOptimisticLockingFailureException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.mongodb.core.FindAndModifyOptions; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; -import java.util.List; +import com.mongodb.DBCollection; -public abstract class AbstractMongoDao { +public abstract class AbstractMongoDao { private static final Logger LOG = LoggerFactory.getLogger(AbstractMongoDao.class); @@ -73,8 +77,13 @@ protected long count(Query query) { } public T save(T dto) { - mongoTemplate.save(dto); - return dto; + try { + mongoTemplate.save(dto); + return dto; + } catch (OptimisticLockingFailureException exception) { + LOG.error("[{}] Can't update entity with version {}. Entity already changed!", getDocumentClass(), dto.getVersion()); + throw new KaaOptimisticLockingFailureException("Can't update entity with version " + dto.getVersion() + ". Entity already changed!"); + } } public V save(V dto, Class clazz) { diff --git a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointProfileMongoDao.java b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointProfileMongoDao.java index 12dd6621f1..2ec0984bfd 100644 --- a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointProfileMongoDao.java +++ b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointProfileMongoDao.java @@ -16,35 +16,14 @@ package org.kaaproject.kaa.server.common.nosql.mongo.dao; -import com.mongodb.DBObject; -import org.kaaproject.kaa.common.dto.EndpointProfileBodyDto; -import org.kaaproject.kaa.common.dto.EndpointProfileDto; -import org.kaaproject.kaa.common.dto.EndpointProfilesBodyDto; -import org.kaaproject.kaa.common.dto.EndpointProfilesPageDto; -import org.kaaproject.kaa.common.dto.PageLinkDto; -import org.kaaproject.kaa.server.common.dao.DaoConstants; -import org.kaaproject.kaa.server.common.dao.impl.EndpointProfileDao; -import org.kaaproject.kaa.server.common.dao.lock.KaaOptimisticLockingFailureException; -import org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoEndpointProfile; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.dao.OptimisticLockingFailureException; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.stereotype.Repository; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.dao.impl.DaoUtil.convertDtoList; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.ENDPOINT_GROUP_ID; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.ENDPOINT_PROFILE; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_ACCESS_TOKEN; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_APPLICATION_ID; -import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_GROUP_STATE; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_ENDPOINT_KEY_HASH; +import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_GROUP_STATE; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SDK_TOKEN; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SERVER_PROFILE_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SERVER_PROFILE_VERSION_PROPERTY; @@ -54,6 +33,26 @@ import static org.springframework.data.mongodb.core.query.Query.query; import static org.springframework.data.mongodb.core.query.Update.update; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +import org.kaaproject.kaa.common.dto.EndpointProfileBodyDto; +import org.kaaproject.kaa.common.dto.EndpointProfileDto; +import org.kaaproject.kaa.common.dto.EndpointProfilesBodyDto; +import org.kaaproject.kaa.common.dto.EndpointProfilesPageDto; +import org.kaaproject.kaa.common.dto.PageLinkDto; +import org.kaaproject.kaa.server.common.dao.DaoConstants; +import org.kaaproject.kaa.server.common.dao.impl.EndpointProfileDao; +import org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoEndpointProfile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Repository; + +import com.mongodb.DBObject; + @Repository public class EndpointProfileMongoDao extends AbstractMongoDao implements EndpointProfileDao { @@ -205,13 +204,7 @@ public void removeById(ByteBuffer key) { @Override public MongoEndpointProfile save(EndpointProfileDto dto) { - try { - MongoEndpointProfile profile = new MongoEndpointProfile(dto); - profile.setOptVersion(findVersionByKey(dto.getEndpointKeyHash())); - return save(profile); - } catch (OptimisticLockingFailureException exception) { - throw new KaaOptimisticLockingFailureException("Can't update endpoint profile. Endpoint profile already changed!", exception); - } + return save(new MongoEndpointProfile(dto)); } @Override diff --git a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointUserMongoDao.java b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointUserMongoDao.java index 2faf390cf9..0752d164a1 100644 --- a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointUserMongoDao.java +++ b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointUserMongoDao.java @@ -16,21 +16,23 @@ package org.kaaproject.kaa.server.common.nosql.mongo.dao; +import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.ENDPOINT_USER; +import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_USER_EXTERNAL_ID; +import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_USER_TENANT_ID; +import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.springframework.data.mongodb.core.query.Query.query; + +import java.util.UUID; + import org.kaaproject.kaa.common.dto.EndpointUserDto; +import org.kaaproject.kaa.server.common.dao.exception.KaaOptimisticLockingFailureException; import org.kaaproject.kaa.server.common.dao.impl.EndpointUserDao; import org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoEndpointUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.stereotype.Repository; -import java.util.UUID; - -import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.ENDPOINT_USER; -import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_USER_EXTERNAL_ID; -import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_USER_TENANT_ID; -import static org.springframework.data.mongodb.core.query.Criteria.where; -import static org.springframework.data.mongodb.core.query.Query.query; - @Repository public class EndpointUserMongoDao extends AbstractMongoDao implements EndpointUserDao { @@ -83,4 +85,5 @@ public boolean checkAccessToken(String externalId, String tenantId, String acces public MongoEndpointUser save(EndpointUserDto dto) { return save(new MongoEndpointUser(dto)); } + } \ No newline at end of file diff --git a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointConfiguration.java b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointConfiguration.java index 7a20121aad..a0f6c87e15 100644 --- a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointConfiguration.java +++ b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointConfiguration.java @@ -19,11 +19,14 @@ import org.kaaproject.kaa.common.dto.EndpointConfigurationDto; import org.kaaproject.kaa.server.common.dao.model.EndpointConfiguration; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Version; import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; import java.io.Serializable; import java.util.Arrays; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.dao.impl.DaoUtil.getArrayCopy; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.ENDPOINT_CONFIGURATION; @@ -35,6 +38,10 @@ public final class MongoEndpointConfiguration implements EndpointConfiguration, @Id private byte[] configurationHash; private byte[] configuration; + + @Version + @Field(OPT_LOCK) + private Long version; public MongoEndpointConfiguration() { } @@ -42,6 +49,7 @@ public MongoEndpointConfiguration() { public MongoEndpointConfiguration(EndpointConfigurationDto dto) { this.configuration = dto.getConfiguration(); this.configurationHash = dto.getConfigurationHash(); + this.version = dto.getVersion(); } public byte[] getConfigurationHash() { @@ -60,6 +68,16 @@ public void setConfiguration(byte[] configuration) { this.configuration = configuration; } + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -85,6 +103,8 @@ public EndpointConfigurationDto toDto() { EndpointConfigurationDto dto = new EndpointConfigurationDto(); dto.setConfiguration(configuration); dto.setConfigurationHash(configurationHash); + dto.setVersion(version); return dto; } + } diff --git a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointNotification.java b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointNotification.java index 92d8fc8110..2863fa1777 100644 --- a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointNotification.java +++ b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointNotification.java @@ -20,6 +20,7 @@ import org.kaaproject.kaa.common.dto.EndpointNotificationDto; import org.kaaproject.kaa.server.common.dao.model.EndpointNotification; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Version; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; @@ -27,6 +28,7 @@ import java.util.Arrays; import static org.kaaproject.kaa.common.dto.Util.getArrayCopy; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_NF_ENDPOINT_KEY_HASH; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.ENDPOINT_NOTIFICATION; @@ -40,6 +42,10 @@ public final class MongoEndpointNotification implements EndpointNotification, Se @Field(EP_NF_ENDPOINT_KEY_HASH) private byte[] endpointKeyHash; private MongoNotification notification; + + @Version + @Field(OPT_LOCK) + private Long version; public MongoEndpointNotification() { } @@ -48,6 +54,7 @@ public MongoEndpointNotification(EndpointNotificationDto dto) { this.id = dto.getId(); this.endpointKeyHash = getArrayCopy(dto.getEndpointKeyHash()); this.notification = dto.getNotificationDto() != null ? new MongoNotification(dto.getNotificationDto()) : null; + this.version = dto.getVersion(); } public String getId() { @@ -61,6 +68,16 @@ public MongoNotification getNotification() { public byte[] getEndpointKeyHash() { return endpointKeyHash; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public boolean equals(Object o) { @@ -105,6 +122,7 @@ public EndpointNotificationDto toDto() { dto.setId(id); dto.setEndpointKeyHash(getArrayCopy(endpointKeyHash)); dto.setNotificationDto(notification != null ? notification.toDto() : null); + dto.setVersion(version); return dto; } } diff --git a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointProfile.java b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointProfile.java index d3eb54f2d9..7af6dac798 100644 --- a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointProfile.java +++ b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointProfile.java @@ -16,49 +16,50 @@ package org.kaaproject.kaa.server.common.nosql.mongo.dao.model; -import com.mongodb.DBObject; -import com.mongodb.util.JSON; -import org.kaaproject.kaa.common.dto.EndpointProfileDto; -import org.kaaproject.kaa.server.common.dao.impl.DaoUtil; -import org.kaaproject.kaa.server.common.dao.model.EndpointProfile; -import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.Version; -import org.springframework.data.mongodb.core.index.Indexed; -import org.springframework.data.mongodb.core.mapping.Document; -import org.springframework.data.mongodb.core.mapping.Field; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.List; - import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.dao.impl.DaoUtil.getArrayCopy; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.ENDPOINT_PROFILE; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_ACCESS_TOKEN; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_APPLICATION_ID; -import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_GROUP_STATE; -import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SEQ_NUM; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_CHANGED_FLAG; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_CONFIGURATION_HASH; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_CONFIGURATION_VERSION; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_ECF_VERSION_STATE; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_ENDPOINT_KEY; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_ENDPOINT_KEY_HASH; +import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_GROUP_STATE; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_LOG_SCHEMA_VERSION; -import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SIMPLE_TOPIC_HASH; -import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_TOPIC_HASH; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_NOTIFICATION_VERSION; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_PROFILE_HASH; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_PROFILE_VERSION; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SDK_TOKEN; +import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SEQ_NUM; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SERVER_HASH; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SERVER_PROFILE_PROPERTY; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SERVER_PROFILE_VERSION_PROPERTY; +import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SIMPLE_TOPIC_HASH; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_SYSTEM_NF_VERSION; +import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_TOPIC_HASH; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_USER_CONFIGURATION_HASH; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_USER_ID; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_USER_NF_VERSION; +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; + +import org.kaaproject.kaa.common.dto.EndpointProfileDto; +import org.kaaproject.kaa.server.common.dao.impl.DaoUtil; +import org.kaaproject.kaa.server.common.dao.model.EndpointProfile; +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Version; +import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import com.mongodb.DBObject; +import com.mongodb.util.JSON; + @Document(collection = ENDPOINT_PROFILE) public final class MongoEndpointProfile implements EndpointProfile, Serializable { @@ -122,8 +123,7 @@ public final class MongoEndpointProfile implements EndpointProfile, Serializable private String serverProfile; @Version @Field(OPT_LOCK) - private Long optVersion; - + private Long version; public MongoEndpointProfile() { } @@ -159,9 +159,7 @@ public MongoEndpointProfile(EndpointProfileDto dto, Long version) { this.serverHash = dto.getServerHash(); this.sdkToken = dto.getSdkToken(); this.serverProfile = dto.getServerProfileBody(); - if (version != null) { - this.optVersion = version; - } + this.version = dto.getVersion(); } @Override @@ -378,14 +376,6 @@ public void setSdkToken(String sdkToken) { this.sdkToken = sdkToken; } - public Long getOptVersion() { - return optVersion; - } - - public void setOptVersion(Long optVersion) { - this.optVersion = optVersion; - } - @Override public String getServerProfile() { return serverProfile; @@ -394,6 +384,16 @@ public String getServerProfile() { public void setServerProfile(String serverProfile) { this.serverProfile = serverProfile; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public boolean equals(Object o) { @@ -547,6 +547,7 @@ public EndpointProfileDto toDto() { dto.setServerHash(serverHash); dto.setSdkToken(sdkToken); dto.setServerProfileBody(serverProfile); + dto.setVersion(version); return dto; } } diff --git a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointUser.java b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointUser.java index 2fddf98467..047d63efde 100644 --- a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointUser.java +++ b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointUser.java @@ -19,12 +19,14 @@ import org.kaaproject.kaa.common.dto.EndpointUserDto; import org.kaaproject.kaa.server.common.dao.model.EndpointUser; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Version; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; import java.io.Serializable; import java.util.List; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.ENDPOINT_USER; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_USER_ACCESS_TOKEN; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.EP_USER_ENDPOINT_IDS; @@ -49,7 +51,10 @@ public final class MongoEndpointUser implements EndpointUser, Serializable { private String accessToken; @Field(EP_USER_ENDPOINT_IDS) private List endpointIds; - + @Version + @Field(OPT_LOCK) + private Long version; + public MongoEndpointUser() { } @@ -60,6 +65,7 @@ public MongoEndpointUser(EndpointUserDto dto) { this.tenantId = dto.getTenantId(); this.accessToken = dto.getAccessToken(); this.endpointIds = dto.getEndpointIds(); + this.version = dto.getVersion(); } public String getId() { @@ -109,6 +115,16 @@ public List getEndpointIds() { public void setEndpointIds(List endpointIds) { this.endpointIds = endpointIds; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public int hashCode() { @@ -163,6 +179,7 @@ public EndpointUserDto toDto() { dto.setTenantId(tenantId); dto.setAccessToken(accessToken); dto.setEndpointIds(endpointIds); + dto.setVersion(version); return dto; } } \ No newline at end of file diff --git a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointUserConfiguration.java b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointUserConfiguration.java index 4593b736a4..4736a3f13f 100644 --- a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointUserConfiguration.java +++ b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoEndpointUserConfiguration.java @@ -15,6 +15,7 @@ */ package org.kaaproject.kaa.server.common.nosql.mongo.dao.model; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.USER_CONFIGURATION; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.USER_CONF_APP_TOKEN; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.USER_CONF_BODY; @@ -26,6 +27,7 @@ import org.kaaproject.kaa.common.dto.EndpointUserConfigurationDto; import org.kaaproject.kaa.server.common.dao.model.EndpointUserConfiguration; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Version; import org.springframework.data.mongodb.core.index.Indexed; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; @@ -49,7 +51,10 @@ public class MongoEndpointUserConfiguration implements EndpointUserConfiguration private Integer schemaVersion; @Field(USER_CONF_BODY) private String body; - + @Version + @Field(OPT_LOCK) + private Long version; + public MongoEndpointUserConfiguration() { } @@ -59,6 +64,7 @@ public MongoEndpointUserConfiguration(EndpointUserConfigurationDto dto) { this.schemaVersion = dto.getSchemaVersion(); this.body = dto.getBody(); this.id = userId + ID_DELIMITER + appToken + ID_DELIMITER + schemaVersion; + this.version = dto.getVersion(); } public String getUserId() { @@ -92,6 +98,16 @@ public String getBody() { public void setBody(String body) { this.body = body; } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } @Override public boolean equals(Object o) { @@ -138,6 +154,7 @@ public EndpointUserConfigurationDto toDto() { dto.setBody(body); dto.setSchemaVersion(schemaVersion); dto.setUserId(userId); + dto.setVersion(version); return dto; } } diff --git a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoModelConstants.java b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoModelConstants.java index d8e2630385..5a5e9c6928 100644 --- a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoModelConstants.java +++ b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoModelConstants.java @@ -21,7 +21,6 @@ public class MongoModelConstants { * Generic constants. */ public static final String ID = "_id"; - public static final String VERSION = "version"; public static final String BODY = "body"; public static final String ACCESS_TOKEN = "access_token"; public static final String ENDPOINT_KEY_HASH = "endpoint_key_hash"; @@ -38,7 +37,7 @@ public class MongoModelConstants { * {@link org.kaaproject.kaa.server.common.nosql.mongo.dao.model.EventClassFamilyVersionState} constants */ public static final String ECF_ID = "ecf_id"; - public static final String EVENT_CLASS_FAMILY_VERSION = VERSION; + public static final String EVENT_CLASS_FAMILY_VERSION = "ecf_version"; /** * {@link org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoEndpointConfiguration} constants @@ -62,7 +61,7 @@ public class MongoModelConstants { public static final String NF_TYPE = "notification_type"; public static final String NF_EXPIRED_AT = "expired_at"; public static final String NF_SEQ_NUM = "seq_num"; - public static final String NF_VERSION = VERSION; + public static final String NF_VERSION = "nf_version"; public static final String NF_BODY = BODY; /** @@ -93,9 +92,10 @@ public class MongoModelConstants { public static final String EP_CONFIGURATION_HASH = "configuration_hash"; public static final String EP_USER_CONFIGURATION_HASH = "user_configuration_hash"; public static final String EP_CONFIGURATION_VERSION = "configuration_version"; - public static final String EP_NOTIFICATION_VERSION = VERSION; public static final String EP_TOPIC_HASH = "topic_hash"; public static final String EP_SIMPLE_TOPIC_HASH = "simple_topic_hash"; + public static final String EP_NOTIFICATION_VERSION = "ep_nf_version"; + public static final String EP_NF_HASH = "nf_hash"; public static final String EP_SYSTEM_NF_VERSION = "system_nf_version"; public static final String EP_USER_NF_VERSION = "user_nf_version"; public static final String EP_LOG_SCHEMA_VERSION = "log_schema_version"; diff --git a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoNotification.java b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoNotification.java index 3a6c8d8793..3205f962c2 100644 --- a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoNotification.java +++ b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoNotification.java @@ -21,6 +21,7 @@ import org.kaaproject.kaa.server.common.dao.model.Notification; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.annotation.Version; import org.springframework.data.mongodb.core.index.Indexed; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; @@ -29,6 +30,7 @@ import java.util.Arrays; import java.util.Date; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.dao.impl.DaoUtil.getArrayCopy; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.NF_APPLICATION_ID; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.NF_EXPIRED_AT; @@ -54,7 +56,7 @@ public final class MongoNotification implements Notification, Serializable { @Field(NF_TOPIC_ID) private String topicId; @Field(NF_VERSION) - private int version; + private int nfVersion; @LastModifiedDate @Field(NF_LAST_MODIFY_TIME) private Date lastModifyTime; @@ -67,7 +69,10 @@ public final class MongoNotification implements Notification, Serializable { private Date expiredAt; @Field(NF_SEQ_NUM) private int secNum; - + @Version + @Field(OPT_LOCK) + private Long version; + public MongoNotification() { } @@ -76,12 +81,13 @@ public MongoNotification(NotificationDto dto) { this.applicationId = dto.getApplicationId(); this.schemaId = dto.getSchemaId(); this.topicId = dto.getTopicId(); - this.version = dto.getVersion(); + this.nfVersion = dto.getNfVersion(); this.lastModifyTime = dto.getLastTimeModify(); this.type = dto.getType(); this.body = getArrayCopy(dto.getBody()); this.expiredAt = dto.getExpiredAt(); this.secNum = dto.getSecNum(); + this.version = dto.getVersion(); } public String getId() { @@ -100,8 +106,8 @@ public String getTopicId() { return topicId; } - public int getVersion() { - return version; + public int getNfVersion() { + return nfVersion; } public Date getLastModifyTime() { @@ -124,6 +130,16 @@ public int getSecNum() { return secNum; } + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -138,7 +154,7 @@ public boolean equals(Object o) { if (secNum != that.secNum) { return false; } - if (version != that.version) { + if (nfVersion != that.nfVersion) { return false; } if (applicationId != null ? !applicationId.equals(that.applicationId) : that.applicationId != null) { @@ -171,7 +187,7 @@ public int hashCode() { int result = applicationId != null ? applicationId.hashCode() : 0; result = 31 * result + (schemaId != null ? schemaId.hashCode() : 0); result = 31 * result + (topicId != null ? topicId.hashCode() : 0); - result = 31 * result + version; + result = 31 * result + nfVersion; result = 31 * result + (lastModifyTime != null ? lastModifyTime.hashCode() : 0); result = 31 * result + (type != null ? type.hashCode() : 0); result = 31 * result + (body != null ? Arrays.hashCode(body) : 0); @@ -187,7 +203,7 @@ public String toString() { ", applicationId=" + applicationId + ", schemaId=" + schemaId + ", topicId=" + topicId + - ", version=" + version + + ", nfVersion=" + nfVersion + ", lastModifyTime=" + lastModifyTime + ", type=" + type + ", body=" + Arrays.toString(body) + @@ -204,11 +220,12 @@ public NotificationDto toDto() { dto.setSchemaId(schemaId); dto.setTopicId(topicId); dto.setLastTimeModify(lastModifyTime); - dto.setVersion(version); + dto.setNfVersion(nfVersion); dto.setType(type); dto.setBody(getArrayCopy(body)); dto.setExpiredAt(expiredAt); dto.setSecNum(secNum); + dto.setVersion(version); return dto; } } diff --git a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoTopicListEntry.java b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoTopicListEntry.java index dafda4a272..903ace9b96 100644 --- a/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoTopicListEntry.java +++ b/server/common/nosql/mongo-dao/src/main/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/model/MongoTopicListEntry.java @@ -20,6 +20,7 @@ import org.kaaproject.kaa.common.dto.TopicListEntryDto; import org.kaaproject.kaa.server.common.dao.model.TopicListEntry; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Version; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; @@ -30,6 +31,7 @@ import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.TOPIC_LIST_SIMPLE_HASH; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.TOPIC_LIST_TOPIC_IDS; +import static org.kaaproject.kaa.server.common.dao.DaoConstants.OPT_LOCK; import static org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoModelConstants.TOPIC_LIST_ENTRY; @Document(collection = TOPIC_LIST_ENTRY) @@ -46,6 +48,10 @@ public final class MongoTopicListEntry implements TopicListEntry, Serializable { @Field(TOPIC_LIST_TOPIC_IDS) private List topicIds; + @Version + @Field(OPT_LOCK) + private Long version; + public MongoTopicListEntry() { } @@ -58,6 +64,7 @@ public MongoTopicListEntry(TopicListEntryDto dto) { topicIds.add(topic.getId()); } } + this.version = dto.getVersion(); } public byte[] getHash() { @@ -120,6 +127,18 @@ public TopicListEntryDto toDto() { topicDto.setId(topicId); topicDtos.add(topicDto); } - return new TopicListEntryDto(simpleHash, hash, topicDtos); + TopicListEntryDto dto = new TopicListEntryDto(simpleHash, hash, topicDtos); + dto.setVersion(version); + return dto; + } + + @Override + public Long getVersion() { + return version; + } + + @Override + public void setVersion(Long version) { + this.version = version; } } diff --git a/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/MongoDBEndpointServiceImplTest.java b/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/MongoDBEndpointServiceImplTest.java index 7b5ef3510e..6c0f72cfb2 100644 --- a/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/MongoDBEndpointServiceImplTest.java +++ b/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/MongoDBEndpointServiceImplTest.java @@ -15,7 +15,6 @@ */ package org.kaaproject.kaa.server.common.dao.service; - import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; diff --git a/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/MongoDBServerProfileServiceImpl.java b/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/MongoDBServerProfileServiceImplTest.java similarity index 94% rename from server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/MongoDBServerProfileServiceImpl.java rename to server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/MongoDBServerProfileServiceImplTest.java index 7b5ecd3c39..4ce91d6713 100644 --- a/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/MongoDBServerProfileServiceImpl.java +++ b/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/dao/service/MongoDBServerProfileServiceImplTest.java @@ -27,7 +27,7 @@ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "/mongo-dao-test-context.xml") @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) -public class MongoDBServerProfileServiceImpl extends ServerProfileServiceImplTest { +public class MongoDBServerProfileServiceImplTest extends ServerProfileServiceImplTest { @BeforeClass public static void init() throws Exception { diff --git a/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointProfileMongoDaoTest.java b/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointProfileMongoDaoTest.java index fb109f90ee..5afbf565cf 100644 --- a/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointProfileMongoDaoTest.java +++ b/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/EndpointProfileMongoDaoTest.java @@ -16,18 +16,31 @@ package org.kaaproject.kaa.server.common.nosql.mongo.dao; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import org.kaaproject.kaa.common.dto.EndpointGroupDto; +import org.kaaproject.kaa.common.dto.EndpointGroupStateDto; import org.kaaproject.kaa.common.dto.EndpointProfileBodyDto; import org.kaaproject.kaa.common.dto.EndpointProfileDto; import org.kaaproject.kaa.common.dto.EndpointProfilesBodyDto; import org.kaaproject.kaa.common.dto.EndpointProfilesPageDto; import org.kaaproject.kaa.common.dto.PageLinkDto; -import org.kaaproject.kaa.server.common.dao.lock.KaaOptimisticLockingFailureException; +import org.kaaproject.kaa.server.common.dao.exception.KaaOptimisticLockingFailureException; import org.kaaproject.kaa.server.common.dao.model.EndpointProfile; import org.kaaproject.kaa.server.common.nosql.mongo.dao.model.MongoEndpointProfile; import org.slf4j.Logger; @@ -36,15 +49,6 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "/mongo-dao-test-context.xml") @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @@ -169,6 +173,7 @@ public void saveEndpointProfileTest() { EndpointProfileDto endpointProfile = generateEndpointProfileDto(null, null); Assert.assertNotNull(endpointProfile); endpointProfile.setId(null); + endpointProfile.setVersion(null); MongoEndpointProfile saved = endpointProfileDao.save(new MongoEndpointProfile(endpointProfile)); Assert.assertNotNull(saved); Assert.assertEquals(endpointProfile, saved.toDto()); @@ -206,6 +211,55 @@ public void removeByAppId() { MongoEndpointProfile found = endpointProfileDao.findByKeyHash(keyHash); Assert.assertNull(found); } + + @Test + public void testUpdate() throws Exception { + List cfGroupStateSave = new ArrayList(); + List cfGroupStateUpdate = new ArrayList(); + PageLinkDto pageLink; + EndpointProfilesPageDto found; + + EndpointGroupDto endpointGroupDto = new EndpointGroupDto(); + endpointGroupDto.setWeight(1); + cfGroupStateSave.add(new EndpointGroupStateDto("111", null, null)); + cfGroupStateSave.add(new EndpointGroupStateDto("222", null, null)); + cfGroupStateSave.add(new EndpointGroupStateDto("333", null, null)); + EndpointProfileDto endpointProfileSave = generateEndpointProfileForTestUpdate(null, "TEST_KEY_HASH".getBytes(), cfGroupStateSave); + EndpointProfile saved = endpointProfileDao.save(endpointProfileSave); + cfGroupStateUpdate.add(new EndpointGroupStateDto("111", null, null)); + cfGroupStateUpdate.add(new EndpointGroupStateDto("444", null, null)); + EndpointProfileDto endpointProfileUpdate = generateEndpointProfileForTestUpdate(saved.getId(), "TEST_KEY_HASH".getBytes(), cfGroupStateUpdate); + endpointProfileUpdate.setVersion(saved.getVersion()); + endpointProfileDao.save(endpointProfileUpdate); + String limit = "10"; + String offset = "0"; + String[] endpointGroupId = {"111", "444", "222", "333"}; + for (int i = 0; i < 2; i++) { + pageLink = new PageLinkDto(endpointGroupId[i], limit, offset); + found = endpointProfileDao.findByEndpointGroupId(pageLink); + Assert.assertFalse(found.getEndpointProfiles().isEmpty()); + } + for (int i = 2; i < 4; i++) { + pageLink = new PageLinkDto(endpointGroupId[i], limit, offset); + found = endpointProfileDao.findByEndpointGroupId(pageLink); + Assert.assertTrue(found.getEndpointProfiles().isEmpty()); + } + } + + protected EndpointProfileDto generateEndpointProfileForTestUpdate(String id, byte[] keyHash, List groupState) { + EndpointProfileDto profileDto = new EndpointProfileDto(); + profileDto.setId(id); + profileDto.setApplicationId(generateStringId()); + profileDto.setEndpointKeyHash(keyHash); + profileDto.setAccessToken(generateStringId()); + profileDto.setGroupState(groupState); + profileDto.setSdkToken(UUID.randomUUID().toString()); + return profileDto; + } + + protected String generateStringId() { + return UUID.randomUUID().toString(); + } @Test(expected = KaaOptimisticLockingFailureException.class) public void testOptimisticLockWithConcurrency() throws Throwable { diff --git a/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/NotificationMongoDaoTest.java b/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/NotificationMongoDaoTest.java index 97808af6ef..f84075acfd 100644 --- a/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/NotificationMongoDaoTest.java +++ b/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/NotificationMongoDaoTest.java @@ -49,7 +49,6 @@ public static void after() throws Exception { @After public void afterTest() { MongoDataLoader.clearDBData(); - clearDBData(); } @Test diff --git a/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/NotificationServiceImplTest.java b/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/NotificationServiceImplTest.java index 0faeb4a680..23d8f71770 100644 --- a/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/NotificationServiceImplTest.java +++ b/server/common/nosql/mongo-dao/src/test/java/org/kaaproject/kaa/server/common/nosql/mongo/dao/NotificationServiceImplTest.java @@ -190,7 +190,7 @@ public void testRemoveNotificationSchemasByAppId() { public void testFindNotificationsByTopicIdAndVersionAndStartSecNum() { NotificationDto dto = generateNotificationsDto(null, null, 3, NotificationTypeDto.USER).get(0); String topicId = dto.getTopicId(); - List notifications = notificationService.findNotificationsByTopicIdAndVersionAndStartSecNum(topicId, 0, 1, dto.getVersion()); + List notifications = notificationService.findNotificationsByTopicIdAndVersionAndStartSecNum(topicId, 0, 1, dto.getNfVersion()); Assert.assertFalse(notifications.isEmpty()); Assert.assertEquals(3, notifications.size()); } diff --git a/server/common/nosql/mongo-dao/src/test/resources/mongo-dao-test-context.xml b/server/common/nosql/mongo-dao/src/test/resources/mongo-dao-test-context.xml index ded54386aa..04307560b5 100644 --- a/server/common/nosql/mongo-dao/src/test/resources/mongo-dao-test-context.xml +++ b/server/common/nosql/mongo-dao/src/test/resources/mongo-dao-test-context.xml @@ -34,6 +34,9 @@ http://www.springframework.org/schema/util/spring-util-3.0.xsd"> + + + diff --git a/server/node/src/main/java/org/kaaproject/kaa/server/operations/service/akka/actors/core/TopicActor.java b/server/node/src/main/java/org/kaaproject/kaa/server/operations/service/akka/actors/core/TopicActor.java index 3925bc1a35..491ad22a33 100644 --- a/server/node/src/main/java/org/kaaproject/kaa/server/operations/service/akka/actors/core/TopicActor.java +++ b/server/node/src/main/java/org/kaaproject/kaa/server/operations/service/akka/actors/core/TopicActor.java @@ -280,9 +280,9 @@ public static List filterMap(SortedMap()); when(eventService.isMainUserNode(Mockito.anyString())).thenReturn(true); - + when(clusterService.getNodeId()).thenReturn(LOCAL_NODE_ID); when(clusterService.getEntityNode(Mockito.any(byte[].class))).thenReturn(LOCAL_NODE_ID); when(clusterService.getEntityNode(Mockito.any(EndpointObjectHash.class))).thenReturn(LOCAL_NODE_ID); @@ -330,7 +330,7 @@ private SessionInitMessage toSignedRequest(final UUID uuid, final ChannelType ch private SessionInitMessage toSignedRequest(final UUID uuid, final ChannelType channelType, final ChannelContext ctx, SyncRequest request, final MessageBuilder responseBuilder, final ErrorBuilder errorBuilder, MessageEncoderDecoder crypt) - throws Exception { + throws Exception { AvroByteArrayConverter requestConverter = new AvroByteArrayConverter<>(SyncRequest.class); byte[] data = requestConverter.toByteArray(request); @@ -496,8 +496,8 @@ public void testEndpointRegistrationRequest() throws Exception { Mockito.verify(operationsService, Mockito.timeout(TIMEOUT * 10).atLeastOnce()).syncClientProfile(Mockito.any(SyncContext.class), Mockito.any(ProfileClientSync.class)); - Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()) - .build(Mockito.any(byte[].class), Mockito.any(boolean.class)); + Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()).build(Mockito.any(byte[].class), + Mockito.any(boolean.class)); } @Test @@ -516,8 +516,8 @@ public void testEndpointUpdateRequest() throws Exception { profileSync.setProfileBody(ByteBuffer.wrap(PROFILE_BODY.getBytes())); request.setProfileSyncRequest(profileSync); - Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))).thenReturn( - clientPair.getPublic()); + Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))) + .thenReturn(clientPair.getPublic()); whenSync(simpleResponse); MessageBuilder responseBuilder = Mockito.mock(MessageBuilder.class); @@ -530,8 +530,8 @@ public void testEndpointUpdateRequest() throws Exception { Mockito.verify(operationsService, Mockito.timeout(TIMEOUT * 10).atLeastOnce()).syncClientProfile(Mockito.any(SyncContext.class), Mockito.any(ProfileClientSync.class)); - Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()) - .build(Mockito.any(byte[].class), Mockito.any(boolean.class)); + Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()).build(Mockito.any(byte[].class), + Mockito.any(boolean.class)); } @Test @@ -548,8 +548,8 @@ public void testSyncRequest() throws Exception { SyncContext holder = simpleResponse; - Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))).thenReturn( - clientPair.getPublic()); + Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))) + .thenReturn(clientPair.getPublic()); whenSync(holder); MessageBuilder responseBuilder = Mockito.mock(MessageBuilder.class); @@ -562,8 +562,8 @@ public void testSyncRequest() throws Exception { Mockito.verify(operationsService, Mockito.timeout(TIMEOUT * 10).atLeastOnce()).syncClientProfile(Mockito.any(SyncContext.class), Mockito.any(ProfileClientSync.class)); - Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()) - .build(Mockito.any(byte[].class), Mockito.any(boolean.class)); + Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()).build(Mockito.any(byte[].class), + Mockito.any(boolean.class)); } @Test @@ -580,8 +580,8 @@ public void testMultipleSyncRequest() throws Exception { SyncContext holder = simpleResponse; - Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))).thenReturn( - clientPair.getPublic()); + Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))) + .thenReturn(clientPair.getPublic()); whenSync(holder); Assert.assertNotNull(akkaService.getActorSystem()); @@ -614,8 +614,8 @@ public void testLongSyncRequest() throws Exception { md.setTimeout(1000l); request.setSyncRequestMetaData(md); - Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))).thenReturn( - clientPair.getPublic()); + Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))) + .thenReturn(clientPair.getPublic()); whenSync(noDeltaResponse); MessageBuilder responseBuilder = Mockito.mock(MessageBuilder.class); @@ -628,13 +628,13 @@ public void testLongSyncRequest() throws Exception { Mockito.verify(operationsService, Mockito.timeout(TIMEOUT).atLeastOnce()).syncClientProfile(Mockito.any(SyncContext.class), Mockito.any(ProfileClientSync.class)); - Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()) - .build(Mockito.any(byte[].class), Mockito.any(boolean.class)); + Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()).build(Mockito.any(byte[].class), + Mockito.any(boolean.class)); } private void whenSync(SyncContext response) throws GetDeltaException { - Mockito.when(operationsService.syncClientProfile(Mockito.any(SyncContext.class), Mockito.any(ProfileClientSync.class))).thenReturn( - response); + Mockito.when(operationsService.syncClientProfile(Mockito.any(SyncContext.class), Mockito.any(ProfileClientSync.class))) + .thenReturn(response); Mockito.when( operationsService.processEndpointAttachDetachRequests(Mockito.any(SyncContext.class), Mockito.any(UserClientSync.class))) .thenReturn(response); @@ -670,12 +670,12 @@ public void testLongSyncNotification() throws Exception { request.setSyncRequestMetaData(md); ConfigurationSyncRequest csRequest = new ConfigurationSyncRequest(); - csRequest.setConfigurationHash(ByteBuffer.wrap(new byte[]{})); + csRequest.setConfigurationHash(ByteBuffer.wrap(new byte[] {})); csRequest.setResyncOnly(true); request.setConfigurationSyncRequest(csRequest); - Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))).thenReturn( - clientPair.getPublic()); + Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))) + .thenReturn(clientPair.getPublic()); whenSync(noDeltaResponse); MessageBuilder responseBuilder = Mockito.mock(MessageBuilder.class); @@ -696,8 +696,8 @@ public void testLongSyncNotification() throws Exception { thriftNotification.setAppId(APP_ID); akkaService.onNotification(thriftNotification); - Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()) - .build(Mockito.any(byte[].class), Mockito.any(boolean.class)); + Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()).build(Mockito.any(byte[].class), + Mockito.any(boolean.class)); } @Test @@ -724,21 +724,21 @@ public void testLongSyncUnicastNotification() throws Exception { Mockito.verify(operationsService, Mockito.timeout(TIMEOUT / 2).atLeastOnce()).syncClientProfile(Mockito.any(SyncContext.class), Mockito.any(ProfileClientSync.class)); - Mockito.when( - operationsService.updateSyncResponse(noDeltaResponse.getResponse(), new ArrayList(), - UNICAST_NOTIFICATION_ID)).thenReturn(noDeltaResponse.getResponse()); + Mockito.when(operationsService.updateSyncResponse(noDeltaResponse.getResponse(), new ArrayList(), + UNICAST_NOTIFICATION_ID)).thenReturn(noDeltaResponse.getResponse()); Mockito.when(applicationService.findAppById(APP_ID)).thenReturn(applicationDto); - - EndpointAddress address = new EndpointAddress(applicationDto.getTenantId(), applicationDto.getApplicationToken(), EndpointObjectHash.fromBytes(clientPublicKeyHash.array())); + + EndpointAddress address = new EndpointAddress(applicationDto.getTenantId(), applicationDto.getApplicationToken(), + EndpointObjectHash.fromBytes(clientPublicKeyHash.array())); ActorClassifier classifier = new ActorClassifier(true); - //TODO: replace nulls with values + // TODO: replace nulls with values ThriftUnicastNotificationMessage msg = new ThriftUnicastNotificationMessage(null, null, UNICAST_NOTIFICATION_ID); clusterServiceListener.onEndpointActorMsg(new ThriftEndpointActorMsg(address, classifier, msg)); - Mockito.verify(operationsService, Mockito.timeout(10 * TIMEOUT / 2).atLeastOnce()).updateSyncResponse( - noDeltaResponse.getResponse(), new ArrayList(), UNICAST_NOTIFICATION_ID); - Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()) - .build(Mockito.any(byte[].class), Mockito.any(boolean.class)); + Mockito.verify(operationsService, Mockito.timeout(10 * TIMEOUT / 2).atLeastOnce()).updateSyncResponse(noDeltaResponse.getResponse(), + new ArrayList(), UNICAST_NOTIFICATION_ID); + Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()).build(Mockito.any(byte[].class), + Mockito.any(boolean.class)); } @@ -766,9 +766,8 @@ public void testLongSyncTopicNotificationOnStart() throws Exception { ErrorBuilder errorBuilder = Mockito.mock(ErrorBuilder.class); whenSync(noDeltaResponseWithTopicState); - Mockito.when( - operationsService.updateSyncResponse(noDeltaResponseWithTopicState.getResponse(), - Collections.singletonList(topicNotification), null)).thenReturn(noDeltaResponseWithTopicState.getResponse()); + Mockito.when(operationsService.updateSyncResponse(noDeltaResponseWithTopicState.getResponse(), + Collections.singletonList(topicNotification), null)).thenReturn(noDeltaResponseWithTopicState.getResponse()); SessionInitMessage message = toSignedRequest(UUID.randomUUID(), ChannelType.SYNC_WITH_TIMEOUT, channelContextMock, request, responseBuilder, errorBuilder); @@ -777,10 +776,10 @@ public void testLongSyncTopicNotificationOnStart() throws Exception { Mockito.verify(operationsService, Mockito.timeout(TIMEOUT / 2).atLeastOnce()).syncClientProfile(Mockito.any(SyncContext.class), Mockito.any(ProfileClientSync.class)); - Mockito.verify(operationsService, Mockito.timeout(TIMEOUT / 2).atLeastOnce()).updateSyncResponse( - noDeltaResponseWithTopicState.getResponse(), Collections.singletonList(topicNotification), null); - Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()) - .build(Mockito.any(byte[].class), Mockito.any(boolean.class)); + Mockito.verify(operationsService, Mockito.timeout(TIMEOUT / 2).atLeastOnce()) + .updateSyncResponse(noDeltaResponseWithTopicState.getResponse(), Collections.singletonList(topicNotification), null); + Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()).build(Mockito.any(byte[].class), + Mockito.any(boolean.class)); } @Test @@ -797,9 +796,8 @@ public void testLongSyncTopicNotification() throws Exception { Mockito.when(applicationService.findAppById(APP_ID)).thenReturn(applicationDto); Mockito.when(notificationDeltaService.findNotificationById(UNICAST_NOTIFICATION_ID)).thenReturn(topicNotification); whenSync(noDeltaResponseWithTopicState); - Mockito.when( - operationsService.updateSyncResponse(noDeltaResponseWithTopicState.getResponse(), - Collections.singletonList(topicNotification), null)).thenReturn(noDeltaResponseWithTopicState.getResponse()); + Mockito.when(operationsService.updateSyncResponse(noDeltaResponseWithTopicState.getResponse(), + Collections.singletonList(topicNotification), null)).thenReturn(noDeltaResponseWithTopicState.getResponse()); MessageBuilder responseBuilder = Mockito.mock(MessageBuilder.class); ErrorBuilder errorBuilder = Mockito.mock(ErrorBuilder.class); @@ -819,10 +817,10 @@ public void testLongSyncTopicNotification() throws Exception { Mockito.verify(operationsService, Mockito.timeout(TIMEOUT / 2).atLeastOnce()).syncClientProfile(Mockito.any(SyncContext.class), Mockito.any(ProfileClientSync.class)); - Mockito.verify(operationsService, Mockito.timeout(TIMEOUT / 2).atLeastOnce()).updateSyncResponse( - noDeltaResponseWithTopicState.getResponse(), Collections.singletonList(topicNotification), null); - Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()) - .build(Mockito.any(byte[].class), Mockito.any(boolean.class)); + Mockito.verify(operationsService, Mockito.timeout(TIMEOUT / 2).atLeastOnce()) + .updateSyncResponse(noDeltaResponseWithTopicState.getResponse(), Collections.singletonList(topicNotification), null); + Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()).build(Mockito.any(byte[].class), + Mockito.any(boolean.class)); } @Test @@ -849,7 +847,8 @@ public void testRedirect() throws Exception { response.setStatus(SyncResponseResultType.REDIRECT); response.setRedirectSyncResponse(new RedirectSyncResponse("testDNS".hashCode())); - Mockito.verify(operationsService, Mockito.timeout(TIMEOUT / 2).never()).syncClientProfile(Mockito.any(SyncContext.class), + Thread.sleep(TIMEOUT / 2); + Mockito.verify(operationsService, Mockito.never()).syncClientProfile(Mockito.any(SyncContext.class), Mockito.any(ProfileClientSync.class)); AvroByteArrayConverter responseConverter = new AvroByteArrayConverter<>(SyncResponse.class); @@ -933,7 +932,8 @@ public byte[] getEncodedMessageData() { response.setStatus(SyncResponseResultType.REDIRECT); response.setRedirectSyncResponse(new RedirectSyncResponse("testDNS".hashCode())); - Mockito.verify(operationsService, Mockito.timeout(TIMEOUT / 2).never()).syncClientProfile(Mockito.any(SyncContext.class), + Thread.sleep(TIMEOUT / 2); + Mockito.verify(operationsService, Mockito.never()).syncClientProfile(Mockito.any(SyncContext.class), Mockito.any(ProfileClientSync.class)); AvroByteArrayConverter responseConverter = new AvroByteArrayConverter<>(SyncResponse.class); @@ -1187,14 +1187,14 @@ public void testRemoteIncomingEndpointEventBasic() throws Exception { org.kaaproject.kaa.server.sync.Event event = new org.kaaproject.kaa.server.sync.Event(0, FQN1, ByteBuffer.wrap(new byte[0]), null, null); - EndpointEvent endpointEvent = new EndpointEvent(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()), event, - UUID.randomUUID(), System.currentTimeMillis(), ECF1_VERSION); - RemoteEndpointEvent remoteEvent = new RemoteEndpointEvent(TENANT_ID, USER_ID, endpointEvent, new RouteTableAddress( - EndpointObjectHash.fromBytes(targetPublicKeyHash.array()), APP_TOKEN, "SERVER1")); + EndpointEvent endpointEvent = new EndpointEvent(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()), event, UUID.randomUUID(), + System.currentTimeMillis(), ECF1_VERSION); + RemoteEndpointEvent remoteEvent = new RemoteEndpointEvent(TENANT_ID, USER_ID, endpointEvent, + new RouteTableAddress(EndpointObjectHash.fromBytes(targetPublicKeyHash.array()), APP_TOKEN, "SERVER1")); akkaService.getListener().onEvent(remoteEvent); - event = new org.kaaproject.kaa.server.sync.Event(0, FQN1, ByteBuffer.wrap(new byte[0]), null, Base64Util.encode(targetPublicKeyHash - .array())); + event = new org.kaaproject.kaa.server.sync.Event(0, FQN1, ByteBuffer.wrap(new byte[0]), null, + Base64Util.encode(targetPublicKeyHash.array())); ServerSync eventResponse = new ServerSync(); eventResponse.setStatus(org.kaaproject.kaa.server.sync.SyncStatus.SUCCESS); @@ -1263,8 +1263,8 @@ public void testRemoteOutcomingEndpointEventBasic() throws Exception { RouteTableAddress remoteAddress = new RouteTableAddress(EndpointObjectHash.fromBytes(targetPublicKeyHash.array()), APP_TOKEN, SERVER2); - RouteInfo routeInfo = new RouteInfo(TENANT_ID, USER_ID, remoteAddress, Arrays.asList(new EventClassFamilyVersion(ECF1_ID, - ECF1_VERSION))); + RouteInfo routeInfo = new RouteInfo(TENANT_ID, USER_ID, remoteAddress, + Arrays.asList(new EventClassFamilyVersion(ECF1_ID, ECF1_VERSION))); TimeUnit.SECONDS.sleep(2); akkaService.getListener().onRouteInfo(routeInfo); @@ -1284,8 +1284,8 @@ public void testLogSyncRequest() throws Exception { md.setTimeout(1000l); request.setSyncRequestMetaData(md); - LogSyncRequest logRequest = new LogSyncRequest(REQUEST_ID, Collections.singletonList(new LogEntry(ByteBuffer.wrap("String" - .getBytes())))); + LogSyncRequest logRequest = new LogSyncRequest(REQUEST_ID, + Collections.singletonList(new LogEntry(ByteBuffer.wrap("String".getBytes())))); request.setLogSyncRequest(logRequest); whenSync(noDeltaResponseWithTopicState); @@ -1296,25 +1296,25 @@ public void testLogSyncRequest() throws Exception { EndpointProfileSchemaDto profileSchemaDto = new EndpointProfileSchemaDto(); profileSchemaDto.setId("1"); profileSchemaDto.setCtlSchemaId("22"); - + CTLSchemaDto ctlSchema = new CTLSchemaDto(); ctlSchema.setId("22"); - + when(cacheService.getProfileSchemaByAppAndVersion(new AppVersionKey(APP_TOKEN, 0))).thenReturn(profileSchemaDto); when(cacheService.getCtlSchemaById("22")).thenReturn(ctlSchema); when(ctlService.flatExportAsString(ctlSchema)).thenReturn("ClientProfileSchema"); - + ServerProfileSchemaDto serverProfileSchemaDto = new ServerProfileSchemaDto(); serverProfileSchemaDto.setId("1"); serverProfileSchemaDto.setCtlSchemaId("23"); - + CTLSchemaDto serverCtlSchema = new CTLSchemaDto(); serverCtlSchema.setId("23"); - + when(cacheService.getServerProfileSchemaByAppAndVersion(new AppVersionKey(APP_TOKEN, 0))).thenReturn(serverProfileSchemaDto); when(cacheService.getCtlSchemaById("23")).thenReturn(serverCtlSchema); when(ctlService.flatExportAsString(serverCtlSchema)).thenReturn("ServerProfileSchema"); - + Mockito.when(mockAppender.isSchemaVersionSupported(Mockito.anyInt())).thenReturn(true); MessageBuilder responseBuilder = Mockito.mock(MessageBuilder.class); @@ -1333,8 +1333,8 @@ public void testLogSyncRequest() throws Exception { Mockito.verify(mockAppender, Mockito.timeout(TIMEOUT).atLeastOnce()).doAppend(Mockito.any(BaseLogEventPack.class), Mockito.any(LogDeliveryCallback.class)); - Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()) - .build(Mockito.any(byte[].class), Mockito.any(boolean.class)); + Mockito.verify(responseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()).build(Mockito.any(byte[].class), + Mockito.any(boolean.class)); } @Test @@ -1391,14 +1391,14 @@ public void testUserChange() throws Exception { RouteTableAddress remoteAddress = new RouteTableAddress(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()), APP_TOKEN, SERVER2); - RouteInfo remoteRouteInfo = new RouteInfo(TENANT_ID, USER_ID, remoteAddress, Arrays.asList(new EventClassFamilyVersion(ECF1_ID, - ECF1_VERSION))); + RouteInfo remoteRouteInfo = new RouteInfo(TENANT_ID, USER_ID, remoteAddress, + Arrays.asList(new EventClassFamilyVersion(ECF1_ID, ECF1_VERSION))); TimeUnit.SECONDS.sleep(2); akkaService.getListener().onRouteInfo(remoteRouteInfo); RouteTableAddress localAddress = new RouteTableAddress(EndpointObjectHash.fromBytes(targetPublicKeyHash.array()), APP_TOKEN, null); - RouteInfo localRouteInfo = new RouteInfo(TENANT_ID, USER_ID, localAddress, Arrays.asList(new EventClassFamilyVersion(ECF1_ID, - ECF1_VERSION))); + RouteInfo localRouteInfo = new RouteInfo(TENANT_ID, USER_ID, localAddress, + Arrays.asList(new EventClassFamilyVersion(ECF1_ID, ECF1_VERSION))); Mockito.verify(eventService, Mockito.timeout(TIMEOUT).atLeastOnce()).sendRouteInfo(Collections.singletonList(localRouteInfo), SERVER2); @@ -1419,8 +1419,8 @@ public void testUserChange() throws Exception { targetRequest, responseBuilder, errorBuilder, targetCrypt); akkaService.process(targetMessage); Mockito.verify(eventService, Mockito.timeout(TIMEOUT).atLeastOnce()).sendUserRouteInfo(new UserRouteInfo(TENANT_ID, USER_ID + "2")); - Mockito.verify(eventService, Mockito.timeout(TIMEOUT).atLeastOnce()).sendRouteInfo( - RouteInfo.deleteRouteFromAddress(TENANT_ID, USER_ID, localAddress), SERVER2); + Mockito.verify(eventService, Mockito.timeout(TIMEOUT).atLeastOnce()) + .sendRouteInfo(RouteInfo.deleteRouteFromAddress(TENANT_ID, USER_ID, localAddress), SERVER2); } @Test @@ -1490,8 +1490,9 @@ public void testEndpointAttach() throws Exception { sourceResponse.setRequestId(REQUEST_ID); sourceResponse.setStatus(org.kaaproject.kaa.server.sync.SyncStatus.SUCCESS); UserServerSync userSyncResponse = new UserServerSync(); - userSyncResponse.setEndpointAttachResponses(Collections.singletonList(new org.kaaproject.kaa.server.sync.EndpointAttachResponse( - REQUEST_ID, Base64Util.encode(targetPublicKeyHash.array()), org.kaaproject.kaa.server.sync.SyncStatus.SUCCESS))); + userSyncResponse + .setEndpointAttachResponses(Collections.singletonList(new org.kaaproject.kaa.server.sync.EndpointAttachResponse(REQUEST_ID, + Base64Util.encode(targetPublicKeyHash.array()), org.kaaproject.kaa.server.sync.SyncStatus.SUCCESS))); sourceResponse.setUserSync(userSyncResponse); SyncContext sourceResponseHolder = new SyncContext(sourceResponse); @@ -1517,8 +1518,8 @@ public void testEndpointAttach() throws Exception { targetSyncResponse.setRequestId(REQUEST_ID); targetSyncResponse.setStatus(SyncResponseResultType.SUCCESS); targetSyncResponse.setUserSyncResponse(new UserSyncResponse()); - targetSyncResponse.getUserSyncResponse().setUserAttachNotification( - new UserAttachNotification(USER_ID, Base64Util.encode(clientPublicKeyHash.array()))); + targetSyncResponse.getUserSyncResponse() + .setUserAttachNotification(new UserAttachNotification(USER_ID, Base64Util.encode(clientPublicKeyHash.array()))); AvroByteArrayConverter responseConverter = new AvroByteArrayConverter<>(SyncResponse.class); byte[] response = responseConverter.toByteArray(targetSyncResponse); @@ -1593,8 +1594,8 @@ public void testEndpointDetach() throws Exception { sourceResponse.setRequestId(REQUEST_ID); sourceResponse.setStatus(org.kaaproject.kaa.server.sync.SyncStatus.SUCCESS); UserServerSync userSyncResponse = new UserServerSync(); - userSyncResponse.setEndpointDetachResponses(Collections.singletonList(new org.kaaproject.kaa.server.sync.EndpointDetachResponse( - REQUEST_ID, org.kaaproject.kaa.server.sync.SyncStatus.SUCCESS))); + userSyncResponse.setEndpointDetachResponses(Collections.singletonList( + new org.kaaproject.kaa.server.sync.EndpointDetachResponse(REQUEST_ID, org.kaaproject.kaa.server.sync.SyncStatus.SUCCESS))); sourceResponse.setUserSync(userSyncResponse); SyncContext sourceResponseHolder = new SyncContext(sourceResponse); sourceResponseHolder.setEndpointProfile(sourceProfileMock); @@ -1618,52 +1619,55 @@ public void testEndpointDetach() throws Exception { targetSyncResponse.setRequestId(REQUEST_ID); targetSyncResponse.setStatus(SyncResponseResultType.SUCCESS); targetSyncResponse.setUserSyncResponse(new UserSyncResponse()); - targetSyncResponse.getUserSyncResponse().setUserDetachNotification( - new UserDetachNotification(Base64Util.encode(clientPublicKeyHash.array()))); + targetSyncResponse.getUserSyncResponse() + .setUserDetachNotification(new UserDetachNotification(Base64Util.encode(clientPublicKeyHash.array()))); AvroByteArrayConverter responseConverter = new AvroByteArrayConverter<>(SyncResponse.class); byte[] response = responseConverter.toByteArray(targetSyncResponse); byte[] encodedData = targetCrypt.encodeData(response); Mockito.verify(targetResponseBuilder, Mockito.timeout(TIMEOUT).atLeastOnce()).build(encodedData, true); } - - //TODO: fix when server profile feature will be ready -// @Test -// public void testServerProfileUpdate() throws Exception { -// ChannelContext channelContextMock = Mockito.mock(ChannelContext.class); -// -// SyncRequest request = new SyncRequest(); -// request.setRequestId(REQUEST_ID); -// SyncRequestMetaData md = buildSyncRequestMetaData(); -// request.setSyncRequestMetaData(md); -// -// ConfigurationSyncRequest csRequest = new ConfigurationSyncRequest(); -// request.setConfigurationSyncRequest(csRequest); -// -// Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))).thenReturn( -// clientPair.getPublic()); -// whenSync(deltaResponseWithProfile); -// -// MessageBuilder responseBuilder = Mockito.mock(MessageBuilder.class); -// ErrorBuilder errorBuilder = Mockito.mock(ErrorBuilder.class); -// -// SessionInitMessage message = toSignedRequest(UUID.randomUUID(), ChannelType.SYNC_WITH_TIMEOUT, channelContextMock, request, -// responseBuilder, errorBuilder); -// Assert.assertNotNull(akkaService.getActorSystem()); -// akkaService.process(message); -// -// Mockito.verify(operationsService, Mockito.timeout(TIMEOUT).atLeastOnce()).syncProfile(Mockito.any(SyncContext.class), -// Mockito.any(ProfileClientSync.class)); -// -// Notification thriftNotification = new Notification(); -// thriftNotification.setAppId(APP_ID); -// thriftNotification.setOp(Operation.UPDATE_SERVER_PROFILE); -// thriftNotification.setKeyHash(clientPublicKeyHash); -// akkaService.onNotification(thriftNotification); -// -// Mockito.verify(operationsService, Mockito.timeout(TIMEOUT*100).atLeastOnce()) -// .refreshServerEndpointProfile(EndpointObjectHash.fromBytes(clientPublicKeyHash.array())); -// } + + // TODO: fix when server profile feature will be ready + // @Test + // public void testServerProfileUpdate() throws Exception { + // ChannelContext channelContextMock = Mockito.mock(ChannelContext.class); + // + // SyncRequest request = new SyncRequest(); + // request.setRequestId(REQUEST_ID); + // SyncRequestMetaData md = buildSyncRequestMetaData(); + // request.setSyncRequestMetaData(md); + // + // ConfigurationSyncRequest csRequest = new ConfigurationSyncRequest(); + // request.setConfigurationSyncRequest(csRequest); + // + // Mockito.when(cacheService.getEndpointKey(EndpointObjectHash.fromBytes(clientPublicKeyHash.array()))).thenReturn( + // clientPair.getPublic()); + // whenSync(deltaResponseWithProfile); + // + // MessageBuilder responseBuilder = Mockito.mock(MessageBuilder.class); + // ErrorBuilder errorBuilder = Mockito.mock(ErrorBuilder.class); + // + // SessionInitMessage message = toSignedRequest(UUID.randomUUID(), + // ChannelType.SYNC_WITH_TIMEOUT, channelContextMock, request, + // responseBuilder, errorBuilder); + // Assert.assertNotNull(akkaService.getActorSystem()); + // akkaService.process(message); + // + // Mockito.verify(operationsService, + // Mockito.timeout(TIMEOUT).atLeastOnce()).syncProfile(Mockito.any(SyncContext.class), + // Mockito.any(ProfileClientSync.class)); + // + // Notification thriftNotification = new Notification(); + // thriftNotification.setAppId(APP_ID); + // thriftNotification.setOp(Operation.UPDATE_SERVER_PROFILE); + // thriftNotification.setKeyHash(clientPublicKeyHash); + // akkaService.onNotification(thriftNotification); + // + // Mockito.verify(operationsService, + // Mockito.timeout(TIMEOUT*100).atLeastOnce()) + // .refreshServerEndpointProfile(EndpointObjectHash.fromBytes(clientPublicKeyHash.array())); + // } private SyncRequestMetaData buildSyncRequestMetaData() { return buildSyncRequestMetaData(clientPublicKeyHash); diff --git a/server/node/src/test/java/org/kaaproject/kaa/server/operations/service/akka/actors/core/TopicActorTest.java b/server/node/src/test/java/org/kaaproject/kaa/server/operations/service/akka/actors/core/TopicActorTest.java index 276ea43394..429da86528 100644 --- a/server/node/src/test/java/org/kaaproject/kaa/server/operations/service/akka/actors/core/TopicActorTest.java +++ b/server/node/src/test/java/org/kaaproject/kaa/server/operations/service/akka/actors/core/TopicActorTest.java @@ -43,17 +43,17 @@ public void before(){ systemNf = new NotificationDto(); systemNf.setType(NotificationTypeDto.SYSTEM); - systemNf.setVersion(42); + systemNf.setNfVersion(42); systemNf.setExpiredAt(expiredDate); userNf = new NotificationDto(); userNf.setType(NotificationTypeDto.USER); - userNf.setVersion(73); + userNf.setNfVersion(73); userNf.setExpiredAt(expiredDate); unicastNf = new NotificationDto(); unicastNf.setType(null); - unicastNf.setVersion(111); + unicastNf.setNfVersion(111); unicastNf.setExpiredAt(expiredDate); } diff --git a/server/node/src/test/resources/dao/mongodb-dao-test-context.xml b/server/node/src/test/resources/dao/mongodb-dao-test-context.xml index 40a8d0c261..73c7524710 100644 --- a/server/node/src/test/resources/dao/mongodb-dao-test-context.xml +++ b/server/node/src/test/resources/dao/mongodb-dao-test-context.xml @@ -34,6 +34,9 @@ http://www.springframework.org/schema/util/spring-util-3.0.xsd"> + + +