Updated monitoring with the latest developments
* Moved 'ems-core' into 'nebulous' dir, and updated it from main repo. * Add 'ems-nebulous' plugin code, the 'metric-model' specs, and a top-level pom.xml to build everything (including EMS-Nebulous image) * Added .gitattributes and changed EOL to LF in top-level files. * Also adopting code to pass Zuul checks Change-Id: Ic414a1fa382d0a9112cbc805375cf603af59cd37
This commit is contained in:
parent
25f0770225
commit
96701613c8
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
* text=auto eol=lf
|
17
.gitignore
vendored
17
.gitignore
vendored
@ -1,2 +1,15 @@
|
||||
__pycache__/
|
||||
.nox/
|
||||
target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
@ -5,7 +5,7 @@
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: "quay.io/nebulous/monitoring-java-spring-boot-demo"
|
||||
repository: "quay.io/nebulous/monitoring"
|
||||
pullPolicy: IfNotPresent
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: ""
|
||||
|
@ -1 +0,0 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=plugin.gr.iccs.imu.ems.common.PluginManager
|
@ -1,7 +0,0 @@
|
||||
______ __ ___ __________ __
|
||||
/ ____/___ _____ ___ ___ / / |__ \ / ____/ __ \/ /
|
||||
/ / / __ `/ __ `__ \/ _ \/ / __/ / / __/ / /_/ / /
|
||||
/ /___/ /_/ / / / / / / __/ / / __/ / /___/ ____/ /___
|
||||
\____/\__,_/_/ /_/ /_/\___/_/ /____/ /_____/_/ /_____/
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
_____ _ ___ ______ _____ _
|
||||
/ ____| | | |__ \ | ____| __ \| |
|
||||
| | __ _ _ __ ___ ___| | ) | | |__ | |__) | |
|
||||
| | / _` | '_ ` _ \ / _ \ | / / | __| | ___/| |
|
||||
| |___| (_| | | | | | | __/ | / /_ | |____| | | |____
|
||||
\_____\__,_|_| |_| |_|\___|_| |____| |______|_| |______|
|
||||
|
||||
|
@ -1,237 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2017-2023 Institute of Communication and Computer Systems (imu.iccs.gr)
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0, unless
|
||||
# Esper library is used, in which case it is subject to the terms of General Public License v2.0.
|
||||
# If a copy of the MPL was not distributed with this file, you can obtain one at
|
||||
# https://www.mozilla.org/en-US/MPL/2.0/
|
||||
#
|
||||
|
||||
# EPL Rule templates per Element-Type and Monitoring-Grouping
|
||||
|
||||
DOLLAR: '$'
|
||||
translator.generator:
|
||||
language: EPL
|
||||
rule-templates:
|
||||
# SCHEDULE (i.e. IUTPUT) CLAUSE
|
||||
SCHEDULE:
|
||||
__ANY__:
|
||||
- |
|
||||
OUTPUT ALL EVERY [(${DOLLAR}{period})] [(${DOLLAR}{unit})]
|
||||
AGG:
|
||||
- |
|
||||
OUTPUT SNAPSHOT EVERY [(${DOLLAR}{period})] [(${DOLLAR}{unit})]
|
||||
# Binary-Event-Pattern templates
|
||||
BEP-AND:
|
||||
GLOBAL:
|
||||
- |
|
||||
/* BEP-AND-GLOBAL */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT le.* FROM [(${DOLLAR}{leftEvent})].std:lastevent() AS le, [(${DOLLAR}{rightEvent})].std:lastevent() AS re
|
||||
BEP-OR:
|
||||
GLOBAL:
|
||||
#XXX: TEST:
|
||||
- |
|
||||
/* BEP-OR-GLOBAL */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT CASE WHEN le IS NULL THEN re ELSE le END AS evt FROM PATTERN [ EVERY ( le=[(${DOLLAR}{leftEvent})] OR re=[(${DOLLAR}{rightEvent})] ) ]
|
||||
BEP-XOR:
|
||||
#XXX: XOR is NOT SUPPORTED: IS IT EQUIVALENT TO OR??
|
||||
GLOBAL:
|
||||
#XXX: TEST:
|
||||
- |
|
||||
/* BEP-XOR-GLOBAL */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT CASE WHEN le IS NULL THEN re ELSE le END AS evt FROM PATTERN [ EVERY ( le=[(${DOLLAR}{leftEvent})] OR re=[(${DOLLAR}{rightEvent})] ) ]
|
||||
BEP-PRECEDES:
|
||||
GLOBAL:
|
||||
#XXX: TEST:
|
||||
- |
|
||||
/* BEP-PRECEDES-GLOBAL */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT le.* FROM PATTERN [ EVERY ( le=[(${DOLLAR}{leftEvent})] -> re=[(${DOLLAR}{rightEvent})] ) ]
|
||||
BEP-REPEAT_UNTIL:
|
||||
GLOBAL:
|
||||
#XXX: TEST:
|
||||
- |
|
||||
/* BEP-REPEAT_UNTIL-GLOBAL */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT re.* FROM PATTERN [ EVERY [ le=[(${DOLLAR}{leftEvent})] UNTIL re=[(${DOLLAR}{rightEvent})] ] ] WHERE le IS NOT NULL
|
||||
|
||||
# Unary-Event-Pattern templates
|
||||
UEP-EVERY:
|
||||
#XXX: WHAT'S THE MEANING OF THIS OPERATOR?? ...IF STANDALONE??
|
||||
GLOBAL:
|
||||
- |
|
||||
/* UEP-EVERY-GLOBAL */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT ue.* FROM PATTERN [ EVERY ue=[(${DOLLAR}{unaryEvent})] ]
|
||||
UEP-NOT:
|
||||
#XXX: WHAT'S THE MEANING OF THIS OPERATOR?? ...IF STANDALONE??
|
||||
GLOBAL:
|
||||
- |
|
||||
/* UEP-NOT-GLOBAL */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT ue.* FROM PATTERN [ NOT ue=[(${DOLLAR}{unaryEvent})] ]
|
||||
UEP-REPEAT:
|
||||
GLOBAL:
|
||||
#XXX: TEST:
|
||||
- |
|
||||
/* UEP-REPEAT-GLOBAL */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT ue[0].* FROM PATTERN [ [[(${DOLLAR}{occurrenceNum})]] ue=[(${DOLLAR}{unaryEvent})] ]
|
||||
UEP-WHEN:
|
||||
#XXX: WHAT'S THE MEANING OF THIS OPERATOR?? ...IF STANDALONE??
|
||||
GLOBAL:
|
||||
- |
|
||||
/* UEP-WHEN-GLOBAL */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT ue.* FROM [(${DOLLAR}{leftEvent})].std:lastevent() AS ue
|
||||
|
||||
# Non-Functional-Event templates
|
||||
NFE:
|
||||
GLOBAL:
|
||||
- |
|
||||
/* NFE-GLOBAL */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT * FROM [(${DOLLAR}{metricConstraint})].std:lastevent()
|
||||
|
||||
# Metric-Constraint templates
|
||||
CONSTR-MET:
|
||||
__ANY__:
|
||||
- |
|
||||
/* CONSTR-MET-any */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT * FROM [(${DOLLAR}{metricContext})] HAVING [(${DOLLAR}{metricContext})].metricValue [(${DOLLAR}{operator})] [(${DOLLAR}{threshold})]
|
||||
|
||||
# Logical-Constraint templates
|
||||
CONSTR-LOG:
|
||||
__ANY__:
|
||||
- |
|
||||
/* CONSTR-LOG-any */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT 1 AS metricValue, 3 AS level, current_timestamp AS timestamp
|
||||
FROM PATTERN [ EVERY ( [# th:each="con,iterStat : ${DOLLAR}{constraints}" th:text="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{con} + ' '+${DOLLAR}{operator}+' ' : ${DOLLAR}{con}"] [/] ) ]
|
||||
|
||||
# If-Then-Constraint templates
|
||||
CONSTR-IF-THEN:
|
||||
__ANY__:
|
||||
#XXX: TEST:
|
||||
- |
|
||||
/* CONSTR-IF-THEN-any */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT 1 AS metricValue, 3 AS level, current_timestamp AS timestamp
|
||||
FROM PATTERN [ EVERY ( [(${DOLLAR}{ifConstraint})] AND [(${DOLLAR}{thenConstraint})] [# th:if="${DOLLAR}{elseConstraint != null}" th:text="'OR NOT ( ' + ${DOLLAR}{ifConstraint} + ' ) AND ' + ${DOLLAR}{elseConstraint}"] [/] ) ]
|
||||
|
||||
# Context templates
|
||||
COMP-CTX:
|
||||
__ANY__:
|
||||
- |
|
||||
/* COMP-CTX-any */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/ [# th:switch="${DOLLAR}{selectMode}"] [# th:case="'epl'"]
|
||||
SELECT [(${DOLLAR}{formula})] [/] [# th:case="*"]
|
||||
SELECT EVAL( '[(${DOLLAR}{formula})]', '[# th:each="ctx,iterStat : ${DOLLAR}{components}" th:text="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx} + ',' : ${DOLLAR}{ctx}"] [/]', [# th:each="ctx,iterStat : ${DOLLAR}{contexts}" th:text="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx} + ', ' : ${DOLLAR}{ctx}"] [/] ) AS metricValue,
|
||||
3 AS level,
|
||||
current_timestamp AS timestamp [/] [/]
|
||||
FROM [# th:each="ctx,iterStat : ${DOLLAR}{contexts}" th:utext="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx}+${DOLLAR}{windowClause}+' AS '+${DOLLAR}{ctx} + ', ' : ${DOLLAR}{ctx}+${DOLLAR}{windowClause}+' AS '+${DOLLAR}{ctx}"] [/]
|
||||
[(${DOLLAR}{scheduleClause})]
|
||||
|
||||
AGG-COMP-CTX:
|
||||
__ANY__:
|
||||
- |
|
||||
/* COMP-CTX-AGG-any */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/ [# th:switch="${DOLLAR}{selectMode}"] [# th:case="'epl'"]
|
||||
SELECT [(${DOLLAR}{formula})] [/] [# th:case="*"]
|
||||
SELECT EVALAGG( '[(${DOLLAR}{formula})]', '[# th:each="ctx,iterStat : ${DOLLAR}{components}" th:text="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx} + ',' : ${DOLLAR}{ctx}"] [/]', [# th:each="ctx,iterStat : ${DOLLAR}{contexts}" th:text="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx} + ', ' : ${DOLLAR}{ctx}"] [/] ) AS metricValue,
|
||||
3 AS level,
|
||||
current_timestamp AS timestamp [/] [/]
|
||||
FROM [# th:each="ctx,iterStat : ${DOLLAR}{contexts}" th:utext="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx}+${DOLLAR}{windowClause}+' AS '+${DOLLAR}{ctx} + ', ' : ${DOLLAR}{ctx}+${DOLLAR}{windowClause}+' AS '+${DOLLAR}{ctx}"] [/]
|
||||
[(${DOLLAR}{scheduleClause})]
|
||||
|
||||
RAW-CTX:
|
||||
PER_INSTANCE:
|
||||
- |
|
||||
/* RAW-CTX-PER_INSTANCE */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT * FROM [(${DOLLAR}{sensor})] [(${DOLLAR}{scheduleClause})]
|
||||
|
||||
# Metric templates
|
||||
TL-MET:
|
||||
__ANY__:
|
||||
- |
|
||||
/* MET-any */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT * FROM [(${DOLLAR}{context})]
|
||||
|
||||
# Metric Variable templates
|
||||
VAR:
|
||||
__ANY__:
|
||||
- |
|
||||
/* VAR-any */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/ [# th:switch="${DOLLAR}{selectMode}"] [# th:case="'epl'"]
|
||||
SELECT [(${DOLLAR}{formula})] [/] [# th:case="*"]
|
||||
SELECT EVAL( '[(${DOLLAR}{formula})]', '[# th:each="ctx,iterStat : ${DOLLAR}{components}" th:text="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx} + ',' : ${DOLLAR}{ctx}"] [/]', [# th:each="ctx,iterStat : ${DOLLAR}{contexts}" th:text="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx} + ', ' : ${DOLLAR}{ctx}"] [/] ) AS metricValue,
|
||||
3 AS level,
|
||||
current_timestamp AS timestamp [/] [/]
|
||||
FROM [# th:each="ctx,iterStat : ${DOLLAR}{contexts}" th:text="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx}+' AS '+${DOLLAR}{ctx} + ', ' : ${DOLLAR}{ctx}+' AS '+${DOLLAR}{ctx}"] [/]
|
||||
|
||||
AGG-VAR:
|
||||
__ANY__:
|
||||
- |
|
||||
/* VAR-AGG-any */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/ [# th:switch="${DOLLAR}{selectMode}"] [# th:case="'epl'"]
|
||||
SELECT [(${DOLLAR}{formula})] [/] [# th:case="*"]
|
||||
SELECT EVALAGG( '[(${DOLLAR}{formula})]', '[# th:each="ctx,iterStat : ${DOLLAR}{components}" th:text="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx} + ',' : ${DOLLAR}{ctx}"] [/]', [# th:each="ctx,iterStat : ${DOLLAR}{contexts}" th:text="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx} + ', ' : ${DOLLAR}{ctx}"] [/] ) AS metricValue,
|
||||
3 AS level,
|
||||
current_timestamp AS timestamp [/] [/]
|
||||
FROM [# th:each="ctx,iterStat : ${DOLLAR}{contexts}" th:text="!${DOLLAR}{iterStat.last} ? ${DOLLAR}{ctx}+' AS '+${DOLLAR}{ctx} + ', ' : ${DOLLAR}{ctx}+' AS '+${DOLLAR}{ctx}"] [/]
|
||||
|
||||
LOAD-VAR:
|
||||
__ANY__:
|
||||
- |
|
||||
/* LOAD-VAR-any */ /*INSERT INTO [(${outputStream})]*/
|
||||
SELECT * FROM [(${context})]
|
||||
|
||||
# Optimisation-Requirement templates
|
||||
OPT-REQ-CTX:
|
||||
__ANY__:
|
||||
- |
|
||||
/* OPT-REQ-any */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT * FROM [(${DOLLAR}{context})]
|
||||
|
||||
OPT-REQ-VAR:
|
||||
__ANY__:
|
||||
- |
|
||||
/* OPT-REQ-any */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT * FROM [(${DOLLAR}{variable})]
|
||||
|
||||
# SLO templates
|
||||
SLO:
|
||||
__ANY__:
|
||||
- |
|
||||
/* SLO-any */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT * FROM [(${DOLLAR}{constraint})]
|
||||
|
||||
#XXX:DEL:...remove next rule
|
||||
XXX-extra-rule-templates:
|
||||
BEP-AND:
|
||||
GLOBAL:
|
||||
- |
|
||||
/* BEP-AND-GLOBAL : ALTERNATIVE */ /*INSERT INTO [(${DOLLAR}{outputStream})]*/
|
||||
SELECT le.* FROM PATTERN [ EVERY (le=[(${DOLLAR}{leftEvent})] AND re=[(${DOLLAR}{rightEvent})]) ]
|
||||
RAW-CTX:
|
||||
PER_INSTANCE:
|
||||
- |
|
||||
/* RAW-CTX-PER_INSTANCE */
|
||||
INSERT INTO TEST_STREAM
|
||||
SELECT EVAL('-1*CPUMetric+CPUMetric_2+CPUMetric_3', '[(${DOLLAR}{metric})],[(${DOLLAR}{metric})]_2,[(${DOLLAR}{metric})]_3', [(${DOLLAR}{metric})], [(${DOLLAR}{metric})]_2, [(${DOLLAR}{metric})]_3) AS metricValue,
|
||||
1 AS level,
|
||||
current_timestamp AS timestamp
|
||||
FROM [(${DOLLAR}{metric})] as [(${DOLLAR}{metric})], [(${DOLLAR}{metric})] as [(${DOLLAR}{metric})]_2, [(${DOLLAR}{metric})] as [(${DOLLAR}{metric})]_3[(${DOLLAR}{scheduleClause})]
|
||||
|
||||
FE:
|
||||
PER_INSTANCE:
|
||||
- |
|
||||
/* XXX: TODO: FE-PER_INSTANCE */
|
||||
.......... Functional Event
|
||||
CONSTR-IF-THEN:
|
||||
PER_INSTANCE:
|
||||
- |
|
||||
/* XXX: TODO: CONSTR-IF-THEN-PER_INSTANCE */
|
||||
.......... If-Then constraint
|
||||
CONSTR-VAR:
|
||||
PER_INSTANCE:
|
||||
- |
|
||||
/* XXX: TODO: CONSTR-VAR-PER_INSTANCE */
|
||||
.......... Metric Variable constraint
|
||||
CONSTR-LOG:
|
||||
PER_INSTANCE:
|
||||
- |
|
||||
/* XXX: TODO: CONSTR-LOG-PER_INSTANCE */
|
||||
.......... Logical constraint
|
||||
VAR:
|
||||
PER_INSTANCE:
|
||||
- |
|
||||
/* XXX: TODO: VAR-PER_INSTANCE */
|
||||
.......... Metric Variable
|
16
nebulous/Dockerfile
Normal file
16
nebulous/Dockerfile
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
# ----------------- Builder image -----------------
|
||||
FROM docker.io/library/maven:3.9.6-eclipse-temurin-21 as builder
|
||||
ENV BASEDIR /app
|
||||
WORKDIR ${BASEDIR}
|
||||
COPY ems-core ${BASEDIR}/ems-core
|
||||
COPY ems-nebulous ${BASEDIR}/ems-nebulous
|
||||
COPY pom.xml ${BASEDIR}/
|
||||
RUN mvn -f ${BASEDIR}/pom.xml -DskipTests clean install
|
||||
|
||||
# ----------------- Runtime image -----------------
|
||||
FROM registry.gitlab.com/nebulous-project/ems-main/ems-server:2024-jan
|
||||
|
||||
COPY --from=builder /app/ems-nebulous/target/ems-nebulous-plugin-1.0.0-SNAPSHOT-jar-with-dependencies.jar /plugins/
|
||||
ENV EXTRA_LOADER_PATHS=/plugins/*
|
||||
ENV SCAN_PACKAGES=eu.nebulous.ems
|
@ -41,6 +41,8 @@ public class ClientInstallationProperties implements InitializingBean {
|
||||
private String clientInstallationRequestsTopic = "ems.client.installation.requests";
|
||||
private String clientInstallationReportsTopic = "ems.client.installation.reports";
|
||||
private List<Pattern> clientInstallationReportNodeInfoPatterns = new ArrayList<>();
|
||||
private String clientInfoRequestsTopic = "ems.client.info.requests";
|
||||
private String clientInfoReportsTopic = "ems.client.info.reports";
|
||||
|
||||
private String baseDir; // EMS client home directory
|
||||
private String rootCmd; // Root command (e.g. 'sudo', or 'echo ${NODE_SSH_PASSWORD} | sudo -S ')
|
@ -29,11 +29,13 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.jms.*;
|
||||
import jakarta.jms.*;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static gr.iccs.imu.ems.baguette.client.install.ClientInstallationTask.TASK_TYPE;
|
||||
|
||||
/**
|
||||
* Installation Event Listener
|
||||
*/
|
||||
@ -93,54 +95,92 @@ public class ClientInstallationRequestListener implements InitializingBean {
|
||||
? connectionFactory.createConnection(brokerCepService.getBrokerUsername(), brokerCepService.getBrokerPassword())
|
||||
: connectionFactory.createConnection());
|
||||
Session session = connection.createSession(true, 0);
|
||||
MessageConsumer consumer = session.createConsumer(
|
||||
new ActiveMQTopic(properties.getClientInstallationRequestsTopic()));
|
||||
consumer.setMessageListener(getMessageListener());
|
||||
|
||||
List<String> topics = Arrays.asList(
|
||||
properties.getClientInstallationRequestsTopic(),
|
||||
properties.getClientInfoRequestsTopic()
|
||||
);
|
||||
log.debug("InstallationEventListener: Will subscribe to topics: {}", topics);
|
||||
|
||||
MessageListener listener = getMessageListener();
|
||||
for (String topic : topics) {
|
||||
MessageConsumer consumer = session.createConsumer(
|
||||
new ActiveMQTopic( topic ));
|
||||
consumer.setMessageListener(listener);
|
||||
log.debug("InstallationEventListener: Subscribed to topic: {}", topic);
|
||||
}
|
||||
|
||||
connection.start();
|
||||
log.debug("InstallationEventListener: STARTED");
|
||||
}
|
||||
|
||||
private MessageListener getMessageListener() {
|
||||
return message -> {
|
||||
String requestId = null;
|
||||
Map<String, String> request = null;
|
||||
TASK_TYPE requestType = TASK_TYPE.OTHER;
|
||||
try {
|
||||
// Extract request from JMS message
|
||||
Map<String, String> request = extractRequest(message);
|
||||
request = extractRequest(message);
|
||||
log.debug("InstallationEventListener: Got a client installation request: {}", request);
|
||||
if (request==null)
|
||||
throw new IllegalArgumentException("Could not extract request data");
|
||||
requestId = request.get("requestId").trim();
|
||||
if (request==null) {
|
||||
clientInstaller.sendErrorClientInstallationReport(TASK_TYPE.OTHER,
|
||||
null, "ERROR: Invalid request. Could not extract request data");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check incoming request
|
||||
List<String> errors = new ArrayList<>();
|
||||
if (StringUtils.isBlank(request.get("requestId"))) errors.add("requestId");
|
||||
if (StringUtils.isBlank(request.get("requestType"))) errors.add("requestType");
|
||||
if (StringUtils.isBlank(request.get("deviceOs"))) errors.add("deviceOs");
|
||||
if (StringUtils.isBlank(request.get("deviceIpAddress"))) errors.add("deviceIpAddress");
|
||||
if (StringUtils.isBlank(request.get("deviceUsername"))) errors.add("deviceUsername");
|
||||
if (StringUtils.isBlank(request.get("devicePassword")) && StringUtils.isBlank(request.get("devicePublicKey")))
|
||||
errors.add("Both devicePublicKey and devicePublicKey");
|
||||
if (! errors.isEmpty()) {
|
||||
String errorMessage = "Missing fields: " + String.join(", ", errors);
|
||||
throw new IllegalArgumentException(errorMessage);
|
||||
// Get request type
|
||||
String requestTypeStr = request.get("requestType");
|
||||
if (StringUtils.isBlank(requestTypeStr)) {
|
||||
clientInstaller.sendErrorClientInstallationReport(TASK_TYPE.OTHER,
|
||||
request, "ERROR: Invalid request. Missing requestType field");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if ("VM".equalsIgnoreCase(requestTypeStr)) requestTypeStr = TASK_TYPE.INSTALL.name();
|
||||
if ("REMOVE".equalsIgnoreCase(requestTypeStr)) requestTypeStr = TASK_TYPE.UNINSTALL.name();
|
||||
if ("UPDATE".equalsIgnoreCase(requestTypeStr)) requestTypeStr = TASK_TYPE.INFO.name();
|
||||
requestType = TASK_TYPE.valueOf(requestTypeStr.trim().toUpperCase());
|
||||
} catch (Exception e) {
|
||||
clientInstaller.sendErrorClientInstallationReport(TASK_TYPE.OTHER,
|
||||
request, "ERROR: Invalid request. Invalid requestType field value: "+requestTypeStr);
|
||||
return;
|
||||
}
|
||||
|
||||
// If not an INFO or NODE_DETAILS request run extra checks
|
||||
if (TASK_TYPE.INFO != requestType && TASK_TYPE.NODE_DETAILS != requestType) {
|
||||
// Check incoming request
|
||||
List<String> errors = new ArrayList<>();
|
||||
if (StringUtils.isBlank(request.get("requestId")) &&
|
||||
(TASK_TYPE.DIAGNOSTICS==requestType || TASK_TYPE.INSTALL==requestType))
|
||||
errors.add("requestId");
|
||||
if (StringUtils.isBlank(request.get("deviceOs"))) errors.add("deviceOs");
|
||||
if (StringUtils.isBlank(request.get("deviceIpAddress"))) errors.add("deviceIpAddress");
|
||||
if (StringUtils.isBlank(request.get("deviceUsername"))) errors.add("deviceUsername");
|
||||
if (StringUtils.isBlank(request.get("devicePassword"))
|
||||
&& StringUtils.isBlank(request.get("devicePublicKey"))) errors.add("Both devicePublicKey and devicePublicKey");
|
||||
if (!errors.isEmpty()) {
|
||||
String errorMessage = "Missing fields: " + String.join(", ", errors);
|
||||
clientInstaller.sendErrorClientInstallationReport(requestType, request, "ERROR: "+errorMessage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Process request based on its type
|
||||
String requestType = request.get("requestType").trim();
|
||||
switch (requestType) {
|
||||
case "DIAGNOSTICS" -> processDiagnosticsRequest(request);
|
||||
case "VM" -> processOnboardingRequest(request);
|
||||
case "REMOVE" -> processRemoveRequest(request);
|
||||
case DIAGNOSTICS -> processDiagnosticsRequest(request);
|
||||
case INSTALL -> processOnboardingRequest(request);
|
||||
case REINSTALL -> processReinstallRequest(request);
|
||||
case UNINSTALL -> processRemoveRequest(request);
|
||||
case NODE_DETAILS -> processNodeDetailsRequest(request);
|
||||
case INFO -> processInfoRequest(request);
|
||||
default -> throw new IllegalArgumentException("Unsupported request type: "+requestType);
|
||||
};
|
||||
|
||||
} catch (Throwable e) {
|
||||
log.error("InstallationEventListener: ERROR: ", e);
|
||||
try {
|
||||
if (StringUtils.isNotBlank(requestId))
|
||||
clientInstaller.sendErrorClientInstallationReport(requestId, "ERROR: "+e.getMessage());
|
||||
else
|
||||
clientInstaller.sendErrorClientInstallationReport("UNKNOWN-REQUEST-ID", "ERROR: "+e.getMessage()+"\n"+message);
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
requestType, request, "ERROR: "+e.getMessage()+"\n"+message);
|
||||
} catch (Throwable t) {
|
||||
log.info("InstallationEventListener: EXCEPTION while sending Client installation report for incoming request: request={}, Exception: ", message, t);
|
||||
}
|
||||
@ -175,7 +215,7 @@ public class ClientInstallationRequestListener implements InitializingBean {
|
||||
// Create client installation task
|
||||
ClientInstallationTask newTask = ClientInstallationTask.builder()
|
||||
.id(request.get("requestId"))
|
||||
.taskType(ClientInstallationTask.TASK_TYPE.DIAGNOSTIC)
|
||||
.taskType(ClientInstallationTask.TASK_TYPE.DIAGNOSTICS)
|
||||
.requestId(request.get("requestId"))
|
||||
.type(request.get("requestType"))
|
||||
.nodeId(request.get("deviceId"))
|
||||
@ -214,7 +254,8 @@ public class ClientInstallationRequestListener implements InitializingBean {
|
||||
String requestId = request.getOrDefault("requestId", "").trim();
|
||||
log.info("InstallationEventListener: New node ONBOARDING request with Id: {}", requestId);
|
||||
if (StringUtils.isBlank(requestId)) {
|
||||
clientInstaller.sendErrorClientInstallationReport("MISSING-REQUEST-ID", "INVALID REQUEST. MISSING REQUEST ID");
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.INSTALL, request, "INVALID REQUEST. MISSING REQUEST ID");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -223,14 +264,132 @@ public class ClientInstallationRequestListener implements InitializingBean {
|
||||
nodeRegistration.registerNode(null, convertToNodeInfoMap(request), new TranslationContext(requestId));
|
||||
} catch (Exception e) {
|
||||
log.warn("InstallationEventListener: EXCEPTION while executing ONBOARDING request with Id: {}\n", requestId, e);
|
||||
clientInstaller.sendErrorClientInstallationReport(requestId, "ERROR: "+e.getMessage());
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.INSTALL, request, "ERROR: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void processReinstallRequest(Map<String,String> request) throws Exception {
|
||||
String requestId = request.getOrDefault("requestId", "").trim();
|
||||
String deviceId = request.getOrDefault("deviceId", "").trim();
|
||||
String ipAddress = request.getOrDefault("deviceIpAddress", "").trim();
|
||||
log.info("InstallationEventListener: REINSTALL request with device Id: {}, ip-address={}", deviceId, ipAddress);
|
||||
if (StringUtils.isBlank(deviceId)) {
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.REINSTALL, request, "INVALID REQUEST. MISSING DEVICE ID");
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isBlank(ipAddress)) {
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.REINSTALL, request, "INVALID REQUEST. MISSING DEVICE IP ADDRESS");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
log.debug("InstallationEventListener: Reinstalling node due to REINSTALL request with Id: {}", deviceId);
|
||||
nodeRegistration.reinstallNode(ipAddress, new TranslationContext(requestId));
|
||||
} catch (Exception e) {
|
||||
log.warn("InstallationEventListener: EXCEPTION while executing REINSTALL request with Id: {}\n", deviceId, e);
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.REINSTALL, request, "ERROR: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void processRemoveRequest(Map<String,String> request) throws Exception {
|
||||
String requestId = request.getOrDefault("requestId", "").trim();
|
||||
String deviceId = request.getOrDefault("deviceId", "").trim();
|
||||
String nodeAddress = request.getOrDefault("deviceIpAddress", "").trim();
|
||||
log.info("InstallationEventListener: New node REMOVE request with Id: {}, address={}", deviceId, nodeAddress);
|
||||
if (StringUtils.isBlank(deviceId)) {
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.UNINSTALL, request, "INVALID REQUEST. MISSING DEVICE ID");
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isBlank(nodeAddress)) {
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.UNINSTALL, request, "INVALID REQUEST. MISSING IP ADDRESS");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
log.debug("InstallationEventListener: Off-boarding node due to REMOVE request with Id: {}, requestId={}", deviceId, requestId);
|
||||
nodeRegistration.unregisterNode(nodeAddress, new TranslationContext(requestId));
|
||||
} catch (Exception e) {
|
||||
log.warn("InstallationEventListener: EXCEPTION while executing REMOVE request with Id: {}\n", deviceId, e);
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.UNINSTALL, request, "ERROR: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void processNodeDetailsRequest(Map<String,String> request) throws Exception {
|
||||
String nodeAddress = request.getOrDefault("deviceIpAddress", "").trim();
|
||||
log.info("InstallationEventListener: New node NODE_DETAILS request with: address={}", nodeAddress);
|
||||
if (StringUtils.isBlank(nodeAddress)) {
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.NODE_DETAILS, request, "INVALID REQUEST. MISSING IP ADDRESS");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("InstallationEventListener: Processing NODE_DETAILS request");
|
||||
try {
|
||||
log.debug("InstallationEventListener: Requesting NODE_DETAILS");
|
||||
NodeRegistryEntry entry = nodeRegistration.requestNodeDetails(nodeAddress);
|
||||
log.trace("InstallationEventListener: NODE_DETAILS: entry={}", entry);
|
||||
|
||||
if (entry!=null) {
|
||||
// Get node details from NodeRegistry
|
||||
Map<String, Object> response = clientInstaller.createReportEventFromNodeData(
|
||||
-1, TASK_TYPE.NODE_DETAILS, "", "",
|
||||
entry.getIpAddress(), entry.getReference(), entry.getPreregistration(), "SUCCESS");
|
||||
log.debug("InstallationEventListener: NODE_DETAILS response (1): {}", response);
|
||||
|
||||
// ...make response map mutable
|
||||
response = new LinkedHashMap<>(response);
|
||||
|
||||
// ...include additional fields
|
||||
Map<String, String> preregData = entry.getPreregistration();
|
||||
response.put("os", preregData.getOrDefault("NODE_OPERATINGSYSTEM", ""));
|
||||
response.put("name", preregData.getOrDefault("NODE_NAME", ""));
|
||||
response.put("username", preregData.getOrDefault("NODE_SSH_USERNAME", ""));
|
||||
response.put("password", preregData.getOrDefault("NODE_SSH_PASSWORD", ""));
|
||||
response.put("key", preregData.getOrDefault("NODE_SSH_KEY", ""));
|
||||
|
||||
response.put("requestId", "");
|
||||
response.put("state", entry.getState()!=null ? entry.getState().name() : "");
|
||||
log.debug("InstallationEventListener: NODE_DETAILS response (2): {}", response);
|
||||
|
||||
// Send NODE_DETAILS response
|
||||
log.trace("InstallationEventListener: Sending NODE_DETAILS response: {}", response);
|
||||
clientInstaller.publishReport(new LinkedHashMap<>(response));
|
||||
|
||||
log.debug("InstallationEventListener: Sent NODE_DETAILS response: {}", response);
|
||||
} else {
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.NODE_DETAILS, request, "ERROR: No node found in NodeRegistry with IP address: "+nodeAddress);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("InstallationEventListener: EXCEPTION while retrieving NODE_DETAILS:\n", e);
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.INFO, request, "ERROR: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void processInfoRequest(Map<String,String> request) throws Exception {
|
||||
log.info("InstallationEventListener: INFO request");
|
||||
try {
|
||||
log.debug("InstallationEventListener: Requesting INFO");
|
||||
nodeRegistration.requestInfo();
|
||||
} catch (Exception e) {
|
||||
log.warn("InstallationEventListener: EXCEPTION while executing INFO:\n", e);
|
||||
clientInstaller.sendErrorClientInstallationReport(
|
||||
TASK_TYPE.INFO, request, "ERROR: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> convertToNodeInfoMap(Map<String, String> request) {
|
||||
log.trace("InstallationEventListener.convertToNodeInfoMap(): BEGIN: request: {}", request);
|
||||
String requestId = request.get("requestId");
|
||||
String nodeId = request.get("requestId");
|
||||
String nodeId = request.get("deviceId");
|
||||
String nodeOs = request.get("deviceOs");
|
||||
String nodeAddress = request.get("deviceIpAddress");
|
||||
String nodeType = request.get("deviceType");
|
||||
@ -267,26 +426,4 @@ public class ClientInstallationRequestListener implements InitializingBean {
|
||||
log.trace("InstallationEventListener.convertToNodeInfoMap(): END: nodeMap: {}", nodeMap);
|
||||
return nodeMap;
|
||||
}
|
||||
|
||||
private void processRemoveRequest(Map<String,String> request) throws Exception {
|
||||
String requestId = request.getOrDefault("requestId", "").trim();
|
||||
String nodeAddress = request.getOrDefault("deviceIpAddress", "").trim();
|
||||
log.info("InstallationEventListener: New node REMOVE request with Id: {}, address={}", requestId, nodeAddress);
|
||||
if (StringUtils.isBlank(requestId)) {
|
||||
clientInstaller.sendErrorClientInstallationReport("MISSING-REQUEST-ID", "INVALID REQUEST. MISSING REQUEST ID");
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isBlank(nodeAddress)) {
|
||||
clientInstaller.sendErrorClientInstallationReport(requestId, "INVALID REQUEST. MISSING IP ADDRESS");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
log.debug("InstallationEventListener: Off-boarding node due to REMOVE request with Id: {}", requestId);
|
||||
nodeRegistration.unregisterNode(nodeAddress, new TranslationContext(requestId));
|
||||
} catch (Exception e) {
|
||||
log.warn("InstallationEventListener: EXCEPTION while executing REMOVE request with Id: {}\n", requestId, e);
|
||||
clientInstaller.sendErrorClientInstallationReport(requestId, "ERROR: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ import java.util.concurrent.Callable;
|
||||
@Data
|
||||
@Builder
|
||||
public class ClientInstallationTask {
|
||||
public enum TASK_TYPE { INSTALL, UNINSTALL, DIAGNOSTIC, OTHER }
|
||||
public enum TASK_TYPE { INSTALL, REINSTALL, UNINSTALL, NODE_DETAILS, INFO, DIAGNOSTICS, OTHER }
|
||||
|
||||
private final String id;
|
||||
private final TASK_TYPE taskType;
|
||||
@ -39,6 +39,7 @@ public class ClientInstallationTask {
|
||||
private final NodeRegistryEntry nodeRegistryEntry;
|
||||
private final List<InstructionsSet> instructionSets;
|
||||
private final TranslationContext translationContext;
|
||||
@Builder.Default
|
||||
private boolean nodeMustBeInRegistry = true;
|
||||
|
||||
private Callable<String> callback;
|
@ -22,8 +22,9 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import jakarta.jms.JMSException;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -33,6 +34,8 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static gr.iccs.imu.ems.baguette.client.install.ClientInstallationTask.TASK_TYPE;
|
||||
|
||||
/**
|
||||
* Client installer
|
||||
*/
|
||||
@ -128,7 +131,7 @@ public class ClientInstaller implements InitializingBean {
|
||||
return executeVmOrBaremetalTask(task, taskCounter);
|
||||
} else
|
||||
//if ("DIAGNOSTICS".equalsIgnoreCase(task.getType())) {
|
||||
if (task.getTaskType()==ClientInstallationTask.TASK_TYPE.DIAGNOSTIC) {
|
||||
if (task.getTaskType()==TASK_TYPE.DIAGNOSTICS) {
|
||||
return executeDiagnosticsTask(task, taskCounter);
|
||||
} else {
|
||||
log.error("ClientInstaller: UNSUPPORTED TASK TYPE: {}", task.getType());
|
||||
@ -181,13 +184,13 @@ public class ClientInstaller implements InitializingBean {
|
||||
}
|
||||
|
||||
// Pre-register Node to baguette Server Coordinator
|
||||
if (task.getTaskType()==ClientInstallationTask.TASK_TYPE.INSTALL) {
|
||||
if (task.getTaskType()==TASK_TYPE.INSTALL) {
|
||||
log.debug("ClientInstaller: POST-INSTALLATION: Node is being pre-registered: {}", entry);
|
||||
baguetteServer.getNodeRegistry().getCoordinator().preregister(entry);
|
||||
}
|
||||
|
||||
// Un-register Node from baguette Server Coordinator
|
||||
if (task.getTaskType()==ClientInstallationTask.TASK_TYPE.UNINSTALL) {
|
||||
if (task.getTaskType()==TASK_TYPE.UNINSTALL) {
|
||||
ClientShellCommand csc = ClientShellCommand.getActiveByIpAddress(entry.getIpAddress());
|
||||
log.debug("ClientInstaller: POST-INSTALLATION: CSC of node to be unregistered: {}", csc);
|
||||
if (csc!=null) {
|
||||
@ -247,43 +250,89 @@ public class ClientInstaller implements InitializingBean {
|
||||
createReportEventFromExecutionResults(taskCnt, task, resultStr));
|
||||
log.info("ClientInstaller: Sending SUCCESS execution report for Task #{}: destination={}, report={}",
|
||||
taskCnt, properties.getClientInstallationReportsTopic(), executionReport);
|
||||
brokerCepService.publishSerializable(
|
||||
null, properties.getClientInstallationReportsTopic(), executionReport, true);
|
||||
publishReport(executionReport);
|
||||
}
|
||||
|
||||
public void sendErrorClientInstallationReport(String requestId, String resultStr) throws JMSException {
|
||||
log.trace("ClientInstaller: Preparing ERROR execution report event for request: result={}, requestId={}", resultStr, requestId);
|
||||
public void sendErrorClientInstallationReport(@NonNull TASK_TYPE requestType, Map<String,String> request, String resultStr) throws JMSException {
|
||||
sendErrorClientInstallationReport(requestType, request, null, resultStr);
|
||||
}
|
||||
|
||||
public void sendErrorClientInstallationReport(@NonNull TASK_TYPE requestType, Map<String,String> request, String reference, String resultStr) throws JMSException {
|
||||
log.trace("ClientInstaller: Preparing ERROR execution report event for request: result={}, request={}", resultStr, request);
|
||||
String requestId = getOrDefault(request, "requestId", "MISSING-REQUEST-ID");
|
||||
String deviceId = getOrDefault(request, "deviceId", "MISSING-DEVICE-ID");
|
||||
String ipAddress = getOrDefault(request, "deviceIpAddress", "MISSING-DEVICE-ADDRESS");
|
||||
LinkedHashMap<String, Object> executionReport = new LinkedHashMap<>(
|
||||
createReportEvent(requestId, null, resultStr, Collections.emptyMap()));
|
||||
log.info("ClientInstaller: Sending ERROR execution report for request: destination={}, report={}",
|
||||
createReportEvent(requestType,
|
||||
requestId, deviceId, ipAddress, reference, resultStr, Collections.emptyMap()));
|
||||
log.info("ClientInstaller: Sending ERROR execution report: destination={}, report={}",
|
||||
properties.getClientInstallationReportsTopic(), executionReport);
|
||||
publishReport(executionReport);
|
||||
}
|
||||
|
||||
private String getOrDefault(Map<String,String> map, String key, String defaultValue) {
|
||||
if (map==null) return defaultValue;
|
||||
return map.getOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
public void publishReport(Serializable report) throws JMSException {
|
||||
brokerCepService.publishSerializable(
|
||||
null, properties.getClientInstallationReportsTopic(), executionReport, true);
|
||||
null, properties.getClientInstallationReportsTopic(), report, true);
|
||||
}
|
||||
|
||||
private Map<String, Object> createReportEventFromExecutionResults(long taskCnt, @NonNull ClientInstallationTask task, String resultStr) {
|
||||
log.trace("ClientInstaller: createReportEventFromExecutionResults: Task #{}: ARGS: result={}, task={}", taskCnt, resultStr, task);
|
||||
|
||||
// Get execution results
|
||||
Map<String, String> data = task.getNodeRegistryEntry().getPreregistration();
|
||||
log.trace("ClientInstaller: createReportEventFromExecutionResults: Task #{}: Execution data:\n{}", taskCnt, data);
|
||||
|
||||
// Create report event
|
||||
TASK_TYPE requestType = task.getTaskType();
|
||||
String requestId = task.getRequestId();
|
||||
String deviceId = task.getNodeId();
|
||||
return createReportEventFromNodeData(taskCnt, requestType, requestId, deviceId,
|
||||
task.getAddress(), task.getNodeRegistryEntry().getReference(), data, resultStr);
|
||||
}
|
||||
|
||||
public Map<String, Object> createReportEventFromNodeData(long taskCnt,
|
||||
TASK_TYPE requestType,
|
||||
String requestId,
|
||||
String deviceId,
|
||||
String ipAddress,
|
||||
String reference,
|
||||
Map<String, String> data,
|
||||
String resultStr)
|
||||
{
|
||||
// Copy node info from execution results
|
||||
Map<String, Object> nodeInfoMap = new LinkedHashMap<>();
|
||||
properties.getClientInstallationReportNodeInfoPatterns().forEach(pattern -> {
|
||||
log.trace("ClientInstaller: createReportEventFromExecutionResults: Task #{}:Applying pattern: {}", taskCnt, pattern);
|
||||
log.trace("ClientInstaller: createReportEventFromNodeData: Task #{}: Applying pattern: {}", taskCnt, pattern);
|
||||
data.keySet().stream()
|
||||
//.peek(key->log.trace(" ----> Checking: key={}, match={}", key, pattern.matcher(key).matches()))
|
||||
.filter(key -> pattern.matcher(key).matches())
|
||||
.forEach(key -> nodeInfoMap.put(key, data.get(key)));
|
||||
});
|
||||
log.debug("ClientInstaller: createReportEventFromExecutionResults: Task #{}: Node info collected: {}", taskCnt, nodeInfoMap);
|
||||
String requestId = StringUtils.defaultIfBlank(task.getRequestId(), task.getId());
|
||||
return createReportEvent(requestId, task.getNodeRegistryEntry().getReference(), resultStr, nodeInfoMap);
|
||||
log.debug("ClientInstaller: createReportEventFromNodeData: Task #{}: Node info collected: {}", taskCnt, nodeInfoMap);
|
||||
|
||||
// Create and send report event
|
||||
return createReportEvent(
|
||||
requestType, requestId, deviceId, ipAddress, reference, resultStr, nodeInfoMap);
|
||||
}
|
||||
|
||||
private static Map<String, Object> createReportEvent(@NonNull String requestId,
|
||||
private static Map<String, Object> createReportEvent(@NonNull TASK_TYPE requestType,
|
||||
String requestId,
|
||||
String deviceId,
|
||||
String ipAddress,
|
||||
String reference,
|
||||
@NonNull String statusStr,
|
||||
Map<String, Object> nodeInfoMap)
|
||||
{
|
||||
return Map.of(
|
||||
"requestId", requestId,
|
||||
"requestType", requestType.name(),
|
||||
"requestId", Objects.requireNonNullElse(requestId, ""),
|
||||
"deviceId", Objects.requireNonNullElse(deviceId, ""),
|
||||
"deviceIpAddress", Objects.requireNonNullElse(ipAddress, ""),
|
||||
"reference", Objects.requireNonNullElse(reference, ""),
|
||||
"status", statusStr,
|
||||
"nodeInfo", nodeInfoMap!=null ? nodeInfoMap : Collections.emptyMap(),
|
@ -408,7 +408,7 @@ public class SshClientInstaller implements ClientInstallerPlugin {
|
||||
setChannelStreams(channel);
|
||||
log.debug("SshClientInstaller: task #{}: EXEC: New channel id: {}", taskCounter, channel.getChannelId());
|
||||
//streamLogger.getInvertedIn().write(command.getBytes());
|
||||
streamLogger.logMessage(String.format("EXEC: %s\n", command));
|
||||
streamLogger.logMessage("EXEC: %s\n".formatted(command));
|
||||
try {
|
||||
// Sending command to remote side
|
||||
log.debug("SshClientInstaller: task #{}: EXEC: Sending command for execution: {} (connect timeout: {}ms)", taskCounter, command, connectTimeout);
|
||||
@ -444,7 +444,7 @@ public class SshClientInstaller implements ClientInstallerPlugin {
|
||||
return true;
|
||||
}
|
||||
|
||||
streamLogger.logMessage(String.format("DOWNLOAD: SCP: %s -> %s\n", remoteFilePath, localFilePath));
|
||||
streamLogger.logMessage("DOWNLOAD: SCP: %s -> %s\n".formatted(remoteFilePath, localFilePath));
|
||||
try {
|
||||
log.info("SshClientInstaller: Downloading file: task #{}: remote: {} -> local: {}", taskCounter, remoteFilePath, localFilePath);
|
||||
ScpClientCreator creator = new DefaultScpClientCreator();
|
||||
@ -465,7 +465,7 @@ public class SshClientInstaller implements ClientInstallerPlugin {
|
||||
return true;
|
||||
}
|
||||
|
||||
streamLogger.logMessage(String.format("UPLOAD: SCP: %s -> %s\n", localFilePath, remoteFilePath));
|
||||
streamLogger.logMessage("UPLOAD: SCP: %s -> %s\n".formatted(localFilePath, remoteFilePath));
|
||||
try {
|
||||
long startTm = System.currentTimeMillis();
|
||||
log.info("SshClientInstaller: Uploading file: task #{}: local: {} -> remote: {}", taskCounter, localFilePath, remoteFilePath);
|
||||
@ -488,7 +488,7 @@ public class SshClientInstaller implements ClientInstallerPlugin {
|
||||
return true;
|
||||
}
|
||||
|
||||
streamLogger.logMessage(String.format("WRITE FILE: SCP: %s, content-length=%d \n", remoteFilePath, content.length()));
|
||||
streamLogger.logMessage("WRITE FILE: SCP: %s, content-length=%d \n".formatted(remoteFilePath, content.length()));
|
||||
try {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
/*Collection<PosixFilePermission> permissions = isExecutable
|
||||
@ -819,7 +819,7 @@ public class SshClientInstaller implements ClientInstallerPlugin {
|
||||
contents = StringSubstitutor.replace(contents, valueMap);
|
||||
log.trace("SshClientInstaller: Task #{}: FILE: {}, final-content:\n{}", taskCounter, targetFile, contents);
|
||||
|
||||
String description = String.format("Copy file from server to temp to client: %s -> %s", sourcePath.toString(), targetFile);
|
||||
String description = "Copy file from server to temp to client: %s -> %s".formatted(sourcePath.toString(), targetFile);
|
||||
|
||||
return sshFileWrite(contents, targetFile, isExecutable);
|
||||
}
|
@ -156,8 +156,7 @@ public class SshJsClientInstaller extends SshClientInstaller {
|
||||
log.error("SshJsClientInstaller: Task #{}: JS installation script returned NULL: {}", getTaskCounter(), jsScript);
|
||||
return INSTRUCTION_RESULT.FAIL;
|
||||
}
|
||||
if (result instanceof Integer) {
|
||||
int code = (int)result;
|
||||
if (result instanceof Integer code) {
|
||||
log.info("SshJsClientInstaller: Task #{}: JS installation script returned: code={}, script: {}", getTaskCounter(), code, jsScript);
|
||||
return code==0 ? INSTRUCTION_RESULT.SUCCESS : INSTRUCTION_RESULT.FAIL;
|
||||
} else {
|
@ -9,6 +9,7 @@
|
||||
|
||||
package gr.iccs.imu.ems.baguette.client.install.api;
|
||||
|
||||
import gr.iccs.imu.ems.baguette.server.NodeRegistryEntry;
|
||||
import gr.iccs.imu.ems.translate.TranslationContext;
|
||||
|
||||
import java.util.Map;
|
||||
@ -16,4 +17,7 @@ import java.util.Map;
|
||||
public interface INodeRegistration {
|
||||
String registerNode(String baseUrl, Map<String,Object> nodeInfo, TranslationContext translationContext) throws Exception;
|
||||
String unregisterNode(String nodeAddress, TranslationContext translationContext) throws Exception;
|
||||
String reinstallNode(String ipAddress, TranslationContext translationContext) throws Exception;
|
||||
NodeRegistryEntry requestNodeDetails(String nodeAddress) throws Exception;
|
||||
void requestInfo() throws Exception;
|
||||
}
|
@ -281,7 +281,8 @@ public abstract class AbstractInstallationHelper implements InitializingBean, Ap
|
||||
contents = StringSubstitutor.replace(contents, valueMap);
|
||||
String tmpFile = clientTmpDir+"/installEMS_"+System.currentTimeMillis();
|
||||
instructionsSet
|
||||
.appendLog(String.format("Copy file from server to temp to client: %s -> %s -> %s", p.toString(), tmpFile, targetFile));
|
||||
.appendLog("Copy file from server to temp to client: %s -> %s -> %s"
|
||||
.formatted(p.toString(), tmpFile, targetFile));
|
||||
return _appendCopyInstructions(instructionsSet, targetFile, tmpFile, contents, clientTmpDir);
|
||||
}
|
||||
|
@ -33,5 +33,6 @@ public interface InstallationHelper {
|
||||
return createClientInstallationTask(entry, null);
|
||||
}
|
||||
ClientInstallationTask createClientInstallationTask(NodeRegistryEntry entry, TranslationContext translationContext) throws Exception;
|
||||
ClientInstallationTask createClientReinstallTask(NodeRegistryEntry entry, TranslationContext translationContext) throws Exception;
|
||||
ClientInstallationTask createClientUninstallTask(NodeRegistryEntry entry, TranslationContext translationContext) throws Exception;
|
||||
}
|
@ -68,6 +68,15 @@ public class VmInstallationHelper extends AbstractInstallationHelper {
|
||||
return createClientTask(ClientInstallationTask.TASK_TYPE.INSTALL, entry, translationContext, instructionsSetList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientInstallationTask createClientReinstallTask(NodeRegistryEntry entry, TranslationContext translationContext) throws IOException {
|
||||
// Get EMS client reinstall instructions for VM node
|
||||
List<InstructionsSet> instructionsSetList =
|
||||
prepareInstallationInstructionsForOs(entry);
|
||||
|
||||
return createClientTask(ClientInstallationTask.TASK_TYPE.REINSTALL, entry, translationContext, instructionsSetList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientInstallationTask createClientUninstallTask(NodeRegistryEntry entry, TranslationContext translationContext) throws Exception {
|
||||
// Clear any cached 'instruction-files' override (from a previous run)
|
||||
@ -358,7 +367,7 @@ public class VmInstallationHelper extends AbstractInstallationHelper {
|
||||
targetFile = remoteTargetDir + targetFile;
|
||||
String contents = new String(Files.readAllBytes(path));
|
||||
contents = StringSubstitutor.replace(contents, valueMap);
|
||||
String description = String.format("Copy file from server to temp to client: %s -> %s", path.toString(), targetFile);
|
||||
String description = "Copy file from server to temp to client: %s -> %s".formatted(path.toString(), targetFile);
|
||||
return _appendCopyInstructions(instructionsSet, targetFile, description, contents);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -59,8 +59,8 @@ public class InstructionsService implements EnvironmentAware {
|
||||
log.trace("InstructionsService: checkCondition: Expression result: {}", result);
|
||||
if (result==null)
|
||||
throw new IllegalArgumentException("Condition evaluation returned null: " + condition);
|
||||
if (result instanceof Boolean)
|
||||
return (Boolean)result;
|
||||
if (result instanceof Boolean booleanValue)
|
||||
return booleanValue;
|
||||
throw new IllegalArgumentException("Condition evaluation returned a non-boolean value: " + result + ", condition: " + condition+", resolved condition: "+ conditionResolved);
|
||||
}
|
||||
|
@ -52,22 +52,15 @@ public class AllowedTopicsProcessorPlugin implements InstallationContextProcesso
|
||||
addedTopicsSet.add(metricName);
|
||||
}
|
||||
|
||||
// Get sensor configuration (as a list of KeyValuePair's)
|
||||
Map<String,String> sensorConfig = null;
|
||||
if (monitor.getSensor().isPullSensor()) {
|
||||
// Pull Sensor
|
||||
sensorConfig = monitor.getSensor().pullSensor().getConfiguration();
|
||||
} else {
|
||||
// Push Sensor
|
||||
sensorConfig = monitor.getSensor().pushSensor().getAdditionalProperties();
|
||||
}
|
||||
// Get sensor configuration
|
||||
Map<String,Object> sensorConfig = monitor.getSensor().getConfiguration();;
|
||||
|
||||
// Process Destination aliases, if specified in configuration
|
||||
if (sensorConfig!=null) {
|
||||
String k = sensorConfig.keySet().stream()
|
||||
.filter(key -> StrUtil.compareNormalized(key, EmsConstant.COLLECTOR_DESTINATION_ALIASES))
|
||||
.findAny().orElse(null);
|
||||
String aliases = (k!=null) ? sensorConfig.get(k) : null;
|
||||
String aliases = (k!=null && sensorConfig.get(k) instanceof String) ? sensorConfig.get(k).toString() : null;
|
||||
|
||||
if (StringUtils.isNotBlank(aliases)) {
|
||||
for (String alias : aliases.trim().split(EmsConstant.COLLECTOR_DESTINATION_ALIASES_DELIMITERS)) {
|
@ -62,7 +62,8 @@ public class PrometheusProcessorPlugin implements InstallationContextProcessorPl
|
||||
log.trace("PrometheusProcessorPlugin: Task #{}: MONITOR: component={}, metric={}", taskCounter, componentName, metricName);
|
||||
if (monitor.getSensor().isPullSensor()) {
|
||||
if (monitor.getSensor().pullSensor().getConfiguration()!=null) {
|
||||
Map<String, String> config = monitor.getSensor().pullSensor().getConfiguration();
|
||||
Map<String, String> config = StrUtil.deepFlattenMap(
|
||||
monitor.getSensor().getConfiguration());
|
||||
log.trace("PrometheusProcessorPlugin: Task #{}: MONITOR with PULL SENSOR: config: {}", taskCounter, config);
|
||||
|
||||
// Get Prometheus related settings
|
@ -654,6 +654,8 @@ public class CommandExecutor {
|
||||
log.info("Cluster: configuration:\n{}", clusterManagerProperties);
|
||||
} else if ("GET-STATS".equals(cmd)) {
|
||||
getStatistics(args[1]);
|
||||
} else if ("COLLECT-STATS".equals(cmd)) {
|
||||
collectStatistics();
|
||||
} else if ("SEND-STATS".equals(cmd)) {
|
||||
if (args.length < 2) {
|
||||
log.warn("Too few arguments");
|
||||
@ -1260,6 +1262,29 @@ public class CommandExecutor {
|
||||
if (out!=null) out.println("-INPUT:"+inputUuid+":"+SerializationUtil.serializeToString(statsMap));
|
||||
}
|
||||
|
||||
private void collectStatistics() {
|
||||
try {
|
||||
// Run system metrics collection script
|
||||
log.debug("Running system metrics collection...");
|
||||
boolean result = systemResourceMonitor.runImmediatelyBlocking(-1); // >=0: timeout in millis; <0: wait forever
|
||||
log.debug("Running system metrics collection... {}", result ? "done" : "cancel/timeout");
|
||||
|
||||
// Collect metrics
|
||||
Map<String, Object> statsMap = brokerCepService.getBrokerCepStatistics();
|
||||
log.debug("BCEP Statistics: {}", statsMap);
|
||||
Map<String, Object> sysMap = systemResourceMonitor.getLatestMeasurements();
|
||||
log.debug("System Statistics: {}", sysMap);
|
||||
|
||||
// Prepare and send response
|
||||
Map<String, Object> clientStats = new HashMap<>();
|
||||
if (statsMap!=null) clientStats.putAll(statsMap);
|
||||
if (sysMap!=null) clientStats.putAll(sysMap);
|
||||
if (out!=null) out.println("-STATS:" + SerializationUtil.serializeToString(statsMap));
|
||||
} catch (Exception ex) {
|
||||
log.error("Exception while getting Statistics to server: ", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void sendStatisticsStart() {
|
||||
statsSendTask = taskScheduler.scheduleWithFixedDelay(() -> {
|
@ -75,7 +75,7 @@ public class TestCallback extends AbstractLogBase implements BrokerUtil.NodeCall
|
||||
}
|
||||
|
||||
public String getConfiguration(Member local) {
|
||||
return String.format("ssl://%s:61617", local.address().host());
|
||||
return "ssl://%s:61617".formatted(local.address().host());
|
||||
}
|
||||
|
||||
public void setConfiguration(String newConfig) {
|
@ -50,19 +50,8 @@ public class NetdataCollector extends gr.iccs.imu.ems.common.collector.netdata.N
|
||||
if (grp!=null)
|
||||
topics.addAll(grp.getEventTypeNames());
|
||||
}
|
||||
log.warn("Collectors::Netdata: activeGroupingChanged: New Allowed Topics for active grouping: {} -- {}", newGrouping, topics);
|
||||
List<String> tmpList = new ArrayList<>(topics);
|
||||
Map<String,String> tmpMap = null;
|
||||
if (properties.getAllowedTopics()!=null) {
|
||||
tmpMap = properties.getAllowedTopics().stream()
|
||||
.map(s -> s.split(":", 2))
|
||||
.collect(Collectors.toMap(a -> a[0], a -> a.length>1 ? a[1]: ""));
|
||||
}
|
||||
log.warn("Collectors::Netdata: activeGroupingChanged: New Allowed Topics -- Topics Map: {} -- {}", tmpList, tmpMap);
|
||||
synchronized (this) {
|
||||
this.allowedTopics = tmpList;
|
||||
this.topicMap = tmpMap;
|
||||
}
|
||||
log.info("Collectors::Netdata: activeGroupingChanged: New Allowed Topics for active grouping: {} -- {}", newGrouping, topics);
|
||||
processAllowedTopics(topics);
|
||||
}
|
||||
|
||||
}
|
@ -50,19 +50,8 @@ public class PrometheusCollector extends gr.iccs.imu.ems.common.collector.promet
|
||||
if (grp!=null)
|
||||
topics.addAll(grp.getEventTypeNames());
|
||||
}
|
||||
log.warn("Collectors::Prometheus: activeGroupingChanged: New Allowed Topics for active grouping: {} -- {}", newGrouping, topics);
|
||||
List<String> tmpList = new ArrayList<>(topics);
|
||||
Map<String,String> tmpMap = null;
|
||||
if (properties.getAllowedTopics()!=null) {
|
||||
tmpMap = properties.getAllowedTopics().stream()
|
||||
.map(s -> s.split(":", 2))
|
||||
.collect(Collectors.toMap(a -> a[0], a -> a.length>1 ? a[1]: ""));
|
||||
}
|
||||
log.warn("Collectors::Prometheus: activeGroupingChanged: New Allowed Topics -- Topics Map: {} -- {}", tmpList, tmpMap);
|
||||
synchronized (this) {
|
||||
this.allowedTopics = tmpList;
|
||||
this.topicMap = tmpMap;
|
||||
}
|
||||
log.info("Collectors::Prometheus: activeGroupingChanged: New Allowed Topics for active grouping: {} -- {}", newGrouping, topics);
|
||||
processAllowedTopics(topics);
|
||||
}
|
||||
|
||||
}
|
@ -137,9 +137,8 @@ public class SelfHealingPlugin implements Plugin, InitializingBean, EventBus.Eve
|
||||
|
||||
private void processClusterNodeRemovedEvent(Object message) {
|
||||
log.debug("SelfHealingPlugin: processClusterNodeRemovedEvent(): BEGIN: message={}", message);
|
||||
if (message instanceof ClusterMembershipEvent) {
|
||||
if (message instanceof ClusterMembershipEvent event) {
|
||||
// Get removed node id and address
|
||||
ClusterMembershipEvent event = (ClusterMembershipEvent)message;
|
||||
String nodeId = event.subject().id().id();
|
||||
String nodeAddress = event.subject().address().host();
|
||||
log.debug("SelfHealingPlugin: processClusterNodeRemovedEvent(): node-id={}, node-address={}", nodeId, nodeAddress);
|
||||
@ -156,9 +155,8 @@ public class SelfHealingPlugin implements Plugin, InitializingBean, EventBus.Eve
|
||||
|
||||
private void processClusterNodeAddedEvent(Object message) {
|
||||
log.debug("SelfHealingPlugin: processClusterNodeAddedEvent(): BEGIN: message={}", message);
|
||||
if (message instanceof ClusterMembershipEvent) {
|
||||
if (message instanceof ClusterMembershipEvent event) {
|
||||
// Get added node id and address
|
||||
ClusterMembershipEvent event = (ClusterMembershipEvent)message;
|
||||
String nodeId = event.subject().id().id();
|
||||
String nodeAddress = event.subject().address().host();
|
||||
log.debug("SelfHealingPlugin: processClusterNodeAddedEvent(): node-id={}, node-address={}", nodeId, nodeAddress);
|
@ -77,15 +77,14 @@
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>2.0.1.Final</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache Commons Text (for StringSubstitutor) -->
|
||||
@ -98,7 +97,7 @@
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.core</groupId>
|
||||
<artifactId>jersey-common</artifactId>
|
||||
<version>3.1.3</version>
|
||||
<version>3.1.4</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
@ -376,7 +376,7 @@ public class BaguetteServer implements InitializingBean, EventBus.EventConsumer<
|
||||
})
|
||||
.sorted(Comparator.comparing(m -> m.get("id")))
|
||||
.collect(Collectors.toMap(m -> m.get("id"), m -> m,
|
||||
(u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); },
|
||||
(u,v) -> { throw new IllegalStateException("Duplicate key %s".formatted(u)); },
|
||||
LinkedHashMap::new));
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ import org.apache.sshd.server.session.ServerSessionAware;
|
||||
import org.cryptacular.util.CertUtil;
|
||||
import org.slf4j.event.Level;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import java.io.*;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -115,7 +115,7 @@ public class ClientShellCommand implements Command, Runnable, ServerSessionAware
|
||||
|
||||
public ClientShellCommand(ServerCoordinator coordinator, boolean allowClientOverrideItsAddress, EventBus<String,Object,Object> eventBus, NodeRegistry registry) {
|
||||
synchronized (LOCK) {
|
||||
id = String.format("#%05d", counter.getAndIncrement());
|
||||
id = "#%05d".formatted(counter.getAndIncrement());
|
||||
}
|
||||
this.coordinator = coordinator;
|
||||
this.clientAddressOverrideAllowed = allowClientOverrideItsAddress;
|
||||
@ -688,8 +688,9 @@ public class ClientShellCommand implements Command, Runnable, ServerSessionAware
|
||||
log.debug("sendGroupingConfiguration: id={}, grouping={}, grouping-config={}", id, grouping, gc);
|
||||
try {
|
||||
String allStr = serializeToString(gc);
|
||||
log.info("sendGroupingConfiguration: Serialization of Grouping configuration for {}: {}", grouping, allStr);
|
||||
sendToClient("SET-GROUPING-CONFIG " + allStr);
|
||||
log.debug("sendGroupingConfiguration: Serialization of Grouping configuration for {}: {}", grouping, allStr);
|
||||
sendToClient("SET-GROUPING-CONFIG " + allStr, Level.DEBUG);
|
||||
log.info("sendGroupingConfiguration: Sent grouping configuration for {}", grouping);
|
||||
} catch (IOException ex) {
|
||||
log.error("sendGroupingConfiguration: Exception while serializing Grouping configuration: ", ex);
|
||||
log.error("sendGroupingConfiguration: SET-GROUPING-CONFIG command *NOT* sent to client");
|
@ -95,8 +95,8 @@ public class NodeRegistryEntry {
|
||||
|
||||
private void _canUpdateEntry(@NonNull STATE newState) {
|
||||
if (! canChangeStateTo(newState)) {
|
||||
throw new IllegalStateException(String.format("Cannot change NodeRegistryEntry state from %s to %s: client-id=%s, client-address=%s",
|
||||
state, newState, clientId, ipAddress));
|
||||
throw new IllegalStateException("Cannot change NodeRegistryEntry state from %s to %s: client-id=%s, client-address=%s"
|
||||
.formatted(state, newState, clientId, ipAddress));
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ public class NodeRegistryEntry {
|
||||
_canUpdateEntry(newState);
|
||||
if (clear) map.clear();
|
||||
map.put(key, val!=null ? val.toString() : defVal);
|
||||
setState(STATE.IGNORE_NODE);
|
||||
setState(newState);
|
||||
return this;
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ public class Sshd {
|
||||
Thread.sleep(period);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
String msg = String.format("Heartbeat %d", System.currentTimeMillis());
|
||||
String msg = "Heartbeat %d".formatted(System.currentTimeMillis());
|
||||
log.debug("--> Heartbeat: {}", msg);
|
||||
for (ClientShellCommand csc : ClientShellCommand.getActive()) {
|
||||
csc.sendToClient(msg, Level.DEBUG);
|
@ -86,11 +86,11 @@ public class NoopCoordinator implements ServerCoordinator {
|
||||
protected boolean _logInvocation(String methodName, Object o, boolean checkStarted) {
|
||||
String className = getClass().getSimpleName();
|
||||
String str = (o==null) ? "" : (
|
||||
o instanceof ClientShellCommand ? String.format(". CSC: %s", o) : (
|
||||
o instanceof NodeRegistryEntry ? String.format(". NRE: %s", o) :
|
||||
String.format(". Object: %s", o)
|
||||
)
|
||||
);
|
||||
o instanceof ClientShellCommand
|
||||
? ". CSC: %s".formatted(o)
|
||||
: (o instanceof NodeRegistryEntry
|
||||
? ". NRE: %s".formatted(o)
|
||||
: ". Object: %s".formatted(o)) );
|
||||
if (checkStarted && !started) {
|
||||
log.warn("{}: {}(): Coordinator has not been started{}", className, methodName, str);
|
||||
} else
|
@ -144,8 +144,8 @@ public class ServerCoordinatorTimeWin implements ServerCoordinator {
|
||||
int brokerPort = broker.getClientPort();
|
||||
if (brokerIpAddress == null || brokerIpAddress.trim().isEmpty() || brokerPort <= 0)
|
||||
throw new Exception("ServerCoordinatorTimeWin: startPhase1(): Unable to get broker IP address or Port: " + broker);
|
||||
this.brokerCfgIpAddressCmd = String.format("SET-PARAM bin/broker.cfg-template BROKER_IP_ADDR %s bin/broker.cfg", brokerIpAddress);
|
||||
this.brokerCfgPortCmd = String.format("SET-PARAM bin/broker.cfg-template BROKER_PORT %d bin/broker.cfg", brokerPort);
|
||||
this.brokerCfgIpAddressCmd = "SET-PARAM bin/broker.cfg-template BROKER_IP_ADDR %s bin/broker.cfg".formatted(brokerIpAddress);
|
||||
this.brokerCfgPortCmd = "SET-PARAM bin/broker.cfg-template BROKER_PORT %d bin/broker.cfg".formatted(brokerPort);
|
||||
} catch (Exception ex) {
|
||||
this.brokerCfgIpAddressCmd = null;
|
||||
this.brokerCfgPortCmd = null;
|
@ -20,7 +20,7 @@ import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bouncycastle.operator.OperatorCreationException;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyStoreException;
|
@ -22,6 +22,7 @@ import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.text.StringSubstitutor;
|
||||
import org.slf4j.event.Level;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@ -383,9 +384,10 @@ public class ClusteringCoordinator extends NoopCoordinator {
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
void sendClusterKey(ClientShellCommand csc, IClusterZone zoneInfo) {
|
||||
csc.sendCommand(String.format("CLUSTER-KEY %s %s %s %s",
|
||||
csc.sendCommand("CLUSTER-KEY %s %s %s %s".formatted(
|
||||
zoneInfo.getClusterKeystoreFile().getName(), zoneInfo.getClusterKeystoreType(),
|
||||
zoneInfo.getClusterKeystorePassword(), zoneInfo.getClusterKeystoreBase64()));
|
||||
zoneInfo.getClusterKeystorePassword(), zoneInfo.getClusterKeystoreBase64()), Level.DEBUG);
|
||||
log.info("sendClusterKey: Sent cluster key to node {}", csc.getClientIpAddress());
|
||||
}
|
||||
|
||||
void sendCommandToZone(String command, List<ClientShellCommand> zoneNodes) {
|
@ -19,8 +19,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user