Skip to content

Commit

Permalink
Feature2.4.11 (#283)
Browse files Browse the repository at this point in the history
* BootHttpFileUploadHandler<T>.T onFileUploaded() accepts return object T

* enhanced email alert and logging

* enhanced email alert and logging

* updated dependencies

* fixed log file name issue

* refactoring

* migrate to jjwt 0.12

* repleace Glassfish EL impl with Tomcat Embed EL; refactoring

* version 2.5.0

* refactoring

* refactor gRPC status logging

* refactoring grpc client

* wip

* wip

* refactoring

* enhanced GRPC client config

* enhanced GRPC client config

* enhanced GRPC client config

* release
  • Loading branch information
SummerBootFramework authored Sep 4, 2024
1 parent d68cd3e commit af6cab1
Show file tree
Hide file tree
Showing 23 changed files with 851 additions and 491 deletions.
63 changes: 35 additions & 28 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.summerboot</groupId>
<artifactId>jexpress</artifactId>
<version>2.4.10</version>
<version>2.4.11</version>
<packaging>jar</packaging>
<name>Summer Boot jExpress</name>
<description>Summer Boot jExpress focuses on solving non-functional and operational maintainability requirements,
Expand Down Expand Up @@ -190,8 +190,8 @@
<maven.resources.version>3.3.1</maven.resources.version>
<maven-surefire.version>3.2.5</maven-surefire.version>
<!-- Commons -->
<commons-lang3.version>3.15.0</commons-lang3.version>
<commons-cli.version>1.8.0</commons-cli.version>
<commons-lang3.version>3.17.0</commons-lang3.version>
<commons-cli.version>1.9.0</commons-cli.version>
<commons-io.version>2.16.1</commons-io.version>
<!-- <commons-text.version>1.11.0</commons-text.version>-->
<!-- <owasp.encoder.version>1.2.3</owasp.encoder.version>-->
Expand All @@ -203,15 +203,15 @@
<!-- Security -->
<bouncycastle.version>1.78.1</bouncycastle.version>
<!-- JWT -->
<jwt.version>0.11.5</jwt.version>
<jwt.version>0.12.6</jwt.version>

<!-- NIO Netty -->
<netty.version>4.1.112.Final</netty.version>
<netty-tcnative.version>2.0.65.Final</netty-tcnative.version>
<netty-tcnative.version>2.0.66.Final</netty-tcnative.version>
<!-- gRPC and protobuf -->
<grpc.version>1.65.1</grpc.version>
<guava.version>33.2.1-jre</guava.version>
<protobuf.version>4.27.3</protobuf.version>
<grpc.version>1.66.0</grpc.version>
<guava.version>33.3.0-jre</guava.version>
<protobuf.version>4.28.0</protobuf.version>
<!-- Web JAX-RS -->
<swagger.core.version>2.2.22</swagger.core.version>
<!--<elastic-apm.version>1.36.0</elastic-apm.version>-->
Expand All @@ -227,18 +227,19 @@
<!-- JSON/XML/Bean Validation -->
<jackson.version>2.17.2</jackson.version>
<!-- Bean Validation -->
<hibernate-validator.version>8.0.1.Final</hibernate-validator.version>
<jakarta.el.version>6.0.1</jakarta.el.version>
<tomcat-embed-el.version>11.0.0-M24</tomcat-embed-el.version>
<hibernate-validator.version>8.0.1.Final</hibernate-validator.version>

<!-- IOC Injection -->
<guice.version>7.0.0</guice.version>

<!-- JPA -->
<hibernate.version>6.5.2.Final</hibernate.version>
<hibernate.version>6.6.0.Final</hibernate.version>
<hikari-cp.version>5.1.0</hikari-cp.version>

<!-- Cache -->
<jedis.version>5.1.4</jedis.version>
<jedis.version>5.1.5</jedis.version>

<quartz.version>2.5.0-rc1</quartz.version>
<mqtt.version>1.2.5</mqtt.version>
Expand All @@ -263,12 +264,6 @@

<dependencies>
<!-- Commons -->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 Apache 2.0-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli Apache 2.0-->
<dependency>
<groupId>commons-cli</groupId>
Expand All @@ -282,6 +277,12 @@
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 Apache 2.0-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-text -->
<!-- <dependency>
<groupId>org.apache.commons</groupId>
Expand Down Expand Up @@ -540,23 +541,29 @@


<!-- Bean Validation -->
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<!-- https://mvnrepository.com/artifact/jakarta.el/jakarta.el-api -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
<version>${jakarta.el.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish/jakarta.el -->
<!-- <dependency>-->
<!-- <groupId>org.glassfish</groupId>-->
<!-- <artifactId>jakarta.el</artifactId>-->
<!-- <version>4.0.2</version>-->
<!-- </dependency>-->
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-el -->
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.el</artifactId>
<version>4.0.2</version>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>${tomcat-embed-el.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jakarta.el/jakarta.el-api -->
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
<version>${jakarta.el.version}</version>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public interface BootConstant {
String APP_ID = String.format("%06d", new Random().nextInt(999999));

//version
String VERSION = "SummerBoot.jExpress 2.4.10";
String VERSION = "jExpress 2.4.11";
String JEXPRESS_PACKAGE_NAME = "org.summerboot.jexpress";

String DEFAULT_ADMIN_MM = "changeit";
Expand Down
16 changes: 12 additions & 4 deletions src/main/java/org/summerboot/jexpress/boot/BootGuiceModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.quartz.Scheduler;
import org.summerboot.jexpress.boot.annotation.Controller;
import org.summerboot.jexpress.boot.annotation.Inspector;
import org.summerboot.jexpress.boot.annotation.Service;
import org.summerboot.jexpress.boot.event.AppLifecycleHandler;
import org.summerboot.jexpress.boot.event.AppLifecycleListener;
import org.summerboot.jexpress.boot.event.HttpExceptionHandler;
Expand Down Expand Up @@ -76,7 +77,7 @@ public BootGuiceModule(Object caller, Class callerClass, Set<String> userSpecifi
this.memo = memo;
}

protected boolean isCliUseImplTag(String implTag) {
protected boolean isTagSpecifiedViaCLI(String implTag) {
return userSpecifiedImplTags != null && userSpecifiedImplTags.contains(implTag);
}

Expand Down Expand Up @@ -171,13 +172,20 @@ protected void scanAnnotation_BindInstance(Binder binder, Class<? extends Annota
if (Modifier.isAbstract(mod) || Modifier.isInterface(mod)) {
continue;
}
String implTag = null;
if (a instanceof Controller) {
Controller ca = (Controller) a;
String implTag = ca.implTag();
if (StringUtils.isNotBlank(implTag) && !isCliUseImplTag(implTag)) {
continue;
implTag = ca.implTag();
} else if (a instanceof Inspector) {
Service sa = (Service) c.getAnnotation(Service.class);
if (sa != null) {
implTag = sa.implTag();
}
}
// no tag = always use this controller, with tag = only use this controller when -use <tag> specified
if (StringUtils.isNotBlank(implTag) && !isTagSpecifiedViaCLI(implTag)) {
continue;
}
classesAll.add(c);
}
//}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public ScanedGuiceModule(Map<Class, Map<String, List<SummerSingularity.ServiceMe
this.memo = memo;
}

protected boolean isCliUseImplTag(String implTag) {
protected boolean isTagSpecifiedViaCLI(String implTag) {
return userSpecifiedImplTags.contains(implTag);
}

Expand All @@ -72,7 +72,7 @@ public void configure() {
continue;
}
String implTag = serviceImpl.getImplTag();
boolean isCliUseImplTag = isCliUseImplTag(implTag);
boolean isCliUseImplTag = isTagSpecifiedViaCLI(implTag);
memo.append(INFO_FOUND).append(interfaceClass.getName()).append(", implTag=").append(uniqueKey).append(BIND_TO).append(serviceImpl).append(", isCliUseImplTag=").append(isCliUseImplTag);

String named = serviceImpl.getNamed();
Expand Down
57 changes: 49 additions & 8 deletions src/main/java/org/summerboot/jexpress/boot/SummerApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
import io.grpc.ServerInterceptor;
import io.grpc.ServerServiceDefinition;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.filter.LevelRangeFilter;
import org.quartz.SchedulerException;
import org.summerboot.jexpress.boot.config.ConfigUtil;
import org.summerboot.jexpress.boot.event.AppLifecycleListener;
Expand All @@ -40,9 +45,11 @@
import org.summerboot.jexpress.nio.server.NioServer;
import org.summerboot.jexpress.util.ApplicationUtil;

import java.io.File;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* In Code We Trust
Expand Down Expand Up @@ -282,12 +289,13 @@ public void start() {
log.info(() -> sb.toString());
}

long timeoutMs = BackOffice.agent.getProcessTimeoutMilliseconds();
String timeoutDesc = BackOffice.agent.getProcessTimeoutAlertMessage();
// 4. health inspection
log.trace("4. health inspection");
String serviceStatus = HealthMonitor.start(true);
String serviceStatus = HealthMonitor.start(true, guiceInjector);

long timeoutMs = BackOffice.agent.getProcessTimeoutMilliseconds();
String timeoutDesc = BackOffice.agent.getProcessTimeoutAlertMessage();
StringBuilder startingMemo = new StringBuilder();
// 5a. start server: gRPC
if (hasGRPCImpl) {
log.trace("5a. start server: gRPC hasGRPCImpl.bs={}", gRPCBindableServiceImplClasses);
Expand Down Expand Up @@ -316,7 +324,7 @@ public void start() {
serverBuilder.addService(impl);
}
if (gRPCCfg.isAutoStart()) {
gRPCServer.start();
gRPCServer.start(startingMemo);
}
gRPCServerList.add(gRPCServer);
}
Expand All @@ -330,14 +338,16 @@ public void start() {
NioChannelInitializer channelInitializer = super.guiceInjector.getInstance(NioChannelInitializer.class);
NIOStatusListener nioListener = super.guiceInjector.getInstance(NIOStatusListener.class);
httpServer = new NioServer(channelInitializer.init(guiceInjector, channelHandlerNames), nioListener);
httpServer.bind(NioConfig.cfg);
httpServer.bind(NioConfig.cfg, startingMemo);
}
}

// 6. announcement
startingMemo.append(BootConstant.BR).append(serviceStatus);
startingMemo.append(BootConstant.BR).append("pid#" + BootConstant.PID);
log.info(() -> BootConstant.BR + BootConstant.BR + I18n.info.launched.format(userSpecifiedResourceBundle, appVersion + " pid#" + BootConstant.PID) + serviceStatus);
if (appLifecycleListener != null) {
appLifecycleListener.onApplicationStart(super.appVersion, serviceStatus);
appLifecycleListener.onApplicationStart(super.appVersion, startingMemo.toString());
}
} catch (java.net.BindException ex) {// from NioServer
log.fatal(ex + BootConstant.BR + BackOffice.agent.getPortInUseAlertMessage());
Expand All @@ -350,11 +360,42 @@ public void start() {
log.fatal(I18n.info.unlaunched.format(userSpecifiedResourceBundle), ex);
}
System.exit(1);
} finally {
// show prompt only with default log4j2.xml in case user is not familiar with log4j2.xml (only one ConsoleAppender with maxLevel is NOT "ALL"), no prompt if user modify the default log4j2.xml due to user knows what he/she is doing
String prompt = null;
try {
org.apache.logging.log4j.core.Logger c = (org.apache.logging.log4j.core.Logger) log;
Map<String, Appender> as = c.getContext().getConfiguration().getAppenders();
int countConsoleAppender = 0;
for (Map.Entry<String, Appender> entry : as.entrySet()) {
Appender appender = entry.getValue();
if (appender instanceof ConsoleAppender) {
countConsoleAppender++;
if (countConsoleAppender > 1) {
prompt = null;
break;
}
ConsoleAppender sa = (ConsoleAppender) appender;
Filter f = sa.getFilter();
if (f instanceof LevelRangeFilter) {
LevelRangeFilter lrf = (LevelRangeFilter) f;
Level maxLevel = lrf.getMaxLevel();
if (!Level.ALL.equals(maxLevel)) {
prompt = "\nTo show logs in console, please edit " + this.userSpecifiedConfigDir + File.separator
+ "log4j2.xml \n\t<Configuration ...>\n\t <Appenders>\n\t <Console name=\"" + sa.getName() + "\" target=\"" + sa.getTarget() + "\">\n\t <LevelRangeFilter maxLevel=\"" + maxLevel + "\"/>\n\tchange around line#13: set maxLevel=\"" + Level.ALL + "\"";
}
}
}
}
} catch (Throwable ex) {
log.error("Failed to inspect " + this.userSpecifiedConfigDir + File.separator + "log4j2.xml", ex);
}
if (prompt != null) {
System.out.println(prompt);
}
}
}

protected static boolean a = true;

public void shutdown() {
log.trace("");
if (gRPCServerList != null && !gRPCServerList.isEmpty()) {
Expand Down
16 changes: 13 additions & 3 deletions src/main/java/org/summerboot/jexpress/boot/SummerBigBang.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
import com.google.inject.Module;
import com.google.inject.Stage;
import com.google.inject.util.Modules;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.MacAlgorithm;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
Expand Down Expand Up @@ -310,8 +311,17 @@ protected boolean runCLI_Utils() {
// generate CLI_JWT root signing key
if (cli.hasOption(BootConstant.CLI_JWT)) {
continueCLI = false;
String algorithm = cli.getOptionValue(BootConstant.CLI_JWT);
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.forName(algorithm);
String algorithm = cli.getOptionValue(BootConstant.CLI_JWT);// <HS256, HS384, HS512>
MacAlgorithm signatureAlgorithm;
switch (algorithm) {
case "HS256" -> signatureAlgorithm = Jwts.SIG.HS256;
case "HS384" -> signatureAlgorithm = Jwts.SIG.HS384;
case "HS512" -> signatureAlgorithm = Jwts.SIG.HS512;
default -> {
System.out.println("invalid -" + BootConstant.CLI_JWT + " value: " + algorithm + ", valid -" + BootConstant.CLI_JWT + " values: <HS256, HS384, HS512>");
return false;
}
}
String jwt = JwtUtil.buildSigningKey(signatureAlgorithm);
System.out.println(jwt);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
import com.google.inject.Singleton;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.summerboot.jexpress.boot.BootConstant;
import org.summerboot.jexpress.boot.config.JExpressConfig;
import org.summerboot.jexpress.boot.instrumentation.HealthMonitor;
import org.summerboot.jexpress.integration.smtp.PostOffice;
import org.summerboot.jexpress.integration.smtp.SMTPClientConfig;

import java.io.File;
import java.time.OffsetDateTime;

/**
* @author Changski Tie Zheng Zhang 张铁铮, 魏泽北, 杜旺财, 杜富贵
Expand All @@ -41,15 +41,15 @@ public class AppLifecycleHandler implements AppLifecycleListener {
@Override
public void onApplicationStart(String appVersion, String fullConfigInfo) {
if (postOffice != null) {
postOffice.sendAlertAsync(SMTPClientConfig.cfg.getEmailToAppSupport(), "Started at " + OffsetDateTime.now(), fullConfigInfo, null, false);
postOffice.sendAlertAsync(SMTPClientConfig.cfg.getEmailToAppSupport(), "Started", fullConfigInfo, null, false);
}
}

@Override
public void onApplicationStop(String appVersion) {
log.info(appVersion);
log.warn(appVersion);
if (postOffice != null) {
postOffice.sendAlertSync(SMTPClientConfig.cfg.getEmailToAppSupport(), "Shutdown at " + OffsetDateTime.now() + " - " + appVersion, "EOM", null, false);
postOffice.sendAlertSync(SMTPClientConfig.cfg.getEmailToAppSupport(), "Shutdown", "pid#" + BootConstant.PID, null, false);
}
}

Expand All @@ -68,7 +68,7 @@ public void onApplicationStatusUpdated(boolean healthOk, boolean paused, boolean
boolean serviceAvaliable = healthOk && !paused;
String content = HealthMonitor.buildMessage();
if (postOffice != null) {
postOffice.sendAlertAsync(SMTPClientConfig.cfg.getEmailToAppSupport(), "Service Status Changed at " + OffsetDateTime.now(), content, null, false);
postOffice.sendAlertAsync(SMTPClientConfig.cfg.getEmailToAppSupport(), "Service Status Changed", content, null, false);
}
}
}
Expand Down
Loading

0 comments on commit af6cab1

Please sign in to comment.