first-fix
This commit is contained in:
1 parent
6d87c1edc8
commit
565d9d673a
6284 files changed
+820267
-76
No files matched your search
@@ -0,0 +1,30 @@
|
||||
*.toDelete
|
||||
output/**
|
||||
*.class
|
||||
*~
|
||||
*.iml
|
||||
*/.idea/**
|
||||
.idea/**
|
||||
.idea
|
||||
*.log
|
||||
*.log.[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
|
||||
*/.classpath
|
||||
.classpath
|
||||
*/.project
|
||||
.project
|
||||
.cache/**
|
||||
target/
|
||||
logs/
|
||||
build/
|
||||
.settings/
|
||||
/bin
|
||||
bin/
|
||||
**/dependency-reduced-pom.xml
|
||||
pom.xml.versionsBackup
|
||||
.DS_Store
|
||||
**/.gradle
|
||||
**/local.properties
|
||||
**/build
|
||||
**/target
|
||||
**/.env
|
||||
node_modules
|
||||
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# Copyright © 2016-2023 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.
|
||||
#
|
||||
|
||||
server:
|
||||
# Server bind address
|
||||
address: "HTTP_BIND_ADDRESS"
|
||||
# Server bind port
|
||||
port: "HTTP_BIND_PORT"
|
||||
thingsboard:
|
||||
enableProxy: "TB_ENABLE_PROXY"
|
||||
# ThingsBoard node host
|
||||
host: "TB_HOST"
|
||||
# ThingsBoard node port
|
||||
port: "TB_PORT"
|
||||
logger:
|
||||
level: "LOGGER_LEVEL"
|
||||
path: "LOG_FOLDER"
|
||||
filename: "LOGGER_FILENAME"
|
||||
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# Copyright © 2016-2023 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.
|
||||
#
|
||||
|
||||
server:
|
||||
# Server bind address
|
||||
address: "0.0.0.0"
|
||||
# Server bind port
|
||||
port: "8090"
|
||||
thingsboard:
|
||||
enableProxy: "false"
|
||||
# ThingsBoard node host
|
||||
host: "localhost"
|
||||
# ThingsBoard node port
|
||||
port: "8080"
|
||||
logger:
|
||||
level: "info"
|
||||
path: "logs"
|
||||
filename: "tb-web-ui-%DATE%.log"
|
||||
@@ -0,0 +1,63 @@
|
||||
///
|
||||
/// Copyright © 2016-2023 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 config from 'config';
|
||||
import path from 'path';
|
||||
import DailyRotateFile from 'winston-daily-rotate-file';
|
||||
import { createLogger, format, transports } from 'winston';
|
||||
import * as Transport from 'winston-transport';
|
||||
const { combine, timestamp, label, printf, splat } = format;
|
||||
|
||||
const loggerTransports: Array<Transport> = [];
|
||||
|
||||
if (process.env.NODE_ENV !== 'production' || process.env.DOCKER_MODE === 'true') {
|
||||
loggerTransports.push(new transports.Console({
|
||||
handleExceptions: true
|
||||
}));
|
||||
} else {
|
||||
const filename = path.join(config.get('logger.path'), config.get('logger.filename'));
|
||||
const transport = new (DailyRotateFile)({
|
||||
filename: filename,
|
||||
datePattern: 'YYYY-MM-DD-HH',
|
||||
zippedArchive: true,
|
||||
maxSize: '20m',
|
||||
maxFiles: '14d',
|
||||
handleExceptions: true
|
||||
});
|
||||
loggerTransports.push(transport);
|
||||
}
|
||||
|
||||
const tbFormat = printf(info => {
|
||||
let logMessage = `${info.timestamp} [${info.label}] ${info.level.toUpperCase()}: ${info.message}`;
|
||||
if (info.stack) {
|
||||
logMessage += ':\n' + info.stack;
|
||||
}
|
||||
return logMessage;
|
||||
});
|
||||
|
||||
export function _logger(moduleLabel: string) {
|
||||
return createLogger({
|
||||
level: config.get('logger.level'),
|
||||
format:combine(
|
||||
splat(),
|
||||
label({ label: moduleLabel }),
|
||||
timestamp({format: 'YYYY-MM-DD HH:mm:ss,SSS'}),
|
||||
tbFormat
|
||||
),
|
||||
transports: loggerTransports
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Copyright © 2016-2023 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.
|
||||
#
|
||||
|
||||
export NODE_CONFIG_DIR=${pkg.installFolder}/conf
|
||||
export LOG_FOLDER=${pkg.logFolder}
|
||||
export NODE_ENV=production
|
||||
export WEB_FOLDER=${pkg.installFolder}/web
|
||||
@@ -0,0 +1,41 @@
|
||||
#
|
||||
# Copyright © 2016-2023 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.
|
||||
#
|
||||
|
||||
FROM thingsboard/node:16.17.0-bullseye-slim
|
||||
|
||||
ENV NODE_ENV production
|
||||
ENV DOCKER_MODE true
|
||||
|
||||
COPY start-web-ui.sh /tmp/
|
||||
|
||||
WORKDIR ${pkg.installFolder}
|
||||
|
||||
COPY ["src/package.json", "src/yarn.lock", "./"]
|
||||
|
||||
COPY package/linux/conf ./conf
|
||||
COPY package/linux/conf ./config
|
||||
COPY web ./web
|
||||
COPY src/config ./config
|
||||
COPY src/server.js ./
|
||||
|
||||
RUN chmod a+x /tmp/*.sh \
|
||||
&& mv /tmp/start-web-ui.sh /usr/bin \
|
||||
&& chown -R node:node ${pkg.installFolder} \
|
||||
&& yarn install --production && yarn cache clean --all
|
||||
|
||||
USER node
|
||||
|
||||
CMD ["start-web-ui.sh"]
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright © 2016-2023 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.
|
||||
#
|
||||
|
||||
|
||||
echo "Starting '${project.name}' ..."
|
||||
|
||||
CONF_FOLDER="${pkg.installFolder}/conf"
|
||||
|
||||
configfile=${pkg.name}.conf
|
||||
|
||||
source "${CONF_FOLDER}/${configfile}"
|
||||
|
||||
cd ${pkg.installFolder}
|
||||
|
||||
# This will forward this PID 1 to the node.js and forward SIGTERM for graceful shutdown as well
|
||||
exec node server.js
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright © 2016-2023 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 fs = require('fs');
|
||||
const fse = require('fs-extra');
|
||||
const path = require('path');
|
||||
|
||||
let _projectRoot = null;
|
||||
|
||||
|
||||
(async() => {
|
||||
await fse.move(path.join(projectRoot(), 'target', 'thingsboard-web-ui-linux'),
|
||||
path.join(targetPackageDir('linux'), 'bin', 'tb-web-ui'),
|
||||
{overwrite: true});
|
||||
await fse.move(path.join(projectRoot(), 'target', 'thingsboard-web-ui-win.exe'),
|
||||
path.join(targetPackageDir('windows'), 'bin', 'tb-web-ui.exe'),
|
||||
{overwrite: true});
|
||||
})();
|
||||
|
||||
|
||||
function projectRoot() {
|
||||
if (!_projectRoot) {
|
||||
_projectRoot = __dirname;
|
||||
}
|
||||
return _projectRoot;
|
||||
}
|
||||
|
||||
function targetPackageDir(platform) {
|
||||
return path.join(projectRoot(), 'target', 'package', platform);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "thingsboard-web-ui",
|
||||
"private": true,
|
||||
"version": "3.5.2",
|
||||
"description": "ThingsBoard Web UI Microservice",
|
||||
"main": "server.ts",
|
||||
"bin": "server.js",
|
||||
"scripts": {
|
||||
"pkg": "tsc && pkg -t node16-linux-x64,node16-win-x64 --out-path ./target ./target/src && node install.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "nodemon --watch '.' --ext 'ts' --exec 'WEB_FOLDER=./target/web ts-node server.ts'",
|
||||
"start-prod": "nodemon --watch '.' --ext 'ts' --exec 'WEB_FOLDER=./target/web NODE_ENV=production ts-node server.ts'",
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"compression": "^1.7.4",
|
||||
"config": "^3.3.7",
|
||||
"connect-history-api-fallback": "^1.6.0",
|
||||
"express": "^4.18.1",
|
||||
"http": "0.0.0",
|
||||
"http-proxy": "^1.18.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"winston": "^3.7.2",
|
||||
"winston-daily-rotate-file": "^4.7.1"
|
||||
},
|
||||
"nyc": {
|
||||
"exclude": [
|
||||
"test",
|
||||
"__tests__",
|
||||
"node_modules",
|
||||
"target"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/compression": "^1.7.2",
|
||||
"@types/config": "^0.0.41",
|
||||
"@types/connect-history-api-fallback": "^1.3.5",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/http-proxy": "^1.17.9",
|
||||
"@types/node": "^18.0.0",
|
||||
"fs-extra": "^10.1.0",
|
||||
"nodemon": "^2.0.16",
|
||||
"pkg": "^5.7.0",
|
||||
"ts-node": "^10.8.1",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"pkg": {
|
||||
"assets": [
|
||||
"node_modules/config/**/*.*"
|
||||
]
|
||||
},
|
||||
"resolutions": {
|
||||
"color-string": "^1.5.5",
|
||||
"follow-redirects": "^1.14.8",
|
||||
"minimist": "^1.2.6"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
<!--
|
||||
|
||||
Copyright © 2016-2023 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.
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.thingsboard</groupId>
|
||||
<version>0.6.2-SNAPSHOT</version>
|
||||
<artifactId>msa</artifactId>
|
||||
</parent>
|
||||
<groupId>org.thingsboard.msa</groupId>
|
||||
<artifactId>web-ui</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>ThingsBoard Web UI Microservice</name>
|
||||
<url>https://thingsboard.io</url>
|
||||
<description>Service for hosting ThingsBoard Web UI</description>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<main.dir>${basedir}/../..</main.dir>
|
||||
<pkg.name>tb-web-ui</pkg.name>
|
||||
<pkg.type>js</pkg.type>
|
||||
<docker.name>tb-web-ui</docker.name>
|
||||
<pkg.name>tb-web-ui</pkg.name>
|
||||
<pkg.type>js</pkg.type>
|
||||
<pkg.disabled>false</pkg.disabled>
|
||||
<pkg.process-resources.phase>process-resources</pkg.process-resources.phase>
|
||||
<pkg.package.phase>package</pkg.package.phase>
|
||||
<pkg.linux.dist>${project.build.directory}/package/linux</pkg.linux.dist>
|
||||
<pkg.win.dist>${project.build.directory}/package/windows</pkg.win.dist>
|
||||
<docker.push-arm-amd-image.phase>pre-integration-test</docker.push-arm-amd-image.phase>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.thingsboard</groupId>
|
||||
<artifactId>ui-ngx</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>jar</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.winsw</groupId>
|
||||
<artifactId>winsw</artifactId>
|
||||
<classifier>bin</classifier>
|
||||
<type>exe</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<installDirectory>target</installDirectory>
|
||||
<workingDirectory>${basedir}</workingDirectory>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install node and yarn</id>
|
||||
<goals>
|
||||
<goal>install-node-and-yarn</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<nodeVersion>v16.15.1</nodeVersion>
|
||||
<yarnVersion>v1.22.17</yarnVersion>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>yarn install</id>
|
||||
<goals>
|
||||
<goal>yarn</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>install</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>yarn pkg</id>
|
||||
<goals>
|
||||
<goal>yarn</goal>
|
||||
</goals>
|
||||
<phase>compile</phase>
|
||||
<configuration>
|
||||
<arguments>run pkg</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>extract-web-ui</id>
|
||||
<goals>
|
||||
<goal>unpack</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>org.thingsboard</groupId>
|
||||
<artifactId>ui-ngx</artifactId>
|
||||
<type>jar</type>
|
||||
<overWrite>false</overWrite>
|
||||
<outputDirectory>${project.build.directory}/web</outputDirectory>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>copy-winsw-service</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>com.sun.winsw</groupId>
|
||||
<artifactId>winsw</artifactId>
|
||||
<classifier>bin</classifier>
|
||||
<type>exe</type>
|
||||
<destFileName>service.exe</destFileName>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
<outputDirectory>${pkg.win.dist}</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-src-root</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/src</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${basedir}</directory>
|
||||
<includes>
|
||||
<include>package.json</include>
|
||||
<include>yarn.lock</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.thingsboard</groupId>
|
||||
<artifactId>gradle-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>dockerfile-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>build-docker-image</id>
|
||||
<phase>pre-integration-test</phase>
|
||||
<goals>
|
||||
<goal>build</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<skip>${dockerfile.skip}</skip>
|
||||
<repository>${docker.repo}/${docker.name}</repository>
|
||||
<verbose>true</verbose>
|
||||
<googleContainerRegistryEnabled>false</googleContainerRegistryEnabled>
|
||||
<contextDirectory>${project.build.directory}</contextDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>tag-docker-image</id>
|
||||
<phase>pre-integration-test</phase>
|
||||
<goals>
|
||||
<goal>tag</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<skip>${dockerfile.skip}</skip>
|
||||
<repository>${docker.repo}/${docker.name}</repository>
|
||||
<tag>${project.version}</tag>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>yarn-start</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>yarn-start</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<installDirectory>target</installDirectory>
|
||||
<workingDirectory>${basedir}</workingDirectory>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>yarn start</id>
|
||||
<goals>
|
||||
<goal>yarn</goal>
|
||||
</goals>
|
||||
|
||||
<configuration>
|
||||
<arguments>start</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>push-docker-image</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>push-docker-image</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>dockerfile-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>push-latest-docker-image</id>
|
||||
<phase>pre-integration-test</phase>
|
||||
<goals>
|
||||
<goal>push</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tag>latest</tag>
|
||||
<repository>${docker.repo}/${docker.name}</repository>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>push-version-docker-image</id>
|
||||
<phase>pre-integration-test</phase>
|
||||
<goals>
|
||||
<goal>push</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tag>${project.version}</tag>
|
||||
<repository>${docker.repo}/${docker.name}</repository>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jenkins</id>
|
||||
<name>Jenkins Repository</name>
|
||||
<url>https://repo.jenkins-ci.org/releases</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
@@ -0,0 +1,154 @@
|
||||
///
|
||||
/// Copyright © 2016-2023 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 express from 'express';
|
||||
import config from 'config';
|
||||
import { _logger} from './config/logger';
|
||||
import path from 'path';
|
||||
import http, { ServerResponse } from 'http';
|
||||
import httpProxy from 'http-proxy';
|
||||
import compression from 'compression';
|
||||
import historyApiFallback from 'connect-history-api-fallback';
|
||||
import { Socket } from 'net';
|
||||
|
||||
const logger = _logger('main');
|
||||
|
||||
let server: http.Server | null;
|
||||
let connections: Socket[] = [];
|
||||
|
||||
(async() => {
|
||||
try {
|
||||
logger.info('Starting ThingsBoard Web UI Microservice...');
|
||||
|
||||
const bindAddress: string = config.get('server.address');
|
||||
const bindPort = Number(config.get('server.port'));
|
||||
|
||||
const thingsboardEnableProxy: string = config.get('thingsboard.enableProxy');
|
||||
|
||||
const thingsboardHost: string = config.get('thingsboard.host');
|
||||
const thingsboardPort = Number(config.get('thingsboard.port'));
|
||||
|
||||
logger.info('Bind address: %s', bindAddress);
|
||||
logger.info('Bind port: %s', bindPort);
|
||||
logger.info('ThingsBoard Enable Proxy: %s', thingsboardEnableProxy);
|
||||
logger.info('ThingsBoard host: %s', thingsboardHost);
|
||||
logger.info('ThingsBoard port: %s', thingsboardPort);
|
||||
|
||||
const useApiProxy = thingsboardEnableProxy === "true";
|
||||
|
||||
let webDir = path.join(__dirname, 'web');
|
||||
|
||||
if (typeof process.env.WEB_FOLDER !== 'undefined') {
|
||||
webDir = path.resolve(process.env.WEB_FOLDER);
|
||||
}
|
||||
logger.info('Web folder: %s', webDir);
|
||||
|
||||
const app = express();
|
||||
server = http.createServer(app);
|
||||
|
||||
let apiProxy: httpProxy;
|
||||
if (useApiProxy) {
|
||||
apiProxy = httpProxy.createProxyServer({
|
||||
target: {
|
||||
host: thingsboardHost,
|
||||
port: thingsboardPort
|
||||
}
|
||||
});
|
||||
|
||||
apiProxy.on('error', (err, req, res) => {
|
||||
logger.warn('API proxy error: %s', err.message);
|
||||
if (res instanceof ServerResponse) {
|
||||
res.writeHead(500);
|
||||
const error = err as any;
|
||||
if (error.code && error.code === 'ECONNREFUSED') {
|
||||
res.end('Unable to connect to ThingsBoard server.');
|
||||
} else {
|
||||
res.end('ThingsBoard server connection error: ' + error.code ? error.code : '');
|
||||
}
|
||||
}
|
||||
});
|
||||
app.all('/api/*', (req, res) => {
|
||||
logger.debug(req.method + ' ' + req.originalUrl);
|
||||
apiProxy.web(req, res);
|
||||
});
|
||||
|
||||
app.all('/static/rulenode/*', (req, res) => {
|
||||
apiProxy.web(req, res);
|
||||
});
|
||||
|
||||
server.on('upgrade', (req, socket, head) => {
|
||||
apiProxy.ws(req, socket, head);
|
||||
});
|
||||
}
|
||||
|
||||
app.use(historyApiFallback());
|
||||
app.use(compression());
|
||||
|
||||
const root = path.join(webDir, 'public');
|
||||
|
||||
app.use(express.static(root));
|
||||
|
||||
server.listen(bindPort, bindAddress, () => {
|
||||
logger.info('==> 🌎 Listening on port %s.', bindPort);
|
||||
logger.info('Started ThingsBoard Web UI Microservice.');
|
||||
}).on('error', async (error) => {
|
||||
logger.error('Failed to start ThingsBoard Web UI Microservice: %s', error.message);
|
||||
logger.error(error.stack);
|
||||
await exit(-1);
|
||||
});
|
||||
|
||||
server.on('connection', connection => {
|
||||
connections.push(connection);
|
||||
connection.on('close', () => connections = connections.filter(curr => curr !== connection));
|
||||
});
|
||||
|
||||
} catch (e: any) {
|
||||
logger.error('Failed to start ThingsBoard Web UI Microservice: %s', e.message);
|
||||
logger.error(e.stack);
|
||||
await exit(-1);
|
||||
}
|
||||
})();
|
||||
|
||||
[`SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`].forEach((eventType) => {
|
||||
process.once(eventType, async () => {
|
||||
logger.info(`${eventType} signal received`);
|
||||
await exit(0);
|
||||
});
|
||||
})
|
||||
|
||||
process.on('exit', async (code: number) => {
|
||||
logger.info(`ThingsBoard Web UI Microservice has been stopped. Exit code: ${code}.`);
|
||||
});
|
||||
|
||||
async function exit(status: number) {
|
||||
logger.info('Exiting with status: %d ...', status);
|
||||
if (server) {
|
||||
logger.info('Stopping HTTP Server...');
|
||||
connections.forEach(curr => curr.end(() => curr.destroy()));
|
||||
const _server = server;
|
||||
server = null;
|
||||
const serverClosePromise = new Promise<void>(
|
||||
(resolve, reject) => {
|
||||
_server.close((err) => {
|
||||
logger.info('HTTP Server stopped.');
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
);
|
||||
await serverClosePromise;
|
||||
}
|
||||
process.exit(status);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "target/src",
|
||||
"target": "es2016",
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"strictPropertyInitialization": false
|
||||
},
|
||||
"exclude": ["node_modules", "target"]
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user