From 2aa4d5bcf15fb45ea874343ffca8780e220743f7 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Fri, 1 Dec 2023 14:53:46 +0200 Subject: [PATCH] Improve code using dynamic approach of updating Install or Update EdgeInstructions --- ...DefaultEdgeInstallInstructionsService.java | 5 ++ ...efaultEdgeUpgradeInstructionsService.java} | 47 ++++++++++--------- .../EdgeInstallInstructionsService.java | 2 + .../EdgeUpgradeInstructionsService.java | 7 +++ .../service/update/DefaultUpdateService.java | 24 ++++++++++ ...ientSparkplugBAttributesInProfileTest.java | 2 +- .../MqttV5ClientSparkplugBAttributesTest.java | 2 +- .../common/data/EdgeUpgradeMessage.java | 33 +++++++++++++ .../server/common/data/UpgradeInfo.java | 11 +++++ 9 files changed, 110 insertions(+), 23 deletions(-) rename application/src/main/java/org/thingsboard/server/service/edge/instructions/{DefaultEdgeUpgradeService.java => DefaultEdgeUpgradeInstructionsService.java} (85%) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/EdgeUpgradeMessage.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/UpgradeInfo.java diff --git a/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeInstallInstructionsService.java b/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeInstallInstructionsService.java index 9da2b2abe8..49f24ac454 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeInstallInstructionsService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeInstallInstructionsService.java @@ -67,6 +67,11 @@ public class DefaultEdgeInstallInstructionsService implements EdgeInstallInstruc } } + @Override + public void updateApplicationVersion(String version) { + appVersion = version; + } + private EdgeInstructions getDockerInstallInstructions(Edge edge, HttpServletRequest request) { String dockerInstallInstructions = readFile(resolveFile("docker", "instructions.md")); String baseUrl = request.getServerName(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeUpgradeInstructionsService.java similarity index 85% rename from application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeUpgradeService.java rename to application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeUpgradeInstructionsService.java index 7ad9e94977..66f12a7ab1 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeUpgradeInstructionsService.java @@ -15,13 +15,12 @@ */ package org.thingsboard.server.service.edge.instructions; -import lombok.AllArgsConstructor; -import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.UpgradeInfo; import org.thingsboard.server.common.data.edge.EdgeInstructions; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.install.InstallScripts; @@ -31,15 +30,16 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; +import java.util.Map; @Service @Slf4j @RequiredArgsConstructor @ConditionalOnProperty(prefix = "edges", value = "enabled", havingValue = "true") @TbCoreComponent -public class DefaultEdgeUpgradeService implements EdgeUpgradeInstructionsService { +public class DefaultEdgeUpgradeInstructionsService implements EdgeUpgradeInstructionsService { - private static final HashMap upgradeVersionHashMap; + private static final Map upgradeVersionHashMap; static { upgradeVersionHashMap = new HashMap<>(); @@ -72,17 +72,29 @@ public class DefaultEdgeUpgradeService implements EdgeUpgradeInstructionsService } } + @Override + public void updateApplicationVersion(String version) { + appVersion = version; + } + + @Override + public void updateInstructionMap(Map map) { + for (String key : map.keySet()) { + upgradeVersionHashMap.put(key, map.get(key)); + } + } + private EdgeInstructions getDockerUpgradeInstructions(String tbVersion, String currentEdgeVersion) { UpgradeInfo upgradeInfo = upgradeVersionHashMap.get(currentEdgeVersion); - if (upgradeInfo == null || upgradeInfo.getNextVersion() == null || tbVersion.equals(currentEdgeVersion)) { + if (upgradeInfo == null || upgradeInfo.getNextEdgeVersion() == null || tbVersion.equals(currentEdgeVersion)) { return new EdgeInstructions("Edge upgrade instruction for " + currentEdgeVersion + "EDGE is not available."); } boolean rmUpgradeCompose = false; StringBuilder result = new StringBuilder(readFile(resolveFile("docker", "upgrade_preparing.md"))); - while (upgradeInfo.getNextVersion() != null || !tbVersion.equals(currentEdgeVersion)) { - String edgeVersion = upgradeInfo.getNextVersion(); + while (upgradeInfo.getNextEdgeVersion() != null || !tbVersion.equals(currentEdgeVersion)) { + String edgeVersion = upgradeInfo.getNextEdgeVersion(); String ubuntuUpgradeInstructions = readFile(resolveFile("docker", "instructions.md")); - if (upgradeInfo.isUpgradeDb()) { + if (upgradeInfo.isRequiresUpdateDb()) { String upgradeDb = readFile(resolveFile("docker", "upgrade_db.md")); ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${UPGRADE_DB}", upgradeDb); } else { @@ -98,7 +110,7 @@ public class DefaultEdgeUpgradeService implements EdgeUpgradeInstructionsService ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${TB_EDGE_VERSION}", edgeVersion + "EDGE"); ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${FROM_TB_EDGE_VERSION}", currentEdgeVersion + "EDGE"); currentEdgeVersion = edgeVersion; - upgradeInfo = upgradeVersionHashMap.get(upgradeInfo.getNextVersion()); + upgradeInfo = upgradeVersionHashMap.get(upgradeInfo.getNextEdgeVersion()); result.append(ubuntuUpgradeInstructions); } String startService = readFile(resolveFile("docker", "start_service.md")); @@ -109,16 +121,16 @@ public class DefaultEdgeUpgradeService implements EdgeUpgradeInstructionsService private EdgeInstructions getLinuxUpgradeInstructions(String tbVersion, String currentEdgeVersion, String os) { UpgradeInfo upgradeInfo = upgradeVersionHashMap.get(currentEdgeVersion); - if (upgradeInfo == null || upgradeInfo.getNextVersion() == null || tbVersion.equals(currentEdgeVersion)) { + if (upgradeInfo == null || upgradeInfo.getNextEdgeVersion() == null || tbVersion.equals(currentEdgeVersion)) { return new EdgeInstructions("Edge upgrade instruction for " + currentEdgeVersion + "EDGE is not available."); } String upgrade_preparing = readFile(resolveFile("upgrade_preparing.md")); upgrade_preparing = upgrade_preparing.replace("${OS}", os.equals("centos") ? "RHEL/CentOS 7/8" : "Ubuntu"); StringBuilder result = new StringBuilder(upgrade_preparing); - while (upgradeInfo.getNextVersion() != null || !tbVersion.equals(currentEdgeVersion)) { - String edgeVersion = upgradeInfo.getNextVersion(); + while (upgradeInfo.getNextEdgeVersion() != null || !tbVersion.equals(currentEdgeVersion)) { + String edgeVersion = upgradeInfo.getNextEdgeVersion(); String ubuntuUpgradeInstructions = readFile(resolveFile(os, "instructions.md")); - if (upgradeInfo.isUpgradeDb()) { + if (upgradeInfo.isRequiresUpdateDb()) { String upgradeDb = readFile(resolveFile("upgrade_db.md")); ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${UPGRADE_DB}", upgradeDb); } else { @@ -129,7 +141,7 @@ public class DefaultEdgeUpgradeService implements EdgeUpgradeInstructionsService ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${TB_EDGE_VERSION}", edgeVersion); ubuntuUpgradeInstructions = ubuntuUpgradeInstructions.replace("${FROM_TB_EDGE_VERSION}", currentEdgeVersion); currentEdgeVersion = edgeVersion; - upgradeInfo = upgradeVersionHashMap.get(upgradeInfo.getNextVersion()); + upgradeInfo = upgradeVersionHashMap.get(upgradeInfo.getNextEdgeVersion()); result.append(ubuntuUpgradeInstructions); } String startService = readFile(resolveFile("start_service.md")); @@ -161,11 +173,4 @@ public class DefaultEdgeUpgradeService implements EdgeUpgradeInstructionsService private Path getEdgeInstallInstructionsDir() { return Paths.get(installScripts.getDataDir(), InstallScripts.JSON_DIR, EDGE_DIR, INSTRUCTIONS_DIR, UPGRADE_DIR); } - - @AllArgsConstructor - @Getter - public static class UpgradeInfo { - private boolean upgradeDb; - private String nextVersion; - } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeInstallInstructionsService.java b/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeInstallInstructionsService.java index af97d7a393..2c1ef4fe87 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeInstallInstructionsService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeInstallInstructionsService.java @@ -23,4 +23,6 @@ import javax.servlet.http.HttpServletRequest; public interface EdgeInstallInstructionsService { EdgeInstructions getInstallInstructions(Edge edge, String installationMethod, HttpServletRequest request); + + void updateApplicationVersion(String version); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeUpgradeInstructionsService.java b/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeUpgradeInstructionsService.java index 61abd113dc..4c67c1ab9c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeUpgradeInstructionsService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeUpgradeInstructionsService.java @@ -15,9 +15,16 @@ */ package org.thingsboard.server.service.edge.instructions; +import org.thingsboard.server.common.data.UpgradeInfo; import org.thingsboard.server.common.data.edge.EdgeInstructions; +import java.util.Map; + public interface EdgeUpgradeInstructionsService { EdgeInstructions getUpgradeInstructions(String edgeVersion, String upgradeMethod); + + void updateInstructionMap(Map upgradeVersions); + + void updateApplicationVersion(String version); } diff --git a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java index f5e3daf05d..7ddc4b0e9d 100644 --- a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java @@ -27,17 +27,21 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.data.EdgeUpgradeMessage; import org.thingsboard.server.common.data.UpdateMessage; import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionTrigger; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.edge.instructions.EdgeInstallInstructionsService; +import org.thingsboard.server.service.edge.instructions.EdgeUpgradeInstructionsService; import javax.annotation.PreDestroy; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.HashMap; import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -65,12 +69,20 @@ public class DefaultUpdateService implements UpdateService { @Autowired private NotificationRuleProcessor notificationRuleProcessor; + @Autowired + private EdgeInstallInstructionsService edgeInstallInstructionsService; + + @Autowired + private EdgeUpgradeInstructionsService edgeUpgradeInstructionsService; + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, ThingsBoardThreadFactory.forName("tb-update-service")); private ScheduledFuture checkUpdatesFuture = null; private final RestTemplate restClient = new RestTemplate(); private UpdateMessage updateMessage; + private EdgeUpgradeMessage edgeUpgradeMessage; + private String edgeInstallVersion; private String platform; private String version; @@ -82,6 +94,7 @@ public class DefaultUpdateService implements UpdateService { updateMessage = new UpdateMessage(false, version, "", "", "https://thingsboard.io/docs/reference/releases", "https://thingsboard.io/docs/reference/releases"); + edgeUpgradeMessage = new EdgeUpgradeMessage(new HashMap<>()); if (updatesEnabled) { try { platform = System.getProperty("platform", "unknown"); @@ -141,6 +154,17 @@ public class DefaultUpdateService implements UpdateService { .updateInfo(updateMessage) .build()); } + String prevEdgeInstallVersion = edgeInstallVersion; + edgeInstallVersion = restClient.postForObject(UPDATE_SERVER_BASE_URL + "/api/v1/edge/install", new HttpEntity<>(request.toString(), headers), String.class); + if (edgeInstallVersion != null && !edgeInstallVersion.equals(prevEdgeInstallVersion)) { + edgeInstallInstructionsService.updateApplicationVersion(edgeInstallVersion); + edgeUpgradeInstructionsService.updateApplicationVersion(edgeInstallVersion); + } + EdgeUpgradeMessage prevEdgeUpgradeMessage = edgeUpgradeMessage; + edgeUpgradeMessage = restClient.postForObject(UPDATE_SERVER_BASE_URL + "/api/v1/edge/upgrades", new HttpEntity<>(request.toString(), headers), EdgeUpgradeMessage.class); + if (edgeUpgradeMessage != null && !edgeUpgradeMessage.equals(prevEdgeUpgradeMessage)) { + edgeUpgradeInstructionsService.updateInstructionMap(edgeUpgradeMessage.getEdgeVersions()); + } } catch (Exception e) { log.trace(e.getMessage()); } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/MqttV5ClientSparkplugBAttributesInProfileTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/MqttV5ClientSparkplugBAttributesInProfileTest.java index 1d5a2c127f..faa29ad35d 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/MqttV5ClientSparkplugBAttributesInProfileTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/MqttV5ClientSparkplugBAttributesInProfileTest.java @@ -52,4 +52,4 @@ public class MqttV5ClientSparkplugBAttributesInProfileTest extends AbstractMqttV processClientDeviceWithCorrectAccessTokenPublish_AttributesInProfileContainsKeyAttributes(); } -} \ No newline at end of file +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/MqttV5ClientSparkplugBAttributesTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/MqttV5ClientSparkplugBAttributesTest.java index f5d42046b7..abe1810887 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/MqttV5ClientSparkplugBAttributesTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/MqttV5ClientSparkplugBAttributesTest.java @@ -78,4 +78,4 @@ public class MqttV5ClientSparkplugBAttributesTest extends AbstractMqttV5ClientSp processClientDeviceWithCorrectAccessTokenPublishWithBirth_SharedAttributes_LongType_IfMetricFailedTypeCheck_SendValueOk(); } -} \ No newline at end of file +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EdgeUpgradeMessage.java b/common/data/src/main/java/org/thingsboard/server/common/data/EdgeUpgradeMessage.java new file mode 100644 index 0000000000..67cbce56cb --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EdgeUpgradeMessage.java @@ -0,0 +1,33 @@ +/** + * Copyright © 2016-2023 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.common.data; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Map; + +@Data +@ApiModel +public class EdgeUpgradeMessage implements Serializable { + + private static final long serialVersionUID = 2872965507642822989L; + + @ApiModelProperty(position = 1, value = "Mapping for upgrade versions and upgrade strategy (next ver).") + private final Map edgeVersions; +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/UpgradeInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/UpgradeInfo.java new file mode 100644 index 0000000000..d9101bd971 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/UpgradeInfo.java @@ -0,0 +1,11 @@ +package org.thingsboard.server.common.data; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class UpgradeInfo { + private boolean requiresUpdateDb; + private String nextEdgeVersion; +}