diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/StoreInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/StoreInfo.java index 9903302592..7ccea234f9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/StoreInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/StoreInfo.java @@ -15,12 +15,16 @@ */ package org.thingsboard.server.common.data.mobile.app; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.validation.NoXss; @Data @Builder +@NoArgsConstructor +@AllArgsConstructor public class StoreInfo { @NoXss diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/util/LwM2MClientSerDes.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/util/LwM2MClientSerDes.java index 6eb54e5447..6b2bff2467 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/util/LwM2MClientSerDes.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/util/LwM2MClientSerDes.java @@ -17,7 +17,6 @@ package org.thingsboard.server.transport.lwm2m.server.store.util; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; @@ -57,7 +56,7 @@ public class LwM2MClientSerDes { @SneakyThrows public static byte[] serialize(LwM2mClient client) { - JsonObject o = new JsonObject(); + JsonObject o = new JsonObject(); o.addProperty("nodeId", client.getNodeId()); o.addProperty("endpoint", client.getEndpoint()); @@ -111,14 +110,7 @@ public class LwM2MClientSerDes { o.addProperty("defaultObjectIDVer", client.getDefaultObjectIDVer().toString()); if (client.getRegistration() != null) { - String registrationAddress = client.getRegistration().getAddress().toString(); JsonNode registrationNode = registrationSerDes.jSerialize(client.getRegistration()); - if (!registrationAddress.equals(registrationNode.get("transportdata").get("address").asText())){ - ObjectNode actualRegAddress = (ObjectNode)registrationNode.get("transportdata"); - actualRegAddress.put("address", registrationAddress); - ObjectNode actualIdentity = (ObjectNode) actualRegAddress.get("identity"); - actualIdentity.put("address", registrationAddress); - } o.addProperty("registration", registrationNode.toString()); } o.addProperty("asleep", client.isAsleep()); @@ -188,7 +180,7 @@ public class LwM2MClientSerDes { case STRING: return value.getAsString(); case TIME: - return Instant.ofEpochMilli(value.getAsLong()); + return new Date(value.getAsLong()); case OBJLNK: return ObjectLink.decodeFromString(value.getAsString()); case UNSIGNED_INTEGER: @@ -249,7 +241,7 @@ public class LwM2MClientSerDes { o.addProperty(VALUE, ((ObjectLink) value).encodeToString()); break; case UNSIGNED_INTEGER: - o.addProperty(VALUE, Integer.toUnsignedString((int)value)); + o.addProperty(VALUE, Integer.toUnsignedString((int) value)); break; default: throw new LwM2mNodeException(String.format("Type %s is not supported", type.name())); diff --git a/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/util/LwM2MClientSerDesTest.java b/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/util/LwM2MClientSerDesTest.java index 6b17225538..710b06a864 100644 --- a/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/util/LwM2MClientSerDesTest.java +++ b/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/util/LwM2MClientSerDesTest.java @@ -18,13 +18,17 @@ package org.thingsboard.server.transport.lwm2m.server.store.util; import org.eclipse.leshan.core.LwM2m.LwM2mVersion; import org.eclipse.leshan.core.endpoint.EndpointUriUtil; import org.eclipse.leshan.core.link.Link; +import org.eclipse.leshan.core.link.attributes.AttributeSet; +import org.eclipse.leshan.core.link.attributes.ResourceTypeAttribute; import org.eclipse.leshan.core.node.LwM2mMultipleResource; import org.eclipse.leshan.core.node.LwM2mPath; import org.eclipse.leshan.core.node.LwM2mResource; import org.eclipse.leshan.core.node.LwM2mSingleResource; import org.eclipse.leshan.core.peer.IpPeer; import org.eclipse.leshan.core.request.WriteRequest; +import org.eclipse.leshan.server.registration.DefaultRegistrationDataExtractor; import org.eclipse.leshan.server.registration.Registration; +import org.eclipse.leshan.server.registration.RegistrationDataExtractor; import org.junit.jupiter.api.Test; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.device.data.PowerMode; @@ -83,12 +87,22 @@ public class LwM2MClientSerDesTest { client.init(credentialsResponse, UUID.randomUUID()); + AttributeSet attrs = new AttributeSet( // + new ResourceTypeAttribute("oma.lwm2m")); + + Link[] objs = new Link[]{new Link("/15", attrs), new Link("/17")}; + + RegistrationDataExtractor.RegistrationData dataFromObjectLinks = new DefaultRegistrationDataExtractor().extractDataFromObjectLinks(objs, + LwM2mVersion.V1_0); + Registration registration = new Registration .Builder("test", "endpoint", new IpPeer(new InetSocketAddress(Inet4Address.getLoopbackAddress(), 1000)), - EndpointUriUtil.createUri("coap://localhost:5685")) - .supportedContentFormats() - .supportedObjects(Map.of(15, LwM2mVersion.V1_0, 17, LwM2mVersion.V1_0)) - .objectLinks(new Link[] { new Link("/15"), new Link("/17") }) + EndpointUriUtil.createUri("coap://localhost:5685")) + .objectLinks(objs) + .rootPath(dataFromObjectLinks.getAlternatePath()) + .supportedContentFormats(dataFromObjectLinks.getSupportedContentFormats()) + .supportedObjects(dataFromObjectLinks.getSupportedObjects()) + .availableInstances(dataFromObjectLinks.getAvailableInstances()) .build(); client.setRegistration(registration); @@ -135,12 +149,7 @@ public class LwM2MClientSerDesTest { assertEquals(client.getPsmActivityTimer(), desClient.getPsmActivityTimer()); assertEquals(client.getPagingTransmissionWindow(), desClient.getPagingTransmissionWindow()); assertEquals(client.getEdrxCycle(), desClient.getEdrxCycle()); - if (((IpPeer)desClient.getRegistration().getClientTransportData()).getSocketAddress().isUnresolved()) { - String actualReg = desClient.getRegistration().toString().replaceAll("/", ""); - assertEquals(client.getRegistration().toString(), actualReg); - } else { - assertEquals(client.getRegistration(), desClient.getRegistration()); - } + assertEquals(client.getRegistration(), desClient.getRegistration()); assertEquals(client.isAsleep(), desClient.isAsleep()); assertEquals(client.getLastUplinkTime(), desClient.getLastUplinkTime()); assertEquals(client.getSleepTask(), desClient.getSleepTask()); diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java index 8498b4a7e4..4841f05471 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java @@ -94,6 +94,10 @@ import java.util.function.Function; import java.util.stream.Collectors; import static org.eclipse.jgit.api.ListBranchCommand.ListMode; +import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_NODELETE; +import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD; +import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_OTHER_REASON; +import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED; @Slf4j public class GitRepository { @@ -358,8 +362,10 @@ public class GitRepository { result.forEach(pushResult -> { for (RemoteRefUpdate update : pushResult.getRemoteUpdates()) { RemoteRefUpdate.Status status = update.getStatus(); - if (status != RemoteRefUpdate.Status.OK && status != RemoteRefUpdate.Status.UP_TO_DATE) { - throw new RuntimeException("Failed to push changes: " + Optional.ofNullable(update.getMessage()).orElseGet(status::name)); + if (status == REJECTED_NONFASTFORWARD || status == REJECTED_NODELETE || + status == REJECTED_REMOTE_CHANGED || status == REJECTED_OTHER_REASON) { + throw new RuntimeException("Remote repository answered with error: " + + Optional.ofNullable(update.getMessage()).orElseGet(status::name)); } } }); diff --git a/dao/src/main/java/org/thingsboard/server/dao/mobile/QrCodeSettingServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/mobile/QrCodeSettingServiceImpl.java index ee3e59c60b..27cc3eebbf 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/mobile/QrCodeSettingServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/mobile/QrCodeSettingServiceImpl.java @@ -115,7 +115,7 @@ public class QrCodeSettingServiceImpl extends AbstractCachedEntityService { mobile.setAppSecret(appSecret); mobile.setPlatformType(platformType); mobile.setStatus(status); - mobile.setVersionInfo(fromJson(versionInfo, MobileAppVersionInfo.class)); - mobile.setStoreInfo(fromJson(storeInfo, StoreInfo.class)); + mobile.setVersionInfo(versionInfo != null ? fromJson(versionInfo, MobileAppVersionInfo.class) : MOBILE_APP_VERSION_INFO_EMPTY_OBJECT); + mobile.setStoreInfo(storeInfo != null ? fromJson(storeInfo, StoreInfo.class) : MOBILE_APP_STORE_INFO_EMPTY_OBJECT); return mobile; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/MobileAppDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/MobileAppDataValidator.java index d91ea8251d..68d9de859b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/MobileAppDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/MobileAppDataValidator.java @@ -30,21 +30,17 @@ public class MobileAppDataValidator extends DataValidator { @Override protected void validateDataImpl(TenantId tenantId, MobileApp mobileApp) { - if (mobileApp.getPlatformType() == PlatformType.ANDROID) { - if (mobileApp.getStoreInfo() != null && + if (mobileApp.getStatus() == MobileAppStatus.PUBLISHED) { + if (mobileApp.getStoreInfo() == null) { + throw new DataValidationException("Store info is required for published apps"); + } + if (mobileApp.getPlatformType() == PlatformType.ANDROID && (mobileApp.getStoreInfo().getSha256CertFingerprints() == null || mobileApp.getStoreInfo().getStoreLink() == null)) { throw new DataValidationException("Sha256CertFingerprints and store link are required"); - } - } else if (mobileApp.getPlatformType() == PlatformType.IOS) { - if (mobileApp.getStoreInfo() != null && + } else if (mobileApp.getPlatformType() == PlatformType.IOS && (mobileApp.getStoreInfo().getAppId() == null || mobileApp.getStoreInfo().getStoreLink() == null)) { throw new DataValidationException("AppId and store link are required"); } - } else { - throw new DataValidationException("Wrong application platform type"); - } - if (mobileApp.getStatus() == MobileAppStatus.PUBLISHED && mobileApp.getStoreInfo() == null) { - throw new DataValidationException("Store info is required for published apps"); } } }