committed by
GitHub
7 changed files with 173 additions and 31 deletions
@ -0,0 +1,56 @@ |
|||
/** |
|||
* Copyright © 2016-2026 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.edge.instructions; |
|||
|
|||
import org.thingsboard.common.util.TbVersionUtils; |
|||
import org.thingsboard.server.common.data.EdgeUpgradeInfo; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
public final class EdgeVersionGraphResolver { |
|||
|
|||
private EdgeVersionGraphResolver() { |
|||
} |
|||
|
|||
/** |
|||
* Collapses a branching upgrade version graph into a single upgrade option per source version. |
|||
* For each version the option with the highest {@code nextEdgeVersion} that is lower than or equal to the |
|||
* given platform version is kept; if every option points to a newer version the source version becomes |
|||
* terminal ({@code nextEdgeVersion == null}). |
|||
*/ |
|||
public static Map<String, EdgeUpgradeInfo> resolve(Map<String, List<EdgeUpgradeInfo>> versionGraph, String platformVersion) { |
|||
String platform = TbVersionUtils.extractStartingDigits(platformVersion); |
|||
Map<String, EdgeUpgradeInfo> resolved = new HashMap<>(); |
|||
for (var entry : versionGraph.entrySet()) { |
|||
EdgeUpgradeInfo best = null; |
|||
for (EdgeUpgradeInfo option : entry.getValue()) { |
|||
String next = option.getNextEdgeVersion(); |
|||
// eligible only if next is present and lower than or equal to the platform version
|
|||
if (next == null || TbVersionUtils.compare(next, platform) > 0) { |
|||
continue; |
|||
} |
|||
// keep the option with the highest eligible nextEdgeVersion
|
|||
if (best == null || TbVersionUtils.compare(next, best.getNextEdgeVersion()) >= 0) { |
|||
best = option; |
|||
} |
|||
} |
|||
resolved.put(entry.getKey(), best != null ? best : new EdgeUpgradeInfo(false, null)); |
|||
} |
|||
return resolved; |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
/** |
|||
* Copyright © 2016-2026 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.v3.oas.annotations.media.Schema; |
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
@Data |
|||
@Schema |
|||
public class EdgeUpgradeMessageV2 implements Serializable { |
|||
|
|||
private static final long serialVersionUID = -6647214126993298281L; |
|||
|
|||
@Schema(description = "Mapping of edge version to the list of available upgrade options (next ver + strategy).") |
|||
private final Map<String, List<EdgeUpgradeInfo>> edgeVersions; |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
/** |
|||
* Copyright © 2016-2026 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.common.util; |
|||
|
|||
public class TbVersionUtils { |
|||
|
|||
private TbVersionUtils() { |
|||
} |
|||
|
|||
/** |
|||
* Compares two dot-separated numeric version strings component-wise, treating missing trailing components as |
|||
* zero (so {@code "3.6"} equals {@code "3.6.0"}). A {@code null} or empty string is treated as the lowest version. |
|||
* |
|||
* @return a negative int, zero, or a positive int as {@code v1} is less than, equal to, or greater than {@code v2} |
|||
*/ |
|||
public static int compare(String v1, String v2) { |
|||
String[] parts1 = split(v1); |
|||
String[] parts2 = split(v2); |
|||
int length = Math.max(parts1.length, parts2.length); |
|||
for (int i = 0; i < length; i++) { |
|||
int num1 = i < parts1.length ? Integer.parseInt(parts1[i]) : 0; |
|||
int num2 = i < parts2.length ? Integer.parseInt(parts2[i]) : 0; |
|||
if (num1 != num2) { |
|||
return Integer.compare(num1, num2); |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
/** |
|||
* Strips any suffix that follows the leading dotted-numeric part of a version string |
|||
* (e.g. {@code "4.3.1.1PE-SNAPSHOT"} -> {@code "4.3.1.1"}). Returns an empty string for a {@code null} input. |
|||
*/ |
|||
public static String extractStartingDigits(String version) { |
|||
return version == null ? "" : version.replaceAll("[^0-9.].*$", ""); |
|||
} |
|||
|
|||
private static String[] split(String version) { |
|||
return version == null || version.isEmpty() ? new String[0] : version.split("\\."); |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue