|
|
|
@ -2,7 +2,7 @@
|
|
|
|
|
* ~~~~~~licensing~~~~~~
|
|
|
|
|
* platform-manager-core
|
|
|
|
|
* ==========
|
|
|
|
|
* Copyright (C) 2020 - 2023 EmDev LLC
|
|
|
|
|
* Copyright (C) 2020 - 2024 EmDev LLC
|
|
|
|
|
* ==========
|
|
|
|
|
* You may not use this file except in accordance with the License Terms of the Copyright
|
|
|
|
|
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
|
|
|
@ -28,28 +28,26 @@ package ru.entaxy.platform.manager.impl;
|
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.io.PrintStream;
|
|
|
|
|
import java.nio.charset.Charset;
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.function.Function;
|
|
|
|
|
|
|
|
|
|
import org.apache.felix.hc.api.Result;
|
|
|
|
|
import org.apache.felix.hc.api.Result.Status;
|
|
|
|
|
import org.apache.felix.hc.api.execution.HealthCheckExecutionOptions;
|
|
|
|
|
import org.apache.felix.hc.api.execution.HealthCheckExecutionResult;
|
|
|
|
|
import org.apache.felix.hc.api.execution.HealthCheckExecutor;
|
|
|
|
|
import org.apache.felix.hc.api.execution.HealthCheckSelector;
|
|
|
|
|
import org.apache.karaf.features.BootFinished;
|
|
|
|
|
import org.apache.karaf.shell.api.console.Session;
|
|
|
|
|
import org.apache.karaf.shell.api.console.SessionFactory;
|
|
|
|
|
import org.apache.karaf.shell.support.ansi.SimpleAnsi;
|
|
|
|
|
import org.apache.karaf.shell.support.table.ShellTable;
|
|
|
|
|
import org.osgi.framework.BundleContext;
|
|
|
|
|
import org.osgi.framework.Constants;
|
|
|
|
|
import org.osgi.framework.FrameworkEvent;
|
|
|
|
|
import org.osgi.framework.FrameworkListener;
|
|
|
|
|
import org.osgi.framework.startlevel.FrameworkStartLevel;
|
|
|
|
|
import org.osgi.service.component.ComponentContext;
|
|
|
|
|
import org.osgi.service.component.annotations.Activate;
|
|
|
|
|
import org.osgi.service.component.annotations.Component;
|
|
|
|
|
import org.osgi.service.component.annotations.Reference;
|
|
|
|
|
import org.osgi.service.component.annotations.ReferenceCardinality;
|
|
|
|
|
import org.osgi.service.component.annotations.ReferencePolicy;
|
|
|
|
|
import org.osgi.service.component.annotations.ReferencePolicyOption;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
@ -58,96 +56,132 @@ import ru.entaxy.platform.manager.EntaxyPlatformManager;
|
|
|
|
|
import ru.entaxy.platform.manager.shell.Utils;
|
|
|
|
|
|
|
|
|
|
@Component(service = EntaxyPlatformManager.class, immediate = true)
|
|
|
|
|
public class EntaxyPlatformManagerImpl implements EntaxyPlatformManager {
|
|
|
|
|
public class EntaxyPlatformManagerImpl implements EntaxyPlatformManager, FrameworkListener {
|
|
|
|
|
|
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(EntaxyPlatformManagerImpl.class);
|
|
|
|
|
|
|
|
|
|
@Reference(cardinality = ReferenceCardinality.MANDATORY, policyOption = ReferencePolicyOption.GREEDY)
|
|
|
|
|
BootFinished bootFinished;
|
|
|
|
|
|
|
|
|
|
@Reference(cardinality = ReferenceCardinality.MANDATORY, policyOption = ReferencePolicyOption.GREEDY)
|
|
|
|
|
HealthCheckExecutor healthCheckExecutor;
|
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(EntaxyPlatformManagerImpl.class);
|
|
|
|
|
|
|
|
|
|
@Reference(cardinality = ReferenceCardinality.MANDATORY, policyOption = ReferencePolicyOption.GREEDY)
|
|
|
|
|
SessionFactory sessionFactory;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Activate
|
|
|
|
|
public void activate(ComponentContext componentContext) {
|
|
|
|
|
Thread thread = new Thread(new Runnable() {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
|
|
|
|
|
doOutput();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
thread.setContextClassLoader(Thread.currentThread().getContextClassLoader());
|
|
|
|
|
thread.run();
|
|
|
|
|
// doOutput();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void doOutput() {
|
|
|
|
|
System.out.println("\n\t******************");
|
|
|
|
|
System.out.println("\t* " + Utils.WLC + SimpleAnsi.INTENSITY_BOLD + "Entaxy started " + Utils.NOR + SimpleAnsi.INTENSITY_NORMAL + "*");
|
|
|
|
|
System.out.println("\t******************\n\n");
|
|
|
|
|
// @Reference(cardinality = ReferenceCardinality.MANDATORY, policyOption =
|
|
|
|
|
// ReferencePolicyOption.GREEDY)
|
|
|
|
|
// BootFinished bootFinished;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
try ( final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
|
|
|
final PrintStream printStream = new PrintStream(byteArrayOutputStream);
|
|
|
|
|
) {
|
|
|
|
|
Session session = sessionFactory.create(System.in, printStream, System.err);
|
|
|
|
|
session.execute("bundle:list");
|
|
|
|
|
System.out.println(byteArrayOutputStream.toString());
|
|
|
|
|
System.out.println("================");
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
log.error("ERROR:", e);
|
|
|
|
|
}
|
|
|
|
|
HealthCheckExecutionOptions options = new HealthCheckExecutionOptions();
|
|
|
|
|
options.setCombineTagsWithOr(true);
|
|
|
|
|
options.setForceInstantExecution(true);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
Thread.sleep(500);
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
// NOOP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HealthCheckSelector selector = HealthCheckSelector.tags(new String[] {""});
|
|
|
|
|
|
|
|
|
|
Collection<HealthCheckExecutionResult> results = healthCheckExecutor.execute(selector);//, options);
|
|
|
|
|
|
|
|
|
|
printHealthCheckResults(results);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void printHealthCheckResults(Collection<HealthCheckExecutionResult> results) {
|
|
|
|
|
|
|
|
|
|
System.out.println("Overall HealthCheck status: " + Utils.colored(Utils.getOverallStatus(results)));
|
|
|
|
|
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PrintStream printStream = new PrintStream(outputStream)) {
|
|
|
|
|
@Reference(cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC,
|
|
|
|
|
policyOption = ReferencePolicyOption.GREEDY)
|
|
|
|
|
volatile HealthCheckExecutor healthCheckExecutor;
|
|
|
|
|
|
|
|
|
|
ShellTable table = Utils.createTable(results);
|
|
|
|
|
|
|
|
|
|
table.print(printStream, StandardCharsets.ISO_8859_1, true);
|
|
|
|
|
System.out.println(outputStream.toString());
|
|
|
|
|
|
|
|
|
|
System.out.println("\n\t ***" + SimpleAnsi.INTENSITY_BOLD + "NOTICE" + SimpleAnsi.INTENSITY_NORMAL + "***");
|
|
|
|
|
System.out.println("Some bundles may start slowly");
|
|
|
|
|
System.out.println("\tUse " + SimpleAnsi.COLOR_BLUE + SimpleAnsi.INTENSITY_BOLD
|
|
|
|
|
+ "entaxy:platform-health" + SimpleAnsi.RESET + SimpleAnsi.INTENSITY_NORMAL
|
|
|
|
|
+ " command to check platform health");
|
|
|
|
|
System.out.println("\tUse " + SimpleAnsi.COLOR_BLUE + SimpleAnsi.INTENSITY_BOLD
|
|
|
|
|
+ "entaxy:inactive" + SimpleAnsi.RESET + SimpleAnsi.INTENSITY_NORMAL
|
|
|
|
|
+ " command to view inactive bundles");
|
|
|
|
|
System.out.println();
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
// NOOP
|
|
|
|
|
}
|
|
|
|
|
@Reference(cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC,
|
|
|
|
|
policyOption = ReferencePolicyOption.GREEDY)
|
|
|
|
|
volatile SessionFactory sessionFactory;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected BundleContext bundleContext;
|
|
|
|
|
|
|
|
|
|
protected static EntaxyPlatformManagerImpl registeredInstance;
|
|
|
|
|
|
|
|
|
|
@Activate
|
|
|
|
|
public void activate(ComponentContext componentContext) {
|
|
|
|
|
this.bundleContext = componentContext.getBundleContext();
|
|
|
|
|
if (registeredInstance != null)
|
|
|
|
|
this.bundleContext.removeFrameworkListener(registeredInstance);
|
|
|
|
|
registeredInstance = this;
|
|
|
|
|
this.bundleContext.addFrameworkListener(registeredInstance);
|
|
|
|
|
if (checkStartLevel())
|
|
|
|
|
executeInitialHealthcheckPrinting();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void frameworkEvent(FrameworkEvent event) {
|
|
|
|
|
|
|
|
|
|
// not fired, may be a bug
|
|
|
|
|
if (event.getType() == FrameworkEvent.STARTED) {
|
|
|
|
|
executeInitialHealthcheckPrinting();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// define startup event via startLevel change
|
|
|
|
|
if (event.getType() == FrameworkEvent.STARTLEVEL_CHANGED) {
|
|
|
|
|
if (checkStartLevel())
|
|
|
|
|
executeInitialHealthcheckPrinting();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected boolean checkStartLevel() {
|
|
|
|
|
int defStartLevel = Integer.parseInt(System
|
|
|
|
|
.getProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL));
|
|
|
|
|
int startLevel = bundleContext.getBundle(0)
|
|
|
|
|
.adapt(FrameworkStartLevel.class).getStartLevel();
|
|
|
|
|
return startLevel >= defStartLevel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void executeInitialHealthcheckPrinting() {
|
|
|
|
|
Thread thread = new Thread(new Runnable() {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
|
|
|
|
|
doOutput();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
thread.setContextClassLoader(Thread.currentThread().getContextClassLoader());
|
|
|
|
|
thread.run();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void doOutput() {
|
|
|
|
|
System.out.println("\n\t******************");
|
|
|
|
|
System.out.println("\t* " + Utils.WLC + SimpleAnsi.INTENSITY_BOLD + "Entaxy started " + Utils.NOR
|
|
|
|
|
+ SimpleAnsi.INTENSITY_NORMAL + "*");
|
|
|
|
|
System.out.println("\t******************\n\n");
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* try ( final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
|
|
|
* final PrintStream printStream = new PrintStream(byteArrayOutputStream); ) { Session
|
|
|
|
|
* session = sessionFactory.create(System.in, printStream, System.err);
|
|
|
|
|
* session.execute("bundle:list"); System.out.println(byteArrayOutputStream.toString());
|
|
|
|
|
* System.out.println("================"); } catch (Exception e) { e.printStackTrace();
|
|
|
|
|
* log.error("ERROR:", e); } HealthCheckExecutionOptions options = new
|
|
|
|
|
* HealthCheckExecutionOptions(); options.setCombineTagsWithOr(true);
|
|
|
|
|
* options.setForceInstantExecution(true);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
Thread.sleep(500);
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
// NOOP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HealthCheckSelector selector = HealthCheckSelector.tags(new String[] {""});
|
|
|
|
|
|
|
|
|
|
Collection<HealthCheckExecutionResult> results = healthCheckExecutor.execute(selector);// ,
|
|
|
|
|
// options);
|
|
|
|
|
|
|
|
|
|
printHealthCheckResults(results);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void printHealthCheckResults(Collection<HealthCheckExecutionResult> results) {
|
|
|
|
|
|
|
|
|
|
System.out.println("Overall HealthCheck status: " + Utils.colored(Utils.getOverallStatus(results)));
|
|
|
|
|
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
|
|
|
PrintStream printStream = new PrintStream(outputStream)) {
|
|
|
|
|
|
|
|
|
|
ShellTable table = Utils.createTable(results);
|
|
|
|
|
|
|
|
|
|
table.print(printStream, StandardCharsets.ISO_8859_1, true);
|
|
|
|
|
System.out.println(outputStream.toString());
|
|
|
|
|
|
|
|
|
|
System.out.println("\n\t ***" + SimpleAnsi.INTENSITY_BOLD + "NOTICE" + SimpleAnsi.INTENSITY_NORMAL + "***");
|
|
|
|
|
System.out.println("Some bundles may start slowly");
|
|
|
|
|
System.out.println("\tUse " + SimpleAnsi.COLOR_BLUE + SimpleAnsi.INTENSITY_BOLD
|
|
|
|
|
+ "entaxy:platform-health" + SimpleAnsi.RESET + SimpleAnsi.INTENSITY_NORMAL
|
|
|
|
|
+ " command to check platform health");
|
|
|
|
|
System.out.println("\tUse " + SimpleAnsi.COLOR_BLUE + SimpleAnsi.INTENSITY_BOLD
|
|
|
|
|
+ "entaxy:inactive" + SimpleAnsi.RESET + SimpleAnsi.INTENSITY_NORMAL
|
|
|
|
|
+ " command to view inactive bundles");
|
|
|
|
|
System.out.println();
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
// NOOP
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|