|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
@ -0,0 +1,66 @@ |
|||
/** |
|||
* Copyright © 2016-2024 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.update; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.stereotype.Service; |
|||
import org.thingsboard.rule.engine.api.NotificationCenter; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.notification.info.GeneralNotificationInfo; |
|||
import org.thingsboard.server.common.data.notification.targets.platform.SystemAdministratorsFilter; |
|||
import org.thingsboard.server.dao.notification.DefaultNotifications; |
|||
import org.thingsboard.server.queue.util.AfterStartUp; |
|||
|
|||
import java.util.Map; |
|||
|
|||
@Service |
|||
@Slf4j |
|||
@RequiredArgsConstructor |
|||
public class DeprecationService { |
|||
|
|||
private final NotificationCenter notificationCenter; |
|||
|
|||
@Value("${queue.type}") |
|||
private String queueType; |
|||
|
|||
@AfterStartUp(order = Integer.MAX_VALUE) |
|||
public void checkDeprecation() { |
|||
checkQueueTypeDeprecation(); |
|||
} |
|||
|
|||
private void checkQueueTypeDeprecation() { |
|||
String queueTypeName; |
|||
switch (queueType) { |
|||
case "aws-sqs" -> queueTypeName = "AWS SQS"; |
|||
case "pubsub" -> queueTypeName = "PubSub"; |
|||
case "service-bus" -> queueTypeName = "Azure Service Bus"; |
|||
case "rabbitmq" -> queueTypeName = "RabbitMQ"; |
|||
default -> { |
|||
return; |
|||
} |
|||
} |
|||
|
|||
log.warn("WARNING: Starting with ThingsBoard 4.0, {} will no longer be supported as a message queue for microservices. " + |
|||
"Please migrate to Apache Kafka. This change will not impact any rule nodes", queueTypeName); |
|||
notificationCenter.sendGeneralWebNotification(TenantId.SYS_TENANT_ID, new SystemAdministratorsFilter(), |
|||
DefaultNotifications.queueTypeDeprecation.toTemplate(), new GeneralNotificationInfo(Map.of( |
|||
"queueType", queueTypeName |
|||
))); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
/** |
|||
* Copyright © 2016-2024 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.script; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.script.api.ScriptType; |
|||
import org.thingsboard.script.api.tbel.TbelInvokeService; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.controller.AbstractControllerTest; |
|||
|
|||
import java.util.Map; |
|||
import java.util.UUID; |
|||
import java.util.concurrent.ExecutionException; |
|||
|
|||
import static org.thingsboard.server.common.data.msg.TbMsgType.POST_TELEMETRY_REQUEST; |
|||
|
|||
public abstract class AbstractTbelInvokeTest extends AbstractControllerTest { |
|||
|
|||
@Autowired |
|||
protected TbelInvokeService invokeService; |
|||
|
|||
protected UUID evalScript(String script) throws ExecutionException, InterruptedException { |
|||
return invokeService.eval(TenantId.SYS_TENANT_ID, ScriptType.RULE_NODE_SCRIPT, script, "msg", "metadata", "msgType").get(); |
|||
} |
|||
|
|||
protected String invokeScriptResultString(UUID scriptId, String str) throws ExecutionException, InterruptedException { |
|||
var msg = JacksonUtil.fromString(str, Map.class); |
|||
return invokeScript(scriptId, str).toString(); |
|||
} |
|||
protected Object invokeScript(UUID scriptId, String str) throws ExecutionException, InterruptedException { |
|||
var msg = JacksonUtil.fromString(str, Map.class); |
|||
return invokeService.invokeScript(TenantId.SYS_TENANT_ID, null, scriptId, msg, "{}", POST_TELEMETRY_REQUEST.name()).get(); |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
/** |
|||
* Copyright © 2016-2024 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.notification.info; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.util.Map; |
|||
|
|||
@Data |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
public class GeneralNotificationInfo implements RuleOriginatedNotificationInfo { |
|||
|
|||
private Map<String, String> data; |
|||
|
|||
@Override |
|||
public Map<String, String> getTemplateData() { |
|||
return data; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,104 @@ |
|||
///
|
|||
/// Copyright © 2016-2024 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.
|
|||
///
|
|||
|
|||
import type { Plugin, PluginBuild, OutputFile } from 'esbuild'; |
|||
import dirTree from 'directory-tree'; |
|||
import * as packageJson from '../package.json'; |
|||
import { gzip } from 'node:zlib'; |
|||
import * as path from 'node:path'; |
|||
|
|||
const defineTbVariablesPlugin: Plugin = { |
|||
name: 'tb-define-variables', |
|||
setup(build: PluginBuild) { |
|||
const options = build.initialOptions; |
|||
|
|||
const langs: string[] = []; |
|||
|
|||
dirTree("./src/assets/locale/", {extensions: /\.json$/}, (item) => { |
|||
/* It is expected what the name of a locale file has the following format: */ |
|||
/* 'locale.constant-LANG_CODE[_REGION_CODE].json', e.g. locale.constant-es.json or locale.constant-zh_CN.json*/ |
|||
langs.push(item.name.slice(item.name.lastIndexOf("-") + 1, -5)); |
|||
}); |
|||
options.define.TB_VERSION = JSON.stringify(packageJson.version); |
|||
options.define.SUPPORTED_LANGS = JSON.stringify(langs); |
|||
options.define.ngJitMode = 'true'; |
|||
}, |
|||
}; |
|||
|
|||
const resolveJQueryPlugin: Plugin = { |
|||
name: 'tb-resolve-jquery-plugin', |
|||
setup(build: PluginBuild) { |
|||
if (isProduction()) { |
|||
const jQueryPath = require.resolve('jquery'); |
|||
build.onResolve({filter: /^(jquery|\$)$/}, () => { |
|||
return {path: jQueryPath}; |
|||
}) |
|||
} |
|||
} |
|||
}; |
|||
|
|||
const compressFileTypes = ['.js', '.css', '.html', '.svg', '.png', '.jpg', '.ttf', '.gif', '.woff', '.woff2', '.eot', '.json']; |
|||
const compressThreshold = 10240; |
|||
|
|||
const compressorPlugin: Plugin = { |
|||
name: 'tb-compressor-plugin', |
|||
setup(build) { |
|||
build.onEnd(async result => { |
|||
if (!result.outputFiles || !isProduction()) return; |
|||
const outputExt = '.gz'; |
|||
const gzippedFiles: OutputFile[] = []; |
|||
for (const file of result.outputFiles) { |
|||
if (!compressFileTypes.some((ext) => ext === path.extname(file.path))) continue; |
|||
if (file.contents.byteLength <= compressThreshold) continue; |
|||
const compressedContent = await gzipContent(file.contents); |
|||
const compressedFilePath = `${file.path}${outputExt}`; |
|||
gzippedFiles.push( |
|||
{ |
|||
path: compressedFilePath, |
|||
hash: file.hash, |
|||
contents: new Uint8Array(compressedContent), |
|||
text: '', |
|||
} |
|||
); |
|||
} |
|||
result.outputFiles.push(...gzippedFiles); |
|||
}); |
|||
}, |
|||
}; |
|||
|
|||
async function gzipContent(content): Promise<Buffer> { |
|||
return new Promise((resolve, reject) => { |
|||
gzip(content, (error, result) => { |
|||
if (error) { |
|||
reject(error); |
|||
} else { |
|||
resolve(result); |
|||
} |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
function isProduction(): boolean { |
|||
const configurationIndex = process.argv.indexOf('--configuration'); |
|||
let production = false; |
|||
if (configurationIndex > -1) { |
|||
const configurationValue = process.argv[configurationIndex + 1]; |
|||
production = configurationValue === 'production'; |
|||
} |
|||
return production; |
|||
} |
|||
|
|||
export default [defineTbVariablesPlugin, resolveJQueryPlugin, compressorPlugin]; |
|||
@ -1,100 +0,0 @@ |
|||
/* |
|||
* Copyright © 2016-2024 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. |
|||
*/ |
|||
const CompressionPlugin = require("compression-webpack-plugin"); |
|||
const JavaScriptOptimizerPlugin = require("@angular-devkit/build-angular/src/tools/webpack/plugins/javascript-optimizer-plugin").JavaScriptOptimizerPlugin; |
|||
const webpack = require("webpack"); |
|||
const dirTree = require("directory-tree"); |
|||
const ngWebpack = require('@ngtools/webpack'); |
|||
const keysTransformer = require('ts-transformer-keys/transformer').default; |
|||
|
|||
var langs = []; |
|||
|
|||
dirTree("./src/assets/locale/", {extensions: /\.json$/}, (item) => { |
|||
/* It is expected what the name of a locale file has the following format: */ |
|||
/* 'locale.constant-LANG_CODE[_REGION_CODE].json', e.g. locale.constant-es.json or locale.constant-zh_CN.json*/ |
|||
langs.push(item.name.slice(item.name.lastIndexOf("-") + 1, -5)); |
|||
}); |
|||
|
|||
module.exports = (config, options) => { |
|||
|
|||
config.ignoreWarnings.push(/Usage of '~' in imports is deprecated/); |
|||
config.ignoreWarnings.push(/Did you mean "left" instead?/); |
|||
config.ignoreWarnings.push(/autoprefixer/); |
|||
|
|||
config.plugins.push( |
|||
new webpack.DefinePlugin({ |
|||
TB_VERSION: JSON.stringify(require("./package.json").version), |
|||
SUPPORTED_LANGS: JSON.stringify(langs), |
|||
}) |
|||
); |
|||
config.plugins.push( |
|||
new webpack.ProvidePlugin( |
|||
{ |
|||
$: "jquery" |
|||
} |
|||
) |
|||
); |
|||
config.plugins.push( |
|||
new CompressionPlugin({ |
|||
filename: "[path][base].gz[query]", |
|||
algorithm: "gzip", |
|||
test: /\.js$|\.css$|\.html$|\.svg?.+$|\.jpg$|\.ttf?.+$|\.woff?.+$|\.eot?.+$|\.json$/, |
|||
threshold: 10240, |
|||
minRatio: 0.8, |
|||
deleteOriginalAssets: false, |
|||
}) |
|||
); |
|||
config.plugins.push( |
|||
new webpack.IgnorePlugin({ |
|||
resourceRegExp: /^\.\/locale$/, |
|||
contextRegExp: /moment$/, |
|||
}) |
|||
); |
|||
|
|||
config.module.rules[2].use[0].options.aot = false; |
|||
const index = config.plugins.findIndex(p => p instanceof ngWebpack.AngularWebpackPlugin); |
|||
let angularWebpackPlugin = config.plugins[index]; |
|||
if (config.mode === 'production') { |
|||
const angularCompilerOptions = angularWebpackPlugin.pluginOptions; |
|||
angularCompilerOptions.emitClassMetadata = true; |
|||
angularCompilerOptions.emitNgModuleScope = true; |
|||
config.plugins.splice(index, 1); |
|||
angularWebpackPlugin = new ngWebpack.AngularWebpackPlugin(angularCompilerOptions); |
|||
config.plugins.push(angularWebpackPlugin); |
|||
const javascriptOptimizerOptions = config.optimization.minimizer[0].options; |
|||
delete javascriptOptimizerOptions.define.ngJitMode; |
|||
config.optimization.minimizer.splice(0, 1); |
|||
config.optimization.minimizer.unshift(new JavaScriptOptimizerPlugin(javascriptOptimizerOptions)); |
|||
} |
|||
|
|||
addTransformerToAngularWebpackPlugin(angularWebpackPlugin, keysTransformer); |
|||
|
|||
return config; |
|||
}; |
|||
|
|||
function addTransformerToAngularWebpackPlugin(plugin, transformer) { |
|||
const originalCreateFileEmitter = plugin.createFileEmitter; // private method
|
|||
plugin.createFileEmitter = function (program, transformers, getExtraDependencies, onAfterEmit) { |
|||
if (!transformers) { |
|||
transformers = {}; |
|||
} |
|||
if (!transformers.before) { |
|||
transformers = { before: [] }; |
|||
} |
|||
transformers.before.push(transformer(program.getProgram())); |
|||
return originalCreateFileEmitter.apply(plugin, [program, transformers, getExtraDependencies, onAfterEmit]); |
|||
}; |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
diff --git a/node_modules/@angular/build/src/tools/angular/compilation/angular-compilation.js b/node_modules/@angular/build/src/tools/angular/compilation/angular-compilation.js
|
|||
index 625c621..4fc8bd8 100755
|
|||
--- a/node_modules/@angular/build/src/tools/angular/compilation/angular-compilation.js
|
|||
+++ b/node_modules/@angular/build/src/tools/angular/compilation/angular-compilation.js
|
|||
@@ -68,8 +68,6 @@ class AngularCompilation {
|
|||
allowEmptyCodegenFiles: false, |
|||
annotationsAs: 'decorators', |
|||
enableResourceInlining: false, |
|||
- supportTestBed: false,
|
|||
- supportJitMode: false,
|
|||
})); |
|||
} |
|||
async diagnoseFiles(modes = DiagnosticModes.All) { |
|||
diff --git a/node_modules/@angular/build/src/tools/esbuild/angular/compiler-plugin.js b/node_modules/@angular/build/src/tools/esbuild/angular/compiler-plugin.js
|
|||
index b1bb6ea..c76b4c6 100755
|
|||
--- a/node_modules/@angular/build/src/tools/esbuild/angular/compiler-plugin.js
|
|||
+++ b/node_modules/@angular/build/src/tools/esbuild/angular/compiler-plugin.js
|
|||
@@ -79,7 +79,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|||
sourcemap: !!pluginOptions.sourcemap, |
|||
thirdPartySourcemaps: pluginOptions.thirdPartySourcemaps, |
|||
advancedOptimizations: pluginOptions.advancedOptimizations, |
|||
- jit: pluginOptions.jit,
|
|||
+ jit: true, // pluginOptions.jit,
|
|||
}, environment_options_1.maxWorkers, cacheStore?.createCache('jstransformer')); |
|||
// Setup defines based on the values used by the Angular compiler-cli |
|||
build.initialOptions.define ??= {}; |
|||
@@ -377,12 +377,14 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|||
async function hasSideEffects(path) { |
|||
if (!pluginOptions.advancedOptimizations) { |
|||
return undefined; |
|||
+ } else {
|
|||
+ return true;
|
|||
} |
|||
- const { sideEffects } = await build.resolve(path, {
|
|||
+ /*const { sideEffects } = await build.resolve(path, {
|
|||
kind: 'import-statement', |
|||
resolveDir: build.initialOptions.absWorkingDir ?? '', |
|||
}); |
|||
- return sideEffects;
|
|||
+ return sideEffects;*/
|
|||
} |
|||
}, |
|||
}; |
|||
@ -1,8 +1,8 @@ |
|||
diff --git a/node_modules/@angular/core/fesm2022/core.mjs b/node_modules/@angular/core/fesm2022/core.mjs
|
|||
index 0fa881f..b844dfa 100755
|
|||
index 6fe7ad6..291e4ed 100755
|
|||
--- a/node_modules/@angular/core/fesm2022/core.mjs
|
|||
+++ b/node_modules/@angular/core/fesm2022/core.mjs
|
|||
@@ -12868,13 +12868,13 @@ function findDirectiveDefMatches(tView, tNode) {
|
|||
@@ -12859,13 +12859,13 @@ function findDirectiveDefMatches(tView, tNode) {
|
|||
if (isNodeMatchingSelectorList(tNode, def.selectors, /* isProjectionMode */ false)) { |
|||
matches || (matches = []); |
|||
if (isComponentDef(def)) { |
|||