extended mobile application settings with default store links
This commit is contained in:
		
							parent
							
								
									be5220a9e9
								
							
						
					
					
						commit
						951f017e7c
					
				@ -58,6 +58,8 @@ public class MobileApplicationController extends BaseController {
 | 
			
		||||
 | 
			
		||||
    @Value("${cache.specs.mobileSecretKey.timeToLiveInMinutes:2}")
 | 
			
		||||
    private int mobileSecretKeyTtl;
 | 
			
		||||
    @Value("${mobileApp.domain:demo.thingsboard.io}")
 | 
			
		||||
    private String defaultAppDomain;
 | 
			
		||||
 | 
			
		||||
    public static final String ASSET_LINKS_PATTERN = "[{\n" +
 | 
			
		||||
            "  \"relation\": [\"delegate_permission/common.handle_all_urls\"],\n" +
 | 
			
		||||
@ -83,7 +85,6 @@ public class MobileApplicationController extends BaseController {
 | 
			
		||||
 | 
			
		||||
    public static final String SECRET = "secret";
 | 
			
		||||
    public static final String SECRET_PARAM_DESCRIPTION = "A string value representing short-lived secret key";
 | 
			
		||||
    public static final String DEFAULT_APP_DOMAIN = "demo.thingsboard.io";
 | 
			
		||||
    public static final String DEEP_LINK_PATTERN = "https://%s/api/noauth/qr?secret=%s&ttl=%s";
 | 
			
		||||
 | 
			
		||||
    private final SystemSecurityService systemSecurityService;
 | 
			
		||||
@ -149,7 +150,7 @@ public class MobileApplicationController extends BaseController {
 | 
			
		||||
        if (!mobileAppSettings.isUseDefaultApp()) {
 | 
			
		||||
            appDomain = platformDomain;
 | 
			
		||||
        } else {
 | 
			
		||||
            appDomain = DEFAULT_APP_DOMAIN;
 | 
			
		||||
            appDomain = defaultAppDomain;
 | 
			
		||||
        }
 | 
			
		||||
        String deepLink = String.format(DEEP_LINK_PATTERN, appDomain, secret, mobileSecretKeyTtl);
 | 
			
		||||
        if (!appDomain.equals(platformDomain)) {
 | 
			
		||||
@ -170,13 +171,16 @@ public class MobileApplicationController extends BaseController {
 | 
			
		||||
    @GetMapping(value = "/api/noauth/qr")
 | 
			
		||||
    public ResponseEntity<?> getApplicationRedirect(@RequestHeader(value = "User-Agent") String userAgent) {
 | 
			
		||||
        MobileAppSettings mobileAppSettings = mobileAppSettingsService.getMobileAppSettings(TenantId.SYS_TENANT_ID);
 | 
			
		||||
        boolean useDefaultApp = mobileAppSettings.isUseDefaultApp();
 | 
			
		||||
        String googlePlayLink = useDefaultApp ? mobileAppSettings.getDefaultGooglePlayLink() : mobileAppSettings.getAndroidConfig().getStoreLink();
 | 
			
		||||
        String appStoreLink = useDefaultApp ? mobileAppSettings.getDefaultGooglePlayLink() : mobileAppSettings.getIosConfig().getStoreLink();
 | 
			
		||||
        if (userAgent.contains("Android")) {
 | 
			
		||||
            return ResponseEntity.status(HttpStatus.FOUND)
 | 
			
		||||
                    .header("Location", mobileAppSettings.getAndroidConfig().getStoreLink())
 | 
			
		||||
                    .header("Location", googlePlayLink)
 | 
			
		||||
                    .build();
 | 
			
		||||
        } else if (userAgent.contains("iPhone") || userAgent.contains("iPad")) {
 | 
			
		||||
            return ResponseEntity.status(HttpStatus.FOUND)
 | 
			
		||||
                    .header("Location", mobileAppSettings.getIosConfig().getStoreLink())
 | 
			
		||||
                    .header("Location", appStoreLink)
 | 
			
		||||
                    .build();
 | 
			
		||||
        } else {
 | 
			
		||||
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
 | 
			
		||||
 | 
			
		||||
@ -1463,9 +1463,9 @@ queue:
 | 
			
		||||
        - key: max.poll.interval.ms
 | 
			
		||||
          # Example of specific consumer properties value per topic for VC
 | 
			
		||||
          value: "${TB_QUEUE_KAFKA_VC_MAX_POLL_INTERVAL_MS:600000}"
 | 
			
		||||
    #      tb_rule_engine.sq:
 | 
			
		||||
    #        - key: max.poll.records
 | 
			
		||||
    #          value: "${TB_QUEUE_KAFKA_SQ_MAX_POLL_RECORDS:1024}"
 | 
			
		||||
      #      tb_rule_engine.sq:
 | 
			
		||||
      #        - key: max.poll.records
 | 
			
		||||
      #          value: "${TB_QUEUE_KAFKA_SQ_MAX_POLL_RECORDS:1024}"
 | 
			
		||||
      tb_housekeeper:
 | 
			
		||||
        # Consumer properties for Housekeeper tasks topic
 | 
			
		||||
        - key: max.poll.records
 | 
			
		||||
@ -1794,3 +1794,12 @@ management:
 | 
			
		||||
    elasticsearch:
 | 
			
		||||
      # Enable the org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator.doHealthCheck
 | 
			
		||||
      enabled: "false"
 | 
			
		||||
 | 
			
		||||
# Mobile application settings for Thingsboard mobile application
 | 
			
		||||
mobileApp:
 | 
			
		||||
  # Host for default Thingsboard mobile application for common edition
 | 
			
		||||
  domain: "${TB_MOBILE_APP_DOMAIN:demo.thingsboard.io}"
 | 
			
		||||
  # Link to Google Play store for default Thingsboard mobile application
 | 
			
		||||
  googlePlayLink: "${TB_MOBILE_APP_GOOGLE_PLAY_LINK:https://play.google.com/store/apps/details?id=org.thingsboard.demo.app}"
 | 
			
		||||
  # Link to App Store for default Thingsboard mobile application
 | 
			
		||||
  appStoreLink: "${TB_MOBILE_APP_APP_STORE_LINK:https://apps.apple.com/us/app/thingsboard-live/id1594355695}"
 | 
			
		||||
 | 
			
		||||
@ -15,29 +15,46 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.common.data.mobile;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonProperty;
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import jakarta.validation.Valid;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
import org.thingsboard.server.common.data.BaseData;
 | 
			
		||||
import org.thingsboard.server.common.data.HasTenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.MobileAppSettingsId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
 | 
			
		||||
@Schema
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
public class MobileAppSettings extends BaseData<MobileAppSettingsId> implements HasTenantId {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 2628323657987010348L;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY)
 | 
			
		||||
    private TenantId tenantId;
 | 
			
		||||
    @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "Type of application: true means use default Thingsboard app", example = "true")
 | 
			
		||||
    private boolean useDefaultApp;
 | 
			
		||||
    @Valid
 | 
			
		||||
    @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "Android mobile app configuration.")
 | 
			
		||||
    private AndroidConfig androidConfig;
 | 
			
		||||
    @Valid
 | 
			
		||||
    @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "Ios mobile app configuration.")
 | 
			
		||||
    private IosConfig iosConfig;
 | 
			
		||||
    @Valid
 | 
			
		||||
    @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "QR code config configuration.")
 | 
			
		||||
    private QRCodeConfig qrCodeConfig;
 | 
			
		||||
 | 
			
		||||
    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
 | 
			
		||||
    private String defaultGooglePlayLink;
 | 
			
		||||
 | 
			
		||||
    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
 | 
			
		||||
    private String defaultAppStoreLink;
 | 
			
		||||
 | 
			
		||||
    public MobileAppSettings() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MobileAppSettings(MobileAppSettingsId id) {
 | 
			
		||||
        super(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,9 @@ package org.thingsboard.server.dao.mobile;
 | 
			
		||||
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Value;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.event.TransactionalEventListener;
 | 
			
		||||
import org.thingsboard.server.common.data.StringUtils;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.mobile.AndroidConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.mobile.BadgePosition;
 | 
			
		||||
@ -40,8 +40,11 @@ public class BaseMobileAppSettingsService extends AbstractCachedEntityService<Te
 | 
			
		||||
 | 
			
		||||
    public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
 | 
			
		||||
    private static final String DEFAULT_QR_CODE_LABEL = "Scan to connect or download mobile app";
 | 
			
		||||
    public static final String DEFAULT_GOOGLE_APP_STORE_LINK = "https://play.google.com/store/apps/details?id=org.thingsboard.demo.app";
 | 
			
		||||
    public static final String DEFAULT_APPLE_APP_STORE_LINK = "https://apps.apple.com/us/app/thingsboard-live/id1594355695";
 | 
			
		||||
 | 
			
		||||
    @Value("${mobileApp.googlePlayLink:https://play.google.com/store/apps/details?id=org.thingsboard.demo.app}")
 | 
			
		||||
    private String googlePlayLink;
 | 
			
		||||
    @Value("${mobileApp.appStoreLink:https://play.google.com/store/apps/details?id=org.thingsboard.demo.app}")
 | 
			
		||||
    private String appStoreLink;
 | 
			
		||||
 | 
			
		||||
    private final MobileAppSettingsDao mobileAppSettingsDao;
 | 
			
		||||
    private final DataValidator<MobileAppSettings> mobileAppSettingsDataValidator;
 | 
			
		||||
@ -52,7 +55,7 @@ public class BaseMobileAppSettingsService extends AbstractCachedEntityService<Te
 | 
			
		||||
        try {
 | 
			
		||||
            MobileAppSettings savedMobileAppSettings = mobileAppSettingsDao.save(tenantId, mobileAppSettings);
 | 
			
		||||
            publishEvictEvent(new MobileAppSettingsEvictEvent(tenantId));
 | 
			
		||||
            return savedMobileAppSettings;
 | 
			
		||||
            return constructMobileAppSettings(savedMobileAppSettings);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            handleEvictEvent(new MobileAppSettingsEvictEvent(tenantId));
 | 
			
		||||
            checkConstraintViolation(e, Map.of(
 | 
			
		||||
@ -90,11 +93,9 @@ public class BaseMobileAppSettingsService extends AbstractCachedEntityService<Te
 | 
			
		||||
 | 
			
		||||
            AndroidConfig androidConfig = AndroidConfig.builder()
 | 
			
		||||
                    .enabled(true)
 | 
			
		||||
                    .storeLink(DEFAULT_GOOGLE_APP_STORE_LINK)
 | 
			
		||||
                    .build();
 | 
			
		||||
            IosConfig iosConfig = IosConfig.builder()
 | 
			
		||||
                    .enabled(true)
 | 
			
		||||
                    .storeLink(DEFAULT_APPLE_APP_STORE_LINK)
 | 
			
		||||
                    .build();
 | 
			
		||||
            QRCodeConfig qrCodeConfig = QRCodeConfig.builder()
 | 
			
		||||
                    .showOnHomePage(true)
 | 
			
		||||
@ -108,13 +109,10 @@ public class BaseMobileAppSettingsService extends AbstractCachedEntityService<Te
 | 
			
		||||
            mobileAppSettings.setQrCodeConfig(qrCodeConfig);
 | 
			
		||||
            mobileAppSettings.setAndroidConfig(androidConfig);
 | 
			
		||||
            mobileAppSettings.setIosConfig(iosConfig);
 | 
			
		||||
        } else {
 | 
			
		||||
            if (StringUtils.isEmpty(mobileAppSettings.getAndroidConfig().getStoreLink())) {
 | 
			
		||||
                mobileAppSettings.getAndroidConfig().setStoreLink(DEFAULT_GOOGLE_APP_STORE_LINK);
 | 
			
		||||
            }
 | 
			
		||||
            if (StringUtils.isEmpty(mobileAppSettings.getIosConfig().getStoreLink())) {
 | 
			
		||||
                mobileAppSettings.getIosConfig().setStoreLink(DEFAULT_APPLE_APP_STORE_LINK);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (mobileAppSettings.isUseDefaultApp()) {
 | 
			
		||||
            mobileAppSettings.setDefaultGooglePlayLink(googlePlayLink);
 | 
			
		||||
            mobileAppSettings.setDefaultAppStoreLink(appStoreLink);
 | 
			
		||||
        }
 | 
			
		||||
        return mobileAppSettings;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user