com.sitewhere.microservice.MicroserviceApplication Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sitewhere-microservice Show documentation
Show all versions of sitewhere-microservice Show documentation
SiteWhere Microservice Components Library
The newest version!
/**
* Copyright © 2014-2021 The SiteWhere Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sitewhere.microservice;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import javax.enterprise.event.Observes;
import com.sitewhere.microservice.lifecycle.LifecycleProgressContext;
import com.sitewhere.microservice.lifecycle.LifecycleProgressMonitor;
import com.sitewhere.microservice.util.Boilerplate;
import com.sitewhere.spi.SiteWhereException;
import com.sitewhere.spi.microservice.IFunctionIdentifier;
import com.sitewhere.spi.microservice.IMicroservice;
import com.sitewhere.spi.microservice.IMicroserviceApplication;
import com.sitewhere.spi.microservice.IMicroserviceConfiguration;
import com.sitewhere.spi.microservice.lifecycle.LifecycleStatus;
import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;
/**
* Base class for SiteWhere microservice application lifecycle.
*/
public abstract class MicroserviceApplication>
implements IMicroserviceApplication {
/** Executor for background thread */
private ExecutorService executor = Executors.newSingleThreadExecutor(new MicroserviceThreadFactory());
/**
* Called to initialize and start microservice components.
*/
void onStart(@Observes StartupEvent ev) {
getMicroservice().getLogger().info("Starting microservice...");
try {
// Set up resources outside of normal lifecycle.
getMicroservice().install();
Future starting = executor.submit(new StartMicroservice());
starting.get();
getMicroservice().getLogger().info("Microservice startup completed.");
} catch (InterruptedException | ExecutionException e) {
getMicroservice().getLogger().info("Exiting due to interrupted startup.", e);
System.exit(1);
} catch (SiteWhereException e) {
getMicroservice().getLogger().info("Exiting due to exception on install.", e);
System.exit(1);
}
}
/**
* Called to shutdown and terminate microservice components.
*/
void onStop(@Observes ShutdownEvent ev) {
getMicroservice().getLogger().info("Shutdown signal received. Stopping microservice...");
Future stopping = executor.submit(new StopMicroservice());
try {
stopping.get();
// Clean up resources outside of normal lifecycle.
getMicroservice().uninstall();
getMicroservice().getLogger().info("Microservice shutdown complete.");
} catch (InterruptedException | ExecutionException e) {
getMicroservice().getLogger().info("Exiting due to interrupted shutdown.");
System.exit(1);
} catch (SiteWhereException e) {
getMicroservice().getLogger().info("Exiting due to exception on uninstall.", e);
System.exit(1);
}
}
/**
* Start a microservice.
*
* @param microservice
* @param showBanner
* @throws SiteWhereException
*/
public static void startMicroservice(IMicroservice, ?> microservice, boolean showBanner)
throws SiteWhereException {
long start = System.currentTimeMillis();
// Adds banner to the top of the log.
String banner = showBanner ? getBanner(microservice) : "";
String microserviceVersion = String.format("%s.%s (%s)", microservice.getVersion().getVersionIdentifier(),
microservice.getVersion().getGitRevisionAbbrev(), microservice.getVersion().getBuildTimestamp());
String corelibVersion = String.format("%s.%s (%s)",
microservice.getMicroserviceLibraryVersion().getVersionIdentifier(),
microservice.getMicroserviceLibraryVersion().getGitRevisionAbbrev(),
microservice.getMicroserviceLibraryVersion().getBuildTimestamp());
// Display banner indicating service information.
List messages = new ArrayList();
messages.add(microservice.getName() + " Microservice");
messages.add("Microservice Version: " + microserviceVersion);
messages.add("Core Library Version: " + corelibVersion);
messages.add("");
messages.add("Git Revision: " + microservice.getVersion().getGitRevision());
messages.add("Build Date: " + microservice.getVersion().getBuildTimestamp());
messages.add("Hostname: " + microservice.getHostname());
String message = Boilerplate.boilerplate(messages, "*");
microservice.getLogger().info(String.format("\n%s\n%s\n", banner, message));
// Initialize microservice.
LifecycleProgressMonitor initMonitor = new LifecycleProgressMonitor(
new LifecycleProgressContext(1, "Initialize " + microservice.getName()), microservice);
microservice.lifecycleInitialize(initMonitor);
if (microservice.getLifecycleStatus() == LifecycleStatus.InitializationError) {
microservice.getLogger().info("Error initializing microservice.", microservice.getLifecycleError());
throw microservice.getLifecycleError();
}
// Start microservice.
LifecycleProgressMonitor startMonitor = new LifecycleProgressMonitor(
new LifecycleProgressContext(1, "Start " + microservice.getName()), microservice);
microservice.lifecycleStart(startMonitor);
if (microservice.getLifecycleStatus() == LifecycleStatus.LifecycleError) {
microservice.getLogger().info("Error starting microservice.", microservice.getLifecycleError());
throw microservice.getLifecycleError();
}
long total = System.currentTimeMillis() - start;
messages.clear();
messages.add(microservice.getName() + " Microservice");
messages.add("Startup time: " + total + "ms");
message = Boilerplate.boilerplate(messages, "*");
microservice.getLogger().info("\n" + message + "\n");
// Execute any post-startup code.
microservice.afterMicroserviceStarted();
}
/**
* Runnable for starting microservice.
*/
private class StartMicroservice implements Callable {
/*
* @see java.util.concurrent.Callable#call()
*/
@Override
public Void call() throws Exception {
try {
MicroserviceApplication.startMicroservice(getMicroservice(), true);
} catch (SiteWhereException e) {
getMicroservice().getLogger().error("Exception on microservice startup.", e);
StringBuilder builder = new StringBuilder();
builder.append("\n!!!! Microservice failed to start !!!!\n");
builder.append("\n");
builder.append("Error: " + e.getMessage() + "\n");
getMicroservice().getLogger().info("\n" + builder.toString() + "\n");
System.exit(2);
} catch (Throwable e) {
getMicroservice().getLogger().error("Unhandled exception in microservice startup.", e);
StringBuilder builder = new StringBuilder();
builder.append("\n!!!! Unhandled Exception !!!!\n");
builder.append("\n");
builder.append("Error: " + e.getMessage() + "\n");
getMicroservice().getLogger().info("\n" + builder.toString() + "\n");
System.exit(3);
}
return null;
}
}
/**
* Stop microservice.
*
* @param microservice
* @throws SiteWhereException
*/
public static void stopMicroservice(IMicroservice, ?> microservice) throws SiteWhereException {
// Stop microservice.
LifecycleProgressMonitor stopMonitor = new LifecycleProgressMonitor(
new LifecycleProgressContext(1, "Stop " + microservice.getName()), microservice);
microservice.lifecycleStop(stopMonitor);
if (microservice.getLifecycleStatus() == LifecycleStatus.LifecycleError) {
throw microservice.getLifecycleError();
}
// Terminate microservice.
LifecycleProgressMonitor termMonitor = new LifecycleProgressMonitor(
new LifecycleProgressContext(1, "Terminate " + microservice.getName()), microservice);
microservice.lifecycleTerminate(termMonitor);
if (microservice.getLifecycleStatus() == LifecycleStatus.LifecycleError) {
throw microservice.getLifecycleError();
}
}
/**
* Stop the microservice.
*/
private class StopMicroservice implements Callable {
/*
* @see java.util.concurrent.Callable#call()
*/
@Override
public Void call() throws Exception {
try {
MicroserviceApplication.stopMicroservice(getMicroservice());
} catch (SiteWhereException e) {
getMicroservice().getLogger().error("Exception on microservice shutdown.", e);
StringBuilder builder = new StringBuilder();
builder.append("\n!!!! Microservice failed to stop !!!!\n");
builder.append("\n");
builder.append("Error: " + e.getMessage() + "\n");
getMicroservice().getLogger().info("\n" + builder.toString() + "\n");
System.exit(2);
} catch (Throwable e) {
getMicroservice().getLogger().error("Unhandled exception in microservice shutdown.", e);
StringBuilder builder = new StringBuilder();
builder.append("\n!!!! Unhandled Exception !!!!\n");
builder.append("\n");
builder.append("Error: " + e.getMessage() + "\n");
getMicroservice().getLogger().info("\n" + builder.toString() + "\n");
System.exit(3);
}
return null;
}
}
/**
* Get banner content from file.
*
* @param microservice
* @return
*/
protected static String getBanner(IMicroservice, ?> microservice) {
InputStream banner = microservice.getClass().getResourceAsStream("/banner.txt");
if (banner != null) {
StringBuilder builder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(banner))) {
String line = reader.readLine();
while (line != null) {
builder.append(line).append("\n");
line = reader.readLine();
}
return builder.toString();
} catch (IOException e) {
microservice.getLogger().warn("Unable to read banner.");
}
} else {
microservice.getLogger().warn("No banner file found.");
}
return "";
}
/** Used for naming primary microservice thread */
private class MicroserviceThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
return new Thread(r, "Service Main");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy