You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2022/11/21 14:39:14 UTC

[syncope] 03/03: Fixing openapi.json content from javadocs at first access

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit 28b3368aae75866178ef935acb54de5087a90c69
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Mon Nov 21 15:20:17 2022 +0100

    Fixing openapi.json content from javadocs at first access
---
 .../core/rest/cxf/IdRepoRESTCXFContext.java        | 40 +++++++++++++--
 .../core/rest/cxf/SyncopeOpenApiCustomizer.java    | 57 +++-------------------
 .../core/persistence/jpa/dao/JPAJobStatusDAO.java  |  1 -
 .../provisioning/java/job/JobStatusUpdater.java    |  6 +++
 4 files changed, 48 insertions(+), 56 deletions(-)

diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdRepoRESTCXFContext.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdRepoRESTCXFContext.java
index ab01ca51ad..51755161c8 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdRepoRESTCXFContext.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdRepoRESTCXFContext.java
@@ -22,6 +22,7 @@ import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
 import com.fasterxml.jackson.jaxrs.xml.JacksonXMLProvider;
 import com.fasterxml.jackson.jaxrs.yaml.JacksonYAMLProvider;
 import io.swagger.v3.oas.models.security.SecurityScheme;
+import java.net.URL;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -35,6 +36,8 @@ import org.apache.cxf.jaxrs.ext.search.SearchContext;
 import org.apache.cxf.jaxrs.ext.search.SearchContextImpl;
 import org.apache.cxf.jaxrs.ext.search.SearchContextProvider;
 import org.apache.cxf.jaxrs.ext.search.SearchUtils;
+import org.apache.cxf.jaxrs.model.doc.JavaDocProvider;
+import org.apache.cxf.jaxrs.openapi.OpenApiCustomizer;
 import org.apache.cxf.jaxrs.openapi.OpenApiFeature;
 import org.apache.cxf.jaxrs.spring.JAXRSServerFactoryBeanDefinitionParser.SpringJAXRSServerFactoryBean;
 import org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor;
@@ -130,6 +133,8 @@ import org.apache.syncope.core.rest.cxf.service.SyncopeServiceImpl;
 import org.apache.syncope.core.rest.cxf.service.TaskServiceImpl;
 import org.apache.syncope.core.rest.cxf.service.UserSelfServiceImpl;
 import org.apache.syncope.core.rest.cxf.service.UserServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -146,6 +151,8 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 @Configuration(proxyBeanMethods = false)
 public class IdRepoRESTCXFContext {
 
+    private static final Logger LOG = LoggerFactory.getLogger(IdRepoRESTCXFContext.class);
+
     @Bean
     public ThreadPoolTaskExecutor batchExecutor(final RESTProperties props) {
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
@@ -243,11 +250,38 @@ public class IdRepoRESTCXFContext {
         return new AddETagFilter();
     }
 
+    @ConditionalOnMissingBean(name = { "openApiCustomizer", "syncopeOpenApiCustomizer" })
+    @Bean
+    public OpenApiCustomizer openApiCustomizer(final DomainHolder domainHolder, final Environment env) {
+        JavaDocProvider javaDocProvider = null;
+
+        URL[] javaDocURLs = JavaDocUtils.getJavaDocURLs();
+        if (javaDocURLs == null) {
+            String[] javaDocPaths = JavaDocUtils.getJavaDocPaths(env);
+            if (javaDocPaths != null) {
+                try {
+                    javaDocProvider = new JavaDocProvider(javaDocPaths);
+                } catch (Exception e) {
+                    LOG.error("Could not set javadoc paths from {}", List.of(javaDocPaths), e);
+                }
+            }
+        } else {
+            javaDocProvider = new JavaDocProvider(javaDocURLs);
+        }
+
+        SyncopeOpenApiCustomizer openApiCustomizer = new SyncopeOpenApiCustomizer(domainHolder);
+        openApiCustomizer.setDynamicBasePath(false);
+        openApiCustomizer.setReplaceTags(false);
+        openApiCustomizer.setJavadocProvider(javaDocProvider);
+        return openApiCustomizer;
+    }
+
     @ConditionalOnMissingBean
     @Bean
-    public OpenApiFeature openapiFeature(final ApplicationContext ctx) {
+    public OpenApiFeature openapiFeature(final OpenApiCustomizer openApiCustomizer, final ApplicationContext ctx) {
         String version = ctx.getEnvironment().getProperty("version");
         OpenApiFeature openapiFeature = new OpenApiFeature();
+        openapiFeature.setUseContextBasedConfig(true);
         openapiFeature.setTitle("Apache Syncope");
         openapiFeature.setVersion(version);
         openapiFeature.setDescription("Apache Syncope " + version);
@@ -256,10 +290,6 @@ public class IdRepoRESTCXFContext {
         openapiFeature.setContactUrl("https://syncope.apache.org");
         openapiFeature.setScan(false);
         openapiFeature.setResourcePackages(Set.of("org.apache.syncope.common.rest.api.service"));
-
-        SyncopeOpenApiCustomizer openApiCustomizer = new SyncopeOpenApiCustomizer(ctx.getEnvironment());
-        openApiCustomizer.setDynamicBasePath(false);
-        openApiCustomizer.setReplaceTags(false);
         openapiFeature.setCustomizer(openApiCustomizer);
 
         Map<String, SecurityScheme> securityDefinitions = new HashMap<>();
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java
index b47f7a1f6d..0d515e39af 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java
@@ -33,8 +33,6 @@ import io.swagger.v3.oas.models.parameters.Parameter;
 import io.swagger.v3.oas.models.responses.ApiResponse;
 import io.swagger.v3.oas.models.responses.ApiResponses;
 import io.swagger.v3.oas.models.servers.Server;
-import java.net.URL;
-import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -45,7 +43,6 @@ import javax.ws.rs.core.Response;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.model.OperationResourceInfo;
-import org.apache.cxf.jaxrs.model.doc.JavaDocProvider;
 import org.apache.cxf.jaxrs.openapi.OpenApiCustomizer;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
@@ -53,60 +50,20 @@ import org.apache.syncope.common.lib.to.ErrorTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.core.persistence.api.DomainHolder;
-import org.apache.syncope.core.spring.ApplicationContextProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.core.env.Environment;
 
 public class SyncopeOpenApiCustomizer extends OpenApiCustomizer {
 
-    private static final Logger LOG = LoggerFactory.getLogger(SyncopeOpenApiCustomizer.class);
+    private final DomainHolder domainHolder;
 
-    private final Environment env;
-
-    private List<String> domains;
-
-    private boolean inited = false;
-
-    public SyncopeOpenApiCustomizer(final Environment env) {
-        this.env = env;
-    }
-
-    private void init() {
-        synchronized (this) {
-            if (!inited) {
-                JavaDocProvider javaDocProvider = null;
-
-                URL[] javaDocURLs = JavaDocUtils.getJavaDocURLs();
-                if (javaDocURLs == null) {
-                    String[] javaDocPaths = JavaDocUtils.getJavaDocPaths(env);
-                    if (javaDocPaths != null) {
-                        try {
-                            javaDocProvider = new JavaDocProvider(javaDocPaths);
-                        } catch (Exception e) {
-                            LOG.error("Could not set javadoc paths from {}", List.of(javaDocPaths), e);
-                        }
-                    }
-                } else {
-                    javaDocProvider = new JavaDocProvider(javaDocURLs);
-                }
-                super.setJavadocProvider(javaDocProvider);
-
-                domains = new ArrayList<>(ApplicationContextProvider.getApplicationContext().
-                        getBean(DomainHolder.class).getDomains().keySet());
-
-                inited = true;
-            }
-        }
+    public SyncopeOpenApiCustomizer(final DomainHolder domainHolder) {
+        this.domainHolder = domainHolder;
     }
 
     @Override
     public OpenAPIConfiguration customize(final OpenAPIConfiguration configuration) {
-        init();
         super.customize(configuration);
 
-        MessageContext ctx = JAXRSUtils.createContextValue(
-                JAXRSUtils.getCurrentMessage(), null, MessageContext.class);
+        MessageContext ctx = JAXRSUtils.createContextValue(JAXRSUtils.getCurrentMessage(), null, MessageContext.class);
 
         String url = StringUtils.substringBeforeLast(ctx.getUriInfo().getRequestUri().getRawPath(), "/");
         configuration.getOpenAPI().setServers(List.of(new Server().url(url)));
@@ -116,8 +73,8 @@ public class SyncopeOpenApiCustomizer extends OpenApiCustomizer {
 
     @Override
     protected void addParameters(final List<Parameter> parameters) {
-        Optional<Parameter> domainHeaderParameter = parameters.stream().filter(parameter
-                -> parameter instanceof HeaderParameter && RESTHeaders.DOMAIN.equals(parameter.getName())).findFirst();
+        Optional<Parameter> domainHeaderParameter = parameters.stream().
+                filter(p -> p instanceof HeaderParameter && RESTHeaders.DOMAIN.equals(p.getName())).findFirst();
         if (domainHeaderParameter.isEmpty()) {
             HeaderParameter parameter = new HeaderParameter();
             parameter.setName(RESTHeaders.DOMAIN);
@@ -130,7 +87,7 @@ public class SyncopeOpenApiCustomizer extends OpenApiCustomizer {
             Schema<String> schema = new Schema<>();
             schema.setDescription("Domains are built to facilitate multitenancy.");
             schema.setExternalDocs(extDoc);
-            schema.setEnum(domains);
+            schema.setEnum(domainHolder.getDomains().keySet().stream().sorted().collect(Collectors.toList()));
             schema.setDefault(SyncopeConstants.MASTER_DOMAIN);
             parameter.setSchema(schema);
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJobStatusDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJobStatusDAO.java
index 560efd1d13..79a3818aaa 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJobStatusDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJobStatusDAO.java
@@ -44,6 +44,5 @@ public class JPAJobStatusDAO extends AbstractDAO<JobStatus> implements JobStatus
         if (jobStatus != null) {
             entityManager().remove(jobStatus);
         }
-
     }
 }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdater.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdater.java
index 04bba663ac..ed39b658cc 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdater.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdater.java
@@ -22,11 +22,15 @@ import org.apache.syncope.core.persistence.api.dao.JobStatusDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.JobStatus;
 import org.apache.syncope.core.provisioning.api.event.JobStatusEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.context.event.EventListener;
 import org.springframework.scheduling.annotation.Async;
 
 public class JobStatusUpdater {
 
+    protected static final Logger LOG = LoggerFactory.getLogger(JobStatusUpdater.class);
+
     protected final JobStatusDAO jobStatusDAO;
 
     protected final EntityFactory entityFactory;
@@ -50,8 +54,10 @@ public class JobStatusUpdater {
     @EventListener
     public void update(final JobStatusEvent event) {
         if (event.getJobStatus() == null) {
+            LOG.debug("Deleting status for job '{}'", event.getJobRefDesc());
             jobStatusDAO.delete(event.getJobRefDesc());
         } else {
+            LOG.debug("Updating job '{}' with status '{}'", event.getJobRefDesc(), event.getJobStatus());
             JobStatus jobStatus = entityFactory.newEntity(JobStatus.class);
             jobStatus.setKey(event.getJobRefDesc());
             jobStatus.setStatus(event.getJobStatus());