Tests for version control; local-only repositories; refactoring
This commit is contained in:
parent
9d60491f19
commit
656e8458ad
@ -301,6 +301,7 @@ public class AdminController extends BaseController {
|
||||
@PostMapping("/repositorySettings")
|
||||
public DeferredResult<RepositorySettings> saveRepositorySettings(@RequestBody RepositorySettings settings) throws ThingsboardException {
|
||||
accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.WRITE);
|
||||
settings.setLocalOnly(false); // overriding, since local repositories are supported only for testing
|
||||
ListenableFuture<RepositorySettings> future = versionControlService.saveVersionControlSettings(getTenantId(), settings);
|
||||
return wrapFuture(Futures.transform(future, savedSettings -> {
|
||||
savedSettings.setPassword(null);
|
||||
|
||||
@ -803,7 +803,7 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest {
|
||||
return readResponse(doPost(urlTemplate, content, params).andExpect(resultMatcher), responseType);
|
||||
}
|
||||
|
||||
protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception {
|
||||
protected <T, R> R doPostAsync(String urlTemplate, T content, Class<R> responseClass, ResultMatcher resultMatcher, String... params) throws Exception {
|
||||
return readResponse(doPostAsync(urlTemplate, content, DEFAULT_TIMEOUT, params).andExpect(resultMatcher), responseClass);
|
||||
}
|
||||
|
||||
|
||||
@ -1,478 +0,0 @@
|
||||
/**
|
||||
* Copyright © 2016-2024 The Thingsboard Authors
|
||||
*
|
||||
* 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 org.thingsboard.server.service.sync.ie;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.fasterxml.jackson.databind.node.TextNode;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.rule.engine.debug.TbMsgGeneratorNode;
|
||||
import org.thingsboard.rule.engine.debug.TbMsgGeneratorNodeConfiguration;
|
||||
import org.thingsboard.rule.engine.metadata.TbGetAttributesNode;
|
||||
import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration;
|
||||
import org.thingsboard.server.common.data.Customer;
|
||||
import org.thingsboard.server.common.data.Dashboard;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.common.data.DeviceProfileType;
|
||||
import org.thingsboard.server.common.data.DeviceTransportType;
|
||||
import org.thingsboard.server.common.data.EntityView;
|
||||
import org.thingsboard.server.common.data.ExportableEntity;
|
||||
import org.thingsboard.server.common.data.HasTenantId;
|
||||
import org.thingsboard.server.common.data.OtaPackage;
|
||||
import org.thingsboard.server.common.data.Tenant;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
import org.thingsboard.server.common.data.asset.AssetProfile;
|
||||
import org.thingsboard.server.common.data.device.data.DefaultDeviceTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.device.data.DeviceData;
|
||||
import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
|
||||
import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
|
||||
import org.thingsboard.server.common.data.id.AssetId;
|
||||
import org.thingsboard.server.common.data.id.AssetProfileId;
|
||||
import org.thingsboard.server.common.data.id.CustomerId;
|
||||
import org.thingsboard.server.common.data.id.DashboardId;
|
||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.RuleChainId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
|
||||
import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
|
||||
import org.thingsboard.server.common.data.ota.OtaPackageType;
|
||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainType;
|
||||
import org.thingsboard.server.common.data.rule.RuleNode;
|
||||
import org.thingsboard.server.common.data.security.Authority;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportSettings;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityImportSettings;
|
||||
import org.thingsboard.server.common.data.util.ThrowingRunnable;
|
||||
import org.thingsboard.server.controller.AbstractControllerTest;
|
||||
import org.thingsboard.server.dao.asset.AssetProfileService;
|
||||
import org.thingsboard.server.dao.asset.AssetService;
|
||||
import org.thingsboard.server.dao.customer.CustomerService;
|
||||
import org.thingsboard.server.dao.dashboard.DashboardService;
|
||||
import org.thingsboard.server.dao.device.DeviceProfileService;
|
||||
import org.thingsboard.server.dao.device.DeviceService;
|
||||
import org.thingsboard.server.dao.entityview.EntityViewService;
|
||||
import org.thingsboard.server.dao.ota.OtaPackageService;
|
||||
import org.thingsboard.server.dao.relation.RelationService;
|
||||
import org.thingsboard.server.dao.rule.RuleChainService;
|
||||
import org.thingsboard.server.dao.tenant.TenantService;
|
||||
import org.thingsboard.server.service.security.model.SecurityUser;
|
||||
import org.thingsboard.server.service.security.model.UserPrincipal;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||
import org.thingsboard.server.service.sync.vc.data.SimpleEntitiesExportCtx;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public abstract class BaseExportImportServiceTest extends AbstractControllerTest {
|
||||
|
||||
@Autowired
|
||||
protected EntitiesExportImportService exportImportService;
|
||||
@Autowired
|
||||
protected DeviceService deviceService;
|
||||
@Autowired
|
||||
protected OtaPackageService otaPackageService;
|
||||
@Autowired
|
||||
protected DeviceProfileService deviceProfileService;
|
||||
@Autowired
|
||||
protected AssetProfileService assetProfileService;
|
||||
@Autowired
|
||||
protected AssetService assetService;
|
||||
@Autowired
|
||||
protected CustomerService customerService;
|
||||
@Autowired
|
||||
protected RuleChainService ruleChainService;
|
||||
@Autowired
|
||||
protected DashboardService dashboardService;
|
||||
@Autowired
|
||||
protected RelationService relationService;
|
||||
@Autowired
|
||||
protected TenantService tenantService;
|
||||
@Autowired
|
||||
protected EntityViewService entityViewService;
|
||||
|
||||
protected TenantId tenantId1;
|
||||
protected User tenantAdmin1;
|
||||
|
||||
protected TenantId tenantId2;
|
||||
protected User tenantAdmin2;
|
||||
|
||||
@Before
|
||||
public void beforeEach() throws Exception {
|
||||
loginSysAdmin();
|
||||
Tenant tenant1 = new Tenant();
|
||||
tenant1.setTitle("Tenant 1");
|
||||
tenant1.setEmail("tenant1@thingsboard.org");
|
||||
this.tenantId1 = tenantService.saveTenant(tenant1).getId();
|
||||
User tenantAdmin1 = new User();
|
||||
tenantAdmin1.setTenantId(tenantId1);
|
||||
tenantAdmin1.setAuthority(Authority.TENANT_ADMIN);
|
||||
tenantAdmin1.setEmail("tenant1-admin@thingsboard.org");
|
||||
this.tenantAdmin1 = createUser(tenantAdmin1, "12345678");
|
||||
Tenant tenant2 = new Tenant();
|
||||
tenant2.setTitle("Tenant 2");
|
||||
tenant2.setEmail("tenant2@thingsboard.org");
|
||||
this.tenantId2 = tenantService.saveTenant(tenant2).getId();
|
||||
User tenantAdmin2 = new User();
|
||||
tenantAdmin2.setTenantId(tenantId2);
|
||||
tenantAdmin2.setAuthority(Authority.TENANT_ADMIN);
|
||||
tenantAdmin2.setEmail("tenant2-admin@thingsboard.org");
|
||||
this.tenantAdmin2 = createUser(tenantAdmin2, "12345678");
|
||||
}
|
||||
|
||||
@After
|
||||
public void afterEach() {
|
||||
tenantService.deleteTenant(tenantId1);
|
||||
tenantService.deleteTenant(tenantId2);
|
||||
}
|
||||
|
||||
protected Device createDevice(TenantId tenantId, CustomerId customerId, DeviceProfileId deviceProfileId, String name) {
|
||||
Device device = new Device();
|
||||
device.setTenantId(tenantId);
|
||||
device.setCustomerId(customerId);
|
||||
device.setName(name);
|
||||
device.setLabel("lbl");
|
||||
device.setDeviceProfileId(deviceProfileId);
|
||||
DeviceData deviceData = new DeviceData();
|
||||
deviceData.setTransportConfiguration(new DefaultDeviceTransportConfiguration());
|
||||
device.setDeviceData(deviceData);
|
||||
return deviceService.saveDevice(device);
|
||||
}
|
||||
|
||||
protected OtaPackage createOtaPackage(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType type) {
|
||||
OtaPackage otaPackage = new OtaPackage();
|
||||
otaPackage.setTenantId(tenantId);
|
||||
otaPackage.setDeviceProfileId(deviceProfileId);
|
||||
otaPackage.setType(type);
|
||||
otaPackage.setTitle("My " + type);
|
||||
otaPackage.setVersion("v1.0");
|
||||
otaPackage.setFileName("filename.txt");
|
||||
otaPackage.setContentType("text/plain");
|
||||
otaPackage.setChecksumAlgorithm(ChecksumAlgorithm.SHA256);
|
||||
otaPackage.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a");
|
||||
otaPackage.setDataSize(1L);
|
||||
otaPackage.setData(ByteBuffer.wrap(new byte[]{(int) 1}));
|
||||
return otaPackageService.saveOtaPackage(otaPackage);
|
||||
}
|
||||
|
||||
protected void checkImportedDeviceData(Device initialDevice, Device importedDevice) {
|
||||
assertThat(importedDevice.getName()).isEqualTo(initialDevice.getName());
|
||||
assertThat(importedDevice.getType()).isEqualTo(initialDevice.getType());
|
||||
assertThat(importedDevice.getDeviceData()).isEqualTo(initialDevice.getDeviceData());
|
||||
assertThat(importedDevice.getLabel()).isEqualTo(initialDevice.getLabel());
|
||||
}
|
||||
|
||||
protected DeviceProfile createDeviceProfile(TenantId tenantId, RuleChainId defaultRuleChainId, DashboardId defaultDashboardId, String name) {
|
||||
DeviceProfile deviceProfile = new DeviceProfile();
|
||||
deviceProfile.setTenantId(tenantId);
|
||||
deviceProfile.setName(name);
|
||||
deviceProfile.setDescription("dscrptn");
|
||||
deviceProfile.setType(DeviceProfileType.DEFAULT);
|
||||
deviceProfile.setTransportType(DeviceTransportType.DEFAULT);
|
||||
deviceProfile.setDefaultRuleChainId(defaultRuleChainId);
|
||||
deviceProfile.setDefaultDashboardId(defaultDashboardId);
|
||||
DeviceProfileData profileData = new DeviceProfileData();
|
||||
profileData.setConfiguration(new DefaultDeviceProfileConfiguration());
|
||||
profileData.setTransportConfiguration(new DefaultDeviceProfileTransportConfiguration());
|
||||
deviceProfile.setProfileData(profileData);
|
||||
return deviceProfileService.saveDeviceProfile(deviceProfile);
|
||||
}
|
||||
|
||||
protected void checkImportedDeviceProfileData(DeviceProfile initialProfile, DeviceProfile importedProfile) {
|
||||
assertThat(initialProfile.getName()).isEqualTo(importedProfile.getName());
|
||||
assertThat(initialProfile.getType()).isEqualTo(importedProfile.getType());
|
||||
assertThat(initialProfile.getTransportType()).isEqualTo(importedProfile.getTransportType());
|
||||
assertThat(initialProfile.getProfileData()).isEqualTo(importedProfile.getProfileData());
|
||||
assertThat(initialProfile.getDescription()).isEqualTo(importedProfile.getDescription());
|
||||
}
|
||||
|
||||
protected AssetProfile createAssetProfile(TenantId tenantId, RuleChainId defaultRuleChainId, DashboardId defaultDashboardId, String name) {
|
||||
AssetProfile assetProfile = new AssetProfile();
|
||||
assetProfile.setTenantId(tenantId);
|
||||
assetProfile.setName(name);
|
||||
assetProfile.setDescription("dscrptn");
|
||||
assetProfile.setDefaultRuleChainId(defaultRuleChainId);
|
||||
assetProfile.setDefaultDashboardId(defaultDashboardId);
|
||||
return assetProfileService.saveAssetProfile(assetProfile);
|
||||
}
|
||||
|
||||
protected void checkImportedAssetProfileData(AssetProfile initialProfile, AssetProfile importedProfile) {
|
||||
assertThat(initialProfile.getName()).isEqualTo(importedProfile.getName());
|
||||
assertThat(initialProfile.getDescription()).isEqualTo(importedProfile.getDescription());
|
||||
}
|
||||
|
||||
protected Asset createAsset(TenantId tenantId, CustomerId customerId, AssetProfileId assetProfileId, String name) {
|
||||
Asset asset = new Asset();
|
||||
asset.setTenantId(tenantId);
|
||||
asset.setCustomerId(customerId);
|
||||
asset.setAssetProfileId(assetProfileId);
|
||||
asset.setName(name);
|
||||
asset.setLabel("lbl");
|
||||
asset.setAdditionalInfo(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
return assetService.saveAsset(asset);
|
||||
}
|
||||
|
||||
protected void checkImportedAssetData(Asset initialAsset, Asset importedAsset) {
|
||||
assertThat(importedAsset.getName()).isEqualTo(initialAsset.getName());
|
||||
assertThat(importedAsset.getType()).isEqualTo(initialAsset.getType());
|
||||
assertThat(importedAsset.getLabel()).isEqualTo(initialAsset.getLabel());
|
||||
assertThat(importedAsset.getAdditionalInfo()).isEqualTo(initialAsset.getAdditionalInfo());
|
||||
}
|
||||
|
||||
protected Customer createCustomer(TenantId tenantId, String name) {
|
||||
Customer customer = new Customer();
|
||||
customer.setTenantId(tenantId);
|
||||
customer.setTitle(name);
|
||||
customer.setCountry("ua");
|
||||
customer.setAddress("abb");
|
||||
customer.setEmail("ccc@aa.org");
|
||||
customer.setAdditionalInfo(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
return customerService.saveCustomer(customer);
|
||||
}
|
||||
|
||||
protected void checkImportedCustomerData(Customer initialCustomer, Customer importedCustomer) {
|
||||
assertThat(importedCustomer.getTitle()).isEqualTo(initialCustomer.getTitle());
|
||||
assertThat(importedCustomer.getCountry()).isEqualTo(initialCustomer.getCountry());
|
||||
assertThat(importedCustomer.getAddress()).isEqualTo(initialCustomer.getAddress());
|
||||
assertThat(importedCustomer.getEmail()).isEqualTo(initialCustomer.getEmail());
|
||||
}
|
||||
|
||||
protected Dashboard createDashboard(TenantId tenantId, CustomerId customerId, String name) {
|
||||
Dashboard dashboard = new Dashboard();
|
||||
dashboard.setTenantId(tenantId);
|
||||
dashboard.setTitle(name);
|
||||
dashboard.setConfiguration(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
dashboard.setImage("abvregewrg");
|
||||
dashboard.setMobileHide(true);
|
||||
dashboard = dashboardService.saveDashboard(dashboard);
|
||||
if (customerId != null) {
|
||||
dashboardService.assignDashboardToCustomer(tenantId, dashboard.getId(), customerId);
|
||||
return dashboardService.findDashboardById(tenantId, dashboard.getId());
|
||||
}
|
||||
return dashboard;
|
||||
}
|
||||
|
||||
protected Dashboard createDashboard(TenantId tenantId, CustomerId customerId, String name, AssetId assetForEntityAlias) {
|
||||
Dashboard dashboard = createDashboard(tenantId, customerId, name);
|
||||
String entityAliases = "{\n" +
|
||||
"\t\"23c4185d-1497-9457-30b2-6d91e69a5b2c\": {\n" +
|
||||
"\t\t\"alias\": \"assets\",\n" +
|
||||
"\t\t\"filter\": {\n" +
|
||||
"\t\t\t\"entityList\": [\n" +
|
||||
"\t\t\t\t\"" + assetForEntityAlias.getId().toString() + "\"\n" +
|
||||
"\t\t\t],\n" +
|
||||
"\t\t\t\"entityType\": \"ASSET\",\n" +
|
||||
"\t\t\t\"resolveMultiple\": true,\n" +
|
||||
"\t\t\t\"type\": \"entityList\"\n" +
|
||||
"\t\t},\n" +
|
||||
"\t\t\"id\": \"23c4185d-1497-9457-30b2-6d91e69a5b2c\"\n" +
|
||||
"\t}\n" +
|
||||
"}";
|
||||
ObjectNode dashboardConfiguration = JacksonUtil.newObjectNode();
|
||||
dashboardConfiguration.set("entityAliases", JacksonUtil.toJsonNode(entityAliases));
|
||||
dashboardConfiguration.set("description", new TextNode("hallo"));
|
||||
dashboard.setConfiguration(dashboardConfiguration);
|
||||
return dashboardService.saveDashboard(dashboard);
|
||||
}
|
||||
|
||||
protected void checkImportedDashboardData(Dashboard initialDashboard, Dashboard importedDashboard) {
|
||||
assertThat(importedDashboard.getTitle()).isEqualTo(initialDashboard.getTitle());
|
||||
assertThat(importedDashboard.getConfiguration()).isEqualTo(initialDashboard.getConfiguration());
|
||||
assertThat(importedDashboard.getImage()).isEqualTo(initialDashboard.getImage());
|
||||
assertThat(importedDashboard.isMobileHide()).isEqualTo(initialDashboard.isMobileHide());
|
||||
if (initialDashboard.getAssignedCustomers() != null) {
|
||||
assertThat(importedDashboard.getAssignedCustomers()).containsAll(initialDashboard.getAssignedCustomers());
|
||||
}
|
||||
}
|
||||
protected RuleChain createRuleChain(TenantId tenantId, String name, EntityId originatorId) {
|
||||
RuleChain ruleChain = new RuleChain();
|
||||
ruleChain.setTenantId(tenantId);
|
||||
ruleChain.setName(name);
|
||||
ruleChain.setType(RuleChainType.CORE);
|
||||
ruleChain.setDebugMode(true);
|
||||
ruleChain.setConfiguration(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
ruleChain = ruleChainService.saveRuleChain(ruleChain);
|
||||
|
||||
RuleChainMetaData metaData = new RuleChainMetaData();
|
||||
metaData.setRuleChainId(ruleChain.getId());
|
||||
|
||||
RuleNode ruleNode1 = new RuleNode();
|
||||
ruleNode1.setName("Generator 1");
|
||||
ruleNode1.setType(TbMsgGeneratorNode.class.getName());
|
||||
ruleNode1.setDebugMode(true);
|
||||
TbMsgGeneratorNodeConfiguration configuration1 = new TbMsgGeneratorNodeConfiguration();
|
||||
configuration1.setOriginatorType(originatorId.getEntityType());
|
||||
configuration1.setOriginatorId(originatorId.getId().toString());
|
||||
ruleNode1.setConfiguration(JacksonUtil.valueToTree(configuration1));
|
||||
|
||||
RuleNode ruleNode2 = new RuleNode();
|
||||
ruleNode2.setName("Simple Rule Node 2");
|
||||
ruleNode2.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName());
|
||||
ruleNode2.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version());
|
||||
ruleNode2.setDebugMode(true);
|
||||
TbGetAttributesNodeConfiguration configuration2 = new TbGetAttributesNodeConfiguration();
|
||||
configuration2.setServerAttributeNames(Collections.singletonList("serverAttributeKey2"));
|
||||
ruleNode2.setConfiguration(JacksonUtil.valueToTree(configuration2));
|
||||
|
||||
metaData.setNodes(Arrays.asList(ruleNode1, ruleNode2));
|
||||
metaData.setFirstNodeIndex(0);
|
||||
metaData.addConnectionInfo(0, 1, TbNodeConnectionType.SUCCESS);
|
||||
ruleChainService.saveRuleChainMetaData(tenantId, metaData, Function.identity());
|
||||
|
||||
return ruleChainService.findRuleChainById(tenantId, ruleChain.getId());
|
||||
}
|
||||
|
||||
protected RuleChain createRuleChain(TenantId tenantId, String name) {
|
||||
RuleChain ruleChain = new RuleChain();
|
||||
ruleChain.setTenantId(tenantId);
|
||||
ruleChain.setName(name);
|
||||
ruleChain.setType(RuleChainType.CORE);
|
||||
ruleChain.setDebugMode(true);
|
||||
ruleChain.setConfiguration(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
ruleChain = ruleChainService.saveRuleChain(ruleChain);
|
||||
|
||||
RuleChainMetaData metaData = new RuleChainMetaData();
|
||||
metaData.setRuleChainId(ruleChain.getId());
|
||||
|
||||
RuleNode ruleNode1 = new RuleNode();
|
||||
ruleNode1.setName("Simple Rule Node 1");
|
||||
ruleNode1.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName());
|
||||
ruleNode1.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version());
|
||||
ruleNode1.setDebugMode(true);
|
||||
TbGetAttributesNodeConfiguration configuration1 = new TbGetAttributesNodeConfiguration();
|
||||
configuration1.setServerAttributeNames(Collections.singletonList("serverAttributeKey1"));
|
||||
ruleNode1.setConfiguration(JacksonUtil.valueToTree(configuration1));
|
||||
|
||||
RuleNode ruleNode2 = new RuleNode();
|
||||
ruleNode2.setName("Simple Rule Node 2");
|
||||
ruleNode2.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName());
|
||||
ruleNode2.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version());
|
||||
ruleNode2.setDebugMode(true);
|
||||
TbGetAttributesNodeConfiguration configuration2 = new TbGetAttributesNodeConfiguration();
|
||||
configuration2.setServerAttributeNames(Collections.singletonList("serverAttributeKey2"));
|
||||
ruleNode2.setConfiguration(JacksonUtil.valueToTree(configuration2));
|
||||
|
||||
metaData.setNodes(Arrays.asList(ruleNode1, ruleNode2));
|
||||
metaData.setFirstNodeIndex(0);
|
||||
metaData.addConnectionInfo(0, 1, TbNodeConnectionType.SUCCESS);
|
||||
ruleChainService.saveRuleChainMetaData(tenantId, metaData, Function.identity());
|
||||
|
||||
return ruleChainService.findRuleChainById(tenantId, ruleChain.getId());
|
||||
}
|
||||
|
||||
protected void checkImportedRuleChainData(RuleChain initialRuleChain, RuleChainMetaData initialMetaData, RuleChain importedRuleChain, RuleChainMetaData importedMetaData) {
|
||||
assertThat(importedRuleChain.getType()).isEqualTo(initialRuleChain.getType());
|
||||
assertThat(importedRuleChain.getName()).isEqualTo(initialRuleChain.getName());
|
||||
assertThat(importedRuleChain.isDebugMode()).isEqualTo(initialRuleChain.isDebugMode());
|
||||
assertThat(importedRuleChain.getConfiguration()).isEqualTo(initialRuleChain.getConfiguration());
|
||||
|
||||
assertThat(importedMetaData.getConnections()).isEqualTo(initialMetaData.getConnections());
|
||||
assertThat(importedMetaData.getFirstNodeIndex()).isEqualTo(initialMetaData.getFirstNodeIndex());
|
||||
for (int i = 0; i < initialMetaData.getNodes().size(); i++) {
|
||||
RuleNode initialNode = initialMetaData.getNodes().get(i);
|
||||
RuleNode importedNode = importedMetaData.getNodes().get(i);
|
||||
assertThat(importedNode.getRuleChainId()).isEqualTo(importedRuleChain.getId());
|
||||
assertThat(importedNode.getName()).isEqualTo(initialNode.getName());
|
||||
assertThat(importedNode.getType()).isEqualTo(initialNode.getType());
|
||||
assertThat(importedNode.getConfiguration()).isEqualTo(initialNode.getConfiguration());
|
||||
assertThat(importedNode.getAdditionalInfo()).isEqualTo(initialNode.getAdditionalInfo());
|
||||
}
|
||||
}
|
||||
|
||||
protected EntityView createEntityView(TenantId tenantId, CustomerId customerId, EntityId entityId, String name) {
|
||||
EntityView entityView = new EntityView();
|
||||
entityView.setTenantId(tenantId);
|
||||
entityView.setEntityId(entityId);
|
||||
entityView.setCustomerId(customerId);
|
||||
entityView.setName(name);
|
||||
entityView.setType("A");
|
||||
return entityViewService.saveEntityView(entityView);
|
||||
}
|
||||
|
||||
protected EntityRelation createRelation(EntityId from, EntityId to) {
|
||||
EntityRelation relation = new EntityRelation();
|
||||
relation.setFrom(from);
|
||||
relation.setTo(to);
|
||||
relation.setType(EntityRelation.MANAGES_TYPE);
|
||||
relation.setAdditionalInfo(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
relation.setTypeGroup(RelationTypeGroup.COMMON);
|
||||
relationService.saveRelation(TenantId.SYS_TENANT_ID, relation);
|
||||
return relation;
|
||||
}
|
||||
|
||||
protected <E extends ExportableEntity<?> & HasTenantId> void checkImportedEntity(TenantId tenantId1, E initialEntity, TenantId tenantId2, E importedEntity) {
|
||||
assertThat(initialEntity.getTenantId()).isEqualTo(tenantId1);
|
||||
assertThat(importedEntity.getTenantId()).isEqualTo(tenantId2);
|
||||
|
||||
assertThat(importedEntity.getExternalId()).isEqualTo(initialEntity.getId());
|
||||
|
||||
boolean sameTenant = tenantId1.equals(tenantId2);
|
||||
if (!sameTenant) {
|
||||
assertThat(importedEntity.getId()).isNotEqualTo(initialEntity.getId());
|
||||
} else {
|
||||
assertThat(importedEntity.getId()).isEqualTo(initialEntity.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected <E extends ExportableEntity<I>, I extends EntityId> EntityExportData<E> exportEntity(User user, I entityId) throws Exception {
|
||||
return exportEntity(user, entityId, EntityExportSettings.builder()
|
||||
.exportCredentials(true)
|
||||
.build());
|
||||
}
|
||||
|
||||
protected <E extends ExportableEntity<I>, I extends EntityId> EntityExportData<E> exportEntity(User user, I entityId, EntityExportSettings exportSettings) throws Exception {
|
||||
return exportImportService.exportEntity(new SimpleEntitiesExportCtx(getSecurityUser(user), null, null, exportSettings), entityId);
|
||||
}
|
||||
|
||||
protected <E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(User user, EntityExportData<E> exportData) throws Exception {
|
||||
return importEntity(user, exportData, EntityImportSettings.builder()
|
||||
.saveCredentials(true)
|
||||
.build());
|
||||
}
|
||||
|
||||
protected <E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(User user, EntityExportData<E> exportData, EntityImportSettings importSettings) throws Exception {
|
||||
EntitiesImportCtx ctx = new EntitiesImportCtx(UUID.randomUUID(), getSecurityUser(user), null, importSettings);
|
||||
ctx.setFinalImportAttempt(true);
|
||||
exportData = JacksonUtil.treeToValue(JacksonUtil.valueToTree(exportData), EntityExportData.class);
|
||||
EntityImportResult<E> importResult = exportImportService.importEntity(ctx, exportData);
|
||||
exportImportService.saveReferencesAndRelations(ctx);
|
||||
for (ThrowingRunnable throwingRunnable : ctx.getEventCallbacks()) {
|
||||
throwingRunnable.run();
|
||||
}
|
||||
return importResult;
|
||||
}
|
||||
|
||||
protected SecurityUser getSecurityUser(User user) {
|
||||
return new SecurityUser(user, true, new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail()));
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,10 +15,10 @@
|
||||
*/
|
||||
package org.thingsboard.server.service.sync.ie;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.fasterxml.jackson.databind.node.TextNode;
|
||||
import com.google.common.collect.Streams;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -26,19 +26,32 @@ import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.rule.engine.debug.TbMsgGeneratorNode;
|
||||
import org.thingsboard.rule.engine.debug.TbMsgGeneratorNodeConfiguration;
|
||||
import org.thingsboard.rule.engine.metadata.TbGetAttributesNode;
|
||||
import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration;
|
||||
import org.thingsboard.server.common.data.Customer;
|
||||
import org.thingsboard.server.common.data.Dashboard;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.common.data.DeviceProfileType;
|
||||
import org.thingsboard.server.common.data.DeviceTransportType;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.EntityView;
|
||||
import org.thingsboard.server.common.data.ExportableEntity;
|
||||
import org.thingsboard.server.common.data.OtaPackage;
|
||||
import org.thingsboard.server.common.data.Tenant;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
import org.thingsboard.server.common.data.asset.AssetProfile;
|
||||
import org.thingsboard.server.common.data.audit.ActionType;
|
||||
import org.thingsboard.server.common.data.device.data.DefaultDeviceTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.device.data.DeviceData;
|
||||
import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
|
||||
import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
|
||||
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
|
||||
import org.thingsboard.server.common.data.id.AssetId;
|
||||
import org.thingsboard.server.common.data.id.AssetProfileId;
|
||||
import org.thingsboard.server.common.data.id.CustomerId;
|
||||
import org.thingsboard.server.common.data.id.DashboardId;
|
||||
import org.thingsboard.server.common.data.id.DeviceId;
|
||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||
@ -46,27 +59,46 @@ import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.EntityViewId;
|
||||
import org.thingsboard.server.common.data.id.RuleChainId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
|
||||
import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
|
||||
import org.thingsboard.server.common.data.ota.OtaPackageType;
|
||||
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
|
||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainType;
|
||||
import org.thingsboard.server.common.data.rule.RuleNode;
|
||||
import org.thingsboard.server.common.data.script.ScriptLanguage;
|
||||
import org.thingsboard.server.common.data.security.DeviceCredentials;
|
||||
import org.thingsboard.server.common.data.sync.ie.DeviceExportData;
|
||||
import org.thingsboard.server.common.data.security.Authority;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportSettings;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityImportSettings;
|
||||
import org.thingsboard.server.common.data.sync.ie.RuleChainExportData;
|
||||
import org.thingsboard.server.dao.device.DeviceCredentialsService;
|
||||
import org.thingsboard.server.common.data.util.ThrowingRunnable;
|
||||
import org.thingsboard.server.controller.AbstractControllerTest;
|
||||
import org.thingsboard.server.dao.asset.AssetProfileService;
|
||||
import org.thingsboard.server.dao.asset.AssetService;
|
||||
import org.thingsboard.server.dao.customer.CustomerService;
|
||||
import org.thingsboard.server.dao.dashboard.DashboardService;
|
||||
import org.thingsboard.server.dao.device.DeviceProfileService;
|
||||
import org.thingsboard.server.dao.device.DeviceService;
|
||||
import org.thingsboard.server.dao.entityview.EntityViewService;
|
||||
import org.thingsboard.server.dao.ota.OtaPackageService;
|
||||
import org.thingsboard.server.dao.relation.RelationService;
|
||||
import org.thingsboard.server.dao.rule.RuleChainService;
|
||||
import org.thingsboard.server.dao.service.DaoSqlTest;
|
||||
import org.thingsboard.server.dao.tenant.TenantService;
|
||||
import org.thingsboard.server.service.action.EntityActionService;
|
||||
import org.thingsboard.server.service.ota.OtaPackageStateService;
|
||||
import org.thingsboard.server.service.security.model.SecurityUser;
|
||||
import org.thingsboard.server.service.security.model.UserPrincipal;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||
import org.thingsboard.server.service.sync.vc.data.SimpleEntitiesExportCtx;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -76,481 +108,77 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@DaoSqlTest
|
||||
public class ExportImportServiceSqlTest extends BaseExportImportServiceTest {
|
||||
public class ExportImportServiceSqlTest extends AbstractControllerTest {
|
||||
|
||||
@Autowired
|
||||
private DeviceCredentialsService deviceCredentialsService;
|
||||
@SpyBean
|
||||
private EntityActionService entityActionService;
|
||||
@SpyBean
|
||||
private OtaPackageStateService otaPackageStateService;
|
||||
|
||||
@Test
|
||||
public void testExportImportAssetWithProfile_betweenTenants() throws Exception {
|
||||
AssetProfile assetProfile = createAssetProfile(tenantId1, null, null, "Asset profile of tenant 1");
|
||||
Asset asset = createAsset(tenantId1, null, assetProfile.getId(), "Asset of tenant 1");
|
||||
@Autowired
|
||||
protected EntitiesExportImportService exportImportService;
|
||||
@Autowired
|
||||
protected DeviceService deviceService;
|
||||
@Autowired
|
||||
protected OtaPackageService otaPackageService;
|
||||
@Autowired
|
||||
protected DeviceProfileService deviceProfileService;
|
||||
@Autowired
|
||||
protected AssetProfileService assetProfileService;
|
||||
@Autowired
|
||||
protected AssetService assetService;
|
||||
@Autowired
|
||||
protected CustomerService customerService;
|
||||
@Autowired
|
||||
protected RuleChainService ruleChainService;
|
||||
@Autowired
|
||||
protected DashboardService dashboardService;
|
||||
@Autowired
|
||||
protected RelationService relationService;
|
||||
@Autowired
|
||||
protected TenantService tenantService;
|
||||
@Autowired
|
||||
protected EntityViewService entityViewService;
|
||||
|
||||
EntityExportData<AssetProfile> profileExportData = exportEntity(tenantAdmin1, assetProfile.getId());
|
||||
protected TenantId tenantId1;
|
||||
protected User tenantAdmin1;
|
||||
|
||||
EntityExportData<Asset> assetExportData = exportEntity(tenantAdmin1, asset.getId());
|
||||
protected TenantId tenantId2;
|
||||
protected User tenantAdmin2;
|
||||
|
||||
EntityImportResult<AssetProfile> profileImportResult = importEntity(tenantAdmin2, profileExportData);
|
||||
checkImportedEntity(tenantId1, assetProfile, tenantId2, profileImportResult.getSavedEntity());
|
||||
checkImportedAssetProfileData(assetProfile, profileImportResult.getSavedEntity());
|
||||
|
||||
EntityImportResult<Asset> assetImportResult = importEntity(tenantAdmin2, assetExportData);
|
||||
Asset importedAsset = assetImportResult.getSavedEntity();
|
||||
checkImportedEntity(tenantId1, asset, tenantId2, importedAsset);
|
||||
checkImportedAssetData(asset, importedAsset);
|
||||
|
||||
assertThat(importedAsset.getAssetProfileId()).isEqualTo(profileImportResult.getSavedEntity().getId());
|
||||
@Before
|
||||
public void beforeEach() throws Exception {
|
||||
loginSysAdmin();
|
||||
Tenant tenant1 = new Tenant();
|
||||
tenant1.setTitle("Tenant 1");
|
||||
tenant1.setEmail("tenant1@thingsboard.org");
|
||||
this.tenantId1 = tenantService.saveTenant(tenant1).getId();
|
||||
User tenantAdmin1 = new User();
|
||||
tenantAdmin1.setTenantId(tenantId1);
|
||||
tenantAdmin1.setAuthority(Authority.TENANT_ADMIN);
|
||||
tenantAdmin1.setEmail("tenant1-admin@thingsboard.org");
|
||||
this.tenantAdmin1 = createUser(tenantAdmin1, "12345678");
|
||||
Tenant tenant2 = new Tenant();
|
||||
tenant2.setTitle("Tenant 2");
|
||||
tenant2.setEmail("tenant2@thingsboard.org");
|
||||
this.tenantId2 = tenantService.saveTenant(tenant2).getId();
|
||||
User tenantAdmin2 = new User();
|
||||
tenantAdmin2.setTenantId(tenantId2);
|
||||
tenantAdmin2.setAuthority(Authority.TENANT_ADMIN);
|
||||
tenantAdmin2.setEmail("tenant2-admin@thingsboard.org");
|
||||
this.tenantAdmin2 = createUser(tenantAdmin2, "12345678");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportImportAsset_sameTenant() throws Exception {
|
||||
AssetProfile assetProfile = createAssetProfile(tenantId1, null, null, "Asset profile v1.0");
|
||||
Asset asset = createAsset(tenantId1, null, assetProfile.getId(), "Asset v1.0");
|
||||
EntityExportData<Asset> exportData = exportEntity(tenantAdmin1, asset.getId());
|
||||
|
||||
EntityImportResult<Asset> importResult = importEntity(tenantAdmin1, exportData);
|
||||
checkImportedEntity(tenantId1, asset, tenantId1, importResult.getSavedEntity());
|
||||
checkImportedAssetData(asset, importResult.getSavedEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportImportAsset_sameTenant_withCustomer() throws Exception {
|
||||
AssetProfile assetProfile = createAssetProfile(tenantId1, null, null, "Asset profile v1.0");
|
||||
Customer customer = createCustomer(tenantId1, "My customer");
|
||||
Asset asset = createAsset(tenantId1, customer.getId(), assetProfile.getId(), "My asset");
|
||||
|
||||
Asset importedAsset = importEntity(tenantAdmin1, this.<Asset, AssetId>exportEntity(tenantAdmin1, asset.getId())).getSavedEntity();
|
||||
assertThat(importedAsset.getCustomerId()).isEqualTo(asset.getCustomerId());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExportImportCustomer_betweenTenants() throws Exception {
|
||||
Customer customer = createCustomer(tenantAdmin1.getTenantId(), "Customer of tenant 1");
|
||||
EntityExportData<Customer> exportData = exportEntity(tenantAdmin1, customer.getId());
|
||||
|
||||
EntityImportResult<Customer> importResult = importEntity(tenantAdmin2, exportData);
|
||||
checkImportedEntity(tenantId1, customer, tenantId2, importResult.getSavedEntity());
|
||||
checkImportedCustomerData(customer, importResult.getSavedEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportImportCustomer_sameTenant() throws Exception {
|
||||
Customer customer = createCustomer(tenantAdmin1.getTenantId(), "Customer v1.0");
|
||||
EntityExportData<Customer> exportData = exportEntity(tenantAdmin1, customer.getId());
|
||||
|
||||
EntityImportResult<Customer> importResult = importEntity(tenantAdmin1, exportData);
|
||||
checkImportedEntity(tenantId1, customer, tenantId1, importResult.getSavedEntity());
|
||||
checkImportedCustomerData(customer, importResult.getSavedEntity());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExportImportDeviceWithProfile_betweenTenants() throws Exception {
|
||||
DeviceProfile deviceProfile = createDeviceProfile(tenantId1, null, null, "Device profile of tenant 1");
|
||||
Device device = createDevice(tenantId1, null, deviceProfile.getId(), "Device of tenant 1");
|
||||
DeviceCredentials credentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId1, device.getId());
|
||||
|
||||
EntityExportData<DeviceProfile> profileExportData = exportEntity(tenantAdmin1, deviceProfile.getId());
|
||||
|
||||
EntityExportData<Device> deviceExportData = exportEntity(tenantAdmin1, device.getId());
|
||||
DeviceCredentials exportedCredentials = ((DeviceExportData) deviceExportData).getCredentials();
|
||||
exportedCredentials.setCredentialsId(credentials.getCredentialsId() + "a");
|
||||
|
||||
EntityImportResult<DeviceProfile> profileImportResult = importEntity(tenantAdmin2, profileExportData);
|
||||
checkImportedEntity(tenantId1, deviceProfile, tenantId2, profileImportResult.getSavedEntity());
|
||||
checkImportedDeviceProfileData(deviceProfile, profileImportResult.getSavedEntity());
|
||||
|
||||
EntityImportResult<Device> deviceImportResult = importEntity(tenantAdmin2, deviceExportData);
|
||||
Device importedDevice = deviceImportResult.getSavedEntity();
|
||||
checkImportedEntity(tenantId1, device, tenantId2, deviceImportResult.getSavedEntity());
|
||||
checkImportedDeviceData(device, importedDevice);
|
||||
|
||||
assertThat(importedDevice.getDeviceProfileId()).isEqualTo(profileImportResult.getSavedEntity().getId());
|
||||
|
||||
DeviceCredentials importedCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId2, importedDevice.getId());
|
||||
assertThat(importedCredentials.getId()).isNotEqualTo(credentials.getId());
|
||||
assertThat(importedCredentials.getCredentialsId()).isEqualTo(exportedCredentials.getCredentialsId());
|
||||
assertThat(importedCredentials.getCredentialsValue()).isEqualTo(credentials.getCredentialsValue());
|
||||
assertThat(importedCredentials.getCredentialsType()).isEqualTo(credentials.getCredentialsType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportImportDevice_sameTenant() throws Exception {
|
||||
DeviceProfile deviceProfile = createDeviceProfile(tenantId1, null, null, "Device profile v1.0");
|
||||
OtaPackage firmware = createOtaPackage(tenantId1, deviceProfile.getId(), OtaPackageType.FIRMWARE);
|
||||
OtaPackage software = createOtaPackage(tenantId1, deviceProfile.getId(), OtaPackageType.SOFTWARE);
|
||||
Device device = createDevice(tenantId1, null, deviceProfile.getId(), "Device v1.0");
|
||||
device.setFirmwareId(firmware.getId());
|
||||
device.setSoftwareId(software.getId());
|
||||
device = deviceService.saveDevice(device);
|
||||
|
||||
DeviceCredentials credentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId1, device.getId());
|
||||
|
||||
EntityExportData<Device> deviceExportData = exportEntity(tenantAdmin1, device.getId());
|
||||
|
||||
EntityImportResult<Device> importResult = importEntity(tenantAdmin1, deviceExportData);
|
||||
Device importedDevice = importResult.getSavedEntity();
|
||||
|
||||
checkImportedEntity(tenantId1, device, tenantId1, importResult.getSavedEntity());
|
||||
assertThat(importedDevice.getDeviceProfileId()).isEqualTo(device.getDeviceProfileId());
|
||||
assertThat(deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId1, device.getId())).isEqualTo(credentials);
|
||||
assertThat(importedDevice.getFirmwareId()).isEqualTo(firmware.getId());
|
||||
assertThat(importedDevice.getSoftwareId()).isEqualTo(software.getId());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExportImportDashboard_betweenTenants() throws Exception {
|
||||
Dashboard dashboard = createDashboard(tenantAdmin1.getTenantId(), null, "Dashboard of tenant 1");
|
||||
EntityExportData<Dashboard> exportData = exportEntity(tenantAdmin1, dashboard.getId());
|
||||
|
||||
EntityImportResult<Dashboard> importResult = importEntity(tenantAdmin2, exportData);
|
||||
checkImportedEntity(tenantId1, dashboard, tenantId2, importResult.getSavedEntity());
|
||||
checkImportedDashboardData(dashboard, importResult.getSavedEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportImportDashboard_sameTenant() throws Exception {
|
||||
Dashboard dashboard = createDashboard(tenantAdmin1.getTenantId(), null, "Dashboard v1.0");
|
||||
EntityExportData<Dashboard> exportData = exportEntity(tenantAdmin1, dashboard.getId());
|
||||
|
||||
EntityImportResult<Dashboard> importResult = importEntity(tenantAdmin1, exportData);
|
||||
checkImportedEntity(tenantId1, dashboard, tenantId1, importResult.getSavedEntity());
|
||||
checkImportedDashboardData(dashboard, importResult.getSavedEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportImportDashboard_betweenTenants_withCustomer_updated() throws Exception {
|
||||
Dashboard dashboard = createDashboard(tenantAdmin1.getTenantId(), null, "Dashboard of tenant 1");
|
||||
EntityExportData<Dashboard> exportData = exportEntity(tenantAdmin1, dashboard.getId());
|
||||
|
||||
Dashboard importedDashboard = importEntity(tenantAdmin2, exportData).getSavedEntity();
|
||||
checkImportedEntity(tenantId1, dashboard, tenantId2, importedDashboard);
|
||||
|
||||
Customer customer = createCustomer(tenantId1, "Customer 1");
|
||||
EntityExportData<Customer> customerExportData = exportEntity(tenantAdmin1, customer.getId());
|
||||
dashboardService.assignDashboardToCustomer(tenantId1, dashboard.getId(), customer.getId());
|
||||
exportData = exportEntity(tenantAdmin1, dashboard.getId());
|
||||
|
||||
Customer importedCustomer = importEntity(tenantAdmin2, customerExportData).getSavedEntity();
|
||||
importedDashboard = importEntity(tenantAdmin2, exportData).getSavedEntity();
|
||||
assertThat(importedDashboard.getAssignedCustomers()).hasOnlyOneElementSatisfying(customerInfo -> {
|
||||
assertThat(customerInfo.getCustomerId()).isEqualTo(importedCustomer.getId());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportImportDashboard_betweenTenants_withEntityAliases() throws Exception {
|
||||
AssetProfile assetProfile = createAssetProfile(tenantId1, null, null, "A");
|
||||
Asset asset1 = createAsset(tenantId1, null, assetProfile.getId(), "Asset 1");
|
||||
Asset asset2 = createAsset(tenantId1, null, assetProfile.getId(), "Asset 2");
|
||||
Dashboard dashboard = createDashboard(tenantId1, null, "Dashboard 1");
|
||||
Dashboard otherDashboard = createDashboard(tenantId1, null, "Dashboard 2");
|
||||
DeviceProfile existingDeviceProfile = createDeviceProfile(tenantId2, null, null, "Existing");
|
||||
|
||||
String aliasId = "23c4185d-1497-9457-30b2-6d91e69a5b2c";
|
||||
String unknownUuid = "ea0dc8b0-3d85-11ed-9200-77fc04fa14fa";
|
||||
String entityAliases = "{\n" +
|
||||
"\"" + aliasId + "\": {\n" +
|
||||
"\"alias\": \"assets\",\n" +
|
||||
"\"filter\": {\n" +
|
||||
" \"entityList\": [\n" +
|
||||
" \"" + asset1.getId() + "\",\n" +
|
||||
" \"" + asset2.getId() + "\",\n" +
|
||||
" \"" + tenantId1.getId() + "\",\n" +
|
||||
" \"" + existingDeviceProfile.getId() + "\",\n" +
|
||||
" \"" + unknownUuid + "\"\n" +
|
||||
" ],\n" +
|
||||
" \"id\":\"" + asset1.getId() + "\",\n" +
|
||||
" \"resolveMultiple\": true\n" +
|
||||
"},\n" +
|
||||
"\"id\": \"" + aliasId + "\"\n" +
|
||||
"}\n" +
|
||||
"}";
|
||||
String widgetId = "ea8f34a0-264a-f11f-cde3-05201bb4ff4b";
|
||||
String actionId = "4a8e6efa-3e68-fa59-7feb-d83366130cae";
|
||||
String widgets = "{\n" +
|
||||
" \"" + widgetId + "\": {\n" +
|
||||
" \"config\": {\n" +
|
||||
" \"actions\": {\n" +
|
||||
" \"rowClick\": [\n" +
|
||||
" {\n" +
|
||||
" \"name\": \"go to dashboard\",\n" +
|
||||
" \"targetDashboardId\": \"" + otherDashboard.getId() + "\",\n" +
|
||||
" \"id\": \"" + actionId + "\"\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"row\": 0,\n" +
|
||||
" \"col\": 0,\n" +
|
||||
" \"id\": \"" + widgetId + "\"\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
ObjectNode dashboardConfiguration = JacksonUtil.newObjectNode();
|
||||
dashboardConfiguration.set("entityAliases", JacksonUtil.toJsonNode(entityAliases));
|
||||
dashboardConfiguration.set("widgets", JacksonUtil.toJsonNode(widgets));
|
||||
dashboardConfiguration.set("description", new TextNode("hallo"));
|
||||
dashboard.setConfiguration(dashboardConfiguration);
|
||||
dashboard = dashboardService.saveDashboard(dashboard);
|
||||
|
||||
EntityExportData<AssetProfile> profileExportData = exportEntity(tenantAdmin1, assetProfile.getId());
|
||||
|
||||
EntityExportData<Asset> asset1ExportData = exportEntity(tenantAdmin1, asset1.getId());
|
||||
EntityExportData<Asset> asset2ExportData = exportEntity(tenantAdmin1, asset2.getId());
|
||||
EntityExportData<Dashboard> dashboardExportData = exportEntity(tenantAdmin1, dashboard.getId());
|
||||
EntityExportData<Dashboard> otherDashboardExportData = exportEntity(tenantAdmin1, otherDashboard.getId());
|
||||
|
||||
AssetProfile importedProfile = importEntity(tenantAdmin2, profileExportData).getSavedEntity();
|
||||
Asset importedAsset1 = importEntity(tenantAdmin2, asset1ExportData).getSavedEntity();
|
||||
Asset importedAsset2 = importEntity(tenantAdmin2, asset2ExportData).getSavedEntity();
|
||||
Dashboard importedOtherDashboard = importEntity(tenantAdmin2, otherDashboardExportData).getSavedEntity();
|
||||
Dashboard importedDashboard = importEntity(tenantAdmin2, dashboardExportData).getSavedEntity();
|
||||
|
||||
Map.Entry<String, JsonNode> entityAlias = importedDashboard.getConfiguration().get("entityAliases").fields().next();
|
||||
assertThat(entityAlias.getKey()).isEqualTo(aliasId);
|
||||
assertThat(entityAlias.getValue().get("id").asText()).isEqualTo(aliasId);
|
||||
|
||||
List<String> aliasEntitiesIds = Streams.stream(entityAlias.getValue().get("filter").get("entityList").elements())
|
||||
.map(JsonNode::asText).collect(Collectors.toList());
|
||||
assertThat(aliasEntitiesIds).size().isEqualTo(5);
|
||||
assertThat(aliasEntitiesIds).element(0).as("external asset 1 was replaced with imported one")
|
||||
.isEqualTo(importedAsset1.getId().toString());
|
||||
assertThat(aliasEntitiesIds).element(1).as("external asset 2 was replaced with imported one")
|
||||
.isEqualTo(importedAsset2.getId().toString());
|
||||
assertThat(aliasEntitiesIds).element(2).as("external tenant id was replaced with new tenant id")
|
||||
.isEqualTo(tenantId2.toString());
|
||||
assertThat(aliasEntitiesIds).element(3).as("existing device profile id was left as is")
|
||||
.isEqualTo(existingDeviceProfile.getId().toString());
|
||||
assertThat(aliasEntitiesIds).element(4).as("unresolved uuid was replaced with tenant id")
|
||||
.isEqualTo(tenantId2.toString());
|
||||
assertThat(entityAlias.getValue().get("filter").get("id").asText()).as("external asset 1 was replaced with imported one")
|
||||
.isEqualTo(importedAsset1.getId().toString());
|
||||
|
||||
ObjectNode widgetConfig = importedDashboard.getWidgetsConfig().get(0);
|
||||
assertThat(widgetConfig.get("id").asText()).as("widget id is not replaced")
|
||||
.isEqualTo(widgetId);
|
||||
JsonNode actionConfig = widgetConfig.get("config").get("actions").get("rowClick").get(0);
|
||||
assertThat(actionConfig.get("id").asText()).as("action id is not replaced")
|
||||
.isEqualTo(actionId);
|
||||
assertThat(actionConfig.get("targetDashboardId").asText()).as("dashboard id is replaced with imported one")
|
||||
.isEqualTo(importedOtherDashboard.getId().toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExportImportRuleChain_betweenTenants() throws Exception {
|
||||
RuleChain ruleChain = createRuleChain(tenantId1, "Rule chain of tenant 1");
|
||||
RuleChainMetaData metaData = ruleChainService.loadRuleChainMetaData(tenantId1, ruleChain.getId());
|
||||
EntityExportData<RuleChain> exportData = exportEntity(tenantAdmin1, ruleChain.getId());
|
||||
|
||||
EntityImportResult<RuleChain> importResult = importEntity(tenantAdmin2, exportData);
|
||||
RuleChain importedRuleChain = importResult.getSavedEntity();
|
||||
RuleChainMetaData importedMetaData = ruleChainService.loadRuleChainMetaData(tenantId2, importedRuleChain.getId());
|
||||
|
||||
checkImportedEntity(tenantId1, ruleChain, tenantId2, importResult.getSavedEntity());
|
||||
checkImportedRuleChainData(ruleChain, metaData, importedRuleChain, importedMetaData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportImportRuleChain_sameTenant() throws Exception {
|
||||
RuleChain ruleChain = createRuleChain(tenantId1, "Rule chain v1.0");
|
||||
RuleChainMetaData metaData = ruleChainService.loadRuleChainMetaData(tenantId1, ruleChain.getId());
|
||||
EntityExportData<RuleChain> exportData = exportEntity(tenantAdmin1, ruleChain.getId());
|
||||
|
||||
EntityImportResult<RuleChain> importResult = importEntity(tenantAdmin1, exportData);
|
||||
RuleChain importedRuleChain = importResult.getSavedEntity();
|
||||
RuleChainMetaData importedMetaData = ruleChainService.loadRuleChainMetaData(tenantId1, importedRuleChain.getId());
|
||||
|
||||
checkImportedEntity(tenantId1, ruleChain, tenantId1, importResult.getSavedEntity());
|
||||
checkImportedRuleChainData(ruleChain, metaData, importedRuleChain, importedMetaData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportRuleChain_ruleNodesConfigs() throws Exception {
|
||||
Customer customer = createCustomer(tenantId1, "Customer 1");
|
||||
RuleChain ruleChain = createRuleChain(tenantId1, "Rule chain 1");
|
||||
RuleChainMetaData metaData = ruleChainService.loadRuleChainMetaData(tenantId1, ruleChain.getId());
|
||||
|
||||
List<RuleNode> nodes = new ArrayList<>(metaData.getNodes());
|
||||
RuleNode generatorNode = new RuleNode();
|
||||
generatorNode.setName("Generator");
|
||||
generatorNode.setType(TbMsgGeneratorNode.class.getName());
|
||||
TbMsgGeneratorNodeConfiguration generatorNodeConfig = new TbMsgGeneratorNodeConfiguration();
|
||||
generatorNodeConfig.setOriginatorType(EntityType.ASSET_PROFILE);
|
||||
generatorNodeConfig.setOriginatorId(customer.getId().toString());
|
||||
generatorNodeConfig.setPeriodInSeconds(5);
|
||||
generatorNodeConfig.setMsgCount(1);
|
||||
generatorNodeConfig.setScriptLang(ScriptLanguage.JS);
|
||||
UUID someUuid = UUID.randomUUID();
|
||||
generatorNodeConfig.setJsScript("var msg = { temp: 42, humidity: 77 };\n" +
|
||||
"var metadata = { data: 40 };\n" +
|
||||
"var msgType = \"POST_TELEMETRY_REQUEST\";\n" +
|
||||
"var someUuid = \"" + someUuid + "\";\n" +
|
||||
"return { msg: msg, metadata: metadata, msgType: msgType };");
|
||||
generatorNode.setConfiguration(JacksonUtil.valueToTree(generatorNodeConfig));
|
||||
nodes.add(generatorNode);
|
||||
metaData.setNodes(nodes);
|
||||
ruleChainService.saveRuleChainMetaData(tenantId1, metaData, Function.identity());
|
||||
|
||||
EntityExportData<RuleChain> ruleChainExportData = exportEntity(tenantAdmin1, ruleChain.getId());
|
||||
EntityExportData<Customer> customerExportData = exportEntity(tenantAdmin1, customer.getId());
|
||||
|
||||
Customer importedCustomer = importEntity(tenantAdmin2, customerExportData).getSavedEntity();
|
||||
RuleChain importedRuleChain = importEntity(tenantAdmin2, ruleChainExportData).getSavedEntity();
|
||||
RuleChainMetaData importedMetaData = ruleChainService.loadRuleChainMetaData(tenantId2, importedRuleChain.getId());
|
||||
|
||||
TbMsgGeneratorNodeConfiguration importedGeneratorNodeConfig = JacksonUtil.treeToValue(importedMetaData.getNodes().stream()
|
||||
.filter(node -> node.getName().equals(generatorNode.getName()))
|
||||
.findFirst().get().getConfiguration(), TbMsgGeneratorNodeConfiguration.class);
|
||||
assertThat(importedGeneratorNodeConfig.getOriginatorId()).isEqualTo(importedCustomer.getId().toString());
|
||||
assertThat(importedGeneratorNodeConfig.getJsScript()).contains("var someUuid = \"" + someUuid + "\";");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExportImportWithInboundRelations_betweenTenants() throws Exception {
|
||||
Asset asset = createAsset(tenantId1, null, null, "Asset 1");
|
||||
Device device = createDevice(tenantId1, null, null, "Device 1");
|
||||
EntityRelation relation = createRelation(asset.getId(), device.getId());
|
||||
|
||||
EntityExportData<Asset> assetExportData = exportEntity(tenantAdmin1, asset.getId());
|
||||
EntityExportData<Device> deviceExportData = exportEntity(tenantAdmin1, device.getId(), EntityExportSettings.builder()
|
||||
.exportRelations(true)
|
||||
.exportCredentials(false)
|
||||
.build());
|
||||
|
||||
assertThat(deviceExportData.getRelations()).size().isOne();
|
||||
assertThat(deviceExportData.getRelations().get(0)).matches(entityRelation -> {
|
||||
return entityRelation.getFrom().equals(asset.getId()) && entityRelation.getTo().equals(device.getId());
|
||||
});
|
||||
((Asset) assetExportData.getEntity()).setAssetProfileId(null);
|
||||
((Device) deviceExportData.getEntity()).setDeviceProfileId(null);
|
||||
|
||||
Asset importedAsset = importEntity(tenantAdmin2, assetExportData).getSavedEntity();
|
||||
Device importedDevice = importEntity(tenantAdmin2, deviceExportData, EntityImportSettings.builder()
|
||||
.updateRelations(true)
|
||||
.build()).getSavedEntity();
|
||||
checkImportedEntity(tenantId1, device, tenantId2, importedDevice);
|
||||
checkImportedEntity(tenantId1, asset, tenantId2, importedAsset);
|
||||
|
||||
List<EntityRelation> importedRelations = relationService.findByTo(TenantId.SYS_TENANT_ID, importedDevice.getId(), RelationTypeGroup.COMMON);
|
||||
assertThat(importedRelations).size().isOne();
|
||||
assertThat(importedRelations.get(0)).satisfies(importedRelation -> {
|
||||
assertThat(importedRelation.getFrom()).isEqualTo(importedAsset.getId());
|
||||
assertThat(importedRelation.getType()).isEqualTo(relation.getType());
|
||||
assertThat(importedRelation.getAdditionalInfo()).isEqualTo(relation.getAdditionalInfo());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportImportWithRelations_betweenTenants() throws Exception {
|
||||
Asset asset = createAsset(tenantId1, null, null, "Asset 1");
|
||||
Device device = createDevice(tenantId1, null, null, "Device 1");
|
||||
EntityRelation relation = createRelation(asset.getId(), device.getId());
|
||||
|
||||
EntityExportData<Asset> assetExportData = exportEntity(tenantAdmin1, asset.getId());
|
||||
EntityExportData<Device> deviceExportData = exportEntity(tenantAdmin1, device.getId(), EntityExportSettings.builder()
|
||||
.exportRelations(true)
|
||||
.exportCredentials(false)
|
||||
.build());
|
||||
assetExportData.getEntity().setAssetProfileId(null);
|
||||
deviceExportData.getEntity().setDeviceProfileId(null);
|
||||
|
||||
Asset importedAsset = importEntity(tenantAdmin2, assetExportData).getSavedEntity();
|
||||
Device importedDevice = importEntity(tenantAdmin2, deviceExportData, EntityImportSettings.builder()
|
||||
.updateRelations(true)
|
||||
.build()).getSavedEntity();
|
||||
|
||||
List<EntityRelation> importedRelations = relationService.findByTo(TenantId.SYS_TENANT_ID, importedDevice.getId(), RelationTypeGroup.COMMON);
|
||||
assertThat(importedRelations).size().isOne();
|
||||
assertThat(importedRelations.get(0)).satisfies(importedRelation -> {
|
||||
assertThat(importedRelation.getFrom()).isEqualTo(importedAsset.getId());
|
||||
assertThat(importedRelation.getType()).isEqualTo(relation.getType());
|
||||
assertThat(importedRelation.getAdditionalInfo()).isEqualTo(relation.getAdditionalInfo());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportImportWithRelations_sameTenant() throws Exception {
|
||||
Asset asset = createAsset(tenantId1, null, null, "Asset 1");
|
||||
Device device1 = createDevice(tenantId1, null, null, "Device 1");
|
||||
EntityRelation relation1 = createRelation(asset.getId(), device1.getId());
|
||||
|
||||
EntityExportData<Asset> assetExportData = exportEntity(tenantAdmin1, asset.getId(), EntityExportSettings.builder()
|
||||
.exportRelations(true)
|
||||
.build());
|
||||
assertThat(assetExportData.getRelations()).size().isOne();
|
||||
|
||||
Device device2 = createDevice(tenantId1, null, null, "Device 2");
|
||||
EntityRelation relation2 = createRelation(asset.getId(), device2.getId());
|
||||
|
||||
importEntity(tenantAdmin1, assetExportData, EntityImportSettings.builder()
|
||||
.updateRelations(true)
|
||||
.build());
|
||||
|
||||
List<EntityRelation> relations = relationService.findByFrom(TenantId.SYS_TENANT_ID, asset.getId(), RelationTypeGroup.COMMON);
|
||||
assertThat(relations).contains(relation1);
|
||||
assertThat(relations).doesNotContain(relation2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void textExportImportWithRelations_sameTenant_removeExisting() throws Exception {
|
||||
Asset asset1 = createAsset(tenantId1, null, null, "Asset 1");
|
||||
Device device = createDevice(tenantId1, null, null, "Device 1");
|
||||
EntityRelation relation1 = createRelation(asset1.getId(), device.getId());
|
||||
|
||||
EntityExportData<Device> deviceExportData = exportEntity(tenantAdmin1, device.getId(), EntityExportSettings.builder()
|
||||
.exportRelations(true)
|
||||
.build());
|
||||
assertThat(deviceExportData.getRelations()).size().isOne();
|
||||
|
||||
Asset asset2 = createAsset(tenantId1, null, null, "Asset 2");
|
||||
EntityRelation relation2 = createRelation(asset2.getId(), device.getId());
|
||||
|
||||
importEntity(tenantAdmin1, deviceExportData, EntityImportSettings.builder()
|
||||
.updateRelations(true)
|
||||
.build());
|
||||
|
||||
List<EntityRelation> relations = relationService.findByTo(TenantId.SYS_TENANT_ID, device.getId(), RelationTypeGroup.COMMON);
|
||||
assertThat(relations).contains(relation1);
|
||||
assertThat(relations).doesNotContain(relation2);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExportImportDefaultDeviceProfile_betweenTenants_findExisting() throws Exception {
|
||||
DeviceProfile defaultDeviceProfile = deviceProfileService.findDefaultDeviceProfile(tenantId1);
|
||||
defaultDeviceProfile.setName("non-default-name");
|
||||
deviceProfileService.saveDeviceProfile(defaultDeviceProfile);
|
||||
EntityExportData<DeviceProfile> deviceProfileExportData = exportEntity(tenantAdmin1, defaultDeviceProfile.getId());
|
||||
|
||||
importEntity(tenantAdmin2, deviceProfileExportData, EntityImportSettings.builder()
|
||||
.findExistingByName(false)
|
||||
.build());
|
||||
DeviceProfile importedDeviceProfile = deviceProfileService.findDefaultDeviceProfile(tenantId2);
|
||||
assertThat(importedDeviceProfile.isDefault()).isTrue();
|
||||
assertThat(importedDeviceProfile.getName()).isEqualTo(defaultDeviceProfile.getName());
|
||||
checkImportedEntity(tenantId1, defaultDeviceProfile, tenantId2, importedDeviceProfile);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("rawTypes")
|
||||
private static EntityExportData getAndClone(Map<EntityType, EntityExportData> map, EntityType entityType) {
|
||||
return JacksonUtil.clone(map.get(entityType));
|
||||
@After
|
||||
public void afterEach() {
|
||||
tenantService.deleteTenant(tenantId1);
|
||||
tenantService.deleteTenant(tenantId2);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawTypes", "unchecked"})
|
||||
@ -712,4 +340,255 @@ public class ExportImportServiceSqlTest extends BaseExportImportServiceTest {
|
||||
deviceProfileService.saveDeviceProfile(importedDeviceProfile);
|
||||
}
|
||||
|
||||
|
||||
protected Device createDevice(TenantId tenantId, CustomerId customerId, DeviceProfileId deviceProfileId, String name) {
|
||||
Device device = new Device();
|
||||
device.setTenantId(tenantId);
|
||||
device.setCustomerId(customerId);
|
||||
device.setName(name);
|
||||
device.setLabel("lbl");
|
||||
device.setDeviceProfileId(deviceProfileId);
|
||||
DeviceData deviceData = new DeviceData();
|
||||
deviceData.setTransportConfiguration(new DefaultDeviceTransportConfiguration());
|
||||
device.setDeviceData(deviceData);
|
||||
return deviceService.saveDevice(device);
|
||||
}
|
||||
|
||||
protected OtaPackage createOtaPackage(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType type) {
|
||||
OtaPackage otaPackage = new OtaPackage();
|
||||
otaPackage.setTenantId(tenantId);
|
||||
otaPackage.setDeviceProfileId(deviceProfileId);
|
||||
otaPackage.setType(type);
|
||||
otaPackage.setTitle("My " + type);
|
||||
otaPackage.setVersion("v1.0");
|
||||
otaPackage.setFileName("filename.txt");
|
||||
otaPackage.setContentType("text/plain");
|
||||
otaPackage.setChecksumAlgorithm(ChecksumAlgorithm.SHA256);
|
||||
otaPackage.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a");
|
||||
otaPackage.setDataSize(1L);
|
||||
otaPackage.setData(ByteBuffer.wrap(new byte[]{(int) 1}));
|
||||
return otaPackageService.saveOtaPackage(otaPackage);
|
||||
}
|
||||
|
||||
protected DeviceProfile createDeviceProfile(TenantId tenantId, RuleChainId defaultRuleChainId, DashboardId defaultDashboardId, String name) {
|
||||
DeviceProfile deviceProfile = new DeviceProfile();
|
||||
deviceProfile.setTenantId(tenantId);
|
||||
deviceProfile.setName(name);
|
||||
deviceProfile.setDescription("dscrptn");
|
||||
deviceProfile.setType(DeviceProfileType.DEFAULT);
|
||||
deviceProfile.setTransportType(DeviceTransportType.DEFAULT);
|
||||
deviceProfile.setDefaultRuleChainId(defaultRuleChainId);
|
||||
deviceProfile.setDefaultDashboardId(defaultDashboardId);
|
||||
DeviceProfileData profileData = new DeviceProfileData();
|
||||
profileData.setConfiguration(new DefaultDeviceProfileConfiguration());
|
||||
profileData.setTransportConfiguration(new DefaultDeviceProfileTransportConfiguration());
|
||||
deviceProfile.setProfileData(profileData);
|
||||
return deviceProfileService.saveDeviceProfile(deviceProfile);
|
||||
}
|
||||
|
||||
protected AssetProfile createAssetProfile(TenantId tenantId, RuleChainId defaultRuleChainId, DashboardId defaultDashboardId, String name) {
|
||||
AssetProfile assetProfile = new AssetProfile();
|
||||
assetProfile.setTenantId(tenantId);
|
||||
assetProfile.setName(name);
|
||||
assetProfile.setDescription("dscrptn");
|
||||
assetProfile.setDefaultRuleChainId(defaultRuleChainId);
|
||||
assetProfile.setDefaultDashboardId(defaultDashboardId);
|
||||
return assetProfileService.saveAssetProfile(assetProfile);
|
||||
}
|
||||
|
||||
protected Asset createAsset(TenantId tenantId, CustomerId customerId, AssetProfileId assetProfileId, String name) {
|
||||
Asset asset = new Asset();
|
||||
asset.setTenantId(tenantId);
|
||||
asset.setCustomerId(customerId);
|
||||
asset.setAssetProfileId(assetProfileId);
|
||||
asset.setName(name);
|
||||
asset.setLabel("lbl");
|
||||
asset.setAdditionalInfo(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
return assetService.saveAsset(asset);
|
||||
}
|
||||
|
||||
protected Customer createCustomer(TenantId tenantId, String name) {
|
||||
Customer customer = new Customer();
|
||||
customer.setTenantId(tenantId);
|
||||
customer.setTitle(name);
|
||||
customer.setCountry("ua");
|
||||
customer.setAddress("abb");
|
||||
customer.setEmail("ccc@aa.org");
|
||||
customer.setAdditionalInfo(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
return customerService.saveCustomer(customer);
|
||||
}
|
||||
|
||||
protected Dashboard createDashboard(TenantId tenantId, CustomerId customerId, String name) {
|
||||
Dashboard dashboard = new Dashboard();
|
||||
dashboard.setTenantId(tenantId);
|
||||
dashboard.setTitle(name);
|
||||
dashboard.setConfiguration(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
dashboard.setImage("abvregewrg");
|
||||
dashboard.setMobileHide(true);
|
||||
dashboard = dashboardService.saveDashboard(dashboard);
|
||||
if (customerId != null) {
|
||||
dashboardService.assignDashboardToCustomer(tenantId, dashboard.getId(), customerId);
|
||||
return dashboardService.findDashboardById(tenantId, dashboard.getId());
|
||||
}
|
||||
return dashboard;
|
||||
}
|
||||
|
||||
protected Dashboard createDashboard(TenantId tenantId, CustomerId customerId, String name, AssetId assetForEntityAlias) {
|
||||
Dashboard dashboard = createDashboard(tenantId, customerId, name);
|
||||
String entityAliases = "{\n" +
|
||||
"\t\"23c4185d-1497-9457-30b2-6d91e69a5b2c\": {\n" +
|
||||
"\t\t\"alias\": \"assets\",\n" +
|
||||
"\t\t\"filter\": {\n" +
|
||||
"\t\t\t\"entityList\": [\n" +
|
||||
"\t\t\t\t\"" + assetForEntityAlias.getId().toString() + "\"\n" +
|
||||
"\t\t\t],\n" +
|
||||
"\t\t\t\"entityType\": \"ASSET\",\n" +
|
||||
"\t\t\t\"resolveMultiple\": true,\n" +
|
||||
"\t\t\t\"type\": \"entityList\"\n" +
|
||||
"\t\t},\n" +
|
||||
"\t\t\"id\": \"23c4185d-1497-9457-30b2-6d91e69a5b2c\"\n" +
|
||||
"\t}\n" +
|
||||
"}";
|
||||
ObjectNode dashboardConfiguration = JacksonUtil.newObjectNode();
|
||||
dashboardConfiguration.set("entityAliases", JacksonUtil.toJsonNode(entityAliases));
|
||||
dashboardConfiguration.set("description", new TextNode("hallo"));
|
||||
dashboard.setConfiguration(dashboardConfiguration);
|
||||
return dashboardService.saveDashboard(dashboard);
|
||||
}
|
||||
|
||||
protected RuleChain createRuleChain(TenantId tenantId, String name, EntityId originatorId) {
|
||||
RuleChain ruleChain = new RuleChain();
|
||||
ruleChain.setTenantId(tenantId);
|
||||
ruleChain.setName(name);
|
||||
ruleChain.setType(RuleChainType.CORE);
|
||||
ruleChain.setDebugMode(true);
|
||||
ruleChain.setConfiguration(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
ruleChain = ruleChainService.saveRuleChain(ruleChain);
|
||||
|
||||
RuleChainMetaData metaData = new RuleChainMetaData();
|
||||
metaData.setRuleChainId(ruleChain.getId());
|
||||
|
||||
RuleNode ruleNode1 = new RuleNode();
|
||||
ruleNode1.setName("Generator 1");
|
||||
ruleNode1.setType(TbMsgGeneratorNode.class.getName());
|
||||
ruleNode1.setDebugMode(true);
|
||||
TbMsgGeneratorNodeConfiguration configuration1 = new TbMsgGeneratorNodeConfiguration();
|
||||
configuration1.setOriginatorType(originatorId.getEntityType());
|
||||
configuration1.setOriginatorId(originatorId.getId().toString());
|
||||
ruleNode1.setConfiguration(JacksonUtil.valueToTree(configuration1));
|
||||
|
||||
RuleNode ruleNode2 = new RuleNode();
|
||||
ruleNode2.setName("Simple Rule Node 2");
|
||||
ruleNode2.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName());
|
||||
ruleNode2.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version());
|
||||
ruleNode2.setDebugMode(true);
|
||||
TbGetAttributesNodeConfiguration configuration2 = new TbGetAttributesNodeConfiguration();
|
||||
configuration2.setServerAttributeNames(Collections.singletonList("serverAttributeKey2"));
|
||||
ruleNode2.setConfiguration(JacksonUtil.valueToTree(configuration2));
|
||||
|
||||
metaData.setNodes(Arrays.asList(ruleNode1, ruleNode2));
|
||||
metaData.setFirstNodeIndex(0);
|
||||
metaData.addConnectionInfo(0, 1, TbNodeConnectionType.SUCCESS);
|
||||
ruleChainService.saveRuleChainMetaData(tenantId, metaData, Function.identity());
|
||||
|
||||
return ruleChainService.findRuleChainById(tenantId, ruleChain.getId());
|
||||
}
|
||||
|
||||
protected RuleChain createRuleChain(TenantId tenantId, String name) {
|
||||
RuleChain ruleChain = new RuleChain();
|
||||
ruleChain.setTenantId(tenantId);
|
||||
ruleChain.setName(name);
|
||||
ruleChain.setType(RuleChainType.CORE);
|
||||
ruleChain.setDebugMode(true);
|
||||
ruleChain.setConfiguration(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
ruleChain = ruleChainService.saveRuleChain(ruleChain);
|
||||
|
||||
RuleChainMetaData metaData = new RuleChainMetaData();
|
||||
metaData.setRuleChainId(ruleChain.getId());
|
||||
|
||||
RuleNode ruleNode1 = new RuleNode();
|
||||
ruleNode1.setName("Simple Rule Node 1");
|
||||
ruleNode1.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName());
|
||||
ruleNode1.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version());
|
||||
ruleNode1.setDebugMode(true);
|
||||
TbGetAttributesNodeConfiguration configuration1 = new TbGetAttributesNodeConfiguration();
|
||||
configuration1.setServerAttributeNames(Collections.singletonList("serverAttributeKey1"));
|
||||
ruleNode1.setConfiguration(JacksonUtil.valueToTree(configuration1));
|
||||
|
||||
RuleNode ruleNode2 = new RuleNode();
|
||||
ruleNode2.setName("Simple Rule Node 2");
|
||||
ruleNode2.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName());
|
||||
ruleNode2.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version());
|
||||
ruleNode2.setDebugMode(true);
|
||||
TbGetAttributesNodeConfiguration configuration2 = new TbGetAttributesNodeConfiguration();
|
||||
configuration2.setServerAttributeNames(Collections.singletonList("serverAttributeKey2"));
|
||||
ruleNode2.setConfiguration(JacksonUtil.valueToTree(configuration2));
|
||||
|
||||
metaData.setNodes(Arrays.asList(ruleNode1, ruleNode2));
|
||||
metaData.setFirstNodeIndex(0);
|
||||
metaData.addConnectionInfo(0, 1, TbNodeConnectionType.SUCCESS);
|
||||
ruleChainService.saveRuleChainMetaData(tenantId, metaData, Function.identity());
|
||||
|
||||
return ruleChainService.findRuleChainById(tenantId, ruleChain.getId());
|
||||
}
|
||||
|
||||
protected EntityView createEntityView(TenantId tenantId, CustomerId customerId, EntityId entityId, String name) {
|
||||
EntityView entityView = new EntityView();
|
||||
entityView.setTenantId(tenantId);
|
||||
entityView.setEntityId(entityId);
|
||||
entityView.setCustomerId(customerId);
|
||||
entityView.setName(name);
|
||||
entityView.setType("A");
|
||||
return entityViewService.saveEntityView(entityView);
|
||||
}
|
||||
|
||||
protected EntityRelation createRelation(EntityId from, EntityId to) {
|
||||
EntityRelation relation = new EntityRelation();
|
||||
relation.setFrom(from);
|
||||
relation.setTo(to);
|
||||
relation.setType(EntityRelation.MANAGES_TYPE);
|
||||
relation.setAdditionalInfo(JacksonUtil.newObjectNode().set("a", new TextNode("b")));
|
||||
relation.setTypeGroup(RelationTypeGroup.COMMON);
|
||||
relationService.saveRelation(TenantId.SYS_TENANT_ID, relation);
|
||||
return relation;
|
||||
}
|
||||
|
||||
protected <E extends ExportableEntity<I>, I extends EntityId> EntityExportData<E> exportEntity(User user, I entityId) throws Exception {
|
||||
return exportEntity(user, entityId, EntityExportSettings.builder()
|
||||
.exportCredentials(true)
|
||||
.build());
|
||||
}
|
||||
|
||||
protected <E extends ExportableEntity<I>, I extends EntityId> EntityExportData<E> exportEntity(User user, I entityId, EntityExportSettings exportSettings) throws Exception {
|
||||
return exportImportService.exportEntity(new SimpleEntitiesExportCtx(getSecurityUser(user), null, null, exportSettings), entityId);
|
||||
}
|
||||
|
||||
protected <E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(User user, EntityExportData<E> exportData) throws Exception {
|
||||
return importEntity(user, exportData, EntityImportSettings.builder()
|
||||
.saveCredentials(true)
|
||||
.build());
|
||||
}
|
||||
|
||||
protected <E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(User user, EntityExportData<E> exportData, EntityImportSettings importSettings) throws Exception {
|
||||
EntitiesImportCtx ctx = new EntitiesImportCtx(UUID.randomUUID(), getSecurityUser(user), null, importSettings);
|
||||
ctx.setFinalImportAttempt(true);
|
||||
exportData = JacksonUtil.treeToValue(JacksonUtil.valueToTree(exportData), EntityExportData.class);
|
||||
EntityImportResult<E> importResult = exportImportService.importEntity(ctx, exportData);
|
||||
exportImportService.saveReferencesAndRelations(ctx);
|
||||
for (ThrowingRunnable throwingRunnable : ctx.getEventCallbacks()) {
|
||||
throwingRunnable.run();
|
||||
}
|
||||
return importResult;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("rawTypes")
|
||||
private static EntityExportData getAndClone(Map<EntityType, EntityExportData> map, EntityType entityType) {
|
||||
return JacksonUtil.clone(map.get(entityType));
|
||||
}
|
||||
|
||||
protected SecurityUser getSecurityUser(User user) {
|
||||
return new SecurityUser(user, true, new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -33,6 +33,7 @@ public class RepositorySettings implements Serializable {
|
||||
private String defaultBranch;
|
||||
private boolean readOnly;
|
||||
private boolean showMergeCommits;
|
||||
private boolean localOnly;
|
||||
|
||||
public RepositorySettings() {
|
||||
}
|
||||
@ -48,5 +49,7 @@ public class RepositorySettings implements Serializable {
|
||||
this.defaultBranch = settings.getDefaultBranch();
|
||||
this.readOnly = settings.isReadOnly();
|
||||
this.showMergeCommits = settings.isShowMergeCommits();
|
||||
this.localOnly = settings.isLocalOnly();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -906,7 +906,8 @@ public class ProtoUtils {
|
||||
.setRepositoryUri(repositorySettings.getRepositoryUri())
|
||||
.setAuthMethod(repositorySettings.getAuthMethod().name())
|
||||
.setReadOnly(repositorySettings.isReadOnly())
|
||||
.setShowMergeCommits(repositorySettings.isShowMergeCommits());
|
||||
.setShowMergeCommits(repositorySettings.isShowMergeCommits())
|
||||
.setLocalOnly(repositorySettings.isLocalOnly());
|
||||
|
||||
if (isNotNull(repositorySettings.getUsername())) {
|
||||
builder.setUsername(repositorySettings.getUsername());
|
||||
@ -935,6 +936,7 @@ public class ProtoUtils {
|
||||
repositorySettings.setAuthMethod(RepositoryAuthMethod.valueOf(proto.getAuthMethod()));
|
||||
repositorySettings.setReadOnly(proto.getReadOnly());
|
||||
repositorySettings.setShowMergeCommits(proto.getShowMergeCommits());
|
||||
repositorySettings.setLocalOnly(proto.getLocalOnly());
|
||||
if (proto.hasUsername()) {
|
||||
repositorySettings.setUsername(proto.getUsername());
|
||||
}
|
||||
|
||||
@ -322,6 +322,7 @@ message RepositorySettingsProto {
|
||||
optional string defaultBranch = 8;
|
||||
bool readOnly = 9;
|
||||
bool showMergeCommits = 10;
|
||||
bool localOnly = 11;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -202,7 +202,7 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe
|
||||
try {
|
||||
Futures.allAsList(futures).get(packProcessingTimeout, TimeUnit.MILLISECONDS);
|
||||
} catch (TimeoutException e) {
|
||||
log.info("Timeout for processing the version control tasks.", e);
|
||||
log.error("Timeout for processing the version control tasks.", e);
|
||||
}
|
||||
consumer.commit();
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.thingsboard.server.service.sync.vc;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
@ -36,7 +37,6 @@ import org.thingsboard.server.common.data.sync.vc.VersionCreationResult;
|
||||
import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo;
|
||||
import org.thingsboard.server.service.sync.vc.GitRepository.Diff;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -83,11 +83,20 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
try {
|
||||
repository.fetch();
|
||||
|
||||
repository.createAndCheckoutOrphanBranch(commit.getWorkingBranch());
|
||||
repository.resetAndClean();
|
||||
|
||||
if (repository.listRemoteBranches().contains(new BranchInfo(branch, false))) {
|
||||
repository.merge(branch);
|
||||
List<String> branches = repository.listBranches().stream().map(BranchInfo::getName).toList();
|
||||
if (repository.getSettings().isLocalOnly()) {
|
||||
if (branches.contains(commit.getBranch())) {
|
||||
repository.checkoutBranch(commit.getBranch());
|
||||
} else {
|
||||
repository.createAndCheckoutOrphanBranch(commit.getBranch());
|
||||
}
|
||||
repository.resetAndClean();
|
||||
} else {
|
||||
repository.createAndCheckoutOrphanBranch(commit.getWorkingBranch());
|
||||
repository.resetAndClean();
|
||||
if (branches.contains(branch)) {
|
||||
repository.merge(branch);
|
||||
}
|
||||
}
|
||||
} catch (IOException | GitAPIException gitAPIException) {
|
||||
//TODO: analyze and return meaningful exceptions that we can show to the client;
|
||||
@ -185,7 +194,7 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
public List<BranchInfo> listBranches(TenantId tenantId) {
|
||||
GitRepository repository = checkRepository(tenantId);
|
||||
try {
|
||||
return repository.listRemoteBranches();
|
||||
return repository.listBranches();
|
||||
} catch (GitAPIException gitAPIException) {
|
||||
//TODO: analyze and return meaningful exceptions that we can show to the client;
|
||||
throw new RuntimeException(gitAPIException);
|
||||
@ -233,9 +242,9 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
|
||||
@Override
|
||||
public void initRepository(TenantId tenantId, RepositorySettings settings) throws Exception {
|
||||
testRepository(tenantId, settings);
|
||||
|
||||
clearRepository(tenantId);
|
||||
if (!settings.isLocalOnly()) {
|
||||
clearRepository(tenantId);
|
||||
}
|
||||
cloneRepository(tenantId, settings);
|
||||
}
|
||||
|
||||
@ -247,11 +256,10 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
|
||||
@Override
|
||||
public void clearRepository(TenantId tenantId) throws IOException {
|
||||
GitRepository repository = repositories.get(tenantId);
|
||||
GitRepository repository = repositories.remove(tenantId);
|
||||
if (repository != null) {
|
||||
log.debug("[{}] Clear tenant repository started.", tenantId);
|
||||
FileUtils.deleteDirectory(new File(repository.getDirectory()));
|
||||
repositories.remove(tenantId);
|
||||
log.debug("[{}] Clear tenant repository completed.", tenantId);
|
||||
}
|
||||
}
|
||||
@ -276,15 +284,23 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
|
||||
private GitRepository cloneRepository(TenantId tenantId, RepositorySettings settings) throws Exception {
|
||||
log.debug("[{}] Init tenant repository started.", tenantId);
|
||||
Path repositoryDirectory = Path.of(repositoriesFolder, tenantId.getId().toString());
|
||||
Path repositoryDirectory = Path.of(repositoriesFolder, settings.isLocalOnly() ? "local_" + settings.getRepositoryUri() : tenantId.getId().toString());
|
||||
|
||||
GitRepository repository;
|
||||
if (Files.exists(repositoryDirectory)) {
|
||||
FileUtils.forceDelete(repositoryDirectory.toFile());
|
||||
repository = GitRepository.open(repositoryDirectory.toFile(), settings);
|
||||
} else {
|
||||
Files.createDirectories(repositoryDirectory);
|
||||
if (settings.isLocalOnly()) {
|
||||
repository = GitRepository.create(settings, repositoryDirectory.toFile());
|
||||
} else {
|
||||
repository = GitRepository.clone(settings, repositoryDirectory.toFile());
|
||||
}
|
||||
}
|
||||
Files.createDirectories(repositoryDirectory);
|
||||
GitRepository repository = GitRepository.clone(settings, repositoryDirectory.toFile());
|
||||
|
||||
repositories.put(tenantId, repository);
|
||||
log.debug("[{}] Init tenant repository completed.", tenantId);
|
||||
return repository;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -21,13 +21,13 @@ import com.google.common.collect.Streams;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.sshd.common.util.security.SecurityUtils;
|
||||
import org.eclipse.jgit.api.CloneCommand;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.GitCommand;
|
||||
import org.eclipse.jgit.api.ListBranchCommand;
|
||||
import org.eclipse.jgit.api.LogCommand;
|
||||
import org.eclipse.jgit.api.LsRemoteCommand;
|
||||
import org.eclipse.jgit.api.ResetCommand;
|
||||
@ -87,6 +87,9 @@ import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.eclipse.jgit.api.ListBranchCommand.ListMode;
|
||||
|
||||
@Slf4j
|
||||
public class GitRepository {
|
||||
|
||||
private final Git git;
|
||||
@ -106,7 +109,16 @@ public class GitRepository {
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
public static GitRepository create(RepositorySettings settings, File directory) throws GitAPIException {
|
||||
log.debug("Executing create [{}]", directory);
|
||||
Git git = Git.init()
|
||||
.setDirectory(directory)
|
||||
.call();
|
||||
return new GitRepository(git, settings, null, directory.getAbsolutePath());
|
||||
}
|
||||
|
||||
public static GitRepository clone(RepositorySettings settings, File directory) throws GitAPIException {
|
||||
log.debug("Executing clone [{}]", settings.getRepositoryUri());
|
||||
CloneCommand cloneCommand = Git.cloneRepository()
|
||||
.setURI(settings.getRepositoryUri())
|
||||
.setDirectory(directory)
|
||||
@ -118,12 +130,17 @@ public class GitRepository {
|
||||
}
|
||||
|
||||
public static GitRepository open(File directory, RepositorySettings settings) throws IOException {
|
||||
log.debug("Executing open [{}][{}]", settings.getRepositoryUri(), directory);
|
||||
Git git = Git.open(directory);
|
||||
AuthHandler authHandler = AuthHandler.createFor(settings, directory);
|
||||
return new GitRepository(git, settings, authHandler, directory.getAbsolutePath());
|
||||
}
|
||||
|
||||
public static void test(RepositorySettings settings, File directory) throws Exception {
|
||||
if (settings.isLocalOnly()) {
|
||||
return;
|
||||
}
|
||||
log.debug("Executing test [{}]", settings.getRepositoryUri());
|
||||
AuthHandler authHandler = AuthHandler.createFor(settings, directory);
|
||||
if (settings.isReadOnly()) {
|
||||
LsRemoteCommand lsRemoteCommand = Git.lsRemoteRepository().setRemote(settings.getRepositoryUri());
|
||||
@ -147,6 +164,10 @@ public class GitRepository {
|
||||
}
|
||||
|
||||
public void fetch() throws GitAPIException {
|
||||
if (settings.isLocalOnly()) {
|
||||
return;
|
||||
}
|
||||
log.debug("Executing fetch [{}]", settings.getRepositoryUri());
|
||||
FetchResult result = execute(git.fetch()
|
||||
.setRemoveDeletedRefs(true));
|
||||
Ref head = result.getAdvertisedRef(Constants.HEAD);
|
||||
@ -156,12 +177,14 @@ public class GitRepository {
|
||||
}
|
||||
|
||||
public void deleteLocalBranchIfExists(String branch) throws GitAPIException {
|
||||
log.debug("Executing deleteLocalBranchIfExists [{}][{}]", settings.getRepositoryUri(), branch);
|
||||
execute(git.branchDelete()
|
||||
.setBranchNames(branch)
|
||||
.setForce(true));
|
||||
}
|
||||
|
||||
public void resetAndClean() throws GitAPIException {
|
||||
log.debug("Executing resetAndClean [{}]", settings.getRepositoryUri());
|
||||
execute(git.reset()
|
||||
.setMode(ResetCommand.ResetType.HARD));
|
||||
execute(git.clean()
|
||||
@ -170,6 +193,7 @@ public class GitRepository {
|
||||
}
|
||||
|
||||
public void merge(String branch) throws IOException, GitAPIException {
|
||||
log.debug("Executing merge [{}][{}]", settings.getRepositoryUri(), branch);
|
||||
ObjectId branchId = resolve("origin/" + branch);
|
||||
if (branchId == null) {
|
||||
throw new IllegalArgumentException("Branch not found");
|
||||
@ -178,9 +202,10 @@ public class GitRepository {
|
||||
.include(branchId));
|
||||
}
|
||||
|
||||
public List<BranchInfo> listRemoteBranches() throws GitAPIException {
|
||||
public List<BranchInfo> listBranches() throws GitAPIException {
|
||||
log.debug("Executing listBranches [{}]", settings.getRepositoryUri());
|
||||
return execute(git.branchList()
|
||||
.setListMode(ListBranchCommand.ListMode.REMOTE)).stream()
|
||||
.setListMode(settings.isLocalOnly() ? ListMode.ALL : ListMode.REMOTE)).stream()
|
||||
.filter(ref -> !ref.getName().equals(Constants.HEAD))
|
||||
.map(this::toBranchInfo)
|
||||
.distinct().collect(Collectors.toList());
|
||||
@ -191,6 +216,7 @@ public class GitRepository {
|
||||
}
|
||||
|
||||
public PageData<Commit> listCommits(String branch, String path, PageLink pageLink) throws IOException, GitAPIException {
|
||||
log.debug("Executing listCommits [{}][{}][{}]", settings.getRepositoryUri(), branch, path);
|
||||
ObjectId branchId = resolve("origin/" + branch);
|
||||
if (branchId == null) {
|
||||
return new PageData<>();
|
||||
@ -212,6 +238,7 @@ public class GitRepository {
|
||||
}
|
||||
|
||||
public List<String> listFilesAtCommit(String commitId, String path) throws IOException {
|
||||
log.debug("Executing listFilesAtCommit [{}][{}][{}]", settings.getRepositoryUri(), commitId, path);
|
||||
List<String> files = new ArrayList<>();
|
||||
RevCommit revCommit = resolveCommit(commitId);
|
||||
try (TreeWalk treeWalk = new TreeWalk(git.getRepository())) {
|
||||
@ -229,6 +256,7 @@ public class GitRepository {
|
||||
|
||||
|
||||
public String getFileContentAtCommit(String file, String commitId) throws IOException {
|
||||
log.debug("Executing getFileContentAtCommit [{}][{}][{}]", settings.getRepositoryUri(), commitId, file);
|
||||
RevCommit revCommit = resolveCommit(commitId);
|
||||
try (TreeWalk treeWalk = TreeWalk.forPath(git.getRepository(), file, revCommit.getTree())) {
|
||||
if (treeWalk == null) {
|
||||
@ -249,18 +277,29 @@ public class GitRepository {
|
||||
|
||||
|
||||
public void createAndCheckoutOrphanBranch(String name) throws GitAPIException {
|
||||
log.debug("Executing createAndCheckoutOrphanBranch [{}][{}]", settings.getRepositoryUri(), name);
|
||||
execute(git.checkout()
|
||||
.setOrphan(true)
|
||||
.setForced(true)
|
||||
.setName(name));
|
||||
}
|
||||
|
||||
public void checkoutBranch(String name) throws GitAPIException {
|
||||
log.debug("Executing checkoutBranch [{}][{}]", settings.getRepositoryUri(), name);
|
||||
git.checkout()
|
||||
.setForced(true)
|
||||
.setName(name)
|
||||
.call();
|
||||
}
|
||||
|
||||
public void add(String filesPattern) throws GitAPIException {
|
||||
log.debug("Executing add [{}][{}]", settings.getRepositoryUri(), filesPattern);
|
||||
execute(git.add().setUpdate(true).addFilepattern(filesPattern));
|
||||
execute(git.add().addFilepattern(filesPattern));
|
||||
}
|
||||
|
||||
public Status status() throws GitAPIException {
|
||||
log.debug("Executing status [{}]", settings.getRepositoryUri());
|
||||
org.eclipse.jgit.api.Status status = execute(git.status());
|
||||
Set<String> modified = new HashSet<>();
|
||||
modified.addAll(status.getModified());
|
||||
@ -269,6 +308,7 @@ public class GitRepository {
|
||||
}
|
||||
|
||||
public Commit commit(String message, String authorName, String authorEmail) throws GitAPIException {
|
||||
log.debug("Executing commit [{}][{}]", settings.getRepositoryUri(), message);
|
||||
RevCommit revCommit = execute(git.commit()
|
||||
.setAuthor(authorName, authorEmail)
|
||||
.setMessage(message));
|
||||
@ -277,6 +317,10 @@ public class GitRepository {
|
||||
|
||||
|
||||
public void push(String localBranch, String remoteBranch) throws GitAPIException {
|
||||
if (settings.isLocalOnly()) {
|
||||
return;
|
||||
}
|
||||
log.debug("Executing push [{}][{}]", settings.getRepositoryUri(), remoteBranch);
|
||||
execute(git.push()
|
||||
.setRefSpecs(new RefSpec(localBranch + ":" + remoteBranch)));
|
||||
}
|
||||
@ -355,6 +399,9 @@ public class GitRepository {
|
||||
}
|
||||
|
||||
private ObjectId resolve(String rev) throws IOException {
|
||||
if (settings.isLocalOnly()) {
|
||||
rev = StringUtils.removeStart(rev, "origin/");
|
||||
}
|
||||
ObjectId result = git.getRepository().resolve(rev);
|
||||
if (result == null) {
|
||||
throw new IllegalArgumentException("Failed to parse git revision string: \"" + rev + "\"");
|
||||
@ -363,8 +410,8 @@ public class GitRepository {
|
||||
}
|
||||
|
||||
private <C extends GitCommand<T>, T> T execute(C command) throws GitAPIException {
|
||||
if (command instanceof TransportCommand) {
|
||||
authHandler.configureCommand((TransportCommand) command);
|
||||
if (command instanceof TransportCommand transportCommand && authHandler != null) {
|
||||
authHandler.configureCommand(transportCommand);
|
||||
}
|
||||
return command.call();
|
||||
}
|
||||
@ -412,6 +459,9 @@ public class GitRepository {
|
||||
private final SshdSessionFactory sshSessionFactory;
|
||||
|
||||
protected static AuthHandler createFor(RepositorySettings settings, File directory) {
|
||||
if (settings.isLocalOnly()) {
|
||||
return null;
|
||||
}
|
||||
CredentialsProvider credentialsProvider = null;
|
||||
SshdSessionFactory sshSessionFactory = null;
|
||||
if (RepositoryAuthMethod.USERNAME_PASSWORD.equals(settings.getAuthMethod())) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user