From 05b2966e1e496a5445317ca414ae99d680a6cf32 Mon Sep 17 00:00:00 2001 From: jetinder20 Date: Mon, 4 Jun 2018 18:06:51 -0400 Subject: [PATCH 1/4] 1. Scripts for Data Model 2. Customer Model changes for additional data model column. 3. Controllers, Model and Service for Persisting/Retrieving Data Model --- .../controller/DataModelController.java | 56 ++++++++++++++ .../server/common/data/Customer.java | 19 +++++ .../server/common/data/DataModel.java | 74 +++++++++++++++++++ .../server/common/data/EntityType.java | 2 +- .../server/common/data/id/DataModelId.java | 38 ++++++++++ .../common/data/id/EntityIdFactory.java | 2 + .../dao/customer/CustomerServiceImpl.java | 7 ++ .../dao/datamodel/CassandraDataModelDao.java | 55 ++++++++++++++ .../server/dao/datamodel/DataModelDao.java | 45 +++++++++++ .../dao/datamodel/DataModelService.java | 24 ++++++ .../dao/datamodel/DataModelServiceImpl.java | 51 +++++++++++++ .../server/dao/model/ModelConstants.java | 2 + .../dao/model/nosql/CustomerEntity.java | 18 +++++ .../server/dao/model/sql/CustomerEntity.java | 11 +++ dao/src/main/resources/cassandra/schema.cql | 10 +++ .../main/resources/cassandra/upgrade/3.cql | 18 +++++ dao/src/main/resources/sql/schema.sql | 9 +++ dao/src/main/resources/sql/upgrade/4.sql | 17 +++++ 18 files changed, 457 insertions(+), 1 deletion(-) create mode 100644 application/src/main/java/com/hashmapinc/server/controller/DataModelController.java create mode 100644 common/data/src/main/java/com/hashmapinc/server/common/data/DataModel.java create mode 100644 common/data/src/main/java/com/hashmapinc/server/common/data/id/DataModelId.java create mode 100644 dao/src/main/java/com/hashmapinc/server/dao/datamodel/CassandraDataModelDao.java create mode 100644 dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelDao.java create mode 100644 dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelService.java create mode 100644 dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelServiceImpl.java create mode 100644 dao/src/main/resources/cassandra/upgrade/3.cql create mode 100644 dao/src/main/resources/sql/upgrade/4.sql diff --git a/application/src/main/java/com/hashmapinc/server/controller/DataModelController.java b/application/src/main/java/com/hashmapinc/server/controller/DataModelController.java new file mode 100644 index 000000000..25f8f9b48 --- /dev/null +++ b/application/src/main/java/com/hashmapinc/server/controller/DataModelController.java @@ -0,0 +1,56 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.controller; + +import com.hashmapinc.server.common.data.DataModel; +import com.hashmapinc.server.common.data.Device; +import com.hashmapinc.server.common.data.EntityType; +import com.hashmapinc.server.common.data.audit.ActionType; +import com.hashmapinc.server.dao.datamodel.DataModelService; +import com.hashmapinc.server.exception.TempusException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api") +@Slf4j +public class DataModelController extends BaseController { + + + @Autowired + private DataModelService dataModelService; + + @PreAuthorize("hasAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/data-model/", method = RequestMethod.POST) + @ResponseBody + public DataModel saveDataModel(@RequestBody DataModel dataModel) throws TempusException { + dataModel.setTenantId(getCurrentUser().getTenantId()); + try { + DataModel savedDataModel = checkNotNull(dataModelService.saveDataModel(dataModel)); + logEntityAction(dataModel.getId(), savedDataModel, + null, + dataModel.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); + return savedDataModel; + } catch (Exception e) { + logEntityAction(emptyId(EntityType.DATA_MODEL), dataModel, + null, dataModel.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e); + throw handleException(e); + } + } + +} diff --git a/common/data/src/main/java/com/hashmapinc/server/common/data/Customer.java b/common/data/src/main/java/com/hashmapinc/server/common/data/Customer.java index decbe5a8c..da5eafd9b 100644 --- a/common/data/src/main/java/com/hashmapinc/server/common/data/Customer.java +++ b/common/data/src/main/java/com/hashmapinc/server/common/data/Customer.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty.Access; import com.hashmapinc.server.common.data.id.CustomerId; +import com.hashmapinc.server.common.data.id.DataModelId; import com.hashmapinc.server.common.data.id.TenantId; public class Customer extends ContactBased implements HasName { @@ -27,6 +28,7 @@ public class Customer extends ContactBased implements HasName { private String title; private TenantId tenantId; + private DataModelId dataModelId; public Customer() { super(); @@ -39,6 +41,7 @@ public Customer(CustomerId id) { public Customer(Customer customer) { super(customer); this.tenantId = customer.getTenantId(); + this.dataModelId = customer.getDataModelId(); this.title = customer.getTitle(); } @@ -46,6 +49,14 @@ public TenantId getTenantId() { return tenantId; } + public DataModelId getDataModelId() { + return dataModelId; + } + + public void setDataModelId(DataModelId dataModelId) { + this.dataModelId = dataModelId; + } + public void setTenantId(TenantId tenantId) { this.tenantId = tenantId; } @@ -88,6 +99,7 @@ public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode()); + result = prime * result + ((dataModelId == null) ? 0 : dataModelId.hashCode()); result = prime * result + ((title == null) ? 0 : title.hashCode()); return result; } @@ -106,6 +118,11 @@ public boolean equals(Object obj) { return false; } else if (!tenantId.equals(other.tenantId)) return false; + if (dataModelId == null) { + if (other.dataModelId != null) + return false; + } else if (!dataModelId.equals(other.dataModelId)) + return false; if (title == null) { if (other.title != null) return false; @@ -121,6 +138,8 @@ public String toString() { builder.append(title); builder.append(", tenantId="); builder.append(tenantId); + builder.append(", dataModelId="); + builder.append(dataModelId); builder.append(", additionalInfo="); builder.append(getAdditionalInfo()); builder.append(", country="); diff --git a/common/data/src/main/java/com/hashmapinc/server/common/data/DataModel.java b/common/data/src/main/java/com/hashmapinc/server/common/data/DataModel.java new file mode 100644 index 000000000..63b82ca82 --- /dev/null +++ b/common/data/src/main/java/com/hashmapinc/server/common/data/DataModel.java @@ -0,0 +1,74 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.common.data; + +import com.hashmapinc.server.common.data.id.DataModelId; +import com.hashmapinc.server.common.data.id.TenantId; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +public class DataModel extends SearchTextBasedWithAdditionalInfo implements HasName { + private static final long serialVersionUID = 5100770312089703084L; + + private TenantId tenantId; + private String name; + private long lastUpdatedTs; + + public DataModel() { + super(); + } + + public DataModel(DataModelId id) { + super(id); + } + + public DataModel(DataModel dataModel) { + super(dataModel); + this.tenantId = dataModel.getTenantId(); + this.name = dataModel.getName(); + this.lastUpdatedTs = dataModel.lastUpdatedTs; + } + + public TenantId getTenantId() { + return tenantId; + } + + public void setTenantId(TenantId tenantId) { + this.tenantId = tenantId; + } + + public void setName(String name) { + this.name = name; + } + + public long getLastUpdatedTs() { + return lastUpdatedTs; + } + + public void setLastUpdatedTs(long lastUpdatedTs) { + this.lastUpdatedTs = lastUpdatedTs; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getSearchText() { + return getName(); + } +} diff --git a/common/data/src/main/java/com/hashmapinc/server/common/data/EntityType.java b/common/data/src/main/java/com/hashmapinc/server/common/data/EntityType.java index efae63c99..35787f827 100644 --- a/common/data/src/main/java/com/hashmapinc/server/common/data/EntityType.java +++ b/common/data/src/main/java/com/hashmapinc/server/common/data/EntityType.java @@ -18,6 +18,6 @@ public enum EntityType { - TENANT, CUSTOMER, USER, RULE, PLUGIN, DASHBOARD, ASSET, DEVICE, ALARM, APPLICATION, COMPUTATION, COMPUTATION_JOB, NODE_METRIC,THEME + TENANT, CUSTOMER, USER, RULE, PLUGIN, DASHBOARD, ASSET, DEVICE, ALARM, APPLICATION, COMPUTATION, COMPUTATION_JOB, NODE_METRIC,THEME, DATA_MODEL } diff --git a/common/data/src/main/java/com/hashmapinc/server/common/data/id/DataModelId.java b/common/data/src/main/java/com/hashmapinc/server/common/data/id/DataModelId.java new file mode 100644 index 000000000..e6daecba1 --- /dev/null +++ b/common/data/src/main/java/com/hashmapinc/server/common/data/id/DataModelId.java @@ -0,0 +1,38 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.common.data.id; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.hashmapinc.server.common.data.EntityType; + +import java.util.UUID; + +public class DataModelId extends UUIDBased implements EntityId { + + @JsonCreator + public DataModelId(@JsonProperty("id") UUID id) { + super(id); + } + + @JsonIgnore + @Override + public EntityType getEntityType() { + return EntityType.DATA_MODEL; + } + +} diff --git a/common/data/src/main/java/com/hashmapinc/server/common/data/id/EntityIdFactory.java b/common/data/src/main/java/com/hashmapinc/server/common/data/id/EntityIdFactory.java index 08f391de2..9fc1e66c2 100644 --- a/common/data/src/main/java/com/hashmapinc/server/common/data/id/EntityIdFactory.java +++ b/common/data/src/main/java/com/hashmapinc/server/common/data/id/EntityIdFactory.java @@ -61,6 +61,8 @@ public static EntityId getByTypeAndUuid(EntityType type, UUID uuid) { return new ComputationJobId(uuid); case NODE_METRIC: return new NodeMetricId(uuid); + case DATA_MODEL: + return new DataModelId(uuid); } throw new IllegalArgumentException("EntityType " + type + " is not supported!"); } diff --git a/dao/src/main/java/com/hashmapinc/server/dao/customer/CustomerServiceImpl.java b/dao/src/main/java/com/hashmapinc/server/dao/customer/CustomerServiceImpl.java index ad81fff8d..df576e958 100644 --- a/dao/src/main/java/com/hashmapinc/server/dao/customer/CustomerServiceImpl.java +++ b/dao/src/main/java/com/hashmapinc/server/dao/customer/CustomerServiceImpl.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.ListenableFuture; import com.hashmapinc.server.common.data.Customer; +import com.hashmapinc.server.common.data.id.DataModelId; import com.hashmapinc.server.common.data.page.TextPageLink; import com.hashmapinc.server.dao.user.UserService; import lombok.extern.slf4j.Slf4j; @@ -44,6 +45,7 @@ import java.util.List; import java.util.Optional; +import static com.hashmapinc.server.dao.model.ModelConstants.NULL_UUID; import static com.hashmapinc.server.dao.service.Validator.validateId; @Service @@ -196,6 +198,11 @@ protected void validateDataImpl(Customer customer) { throw new DataValidationException("Customer is referencing to non-existent tenant!"); } } + if(customer.getDataModelId() == null) { + customer.setDataModelId(new DataModelId(NULL_UUID)); + } else if(!customer.getDataModelId().getId().equals(NULL_UUID)) { + //todo Validation to check if data model exists or not before persisting + } } }; diff --git a/dao/src/main/java/com/hashmapinc/server/dao/datamodel/CassandraDataModelDao.java b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/CassandraDataModelDao.java new file mode 100644 index 000000000..78351b2c8 --- /dev/null +++ b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/CassandraDataModelDao.java @@ -0,0 +1,55 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.dao.datamodel; + +import com.google.common.util.concurrent.ListenableFuture; +import com.hashmapinc.server.common.data.DataModel; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public class CassandraDataModelDao implements DataModelDao { + @Override + public List find() { + return null; + } + + @Override + public DataModel findById(UUID id) { + return null; + } + + @Override + public ListenableFuture findByIdAsync(UUID id) { + return null; + } + + @Override + public DataModel save(DataModel dataModel) { + return null; + } + + @Override + public boolean removeById(UUID id) { + return false; + } + + @Override + public Optional findDataModelByTenantIdAndName(UUID tenantId, String name) { + return Optional.empty(); + } +} diff --git a/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelDao.java b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelDao.java new file mode 100644 index 000000000..40c9151ed --- /dev/null +++ b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelDao.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.dao.datamodel; + +import com.hashmapinc.server.common.data.DataModel; +import com.hashmapinc.server.dao.Dao; + +import java.util.Optional; +import java.util.UUID; + +public interface DataModelDao extends Dao { + + /** + * Save or update DataModel object + * + * @param dataModel the DataModel object + * @return saved DataModel object + */ + DataModel save(DataModel dataModel); + + + /** + * Find data models by tenantId and data model name. + * + * @param tenantId the tenantId + * @param name the DataModel name + * @return the optional DataModel object + */ + Optional findDataModelByTenantIdAndName(UUID tenantId, String name); + + +} diff --git a/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelService.java b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelService.java new file mode 100644 index 000000000..8a163b2fe --- /dev/null +++ b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelService.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.dao.datamodel; + +import com.hashmapinc.server.common.data.DataModel; + +public interface DataModelService { + + DataModel saveDataModel(DataModel dataModel); + +} diff --git a/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelServiceImpl.java b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelServiceImpl.java new file mode 100644 index 000000000..286b6c7e6 --- /dev/null +++ b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelServiceImpl.java @@ -0,0 +1,51 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.dao.datamodel; + +import com.hashmapinc.server.common.data.DataModel; +import com.hashmapinc.server.dao.entity.AbstractEntityService; +import com.hashmapinc.server.dao.exception.DataValidationException; +import com.hashmapinc.server.dao.service.DataValidator; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class DataModelServiceImpl extends AbstractEntityService implements DataModelService { + + + @Autowired + private DataModelDao dataModelDao; + + @Override + public DataModel saveDataModel(DataModel dataModel) { + log.trace("Executing saveDataModel [{}]", dataModel); + dataModelValidator.validate(dataModel); + return dataModelDao.save(dataModel); + } + + private DataValidator dataModelValidator = new DataValidator() { + @Override + protected void validateCreate(DataModel dataModel) { + dataModelDao.findDataModelByTenantIdAndName(dataModel.getTenantId().getId(), dataModel.getName()).ifPresent( + d -> { + throw new DataValidationException("Data Model with such name already exists!"); + } + ); + } + }; +} diff --git a/dao/src/main/java/com/hashmapinc/server/dao/model/ModelConstants.java b/dao/src/main/java/com/hashmapinc/server/dao/model/ModelConstants.java index 6e680e7e9..98dc3c348 100644 --- a/dao/src/main/java/com/hashmapinc/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/com/hashmapinc/server/dao/model/ModelConstants.java @@ -37,6 +37,7 @@ private ModelConstants() { public static final String ID_PROPERTY = "id"; public static final String USER_ID_PROPERTY = "user_id"; public static final String TENANT_ID_PROPERTY = "tenant_id"; + public static final String DATA_MODEL_ID_PROPERTY = "data_model_id"; public static final String CUSTOMER_ID_PROPERTY = "customer_id"; public static final String DEVICE_ID_PROPERTY = "device_id"; public static final String TITLE_PROPERTY = "title"; @@ -128,6 +129,7 @@ private ModelConstants() { */ public static final String CUSTOMER_COLUMN_FAMILY_NAME = "customer"; public static final String CUSTOMER_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; + public static final String CUSTOMER_DATA_MODEL_ID_PROPERTY = DATA_MODEL_ID_PROPERTY; public static final String CUSTOMER_TITLE_PROPERTY = TITLE_PROPERTY; public static final String CUSTOMER_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; diff --git a/dao/src/main/java/com/hashmapinc/server/dao/model/nosql/CustomerEntity.java b/dao/src/main/java/com/hashmapinc/server/dao/model/nosql/CustomerEntity.java index ebcdce65f..59f156ece 100644 --- a/dao/src/main/java/com/hashmapinc/server/dao/model/nosql/CustomerEntity.java +++ b/dao/src/main/java/com/hashmapinc/server/dao/model/nosql/CustomerEntity.java @@ -21,6 +21,7 @@ import com.datastax.driver.mapping.annotations.Table; import com.fasterxml.jackson.databind.JsonNode; import com.hashmapinc.server.common.data.Customer; +import com.hashmapinc.server.common.data.id.DataModelId; import lombok.EqualsAndHashCode; import lombok.ToString; import com.hashmapinc.server.common.data.id.CustomerId; @@ -44,6 +45,9 @@ public final class CustomerEntity implements SearchTextEntity { @PartitionKey(value = 1) @Column(name = CUSTOMER_TENANT_ID_PROPERTY) private UUID tenantId; + + @Column(name = CUSTOMER_DATA_MODEL_ID_PROPERTY) + private UUID dataModelId; @Column(name = CUSTOMER_TITLE_PROPERTY) private String title; @@ -87,6 +91,7 @@ public CustomerEntity(Customer customer) { this.id = customer.getId().getId(); } this.tenantId = customer.getTenantId().getId(); + this.dataModelId = customer.getDataModelId().getId(); this.title = customer.getTitle(); this.country = customer.getCountry(); this.state = customer.getState(); @@ -115,6 +120,14 @@ public void setTenantId(UUID tenantId) { this.tenantId = tenantId; } + public UUID getDataModelId() { + return dataModelId; + } + + public void setDataModelId(UUID dataModelId) { + this.dataModelId = dataModelId; + } + public String getTitle() { return title; } @@ -213,6 +226,11 @@ public String getSearchText() { public Customer toData() { Customer customer = new Customer(new CustomerId(id)); customer.setCreatedTime(UUIDs.unixTimestamp(id)); + if(dataModelId != null) { + customer.setDataModelId(new DataModelId(dataModelId)); + } else { + customer.setDataModelId(new DataModelId(NULL_UUID)); + } customer.setTenantId(new TenantId(tenantId)); customer.setTitle(title); customer.setCountry(country); diff --git a/dao/src/main/java/com/hashmapinc/server/dao/model/sql/CustomerEntity.java b/dao/src/main/java/com/hashmapinc/server/dao/model/sql/CustomerEntity.java index 610e3b0bd..e1d08a9f9 100644 --- a/dao/src/main/java/com/hashmapinc/server/dao/model/sql/CustomerEntity.java +++ b/dao/src/main/java/com/hashmapinc/server/dao/model/sql/CustomerEntity.java @@ -18,6 +18,8 @@ import com.datastax.driver.core.utils.UUIDs; import com.fasterxml.jackson.databind.JsonNode; import com.hashmapinc.server.common.data.Customer; +import com.hashmapinc.server.common.data.id.DataModelId; +import com.hashmapinc.server.common.data.id.EntityId; import com.hashmapinc.server.common.data.id.TenantId; import com.hashmapinc.server.dao.model.BaseSqlEntity; import com.hashmapinc.server.dao.util.mapping.JsonStringType; @@ -43,6 +45,9 @@ public final class CustomerEntity extends BaseSqlEntity implements Sea @Column(name = ModelConstants.CUSTOMER_TENANT_ID_PROPERTY) private String tenantId; + + @Column(name = ModelConstants.CUSTOMER_DATA_MODEL_ID_PROPERTY) + private String dataModelId; @Column(name = ModelConstants.CUSTOMER_TITLE_PROPERTY) private String title; @@ -87,6 +92,7 @@ public CustomerEntity(Customer customer) { this.setId(customer.getId().getId()); } this.tenantId = UUIDConverter.fromTimeUUID(customer.getTenantId().getId()); + this.dataModelId = UUIDConverter.fromTimeUUID(customer.getDataModelId().getId()); this.title = customer.getTitle(); this.country = customer.getCountry(); this.state = customer.getState(); @@ -114,6 +120,11 @@ public Customer toData() { Customer customer = new Customer(new CustomerId(getId())); customer.setCreatedTime(UUIDs.unixTimestamp(getId())); customer.setTenantId(new TenantId(UUIDConverter.fromString(tenantId))); + if(dataModelId != null) { + customer.setDataModelId(new DataModelId(UUIDConverter.fromString(dataModelId))); + } else { + customer.setDataModelId(new DataModelId(EntityId.NULL_UUID)); + } customer.setTitle(title); customer.setCountry(country); customer.setState(state); diff --git a/dao/src/main/resources/cassandra/schema.cql b/dao/src/main/resources/cassandra/schema.cql index 5a1ec8aad..25f46a7aa 100644 --- a/dao/src/main/resources/cassandra/schema.cql +++ b/dao/src/main/resources/cassandra/schema.cql @@ -161,6 +161,16 @@ CREATE TABLE IF NOT EXISTS tempus.device ( PRIMARY KEY (id, tenant_id, customer_id, type) ); +CREATE TABLE IF NOT EXISTS tempus.data_model ( + id timeuuid, + tenant_id timeuuid, + name text, + search_text text, + additional_info text, + last_update_ts bigint, + PRIMARY KEY (id, tenant_id) +); + CREATE MATERIALIZED VIEW IF NOT EXISTS tempus.device_by_tenant_and_name AS SELECT * from tempus.device diff --git a/dao/src/main/resources/cassandra/upgrade/3.cql b/dao/src/main/resources/cassandra/upgrade/3.cql new file mode 100644 index 000000000..f4fbef6ec --- /dev/null +++ b/dao/src/main/resources/cassandra/upgrade/3.cql @@ -0,0 +1,18 @@ +-- +-- Copyright © 2017-2018 Hashmap, 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. +-- + +ALTER TABLE tempus.customer ADD data_model_id timeuuid; + diff --git a/dao/src/main/resources/sql/schema.sql b/dao/src/main/resources/sql/schema.sql index c77e282b5..b55c6849a 100644 --- a/dao/src/main/resources/sql/schema.sql +++ b/dao/src/main/resources/sql/schema.sql @@ -122,6 +122,15 @@ CREATE TABLE IF NOT EXISTS device ( tenant_id varchar(31) ); +CREATE TABLE IF NOT EXISTS data_model ( + id varchar (31) NOT NULL CONSTRAINT data_model_pkey PRIMARY KEY, + name varchar(255), + tenant_id varchar(31), + search_text varchar(255), + additional_info varchar, + last_update_ts bigint +); + CREATE TABLE IF NOT EXISTS device_credentials ( id varchar(31) NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY, credentials_id varchar, diff --git a/dao/src/main/resources/sql/upgrade/4.sql b/dao/src/main/resources/sql/upgrade/4.sql new file mode 100644 index 000000000..9dd13b1d2 --- /dev/null +++ b/dao/src/main/resources/sql/upgrade/4.sql @@ -0,0 +1,17 @@ +-- +-- Copyright © 2017-2018 Hashmap, 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. +-- + +ALTER TABLE customer ADD data_model_id varchar(31) DEFAULT '1b21dd2138140008080808080808080'; \ No newline at end of file From 97f45cbac756b0c07c4fcf5e11e669dc383901cf Mon Sep 17 00:00:00 2001 From: jetinder20 Date: Tue, 5 Jun 2018 16:59:19 -0400 Subject: [PATCH 2/4] 1. Tests and validations for data model save 2. Customer validation when it references a non existent data model --- .../server/controller/BaseController.java | 4 + .../controller/DataModelController.java | 12 +- .../BaseDataModelControllerTest.java | 77 +++++++++++++ .../nosql/DataModelControllerNoSqlTest.java | 23 ++++ .../sql/DataModelControllerSqlTest.java | 24 ++++ .../server/common/data/DataModel.java | 6 +- .../dao/customer/CustomerServiceImpl.java | 10 +- .../dao/datamodel/CassandraDataModelDao.java | 47 ++++---- .../dao/datamodel/DataModelServiceImpl.java | 37 ++++++ .../server/dao/model/ModelConstants.java | 16 ++- .../dao/model/nosql/DataModelEntity.java | 103 +++++++++++++++++ .../server/dao/model/sql/DataModelEntity.java | 100 ++++++++++++++++ .../sql/datamodel/DataModelRepository.java | 26 +++++ .../dao/sql/datamodel/JpaDataModelDao.java | 56 +++++++++ dao/src/main/resources/cassandra/schema.cql | 8 ++ .../dao/service/AbstractServiceTest.java | 4 + .../dao/service/BaseCustomerServiceTest.java | 10 ++ .../dao/service/BaseDataModelServiceTest.java | 107 ++++++++++++++++++ .../nosql/DataModelServiceNoSqlTest.java | 23 ++++ .../service/sql/DataModelServiceSqlTest.java | 23 ++++ 20 files changed, 675 insertions(+), 41 deletions(-) create mode 100644 application/src/test/java/com/hashmapinc/server/controller/BaseDataModelControllerTest.java create mode 100644 application/src/test/java/com/hashmapinc/server/controller/nosql/DataModelControllerNoSqlTest.java create mode 100644 application/src/test/java/com/hashmapinc/server/controller/sql/DataModelControllerSqlTest.java create mode 100644 dao/src/main/java/com/hashmapinc/server/dao/model/nosql/DataModelEntity.java create mode 100644 dao/src/main/java/com/hashmapinc/server/dao/model/sql/DataModelEntity.java create mode 100644 dao/src/main/java/com/hashmapinc/server/dao/sql/datamodel/DataModelRepository.java create mode 100644 dao/src/main/java/com/hashmapinc/server/dao/sql/datamodel/JpaDataModelDao.java create mode 100644 dao/src/test/java/com/hashmapinc/server/dao/service/BaseDataModelServiceTest.java create mode 100644 dao/src/test/java/com/hashmapinc/server/dao/service/nosql/DataModelServiceNoSqlTest.java create mode 100644 dao/src/test/java/com/hashmapinc/server/dao/service/sql/DataModelServiceSqlTest.java diff --git a/application/src/main/java/com/hashmapinc/server/controller/BaseController.java b/application/src/main/java/com/hashmapinc/server/controller/BaseController.java index 9ed09906a..9b6bad152 100644 --- a/application/src/main/java/com/hashmapinc/server/controller/BaseController.java +++ b/application/src/main/java/com/hashmapinc/server/controller/BaseController.java @@ -26,6 +26,7 @@ import com.hashmapinc.server.common.data.plugin.ComponentDescriptor; import com.hashmapinc.server.dao.application.ApplicationService; import com.hashmapinc.server.dao.cluster.NodeMetricService; +import com.hashmapinc.server.dao.datamodel.DataModelService; import com.hashmapinc.server.dao.device.DeviceCredentialsService; import com.hashmapinc.server.dao.rule.RuleService; import com.hashmapinc.server.dao.user.UserService; @@ -98,6 +99,9 @@ public abstract class BaseController { @Autowired protected AssetService assetService; + @Autowired + protected DataModelService dataModelService; + @Autowired protected AlarmService alarmService; diff --git a/application/src/main/java/com/hashmapinc/server/controller/DataModelController.java b/application/src/main/java/com/hashmapinc/server/controller/DataModelController.java index 25f8f9b48..c09bee7a3 100644 --- a/application/src/main/java/com/hashmapinc/server/controller/DataModelController.java +++ b/application/src/main/java/com/hashmapinc/server/controller/DataModelController.java @@ -16,13 +16,10 @@ package com.hashmapinc.server.controller; import com.hashmapinc.server.common.data.DataModel; -import com.hashmapinc.server.common.data.Device; import com.hashmapinc.server.common.data.EntityType; import com.hashmapinc.server.common.data.audit.ActionType; -import com.hashmapinc.server.dao.datamodel.DataModelService; import com.hashmapinc.server.exception.TempusException; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -31,18 +28,17 @@ @Slf4j public class DataModelController extends BaseController { - - @Autowired - private DataModelService dataModelService; + public static final String DATA_MODEL_ID = "dataModelId"; @PreAuthorize("hasAuthority('TENANT_ADMIN')") - @RequestMapping(value = "/data-model/", method = RequestMethod.POST) + @RequestMapping(value = "/data-model", method = RequestMethod.POST) @ResponseBody public DataModel saveDataModel(@RequestBody DataModel dataModel) throws TempusException { dataModel.setTenantId(getCurrentUser().getTenantId()); + dataModel.setLastUpdatedTs(System.currentTimeMillis()); try { DataModel savedDataModel = checkNotNull(dataModelService.saveDataModel(dataModel)); - logEntityAction(dataModel.getId(), savedDataModel, + logEntityAction(savedDataModel.getId(), savedDataModel, null, dataModel.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); return savedDataModel; diff --git a/application/src/test/java/com/hashmapinc/server/controller/BaseDataModelControllerTest.java b/application/src/test/java/com/hashmapinc/server/controller/BaseDataModelControllerTest.java new file mode 100644 index 000000000..6e91b8c7c --- /dev/null +++ b/application/src/test/java/com/hashmapinc/server/controller/BaseDataModelControllerTest.java @@ -0,0 +1,77 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.controller; + +import com.hashmapinc.server.common.data.DataModel; +import com.hashmapinc.server.common.data.Tenant; +import com.hashmapinc.server.common.data.User; +import com.hashmapinc.server.common.data.security.Authority; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class BaseDataModelControllerTest extends AbstractControllerTest { + + private Tenant savedTenant; + private User tenantAdmin; + + @Before + public void beforeTest() throws Exception { + loginSysAdmin(); + + Tenant tenant = new Tenant(); + tenant.setTitle("My tenant"); + savedTenant = doPost("/api/tenant", tenant, Tenant.class); + Assert.assertNotNull(savedTenant); + + tenantAdmin = new User(); + tenantAdmin.setAuthority(Authority.TENANT_ADMIN); + tenantAdmin.setTenantId(savedTenant.getId()); + tenantAdmin.setEmail("tenant2@tempus.org"); + tenantAdmin.setFirstName("Joe"); + tenantAdmin.setLastName("Downs"); + + tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); + } + + @After + public void afterTest() throws Exception { + loginSysAdmin(); + + doDelete("/api/tenant/"+savedTenant.getId().getId().toString()) + .andExpect(status().isOk()); + } + + + @Test + public void testSaveDataModel() throws Exception { + DataModel dataModel = new DataModel(); + dataModel.setName("Drilling Data Model1"); + dataModel.setLastUpdatedTs(System.currentTimeMillis()); + + DataModel savedDataModel = doPost("/api/data-model", dataModel, DataModel.class); + + Assert.assertNotNull(savedDataModel); + Assert.assertNotNull(savedDataModel.getId()); + Assert.assertTrue(savedDataModel.getCreatedTime() > 0); + Assert.assertEquals(savedTenant.getId(), savedDataModel.getTenantId()); + Assert.assertEquals(dataModel.getName(), savedDataModel.getName()); + Assert.assertTrue(savedDataModel.getLastUpdatedTs() > 0); + } +} diff --git a/application/src/test/java/com/hashmapinc/server/controller/nosql/DataModelControllerNoSqlTest.java b/application/src/test/java/com/hashmapinc/server/controller/nosql/DataModelControllerNoSqlTest.java new file mode 100644 index 000000000..ee2d2af95 --- /dev/null +++ b/application/src/test/java/com/hashmapinc/server/controller/nosql/DataModelControllerNoSqlTest.java @@ -0,0 +1,23 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.controller.nosql; + +import com.hashmapinc.server.controller.BaseDataModelControllerTest; +import com.hashmapinc.server.dao.service.DaoNoSqlTest; + +@DaoNoSqlTest +public class DataModelControllerNoSqlTest extends BaseDataModelControllerTest { +} diff --git a/application/src/test/java/com/hashmapinc/server/controller/sql/DataModelControllerSqlTest.java b/application/src/test/java/com/hashmapinc/server/controller/sql/DataModelControllerSqlTest.java new file mode 100644 index 000000000..46ed6a74f --- /dev/null +++ b/application/src/test/java/com/hashmapinc/server/controller/sql/DataModelControllerSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.controller.sql; + +import com.hashmapinc.server.controller.BaseDataModelControllerTest; +import com.hashmapinc.server.dao.service.DaoSqlTest; + +@DaoSqlTest +public class DataModelControllerSqlTest extends BaseDataModelControllerTest { + +} diff --git a/common/data/src/main/java/com/hashmapinc/server/common/data/DataModel.java b/common/data/src/main/java/com/hashmapinc/server/common/data/DataModel.java index 63b82ca82..0b2168fa4 100644 --- a/common/data/src/main/java/com/hashmapinc/server/common/data/DataModel.java +++ b/common/data/src/main/java/com/hashmapinc/server/common/data/DataModel.java @@ -25,7 +25,7 @@ public class DataModel extends SearchTextBasedWithAdditionalInfo im private TenantId tenantId; private String name; - private long lastUpdatedTs; + private Long lastUpdatedTs; public DataModel() { super(); @@ -54,11 +54,11 @@ public void setName(String name) { this.name = name; } - public long getLastUpdatedTs() { + public Long getLastUpdatedTs() { return lastUpdatedTs; } - public void setLastUpdatedTs(long lastUpdatedTs) { + public void setLastUpdatedTs(Long lastUpdatedTs) { this.lastUpdatedTs = lastUpdatedTs; } diff --git a/dao/src/main/java/com/hashmapinc/server/dao/customer/CustomerServiceImpl.java b/dao/src/main/java/com/hashmapinc/server/dao/customer/CustomerServiceImpl.java index df576e958..de8de1070 100644 --- a/dao/src/main/java/com/hashmapinc/server/dao/customer/CustomerServiceImpl.java +++ b/dao/src/main/java/com/hashmapinc/server/dao/customer/CustomerServiceImpl.java @@ -19,8 +19,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.ListenableFuture; import com.hashmapinc.server.common.data.Customer; +import com.hashmapinc.server.common.data.DataModel; import com.hashmapinc.server.common.data.id.DataModelId; import com.hashmapinc.server.common.data.page.TextPageLink; +import com.hashmapinc.server.dao.datamodel.DataModelDao; import com.hashmapinc.server.dao.user.UserService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -65,6 +67,9 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @Autowired private TenantDao tenantDao; + @Autowired + private DataModelDao dataModelDao; + @Autowired private AssetService assetService; @@ -201,7 +206,10 @@ protected void validateDataImpl(Customer customer) { if(customer.getDataModelId() == null) { customer.setDataModelId(new DataModelId(NULL_UUID)); } else if(!customer.getDataModelId().getId().equals(NULL_UUID)) { - //todo Validation to check if data model exists or not before persisting + DataModel dataModel = dataModelDao.findById(customer.getDataModelId().getId()); + if(dataModel == null) { + throw new DataValidationException("Customer is referencing to non-existent data model!"); + } } } }; diff --git a/dao/src/main/java/com/hashmapinc/server/dao/datamodel/CassandraDataModelDao.java b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/CassandraDataModelDao.java index 78351b2c8..fb6063c98 100644 --- a/dao/src/main/java/com/hashmapinc/server/dao/datamodel/CassandraDataModelDao.java +++ b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/CassandraDataModelDao.java @@ -15,41 +15,42 @@ */ package com.hashmapinc.server.dao.datamodel; -import com.google.common.util.concurrent.ListenableFuture; +import com.datastax.driver.core.querybuilder.Select; import com.hashmapinc.server.common.data.DataModel; - -import java.util.List; +import com.hashmapinc.server.dao.DaoUtil; +import com.hashmapinc.server.dao.model.ModelConstants; +import com.hashmapinc.server.dao.model.nosql.DataModelEntity; +import com.hashmapinc.server.dao.nosql.CassandraAbstractSearchTextDao; +import com.hashmapinc.server.dao.util.NoSqlDao; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; import java.util.Optional; import java.util.UUID; -public class CassandraDataModelDao implements DataModelDao { - @Override - public List find() { - return null; - } - - @Override - public DataModel findById(UUID id) { - return null; - } +import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; +import static com.datastax.driver.core.querybuilder.QueryBuilder.select; - @Override - public ListenableFuture findByIdAsync(UUID id) { - return null; - } +@Component +@Slf4j +@NoSqlDao +public class CassandraDataModelDao extends CassandraAbstractSearchTextDao implements DataModelDao { @Override - public DataModel save(DataModel dataModel) { - return null; + public Optional findDataModelByTenantIdAndName(UUID tenantId, String name) { + Select select = select().from(ModelConstants.DATA_MODEL_BY_TENANT_AND_NAME_VIEW_NAME); + Select.Where query = select.where(); + query.and(eq(ModelConstants.DATA_MODEL_TENANT_ID_PROPERTY, tenantId)); + query.and(eq(ModelConstants.DATA_MODEL_NAME_PROPERTY, name)); + return Optional.ofNullable(DaoUtil.getData(findOneByStatement(query))); } @Override - public boolean removeById(UUID id) { - return false; + protected Class getColumnFamilyClass() { + return DataModelEntity.class; } @Override - public Optional findDataModelByTenantIdAndName(UUID tenantId, String name) { - return Optional.empty(); + protected String getColumnFamilyName() { + return ModelConstants.DATA_MODEL_TABLE_NAME; } } diff --git a/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelServiceImpl.java b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelServiceImpl.java index 286b6c7e6..0b7c7d594 100644 --- a/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelServiceImpl.java +++ b/dao/src/main/java/com/hashmapinc/server/dao/datamodel/DataModelServiceImpl.java @@ -16,12 +16,15 @@ package com.hashmapinc.server.dao.datamodel; import com.hashmapinc.server.common.data.DataModel; +import com.hashmapinc.server.common.data.Tenant; import com.hashmapinc.server.dao.entity.AbstractEntityService; import com.hashmapinc.server.dao.exception.DataValidationException; import com.hashmapinc.server.dao.service.DataValidator; +import com.hashmapinc.server.dao.tenant.TenantDao; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; @Service @Slf4j @@ -31,6 +34,9 @@ public class DataModelServiceImpl extends AbstractEntityService implements DataM @Autowired private DataModelDao dataModelDao; + @Autowired + private TenantDao tenantDao; + @Override public DataModel saveDataModel(DataModel dataModel) { log.trace("Executing saveDataModel [{}]", dataModel); @@ -47,5 +53,36 @@ protected void validateCreate(DataModel dataModel) { } ); } + + @Override + protected void validateUpdate(DataModel dataModel) { + dataModelDao.findDataModelByTenantIdAndName(dataModel.getTenantId().getId(), dataModel.getName()).ifPresent( + d -> { + if (!d.getUuidId().equals(dataModel.getUuidId())) { + throw new DataValidationException("Device with such name already exists!"); + } + } + ); + } + @Override + protected void validateDataImpl(DataModel dataModel) { + if(StringUtils.isEmpty(dataModel.getName())) { + throw new DataValidationException("Data Model name should be specified"); + } + + if (dataModel.getTenantId() == null) { + throw new DataValidationException("Data Model should be assigned to tenant!"); + } else { + Tenant tenant = tenantDao.findById(dataModel.getTenantId().getId()); + if (tenant == null) { + throw new DataValidationException("Data Model is referencing to non-existent tenant!"); + } + } + + if(dataModel.getLastUpdatedTs() == null) { + throw new DataValidationException("Data Model last updated time should be specified!"); + } + } + }; } diff --git a/dao/src/main/java/com/hashmapinc/server/dao/model/ModelConstants.java b/dao/src/main/java/com/hashmapinc/server/dao/model/ModelConstants.java index 98dc3c348..c1fe1b722 100644 --- a/dao/src/main/java/com/hashmapinc/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/com/hashmapinc/server/dao/model/ModelConstants.java @@ -132,9 +132,13 @@ private ModelConstants() { public static final String CUSTOMER_DATA_MODEL_ID_PROPERTY = DATA_MODEL_ID_PROPERTY; public static final String CUSTOMER_TITLE_PROPERTY = TITLE_PROPERTY; public static final String CUSTOMER_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; - public static final String CUSTOMER_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "customer_by_tenant_and_search_text"; public static final String CUSTOMER_BY_TENANT_AND_TITLE_VIEW_NAME = "customer_by_tenant_and_title"; + public static final String DATA_MODEL_TABLE_NAME = "data_model"; + public static final String DATA_MODEL_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; + public static final String DATA_MODEL_NAME_PROPERTY = "name"; + public static final String DATA_MODEL_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; + public static final String DATA_MODEL_BY_TENANT_AND_NAME_VIEW_NAME = "data_model_by_tenant_and_name"; /** * Cassandra device constants. @@ -222,10 +226,10 @@ private ModelConstants() { public static final String NODE_METRIC_STATUS = "status"; public static final String NODE_METRIC_RPC_SESSION = "rpc_session_count"; public static final String NODE_METRIC_DEVICE_SESSION = "device_session_count"; - + /* Cassandra audit log constants. */ - + public static final String AUDIT_LOG_COLUMN_FAMILY_NAME = "audit_log"; public static final String AUDIT_LOG_BY_ENTITY_ID_CF = "audit_log_by_entity_id"; @@ -499,11 +503,11 @@ private ModelConstants() { protected static final String[] COUNT_AGGREGATION_COLUMNS = new String[]{count(LONG_VALUE_COLUMN), count(DOUBLE_VALUE_COLUMN), count(BOOLEAN_VALUE_COLUMN), count(STRING_VALUE_COLUMN), count(JSON_VALUE_COLUMN)}; protected static final String[] MIN_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, - new String[]{min(LONG_VALUE_COLUMN), min(DOUBLE_VALUE_COLUMN), min(BOOLEAN_VALUE_COLUMN), min(STRING_VALUE_COLUMN), min(JSON_VALUE_COLUMN)}); + new String[]{min(LONG_VALUE_COLUMN), min(DOUBLE_VALUE_COLUMN), min(BOOLEAN_VALUE_COLUMN), min(STRING_VALUE_COLUMN), min(JSON_VALUE_COLUMN)}); protected static final String[] MAX_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, - new String[]{max(LONG_VALUE_COLUMN), max(DOUBLE_VALUE_COLUMN), max(BOOLEAN_VALUE_COLUMN), max(STRING_VALUE_COLUMN), min(JSON_VALUE_COLUMN)}); + new String[]{max(LONG_VALUE_COLUMN), max(DOUBLE_VALUE_COLUMN), max(BOOLEAN_VALUE_COLUMN), max(STRING_VALUE_COLUMN), min(JSON_VALUE_COLUMN)}); protected static final String[] SUM_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, - new String[]{sum(LONG_VALUE_COLUMN), sum(DOUBLE_VALUE_COLUMN)}); + new String[]{sum(LONG_VALUE_COLUMN), sum(DOUBLE_VALUE_COLUMN)}); protected static final String[] AVG_AGGREGATION_COLUMNS = SUM_AGGREGATION_COLUMNS; public static String min(String s) { diff --git a/dao/src/main/java/com/hashmapinc/server/dao/model/nosql/DataModelEntity.java b/dao/src/main/java/com/hashmapinc/server/dao/model/nosql/DataModelEntity.java new file mode 100644 index 000000000..b892df563 --- /dev/null +++ b/dao/src/main/java/com/hashmapinc/server/dao/model/nosql/DataModelEntity.java @@ -0,0 +1,103 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.dao.model.nosql; + +import com.datastax.driver.core.utils.UUIDs; +import com.datastax.driver.mapping.annotations.Column; +import com.datastax.driver.mapping.annotations.PartitionKey; +import com.datastax.driver.mapping.annotations.Table; +import com.fasterxml.jackson.databind.JsonNode; +import com.hashmapinc.server.common.data.DataModel; +import com.hashmapinc.server.common.data.id.DataModelId; +import com.hashmapinc.server.common.data.id.TenantId; +import com.hashmapinc.server.dao.model.ModelConstants; +import com.hashmapinc.server.dao.model.SearchTextEntity; +import com.hashmapinc.server.dao.model.type.JsonCodec; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.UUID; + +import static com.hashmapinc.server.dao.model.ModelConstants.*; + + +@Table(name = DATA_MODEL_TABLE_NAME) +@EqualsAndHashCode +@ToString +@Data +public final class DataModelEntity implements SearchTextEntity { + + @PartitionKey(value = 0) + @Column(name = ID_PROPERTY) + private UUID id; + + @PartitionKey(value = 1) + @Column(name = DEVICE_TENANT_ID_PROPERTY) + private UUID tenantId; + + @Column(name = DEVICE_NAME_PROPERTY) + private String name; + + @Column(name = SEARCH_TEXT_PROPERTY) + private String searchText; + + @Column(name = DEVICE_ADDITIONAL_INFO_PROPERTY, codec = JsonCodec.class) + private JsonNode additionalInfo; + + @Column(name = ModelConstants.LAST_UPDATE_TS_COLUMN) + private Long lastUpdateTs; + + public DataModelEntity() { + super(); + } + + public DataModelEntity(DataModel dataModel) { + if (dataModel.getId() != null) { + this.id = dataModel.getId().getId(); + } + if (dataModel.getTenantId() != null) { + this.tenantId = dataModel.getTenantId().getId(); + } + this.name = dataModel.getName(); + this.additionalInfo = dataModel.getAdditionalInfo(); + this.lastUpdateTs = dataModel.getLastUpdatedTs(); + } + + @Override + public String getSearchTextSource() { + return getName(); + } + + @Override + public void setSearchText(String searchText) { + this.searchText = searchText; + } + + + @Override + public DataModel toData() { + DataModel dataModel = new DataModel(new DataModelId(id)); + dataModel.setCreatedTime(UUIDs.unixTimestamp(id)); + if (tenantId != null) { + dataModel.setTenantId(new TenantId(tenantId)); + } + dataModel.setName(name); + dataModel.setAdditionalInfo(additionalInfo); + dataModel.setLastUpdatedTs(lastUpdateTs); + return dataModel; + } +} diff --git a/dao/src/main/java/com/hashmapinc/server/dao/model/sql/DataModelEntity.java b/dao/src/main/java/com/hashmapinc/server/dao/model/sql/DataModelEntity.java new file mode 100644 index 000000000..d921c4f41 --- /dev/null +++ b/dao/src/main/java/com/hashmapinc/server/dao/model/sql/DataModelEntity.java @@ -0,0 +1,100 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.dao.model.sql; + + +import com.datastax.driver.core.utils.UUIDs; +import com.fasterxml.jackson.databind.JsonNode; +import com.hashmapinc.server.common.data.DataModel; +import com.hashmapinc.server.common.data.id.DataModelId; +import com.hashmapinc.server.common.data.id.TenantId; +import com.hashmapinc.server.dao.model.BaseSqlEntity; +import com.hashmapinc.server.dao.model.ModelConstants; +import com.hashmapinc.server.dao.model.SearchTextEntity; +import com.hashmapinc.server.dao.util.mapping.JsonStringType; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +@Data +@EqualsAndHashCode(callSuper = true) +@Entity +@TypeDef(name = "json", typeClass = JsonStringType.class) +@Table(name = ModelConstants.DATA_MODEL_TABLE_NAME) +public class DataModelEntity extends BaseSqlEntity implements SearchTextEntity { + + + @Column(name = ModelConstants.DATA_MODEL_TENANT_ID_PROPERTY) + private String tenantId; + + @Column(name = ModelConstants.DATA_MODEL_NAME_PROPERTY) + private String name; + + @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) + private String searchText; + + @Type(type = "json") + @Column(name = ModelConstants.DATA_MODEL_ADDITIONAL_INFO_PROPERTY) + private JsonNode additionalInfo; + + @Column(name = ModelConstants.LAST_UPDATE_TS_COLUMN) + private Long lastUpdateTs; + + + public DataModelEntity() { + super(); + } + + public DataModelEntity(DataModel dataModel) { + if (dataModel.getId() != null) { + this.setId(dataModel.getId().getId()); + } + if (dataModel.getTenantId() != null) { + this.tenantId = toString(dataModel.getTenantId().getId()); + } + this.name = dataModel.getName(); + this.additionalInfo = dataModel.getAdditionalInfo(); + this.lastUpdateTs = dataModel.getLastUpdatedTs(); + } + + @Override + public String getSearchTextSource() { + return name; + } + + @Override + public void setSearchText(String searchText) { + this.searchText = searchText; + } + + @Override + public DataModel toData() { + DataModel dataModel = new DataModel(new DataModelId(getId())); + dataModel.setCreatedTime(UUIDs.unixTimestamp(getId())); + if (tenantId != null) { + dataModel.setTenantId(new TenantId(toUUID(tenantId))); + } + dataModel.setName(name); + dataModel.setAdditionalInfo(additionalInfo); + dataModel.setLastUpdatedTs(lastUpdateTs); + return dataModel; + } +} diff --git a/dao/src/main/java/com/hashmapinc/server/dao/sql/datamodel/DataModelRepository.java b/dao/src/main/java/com/hashmapinc/server/dao/sql/datamodel/DataModelRepository.java new file mode 100644 index 000000000..3abd081fa --- /dev/null +++ b/dao/src/main/java/com/hashmapinc/server/dao/sql/datamodel/DataModelRepository.java @@ -0,0 +1,26 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.dao.sql.datamodel; + +import com.hashmapinc.server.dao.model.sql.DataModelEntity; +import com.hashmapinc.server.dao.util.SqlDao; +import org.springframework.data.repository.CrudRepository; + +@SqlDao +public interface DataModelRepository extends CrudRepository { + + DataModelEntity findByTenantIdAndName(String tenantId, String name); +} diff --git a/dao/src/main/java/com/hashmapinc/server/dao/sql/datamodel/JpaDataModelDao.java b/dao/src/main/java/com/hashmapinc/server/dao/sql/datamodel/JpaDataModelDao.java new file mode 100644 index 000000000..be20f9127 --- /dev/null +++ b/dao/src/main/java/com/hashmapinc/server/dao/sql/datamodel/JpaDataModelDao.java @@ -0,0 +1,56 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.dao.sql.datamodel; + +import com.hashmapinc.server.common.data.DataModel; +import com.hashmapinc.server.dao.DaoUtil; +import com.hashmapinc.server.dao.datamodel.DataModelDao; +import com.hashmapinc.server.dao.model.sql.DataModelEntity; +import com.hashmapinc.server.dao.sql.JpaAbstractSearchTextDao; +import com.hashmapinc.server.dao.util.SqlDao; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Component; + +import java.util.Optional; +import java.util.UUID; + +import static com.hashmapinc.server.common.data.UUIDConverter.fromTimeUUID; + +@Component +@SqlDao +public class JpaDataModelDao extends JpaAbstractSearchTextDao implements DataModelDao { + + + @Autowired + private DataModelRepository dataModelRepository; + + @Override + public Optional findDataModelByTenantIdAndName(UUID tenantId, String name) { + DataModel dataModel = DaoUtil.getData(dataModelRepository.findByTenantIdAndName(fromTimeUUID(tenantId), name)); + return Optional.ofNullable(dataModel); + } + + @Override + protected Class getEntityClass() { + return DataModelEntity.class; + } + + @Override + protected CrudRepository getCrudRepository() { + return dataModelRepository; + } +} diff --git a/dao/src/main/resources/cassandra/schema.cql b/dao/src/main/resources/cassandra/schema.cql index 25f46a7aa..fc3d142d2 100644 --- a/dao/src/main/resources/cassandra/schema.cql +++ b/dao/src/main/resources/cassandra/schema.cql @@ -171,6 +171,14 @@ CREATE TABLE IF NOT EXISTS tempus.data_model ( PRIMARY KEY (id, tenant_id) ); +CREATE MATERIALIZED VIEW IF NOT EXISTS tempus.data_model_by_tenant_and_name AS + SELECT * + from tempus.data_model + WHERE tenant_id IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL + PRIMARY KEY ( tenant_id, name, id) + WITH CLUSTERING ORDER BY (name ASC, id DESC); + + CREATE MATERIALIZED VIEW IF NOT EXISTS tempus.device_by_tenant_and_name AS SELECT * from tempus.device diff --git a/dao/src/test/java/com/hashmapinc/server/dao/service/AbstractServiceTest.java b/dao/src/test/java/com/hashmapinc/server/dao/service/AbstractServiceTest.java index 9d6c19ab3..701b5d860 100644 --- a/dao/src/test/java/com/hashmapinc/server/dao/service/AbstractServiceTest.java +++ b/dao/src/test/java/com/hashmapinc/server/dao/service/AbstractServiceTest.java @@ -27,6 +27,7 @@ import com.hashmapinc.server.common.data.plugin.ComponentDescriptor; import com.hashmapinc.server.dao.TagMetaData.TagMetaDataService; import com.hashmapinc.server.dao.cluster.NodeMetricService; +import com.hashmapinc.server.dao.datamodel.DataModelService; import com.hashmapinc.server.dao.theme.ThemeService; import com.hashmapinc.server.dao.user.UserService; import org.junit.runner.RunWith; @@ -95,6 +96,9 @@ public abstract class AbstractServiceTest { @Autowired protected CustomerService customerService; + @Autowired + protected DataModelService dataModelService; + @Autowired protected DeviceService deviceService; diff --git a/dao/src/test/java/com/hashmapinc/server/dao/service/BaseCustomerServiceTest.java b/dao/src/test/java/com/hashmapinc/server/dao/service/BaseCustomerServiceTest.java index 5c525c557..f5ec5ced0 100644 --- a/dao/src/test/java/com/hashmapinc/server/dao/service/BaseCustomerServiceTest.java +++ b/dao/src/test/java/com/hashmapinc/server/dao/service/BaseCustomerServiceTest.java @@ -17,6 +17,7 @@ import com.datastax.driver.core.utils.UUIDs; import com.hashmapinc.server.common.data.Customer; +import com.hashmapinc.server.common.data.id.DataModelId; import com.hashmapinc.server.common.data.page.TextPageLink; import org.apache.commons.lang3.RandomStringUtils; import org.junit.After; @@ -109,6 +110,15 @@ public void testSaveCustomerWithInvalidTenant() { customerService.saveCustomer(customer); } + @Test(expected = DataValidationException.class) + public void testSaveCustomerWithInvalidDataModel() { + Customer customer = new Customer(); + customer.setTitle("My customer"); + customer.setDataModelId(new DataModelId(UUIDs.timeBased())); + customerService.saveCustomer(customer); + } + + @Test(expected = DataValidationException.class) public void testSaveCustomerWithInvalidEmail() { Customer customer = new Customer(); diff --git a/dao/src/test/java/com/hashmapinc/server/dao/service/BaseDataModelServiceTest.java b/dao/src/test/java/com/hashmapinc/server/dao/service/BaseDataModelServiceTest.java new file mode 100644 index 000000000..f3f2e641a --- /dev/null +++ b/dao/src/test/java/com/hashmapinc/server/dao/service/BaseDataModelServiceTest.java @@ -0,0 +1,107 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.dao.service; + +import com.datastax.driver.core.utils.UUIDs; +import com.hashmapinc.server.common.data.DataModel; +import com.hashmapinc.server.common.data.Tenant; +import com.hashmapinc.server.common.data.id.TenantId; +import com.hashmapinc.server.dao.exception.DataValidationException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public abstract class BaseDataModelServiceTest extends AbstractServiceTest{ + private TenantId tenantId; + + @Before + public void before() { + Tenant tenant = new Tenant(); + tenant.setTitle("My tenant"); + Tenant savedTenant = tenantService.saveTenant(tenant); + Assert.assertNotNull(savedTenant); + tenantId = savedTenant.getId(); + } + + @After + public void after() { + tenantService.deleteTenant(tenantId); + } + + @Test(expected = DataValidationException.class) + public void testSaveDataModelWithEmptyName() { + DataModel dataModel = new DataModel(); + dataModel.setLastUpdatedTs(System.currentTimeMillis()); + dataModel.setTenantId(tenantId); + + dataModelService.saveDataModel(dataModel); + } + + + @Test(expected = DataValidationException.class) + public void testSaveDataModelWithInvalidTenant() { + DataModel dataModel = new DataModel(); + dataModel.setName("Data model 1"); + dataModel.setLastUpdatedTs(System.currentTimeMillis()); + dataModel.setTenantId(new TenantId(UUIDs.timeBased())); + + dataModelService.saveDataModel(dataModel); + } + + @Test(expected = DataValidationException.class) + public void testSaveDataModelWithoutLastUpdatedTs() { + DataModel dataModel = new DataModel(); + dataModel.setName("Data model 1"); + dataModel.setTenantId(tenantId); + dataModel.setTenantId(new TenantId(UUIDs.timeBased())); + + dataModelService.saveDataModel(dataModel); + } + + + @Test(expected = DataValidationException.class) + public void testSaveDataModeleWithEmptyTenant() { + DataModel dataModel = new DataModel(); + dataModel.setName("Data model 1"); + dataModel.setLastUpdatedTs(System.currentTimeMillis()); + + dataModelService.saveDataModel(dataModel); + } + + @Test(expected = DataValidationException.class) + public void testSaveDataModeleWithSameName() { + DataModel dataModel = new DataModel(); + dataModel.setName("Data model 1"); + dataModel.setLastUpdatedTs(System.currentTimeMillis()); + dataModel.setTenantId(tenantId); + + DataModel savedDataModel1 = dataModelService.saveDataModel(dataModel); + Assert.assertNotNull(savedDataModel1.getId()); + + DataModel sameNamedataModel= new DataModel(); + sameNamedataModel.setName("Data model 1"); + sameNamedataModel.setLastUpdatedTs(System.currentTimeMillis()); + sameNamedataModel.setTenantId(tenantId); + + dataModelService.saveDataModel(sameNamedataModel); + } + + + + + +} diff --git a/dao/src/test/java/com/hashmapinc/server/dao/service/nosql/DataModelServiceNoSqlTest.java b/dao/src/test/java/com/hashmapinc/server/dao/service/nosql/DataModelServiceNoSqlTest.java new file mode 100644 index 000000000..9a38a6e63 --- /dev/null +++ b/dao/src/test/java/com/hashmapinc/server/dao/service/nosql/DataModelServiceNoSqlTest.java @@ -0,0 +1,23 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.dao.service.nosql; + +import com.hashmapinc.server.dao.service.BaseDataModelServiceTest; +import com.hashmapinc.server.dao.service.DaoNoSqlTest; + +@DaoNoSqlTest +public class DataModelServiceNoSqlTest extends BaseDataModelServiceTest{ +} diff --git a/dao/src/test/java/com/hashmapinc/server/dao/service/sql/DataModelServiceSqlTest.java b/dao/src/test/java/com/hashmapinc/server/dao/service/sql/DataModelServiceSqlTest.java new file mode 100644 index 000000000..8d7d697bb --- /dev/null +++ b/dao/src/test/java/com/hashmapinc/server/dao/service/sql/DataModelServiceSqlTest.java @@ -0,0 +1,23 @@ +/** + * Copyright © 2017-2018 Hashmap, 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. + */ +package com.hashmapinc.server.dao.service.sql; + +import com.hashmapinc.server.dao.service.BaseDataModelServiceTest; +import com.hashmapinc.server.dao.service.DaoSqlTest; + +@DaoSqlTest +public class DataModelServiceSqlTest extends BaseDataModelServiceTest { +} From 28eeffe74631799874c7dfb7ce663c25a9d38a63 Mon Sep 17 00:00:00 2001 From: jetinder20 Date: Tue, 5 Jun 2018 17:54:55 -0400 Subject: [PATCH 3/4] Including upgrade scripts in test suites --- .../hashmapinc/server/controller/ControllerNoSqlTestSuite.java | 3 ++- .../hashmapinc/server/controller/ControllerSqlTestSuite.java | 2 +- .../test/java/com/hashmapinc/server/mqtt/MqttSqlTestSuite.java | 2 +- .../java/com/hashmapinc/server/system/SystemSqlTestSuite.java | 2 +- .../test/java/com/hashmapinc/server/dao/JpaDaoTestSuite.java | 2 +- .../com/hashmapinc/server/dao/NoSqlDaoServiceTestSuite.java | 3 ++- .../java/com/hashmapinc/server/dao/SqlDaoServiceTestSuite.java | 2 +- 7 files changed, 9 insertions(+), 7 deletions(-) diff --git a/application/src/test/java/com/hashmapinc/server/controller/ControllerNoSqlTestSuite.java b/application/src/test/java/com/hashmapinc/server/controller/ControllerNoSqlTestSuite.java index 4cad94754..d078b82dc 100644 --- a/application/src/test/java/com/hashmapinc/server/controller/ControllerNoSqlTestSuite.java +++ b/application/src/test/java/com/hashmapinc/server/controller/ControllerNoSqlTestSuite.java @@ -43,7 +43,8 @@ private static List getDataSetLists(){ dataSets.add(new ClassPathCQLDataSet("cassandra/system-data.cql", false, false)); dataSets.add(new ClassPathCQLDataSet("cassandra/system-test.cql", false, false)); dataSets.addAll(Arrays.asList( - new ClassPathCQLDataSet("cassandra/upgrade/1.cql", false, false) + new ClassPathCQLDataSet("cassandra/upgrade/1.cql", false, false), + new ClassPathCQLDataSet("cassandra/upgrade/3.cql", false, false) )); return dataSets; } diff --git a/application/src/test/java/com/hashmapinc/server/controller/ControllerSqlTestSuite.java b/application/src/test/java/com/hashmapinc/server/controller/ControllerSqlTestSuite.java index b6a2985df..9cca6070f 100644 --- a/application/src/test/java/com/hashmapinc/server/controller/ControllerSqlTestSuite.java +++ b/application/src/test/java/com/hashmapinc/server/controller/ControllerSqlTestSuite.java @@ -33,6 +33,6 @@ public class ControllerSqlTestSuite { Arrays.asList("sql/schema.sql", "sql/system-data.sql"), "sql/drop-all-tables.sql", "sql-test.properties", - Arrays.asList("sql/upgrade/1.sql", "sql/upgrade/2.sql") + Arrays.asList("sql/upgrade/1.sql", "sql/upgrade/2.sql", "sql/upgrade/4.sql") ); } diff --git a/application/src/test/java/com/hashmapinc/server/mqtt/MqttSqlTestSuite.java b/application/src/test/java/com/hashmapinc/server/mqtt/MqttSqlTestSuite.java index 60957d645..63279d1f5 100644 --- a/application/src/test/java/com/hashmapinc/server/mqtt/MqttSqlTestSuite.java +++ b/application/src/test/java/com/hashmapinc/server/mqtt/MqttSqlTestSuite.java @@ -32,5 +32,5 @@ public class MqttSqlTestSuite { Arrays.asList("sql/schema.sql", "sql/system-data.sql"), "sql/drop-all-tables.sql", "sql-test.properties", - Arrays.asList("sql/upgrade/1.sql", "sql/upgrade/2.sql")); + Arrays.asList("sql/upgrade/1.sql", "sql/upgrade/2.sql", "sql/upgrade/4.sql")); } diff --git a/application/src/test/java/com/hashmapinc/server/system/SystemSqlTestSuite.java b/application/src/test/java/com/hashmapinc/server/system/SystemSqlTestSuite.java index 892c4eb3e..57a1a93e3 100644 --- a/application/src/test/java/com/hashmapinc/server/system/SystemSqlTestSuite.java +++ b/application/src/test/java/com/hashmapinc/server/system/SystemSqlTestSuite.java @@ -34,7 +34,7 @@ public class SystemSqlTestSuite { Arrays.asList("sql/schema.sql", "sql/system-data.sql"), "sql/drop-all-tables.sql", "sql-test.properties", - Arrays.asList("sql/upgrade/1.sql", "sql/upgrade/2.sql") + Arrays.asList("sql/upgrade/1.sql", "sql/upgrade/2.sql", "sql/upgrade/4.sql") ); diff --git a/dao/src/test/java/com/hashmapinc/server/dao/JpaDaoTestSuite.java b/dao/src/test/java/com/hashmapinc/server/dao/JpaDaoTestSuite.java index f681a2c56..c2fc0f2d0 100644 --- a/dao/src/test/java/com/hashmapinc/server/dao/JpaDaoTestSuite.java +++ b/dao/src/test/java/com/hashmapinc/server/dao/JpaDaoTestSuite.java @@ -33,7 +33,7 @@ public class JpaDaoTestSuite { Arrays.asList("sql/schema.sql", "sql/system-data.sql"), "sql/drop-all-tables.sql", "sql-test.properties", - Arrays.asList("sql/upgrade/1.sql", "sql/upgrade/2.sql") + Arrays.asList("sql/upgrade/1.sql", "sql/upgrade/2.sql", "sql/upgrade/4.sql") ); } diff --git a/dao/src/test/java/com/hashmapinc/server/dao/NoSqlDaoServiceTestSuite.java b/dao/src/test/java/com/hashmapinc/server/dao/NoSqlDaoServiceTestSuite.java index 986f18bea..3e6daec6e 100644 --- a/dao/src/test/java/com/hashmapinc/server/dao/NoSqlDaoServiceTestSuite.java +++ b/dao/src/test/java/com/hashmapinc/server/dao/NoSqlDaoServiceTestSuite.java @@ -43,7 +43,8 @@ private static List getDataSetLists(){ dataSets.add(new ClassPathCQLDataSet("cassandra/system-data.cql", false, false)); dataSets.add(new ClassPathCQLDataSet("cassandra/system-test.cql", false, false)); dataSets.addAll(Arrays.asList( - new ClassPathCQLDataSet("cassandra/upgrade/1.cql", false, false) + new ClassPathCQLDataSet("cassandra/upgrade/1.cql", false, false), + new ClassPathCQLDataSet("cassandra/upgrade/3.cql", false, false) )); return dataSets; } diff --git a/dao/src/test/java/com/hashmapinc/server/dao/SqlDaoServiceTestSuite.java b/dao/src/test/java/com/hashmapinc/server/dao/SqlDaoServiceTestSuite.java index fe7ed2099..9e4826f77 100644 --- a/dao/src/test/java/com/hashmapinc/server/dao/SqlDaoServiceTestSuite.java +++ b/dao/src/test/java/com/hashmapinc/server/dao/SqlDaoServiceTestSuite.java @@ -33,6 +33,6 @@ public class SqlDaoServiceTestSuite { Arrays.asList("sql/schema.sql", "sql/system-data.sql"), "sql/drop-all-tables.sql", "sql-test.properties", - Arrays.asList("sql/upgrade/1.sql", "sql/upgrade/2.sql") + Arrays.asList("sql/upgrade/1.sql", "sql/upgrade/2.sql", "sql/upgrade/4.sql") ); } From 113032869b4ac31f6be713128a3e22f550c31094 Mon Sep 17 00:00:00 2001 From: jetinder20 Date: Thu, 7 Jun 2018 13:40:37 -0400 Subject: [PATCH 4/4] Using Datamodel constants instead of mistyped device model constants --- .../hashmapinc/server/dao/model/nosql/DataModelEntity.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dao/src/main/java/com/hashmapinc/server/dao/model/nosql/DataModelEntity.java b/dao/src/main/java/com/hashmapinc/server/dao/model/nosql/DataModelEntity.java index b892df563..6851d7cdf 100644 --- a/dao/src/main/java/com/hashmapinc/server/dao/model/nosql/DataModelEntity.java +++ b/dao/src/main/java/com/hashmapinc/server/dao/model/nosql/DataModelEntity.java @@ -46,16 +46,16 @@ public final class DataModelEntity implements SearchTextEntity { private UUID id; @PartitionKey(value = 1) - @Column(name = DEVICE_TENANT_ID_PROPERTY) + @Column(name = DATA_MODEL_TENANT_ID_PROPERTY) private UUID tenantId; - @Column(name = DEVICE_NAME_PROPERTY) + @Column(name = DATA_MODEL_NAME_PROPERTY) private String name; @Column(name = SEARCH_TEXT_PROPERTY) private String searchText; - @Column(name = DEVICE_ADDITIONAL_INFO_PROPERTY, codec = JsonCodec.class) + @Column(name = DATA_MODEL_ADDITIONAL_INFO_PROPERTY, codec = JsonCodec.class) private JsonNode additionalInfo; @Column(name = ModelConstants.LAST_UPDATE_TS_COLUMN)