一、现象
管理员登录系统时,提示【New ThingsBoard version xx is availabled】有新的版本可用。这个信息时怎么产生的,如何才能不显示呢?
二、调查源码
1、前台调查
- 登录时,发现请求了后台的API(pi/admin/updates),返回信息中包含了提示的内容。
- 请求代码为:ui-ngx\src\app\core\auth\auth.service.ts的254行左右
} else if (authState.authUser.authority === Authority.SYS_ADMIN) {
this.adminService.checkUpdates().subscribe((updateMessage) => {
if (updateMessage && updateMessage.updateAvailable) {
this.store.dispatch(new ActionNotificationShow(
{message: updateMessage.message,
type: 'info',
verticalPosition: 'bottom',
horizontalPosition: 'right'}));
}
});
}
- adminService为ui-ngx\src\app\core\http\admin.service.ts。检查更新代码如下:
public checkUpdates(config?: RequestConfig): Observable<UpdateMessage> {
return this.http.get<UpdateMessage>(`/api/admin/updates`, defaultHttpOptionsFromConfig(config));
}
2、后台API
- 后台接口为application\src\main\java\org\thingsboard\server\controller\AdminController.java。 实现的接口代码如下:
@PreAuthorize("hasAuthority('SYS_ADMIN')")
@RequestMapping(value = "/updates", method = RequestMethod.GET)
@ResponseBody
public UpdateMessage checkUpdates() throws ThingsboardException {
try {
return updateService.checkUpdates();
} catch (Exception e) {
throw handleException(e);
}
}
- service为application\src\main\java\org\thingsboard\server\service\update\DefaultUpdateService.java。代码关键实现如下:
@Service
@TbCoreComponent
@Slf4j
public class DefaultUpdateService implements UpdateService {
private static final String UPDATE_SERVER_BASE_URL = "https://updates.thingsboard.io";
@Value("${updates.enabled}")
private boolean updatesEnabled;
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, ThingsBoardThreadFactory.forName("tb-update-service"));
private ScheduledFuture checkUpdatesFuture = null;
private RestTemplate restClient = new RestTemplate();
@PostConstruct
private void init() {
updateMessage = new UpdateMessage("", false);
if (updatesEnabled) {
try {
platform = System.getProperty("platform", "unknown");
version = getClass().getPackage().getImplementationVersion();
if (version == null) {
version = "unknown";
}
instanceId = parseInstanceId();
checkUpdatesFuture = scheduler.scheduleAtFixedRate(checkUpdatesRunnable, 0, 1, TimeUnit.HOURS);
} catch (Exception e) {
//Do nothing
}
}
}
Runnable checkUpdatesRunnable = () -> {
try {
log.trace("Executing check update method for instanceId [{}], platform [{}] and version [{}]", instanceId, platform, version);
ObjectNode request = new ObjectMapper().createObjectNode();
request.put(PLATFORM_PARAM, platform);
request.put(VERSION_PARAM, version);
request.put(INSTANCE_ID_PARAM, instanceId.toString());
JsonNode response = restClient.postForObject(UPDATE_SERVER_BASE_URL+"/api/thingsboard/updates", request, JsonNode.class);
updateMessage = new UpdateMessage(
response.get("message").asText(),
response.get("updateAvailable").asBoolean()
);
} catch (Exception e) {
log.trace(e.getMessage());
}
};
@Override
public UpdateMessage checkUpdates() {
return updateMessage;
}
}
项目启动时启动了一个定时器,每隔一个小时,调用updates.thingsboard.io的api一次,并把返回信息存储到内存中。定时器是否启动,有一个标志为updatesEnabled,如果updatesEnabled为false,就不会启动更新检查。
- thingsboard.yml
updates.enabled的值是配置在thingsboard.yml文件中的。
配置后台是否定时检查有新的版本,默认为true。
# Check new version updates parameters
updates:
# Enable/disable updates checking.
enabled: "${UPDATES_ENABLED:true}"
三、解决对策
-
修改代码,不再进行版本检查,需要重新编译。
-
修改配置文件,可能需要重新编译。
-
设置环境变量:UPDATES_ENABLED,需要重启服务。
-
修改域名解析地址。比如本地hosts文件,最好重启服务。