Health extension implemented
This commit is contained in:
parent
98c41e7463
commit
b873f97187
6
pom.xml
6
pom.xml
|
@ -38,9 +38,9 @@
|
|||
</scm>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.reflections</groupId>
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>0.9.10</version>
|
||||
<groupId>io.github.classgraph</groupId>
|
||||
<artifactId>classgraph</artifactId>
|
||||
<version>4.8.28</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
|
|
|
@ -82,5 +82,5 @@ public interface ApplicationContext {
|
|||
* @return the AuhtorizationProvider
|
||||
**/
|
||||
AuthorizationProvider authorizationProvider();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import org.gcube.common.events.Hub;
|
|||
import org.gcube.smartgears.configuration.application.ApplicationConfiguration;
|
||||
import org.gcube.smartgears.context.Properties;
|
||||
import org.gcube.smartgears.context.container.ContainerContext;
|
||||
import org.gcube.smartgears.health.HealthManager;
|
||||
import org.gcube.smartgears.lifecycle.application.ApplicationLifecycle;
|
||||
import org.gcube.smartgears.persistence.PersistenceWriter;
|
||||
import org.gcube.smartgears.security.AuthorizationProvider;
|
||||
|
@ -42,7 +43,7 @@ public class DefaultApplicationContext implements ApplicationContext {
|
|||
this.configuration=configuration;
|
||||
this.hub=hub;
|
||||
this.lifecycle = lifecycle;
|
||||
this.properties=properties;
|
||||
this.properties=properties;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,6 +107,6 @@ public class DefaultApplicationContext implements ApplicationContext {
|
|||
**/
|
||||
public AuthorizationProvider authorizationProvider() {
|
||||
return container().authorizationProvider();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,4 +51,5 @@ public interface ContainerContext {
|
|||
|
||||
|
||||
AuthorizationProvider authorizationProvider();
|
||||
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public abstract class ApiResource extends HttpExtension {
|
|||
public Set<Exclude> excludes() {
|
||||
return Collections.singleton(new Exclude(Constants.root_mapping+mapping()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this resource supports a given method.
|
||||
* @param method the method
|
||||
|
|
|
@ -22,6 +22,8 @@ public interface ApplicationExtension extends Servlet {
|
|||
*/
|
||||
void init(ApplicationContext context) throws Exception;
|
||||
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* Returns the name of this extension.
|
||||
* @return the name
|
||||
|
|
|
@ -76,6 +76,9 @@ public abstract class HttpExtension extends HttpServlet implements ApplicationEx
|
|||
this.context=context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {}
|
||||
|
||||
@Override
|
||||
public Set<Exclude> excludes() {
|
||||
return new HashSet<Exclude>(); //all managed by default
|
||||
|
|
|
@ -4,41 +4,108 @@ import static org.gcube.smartgears.Constants.application_json;
|
|||
import static org.gcube.smartgears.extensions.HttpExtension.Method.GET;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.gcube.common.health.api.response.HealthResponse;
|
||||
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.gcube.common.health.api.HealthCheck;
|
||||
import org.gcube.common.health.api.ReadinessChecker;
|
||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||
import org.gcube.smartgears.extensions.ApiResource;
|
||||
import org.gcube.smartgears.extensions.ApiSignature;
|
||||
import org.gcube.smartgears.handlers.application.request.RequestError;
|
||||
import org.gcube.smartgears.health.HealthManager;
|
||||
import org.gcube.smartgears.health.HealthResponse;
|
||||
import org.gcube.smartgears.health.HealthTask;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.github.classgraph.ClassGraph;
|
||||
import io.github.classgraph.ClassInfo;
|
||||
import io.github.classgraph.ClassInfoList;
|
||||
import io.github.classgraph.ScanResult;
|
||||
|
||||
public class HealthResource extends ApiResource {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(HealthResource.class);
|
||||
|
||||
public static final String mapping = "/health";
|
||||
|
||||
private static final ApiSignature signature = handles(mapping).with(method(GET).produces(application_json));
|
||||
|
||||
|
||||
private HealthManager manager;
|
||||
|
||||
private HealthTask task;
|
||||
|
||||
private Timer timer;
|
||||
|
||||
HealthResource() {
|
||||
super(signature);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
public void init(ApplicationContext context) throws Exception {
|
||||
Set<Class<?>> annotatedReadiness;
|
||||
|
||||
try (ScanResult result = new ClassGraph().enableClassInfo().enableAnnotationInfo().scan()) {
|
||||
|
||||
ClassInfoList classInfos = result.getClassesWithAnnotation(ReadinessChecker.class.getName());
|
||||
|
||||
annotatedReadiness = classInfos.stream().map(ClassInfo::loadClass)
|
||||
.filter(c -> HealthCheck.class.isAssignableFrom(c)).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
manager = new HealthManager();
|
||||
for (Class<?> readnessClass : annotatedReadiness)
|
||||
try {
|
||||
manager.register((HealthCheck) readnessClass.getDeclaredConstructor().newInstance());
|
||||
log.info("added class {} to health manager", readnessClass.getCanonicalName());
|
||||
} catch (Throwable e) {
|
||||
log.error("healthChecher class {} cannot be instantiated", readnessClass.getCanonicalName(), e);
|
||||
}
|
||||
|
||||
task = new HealthTask(manager);
|
||||
|
||||
timer = new Timer(true);
|
||||
|
||||
timer.scheduleAtFixedRate(task, 0, 10000);
|
||||
|
||||
super.init(context);
|
||||
}
|
||||
|
||||
|
||||
public HealthResponse liveness() {
|
||||
return null;
|
||||
public void stop() {
|
||||
timer.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
PrintWriter out = resp.getWriter();
|
||||
resp.setContentType("application/json");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
Object response = null;
|
||||
|
||||
String contextpath = req.getContextPath();
|
||||
log.info("context path is {}", req.getContextPath());
|
||||
if (contextpath.endsWith("/readiness"))
|
||||
response = readiness();
|
||||
else
|
||||
RequestError.resource_notfound_error.fire();
|
||||
|
||||
new ObjectMapper().writeValue(out, response);
|
||||
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public HealthResponse readiness() {
|
||||
return null;
|
||||
return task.getResponse();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package org.gcube.smartgears.health;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.common.health.api.HealthCheck;
|
||||
|
||||
public class HealthManager {
|
||||
|
||||
private List<HealthCheck> checks;
|
||||
|
||||
public void register(HealthCheck check){
|
||||
checks.add(check);
|
||||
}
|
||||
|
||||
public List<HealthCheck> getChecks() {
|
||||
return checks;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package org.gcube.smartgears.health;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import org.gcube.com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import org.gcube.common.health.api.Status;
|
||||
import org.gcube.common.health.api.response.HealthCheckResponse;
|
||||
import org.gcube.common.validator.annotations.NotNull;
|
||||
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
public class HealthResponse {
|
||||
|
||||
@NotNull
|
||||
private Status status;
|
||||
|
||||
private List<HealthCheckResponse> checks;
|
||||
|
||||
|
||||
|
||||
public HealthResponse(Status status, List<HealthCheckResponse> checks) {
|
||||
super();
|
||||
this.status = status;
|
||||
this.checks = checks;
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public List<HealthCheckResponse> getChecks() {
|
||||
return checks;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package org.gcube.smartgears.health;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.TimerTask;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.gcube.common.health.api.HealthCheck;
|
||||
import org.gcube.common.health.api.Status;
|
||||
import org.gcube.common.health.api.response.HealthCheckResponse;
|
||||
|
||||
public class HealthTask extends TimerTask{
|
||||
|
||||
private HealthResponse response;
|
||||
|
||||
private HealthManager healthManager;
|
||||
|
||||
public HealthTask(HealthManager healthManager) {
|
||||
this.healthManager = healthManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<HealthCheck> checks = healthManager.getChecks();
|
||||
|
||||
List<HealthCheckResponse> responses = checks.stream().map(c -> this.wrap(c)).collect(Collectors.toList());
|
||||
Status totalStatus = responses.stream().anyMatch(r -> r.getStatus().equals(Status.DOWN)) ? Status.DOWN : Status.UP;
|
||||
|
||||
this.response = new HealthResponse(totalStatus, responses);
|
||||
}
|
||||
|
||||
public HealthResponse getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
private HealthCheckResponse wrap(HealthCheck check){
|
||||
try {
|
||||
return check.check();
|
||||
}catch (Throwable t) {
|
||||
return HealthCheckResponse.builder(check.getName()).down().withMessage("unexpected error executing check").build();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -12,6 +12,10 @@ public class KeyCloakHealthCheck implements HealthCheck{
|
|||
|
||||
private static final String CHECK_NAME = "authorization-check" ;
|
||||
|
||||
public String getName(){
|
||||
return CHECK_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthCheckResponse check() {
|
||||
try {
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.io.File;
|
|||
import java.io.FileOutputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
@ -52,6 +53,8 @@ public class ApplicationManager {
|
|||
|
||||
private ApplicationContext context;
|
||||
|
||||
private ApplicationExtensions extensions;
|
||||
|
||||
/**
|
||||
* Starts application management.
|
||||
*
|
||||
|
@ -80,7 +83,7 @@ public class ApplicationManager {
|
|||
|
||||
ApplicationHandlers handlers = provider().handlersFor(context);
|
||||
|
||||
ApplicationExtensions extensions = provider().extensionsFor(context);
|
||||
extensions = provider().extensionsFor(context);
|
||||
extensions.validate();
|
||||
|
||||
List<ApplicationLifecycleHandler> lifecycleHandlers = handlers.lifecycleHandlers();
|
||||
|
@ -150,7 +153,10 @@ public class ApplicationManager {
|
|||
context.lifecycle().tryMoveTo(stopped);
|
||||
|
||||
context.events().fire(context, ApplicationLifecycle.stop);
|
||||
|
||||
|
||||
if (extensions != null)
|
||||
unregister(extensions);
|
||||
|
||||
stopLifecycleHandlers();
|
||||
|
||||
log.info("stopping application events for {}", context.name());
|
||||
|
@ -227,6 +233,15 @@ public class ApplicationManager {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
private void unregister(ApplicationExtensions extensions) {
|
||||
|
||||
for (ApplicationExtension extension : extensions.extensions())
|
||||
|
||||
extension.stop();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void start(List<ApplicationLifecycleHandler> handlers) {
|
||||
|
||||
|
|
|
@ -14,12 +14,11 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
|
@ -48,14 +47,14 @@ import org.gcube.smartgears.publishing.SmartgearsProfilePublisher;
|
|||
import org.gcube.smartgears.security.AuthorizationProvider;
|
||||
import org.gcube.smartgears.security.AuthorizationProviderFactory;
|
||||
import org.gcube.smartgears.utils.Utils;
|
||||
import org.reflections.Reflections;
|
||||
import org.reflections.scanners.SubTypesScanner;
|
||||
import org.reflections.scanners.TypeAnnotationsScanner;
|
||||
import org.reflections.util.ClasspathHelper;
|
||||
import org.reflections.util.ConfigurationBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.github.classgraph.ClassGraph;
|
||||
import io.github.classgraph.ClassInfo;
|
||||
import io.github.classgraph.ClassInfoList;
|
||||
import io.github.classgraph.ScanResult;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link Provider} interface.
|
||||
*
|
||||
|
@ -67,8 +66,7 @@ public class DefaultProvider implements Provider {
|
|||
private static Logger log = LoggerFactory.getLogger(Provider.class);
|
||||
|
||||
private ContainerContext containerContext;
|
||||
//TODO: do the same with applicationContext (with a map)
|
||||
|
||||
// TODO: do the same with applicationContext (with a map)
|
||||
|
||||
private File configFile = null;
|
||||
|
||||
|
@ -78,13 +76,13 @@ public class DefaultProvider implements Provider {
|
|||
|
||||
List<Publisher> publishers;
|
||||
|
||||
|
||||
protected DefaultProvider(){};
|
||||
protected DefaultProvider() {
|
||||
};
|
||||
|
||||
@Override
|
||||
public ContainerContext containerContext() {
|
||||
|
||||
if(containerContext==null){
|
||||
if (containerContext == null) {
|
||||
ContainerConfiguration configuration = containerConfiguration();
|
||||
|
||||
Hub hub = new DefaultHub();
|
||||
|
@ -94,27 +92,29 @@ public class DefaultProvider implements Provider {
|
|||
File file = configuration.persistence().file(container_profile_file_path);
|
||||
|
||||
String id = null;
|
||||
if (file.exists()){
|
||||
if (file.exists()) {
|
||||
log.info("loading persisted state for container");
|
||||
try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))){
|
||||
id = (String)ois.readObject();
|
||||
}catch(Exception e){
|
||||
log.error("error loading persisted state, creating new uuid",e);
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
|
||||
id = (String) ois.readObject();
|
||||
} catch (Exception e) {
|
||||
log.error("error loading persisted state, creating new uuid", e);
|
||||
}
|
||||
|
||||
}
|
||||
if (id==null){
|
||||
}
|
||||
if (id == null) {
|
||||
id = UUID.randomUUID().toString();
|
||||
log.info("container id created is {}",id);
|
||||
log.info("container id created is {}", id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
AuthorizationProviderFactory<?> authfactory = configuration.getauthorizationConfiguration().getAuthProviderFactory();
|
||||
AuthorizationProviderFactory<?> authfactory = configuration.getauthorizationConfiguration()
|
||||
.getAuthProviderFactory();
|
||||
Credentials credentials = configuration.getauthorizationConfiguration().getCredentials();
|
||||
|
||||
|
||||
AuthorizationProvider authProvider = authfactory.connect(credentials);
|
||||
|
||||
containerContext = new DefaultContainerContext(id, configuration, hub, lifecycle, authProvider, new Properties());
|
||||
|
||||
containerContext = new DefaultContainerContext(id, configuration, hub, lifecycle, authProvider,
|
||||
new Properties());
|
||||
}
|
||||
return containerContext;
|
||||
}
|
||||
|
@ -127,12 +127,13 @@ public class DefaultProvider implements Provider {
|
|||
ContainerConfigurationBinder binder = new ContainerConfigurationBinder();
|
||||
|
||||
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (currentClassLoader.getParent()!=null && !currentClassLoader.getParent().equals(ClassLoader.getSystemClassLoader())){
|
||||
if (currentClassLoader.getParent() != null
|
||||
&& !currentClassLoader.getParent().equals(ClassLoader.getSystemClassLoader())) {
|
||||
log.trace("probably i'm in a webapp classloader");
|
||||
currentClassLoader = currentClassLoader.getParent();
|
||||
}
|
||||
|
||||
List<ContainerHandler> defaultHandlers = binder.bindHandlers(currentClassLoader);
|
||||
List<ContainerHandler> defaultHandlers = binder.bindHandlers(currentClassLoader);
|
||||
|
||||
return defaultHandlers;
|
||||
|
||||
|
@ -150,34 +151,37 @@ public class DefaultProvider implements Provider {
|
|||
ApplicationConfiguration embedded = configurationFor(application);
|
||||
ApplicationConfiguration external = context.configuration().app(application.getContextPath());
|
||||
|
||||
//shouldn't happen: management shouldn't have started at all
|
||||
if (embedded==null && external==null)
|
||||
throw new AssertionError("application @ "+application.getContextPath()+" is not distributed with "
|
||||
+ configuration_file_path+" and there is no external configuration for it in "+container_configuraton_file_path);
|
||||
// shouldn't happen: management shouldn't have started at all
|
||||
if (embedded == null && external == null)
|
||||
throw new AssertionError("application @ " + application.getContextPath() + " is not distributed with "
|
||||
+ configuration_file_path + " and there is no external configuration for it in "
|
||||
+ container_configuraton_file_path);
|
||||
|
||||
//no embedded configuration
|
||||
// no embedded configuration
|
||||
if (embedded == null) {
|
||||
|
||||
configuration = external ;
|
||||
configuration = external;
|
||||
|
||||
log.info("loaded configuration for application "+configuration.name()+" from "+container_configuraton_file_path);
|
||||
}
|
||||
else {
|
||||
log.info("loaded configuration for application " + configuration.name() + " from "
|
||||
+ container_configuraton_file_path);
|
||||
} else {
|
||||
|
||||
configuration = embedded;
|
||||
|
||||
if (external == null)
|
||||
|
||||
log.info("loaded configuration for application "+configuration.name()+" from "+configuration_file_path);
|
||||
log.info("loaded configuration for application " + configuration.name() + " from "
|
||||
+ configuration_file_path);
|
||||
|
||||
else {
|
||||
|
||||
configuration.merge(external);
|
||||
|
||||
log.info("loaded configuration for application "+configuration.name()+" from "+configuration_file_path+" and "+container_configuraton_file_path);
|
||||
log.info("loaded configuration for application " + configuration.name() + " from "
|
||||
+ configuration_file_path + " and " + container_configuraton_file_path);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationConfiguration bridgedConfiguration = new BridgedApplicationConfiguration(context.configuration(),
|
||||
configuration);
|
||||
|
@ -187,16 +191,16 @@ public class DefaultProvider implements Provider {
|
|||
ApplicationLifecycle lifecycle = new ApplicationLifecycle(hub, configuration.name());
|
||||
|
||||
File file = bridgedConfiguration.persistence().file(profile_file_path);
|
||||
String id= null;
|
||||
if (file.exists()){
|
||||
String id = null;
|
||||
if (file.exists()) {
|
||||
log.info("loading persisted state for application {}", application.getContextPath());
|
||||
try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))){
|
||||
id = (String)ois.readObject();
|
||||
}catch(Exception e){
|
||||
log.error("error loading persisted state, creating new uuid",e);
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
|
||||
id = (String) ois.readObject();
|
||||
} catch (Exception e) {
|
||||
log.error("error loading persisted state, creating new uuid", e);
|
||||
}
|
||||
}
|
||||
if (id==null)
|
||||
}
|
||||
if (id == null)
|
||||
id = UUID.randomUUID().toString();
|
||||
|
||||
return new DefaultApplicationContext(id, context, application, bridgedConfiguration, hub, lifecycle,
|
||||
|
@ -208,31 +212,29 @@ public class DefaultProvider implements Provider {
|
|||
|
||||
try {
|
||||
|
||||
|
||||
ApplicationConfigurationBinder binder = new ApplicationConfigurationBinder();
|
||||
|
||||
|
||||
|
||||
//searching for smartegars related application handlers in the common classloader
|
||||
// searching for smartegars related application handlers in the common
|
||||
// classloader
|
||||
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (currentClassLoader.getParent()!=null && !currentClassLoader.getParent().equals(ClassLoader.getSystemClassLoader())){
|
||||
if (currentClassLoader.getParent() != null
|
||||
&& !currentClassLoader.getParent().equals(ClassLoader.getSystemClassLoader())) {
|
||||
log.trace("probably i'm in a webapp classloader");
|
||||
currentClassLoader = currentClassLoader.getParent();
|
||||
}
|
||||
|
||||
ApplicationHandlers defaultHandlers = binder.bindHandlers(currentClassLoader);
|
||||
|
||||
return defaultHandlers;
|
||||
|
||||
return defaultHandlers;
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
|
||||
throw new RuntimeException("cannot install handlers for application @ " + context.name()+" (see cause) ", e);
|
||||
throw new RuntimeException("cannot install handlers for application @ " + context.name() + " (see cause) ",
|
||||
e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ApplicationExtensions extensionsFor(ApplicationContext context) {
|
||||
|
||||
|
@ -248,7 +250,8 @@ public class DefaultProvider implements Provider {
|
|||
config = getClass().getResourceAsStream(default_extensions_file_path);
|
||||
|
||||
if (config == null)
|
||||
throw new IllegalStateException("invalid distribution: cannot find " + default_extensions_file_path);
|
||||
throw new IllegalStateException(
|
||||
"invalid distribution: cannot find " + default_extensions_file_path);
|
||||
|
||||
} else
|
||||
log.info("{} uses custom extensions @ {}", context.name(), extensions_file_path);
|
||||
|
@ -259,12 +262,12 @@ public class DefaultProvider implements Provider {
|
|||
|
||||
} catch (RuntimeException e) {
|
||||
|
||||
throw new RuntimeException("cannot install extensions for application @ " + context.name()+" (see cause) ", e);
|
||||
throw new RuntimeException(
|
||||
"cannot install extensions for application @ " + context.name() + " (see cause) ", e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SmartGearsConfiguration smartgearsConfiguration() {
|
||||
|
||||
|
@ -297,7 +300,7 @@ public class DefaultProvider implements Provider {
|
|||
|
||||
InputStream config = application.getResourceAsStream(configuration_file_path);
|
||||
|
||||
if (config == null)
|
||||
if (config == null)
|
||||
return null;
|
||||
|
||||
ApplicationConfigurationBinder binder = new ApplicationConfigurationBinder();
|
||||
|
@ -313,7 +316,7 @@ public class DefaultProvider implements Provider {
|
|||
|
||||
private ContainerConfiguration containerConfiguration() {
|
||||
|
||||
if (configFile==null) {
|
||||
if (configFile == null) {
|
||||
|
||||
String home = Utils.home();
|
||||
|
||||
|
@ -324,22 +327,24 @@ public class DefaultProvider implements Provider {
|
|||
File homeDir = new File(home);
|
||||
|
||||
if (!(homeDir.exists() && homeDir.isDirectory() && homeDir.canRead() && homeDir.canWrite()))
|
||||
throw new IllegalStateException("invalid node configuration: home "+home+" does not exist or is not a directory or cannot be accessed in read/write mode");
|
||||
|
||||
configFile = new File(homeDir,container_configuraton_file_path);
|
||||
throw new IllegalStateException("invalid node configuration: home " + home
|
||||
+ " does not exist or is not a directory or cannot be accessed in read/write mode");
|
||||
|
||||
configFile = new File(homeDir, container_configuraton_file_path);
|
||||
|
||||
log.trace("reading container configuration @ {} ", configFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
if (!(configFile.exists() && configFile.canRead()))
|
||||
throw new IllegalStateException("invalid node configuration: file "+configFile.getAbsolutePath()+" does not exist or cannot be accessed");
|
||||
throw new IllegalStateException("invalid node configuration: file " + configFile.getAbsolutePath()
|
||||
+ " does not exist or cannot be accessed");
|
||||
|
||||
ContainerConfiguration configuration;
|
||||
try (InputStream stream = new FileInputStream(configFile)){
|
||||
configuration= new ContainerConfigurationBinder().load(stream);
|
||||
}catch (Exception e) {
|
||||
throw new IllegalStateException("invalid node configuration: file "+configFile.getAbsolutePath()+" is invalid", e);
|
||||
try (InputStream stream = new FileInputStream(configFile)) {
|
||||
configuration = new ContainerConfigurationBinder().load(stream);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(
|
||||
"invalid node configuration: file " + configFile.getAbsolutePath() + " is invalid", e);
|
||||
}
|
||||
|
||||
return configuration;
|
||||
|
@ -348,43 +353,56 @@ public class DefaultProvider implements Provider {
|
|||
@Override
|
||||
public synchronized List<Publisher> publishers() {
|
||||
if (this.publishers == null) {
|
||||
//retrieve from root class loader
|
||||
Collection<URL> urls = ClasspathHelper.forClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
urls.removeIf(url -> url.toString().endsWith(".so") || url.toString().endsWith(".zip") );
|
||||
|
||||
Set<Class<?>> annotatedPublishers;
|
||||
|
||||
ConfigurationBuilder reflectionConf = new ConfigurationBuilder().addUrls(urls).setScanners(new TypeAnnotationsScanner(), new SubTypesScanner());
|
||||
try (ScanResult result = new ClassGraph().enableClassInfo().enableAnnotationInfo()
|
||||
.addClassLoader(Thread.currentThread().getContextClassLoader()).scan()) {
|
||||
|
||||
Reflections reflection = new Reflections(reflectionConf);
|
||||
ClassInfoList classInfos = result.getClassesWithAnnotation(SmartgearsProfilePublisher.class.getName());
|
||||
|
||||
annotatedPublishers = classInfos.stream().map(ClassInfo::loadClass)
|
||||
.filter(c -> Publisher.class.isAssignableFrom(c)).collect(Collectors.toSet());
|
||||
|
||||
}
|
||||
/*
|
||||
* Collection<URL> urls =
|
||||
* ClasspathHelper.forClassLoader(Thread.currentThread().getContextClassLoader()
|
||||
* ); urls.removeIf(url -> url.toString().endsWith(".so") ||
|
||||
* url.toString().endsWith(".zip") );
|
||||
*
|
||||
*
|
||||
* ConfigurationBuilder reflectionConf = new
|
||||
* ConfigurationBuilder().addUrls(urls).setScanners(new
|
||||
* TypeAnnotationsScanner(), new SubTypesScanner());
|
||||
*
|
||||
* Reflections reflection = new Reflections(reflectionConf);
|
||||
*
|
||||
* = reflection.getTypesAnnotatedWith(SmartgearsProfilePublisher.class);
|
||||
*/
|
||||
|
||||
Set<Class<?>> annotatedPublishers = reflection.getTypesAnnotatedWith(SmartgearsProfilePublisher.class);
|
||||
List<Publisher> foundPublishers = new ArrayList<Publisher>();
|
||||
for (Class<?> annotatedPublisher: annotatedPublishers) {
|
||||
if (Publisher.class.isAssignableFrom(annotatedPublisher))
|
||||
try {
|
||||
foundPublishers.add((Publisher)annotatedPublisher.newInstance());
|
||||
log.info("added class {} to publishers",annotatedPublisher);
|
||||
} catch (Exception e) {
|
||||
log.error("publisher class {} cannot be instantiated", annotatedPublisher.getCanonicalName(),e);
|
||||
}
|
||||
else
|
||||
log.warn("publisher class {} discarded, it doesn't implements Publisher class", annotatedPublisher.getCanonicalName());
|
||||
|
||||
for (Class<?> annotatedPublisher : annotatedPublishers) {
|
||||
try {
|
||||
foundPublishers.add((Publisher) annotatedPublisher.getDeclaredConstructor().newInstance());
|
||||
log.info("added class {} to publishers", annotatedPublisher);
|
||||
} catch (Throwable e) {
|
||||
log.error("publisher class {} cannot be instantiated", annotatedPublisher.getCanonicalName(), e);
|
||||
}
|
||||
|
||||
}
|
||||
this.publishers = foundPublishers;
|
||||
|
||||
if (foundPublishers.isEmpty())
|
||||
log.warn("no publishers found in classloader");
|
||||
}
|
||||
|
||||
|
||||
return this.publishers;
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public AuthorizationProvider authorizationProvider() {
|
||||
return containerContext.authorizationProvider();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* @Override public AuthorizationProvider authorizationProvider() { return
|
||||
* containerContext.authorizationProvider(); }
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue