Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,84 +1,91 @@
package io.mosip.registration.processor.stages.executor;

import io.mosip.kernel.core.exception.ExceptionUtils;
import io.mosip.kernel.core.logger.spi.Logger;
import io.mosip.registration.processor.core.abstractverticle.MosipVerticleAPIManager;
import io.mosip.registration.processor.core.logger.RegProcessorLogger;
import io.mosip.registration.processor.stages.executor.config.StagesConfig;
import io.mosip.registration.processor.stages.executor.util.StageClassesUtil;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.MutablePropertySources;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.LogManager;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import io.mosip.registration.processor.core.logger.RegProcessorLogger;
import io.mosip.kernel.core.logger.spi.Logger;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.MutablePropertySources;

import io.mosip.kernel.core.exception.ExceptionUtils;
import io.mosip.registration.processor.core.abstractverticle.MosipVerticleAPIManager;

import io.mosip.registration.processor.stages.executor.config.StagesConfig;
import io.mosip.registration.processor.stages.executor.util.StageClassesUtil;

/**
* The Class MosipStageExecutorApplication.
*/
public class MosipStageExecutorApplication {

/** The Constant regProcLogger. */
private static final Logger regProcLogger = RegProcessorLogger.getLogger(MosipStageExecutorApplication.class);

/**
* main method to launch external stage application.
*
* @param args the arguments
*/
public static void main(String[] args) {
regProcLogger.info("Starting mosip-stage-executor...");
//This context is closed after deploying the stages
try (AnnotationConfigApplicationContext stageInfoApplicationContext = new AnnotationConfigApplicationContext(
new Class<?>[] { StagesConfig.class });) {
StagesConfig stagesConfig = stageInfoApplicationContext.getBean(StagesConfig.class);
MutablePropertySources propertySources = stagesConfig.getCloudPropertySources();

List<String> stageBeansBasePackages = StageClassesUtil.getStageBeansBasePackages(stagesConfig, propertySources);

if(!stageBeansBasePackages.isEmpty()) {

regProcLogger.info("Base packages for stage beans from configuration: {}", stageBeansBasePackages);

List<Class<MosipVerticleAPIManager>> stageClasses = StageClassesUtil.getStageBeanClasses(stageBeansBasePackages);

regProcLogger.info("Stage classes identified: {}", stageClasses.stream().map(Class::getCanonicalName).collect(Collectors.joining(", ")));

Class<?>[] entrypointConfigClasses = Stream.concat(Stream.of(StagesConfig.class), stageClasses.stream())
.toArray(size -> new Class<?>[size]);

//This context should not be closed and to be kept for consumption by the verticles
AnnotationConfigApplicationContext mainApplicationContext = new PropertySourcesCustomizingApplicationContext(
entrypointConfigClasses) {
@Override
public MutablePropertySources getPropertySources() {
return propertySources;
};
};

if (!stageClasses.isEmpty()) {
ExecutorService executorService = Executors.newFixedThreadPool(stageClasses.size());
stageClasses.forEach(stageClass -> executorService.execute(() -> {
try {
regProcLogger.info("Executing Stage: {}", stageClass.getCanonicalName());
MosipVerticleAPIManager stageBean = StageClassesUtil.getStageBean(mainApplicationContext, stageClass);
stageBean.deployVerticle();
} catch (Exception e) {
regProcLogger.error("Exception occured while loading verticles. Please make sure correct verticle name was passed from deployment script. \n {}",
ExceptionUtils.getStackTrace(e));
}
}));
executorService.close();
} else {
regProcLogger.error("No stage class is found. Please make sure correct correct stage class base packages are specified in properties and stages are added to classpath/dependencies.");
}
} else {
regProcLogger.error("No base packages configured for stages.");
}
}
}
/**
* The Constant regProcLogger.
*/
Comment on lines +25 to +27

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why these unnecessary changes are there ?

private static final Logger regProcLogger = RegProcessorLogger.getLogger(MosipStageExecutorApplication.class);

/**
* main method to launch external stage application.
*
* @param args the arguments
*/
public static void main(String[] args) {
LogManager.getLogManager().reset();
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
Comment on lines +36 to +38

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Why we need to explicitly install the JUL --> SLF4J bride. How it is different as compared to other apps such as packet manager etc. Why we are not able to see these different format there?

regProcLogger.info("Starting mosip-stage-executor...");
//This context is closed after deploying the stages
try (AnnotationConfigApplicationContext stageInfoApplicationContext = new AnnotationConfigApplicationContext(
new Class<?>[]{StagesConfig.class});) {
StagesConfig stagesConfig = stageInfoApplicationContext.getBean(StagesConfig.class);
MutablePropertySources propertySources = stagesConfig.getCloudPropertySources();

List<String> stageBeansBasePackages = StageClassesUtil.getStageBeansBasePackages(stagesConfig, propertySources);

if (!stageBeansBasePackages.isEmpty()) {

regProcLogger.info("Base packages for stage beans from configuration: {}", stageBeansBasePackages);

List<Class<MosipVerticleAPIManager>> stageClasses = StageClassesUtil.getStageBeanClasses(stageBeansBasePackages);

regProcLogger.info("Stage classes identified: {}", stageClasses.stream().map(Class::getCanonicalName).collect(Collectors.joining(", ")));

Class<?>[] entrypointConfigClasses = Stream.concat(Stream.of(StagesConfig.class), stageClasses.stream())
.toArray(size -> new Class<?>[size]);

//This context should not be closed and to be kept for consumption by the verticles
AnnotationConfigApplicationContext mainApplicationContext = new PropertySourcesCustomizingApplicationContext(
entrypointConfigClasses) {
@Override
public MutablePropertySources getPropertySources() {
return propertySources;
}

;
};

if (!stageClasses.isEmpty()) {
ExecutorService executorService = Executors.newFixedThreadPool(stageClasses.size());
stageClasses.forEach(stageClass -> executorService.execute(() -> {
try {
regProcLogger.info("Executing Stage: {}", stageClass.getCanonicalName());
MosipVerticleAPIManager stageBean = StageClassesUtil.getStageBean(mainApplicationContext, stageClass);
stageBean.deployVerticle();
} catch (Exception e) {
regProcLogger.error("Exception occured while loading verticles. Please make sure correct verticle name was passed from deployment script. \n {}",
ExceptionUtils.getStackTrace(e));
}
}));
executorService.close();
} else {
regProcLogger.error("No stage class is found. Please make sure correct correct stage class base packages are specified in properties and stages are added to classpath/dependencies.");
}
} else {
regProcLogger.error("No base packages configured for stages.");
}
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we need change in this file. We need to need JUL to SLF4J bridge to be installed before other loggers gets initialized.

Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
<configuration>
<springProperty scope="context" name="appName" source="spring.application.name"/>

<!-- Default logs: JSON structured -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<includeMdcKeyName>traceId</includeMdcKeyName>
<includeMdcKeyName>spanId</includeMdcKeyName>
<includeMdcKeyName>parentId</includeMdcKeyName>
</encoder>
</appender>

<!-- Brave logs: print raw JSON as-is -->
<appender name="BRAVE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<!-- Send Brave span logs only to BRAVE -->
<logger name="brave.Tracing$LogSpanHandler" level="INFO" additivity="false">
<appender-ref ref="BRAVE"/>
</logger>
<!-- Optional: keep Tracer clean -->
<logger name="brave.Tracer" level="INFO" additivity="false">
<appender-ref ref="BRAVE"/>
</logger>
<!-- Root app logs -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="STDOUT"/>
</root>
</configuration>