Browse Source

Merge pull request #12451 from thingsboard/rc

rc
pull/12488/head
Viacheslav Klimov 2 years ago
committed by GitHub
parent
commit
ab2b1d7ff8
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/StoreInfo.java
  2. 14
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/util/LwM2MClientSerDes.java
  3. 29
      common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/util/LwM2MClientSerDesTest.java
  4. 10
      common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java
  5. 2
      dao/src/main/java/org/thingsboard/server/dao/mobile/QrCodeSettingServiceImpl.java
  6. 4
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  7. 6
      dao/src/main/java/org/thingsboard/server/dao/model/sql/MobileAppEntity.java
  8. 16
      dao/src/main/java/org/thingsboard/server/dao/service/validator/MobileAppDataValidator.java

4
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

14
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()));

29
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("/<unresolved>", "");
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());

10
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));
}
}
});

2
dao/src/main/java/org/thingsboard/server/dao/mobile/QrCodeSettingServiceImpl.java

@ -115,7 +115,7 @@ public class QrCodeSettingServiceImpl extends AbstractCachedEntityService<Tenant
qrCodeSettings.setQrCodeConfig(qrCodeConfig);
qrCodeSettings.setMobileAppBundleId(qrCodeSettings.getMobileAppBundleId());
}
if (qrCodeSettings.isUseDefaultApp()) {
if (qrCodeSettings.isUseDefaultApp() || qrCodeSettings.getMobileAppBundleId() == null) {
qrCodeSettings.setGooglePlayLink(googlePlayLink);
qrCodeSettings.setAppStoreLink(appStoreLink);
} else {

4
dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java

@ -19,6 +19,8 @@ import com.datastax.oss.driver.api.core.uuid.Uuids;
import org.apache.commons.lang3.ArrayUtils;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.Aggregation;
import org.thingsboard.server.common.data.mobile.app.MobileAppVersionInfo;
import org.thingsboard.server.common.data.mobile.app.StoreInfo;
import java.util.UUID;
@ -454,6 +456,8 @@ public class ModelConstants {
public static final String MOBILE_APP_STATUS_PROPERTY = "status";
public static final String MOBILE_APP_VERSION_INFO_PROPERTY = "version_info";
public static final String MOBILE_APP_STORE_INFO_PROPERTY = "store_info";
public static final MobileAppVersionInfo MOBILE_APP_VERSION_INFO_EMPTY_OBJECT = new MobileAppVersionInfo();
public static final StoreInfo MOBILE_APP_STORE_INFO_EMPTY_OBJECT = new StoreInfo();
/**
* Mobile application bundle constants.

6
dao/src/main/java/org/thingsboard/server/dao/model/sql/MobileAppEntity.java

@ -37,6 +37,8 @@ import org.thingsboard.server.dao.util.mapping.JsonConverter;
import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.MOBILE_APP_STORE_INFO_EMPTY_OBJECT;
import static org.thingsboard.server.dao.model.ModelConstants.MOBILE_APP_VERSION_INFO_EMPTY_OBJECT;
import static org.thingsboard.server.dao.model.ModelConstants.TENANT_ID_COLUMN;
@Data
@ -99,8 +101,8 @@ public class MobileAppEntity extends BaseSqlEntity<MobileApp> {
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;
}
}

16
dao/src/main/java/org/thingsboard/server/dao/service/validator/MobileAppDataValidator.java

@ -30,21 +30,17 @@ public class MobileAppDataValidator extends DataValidator<MobileApp> {
@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");
}
}
}

Loading…
Cancel
Save