Add improvements for api publishing procedure

secure-folder-policy
Lasantha Dharmakeerthi 3 months ago
commit 4660b59c97

@ -20,6 +20,7 @@ package io.entgra.device.mgt.core.apimgt.webapp.publisher;
import com.google.gson.Gson; import com.google.gson.Gson;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants; import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiScope;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.exception.APIManagerPublisherException; import io.entgra.device.mgt.core.apimgt.webapp.publisher.exception.APIManagerPublisherException;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.internal.APIPublisherDataHolder; import io.entgra.device.mgt.core.apimgt.webapp.publisher.internal.APIPublisherDataHolder;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException; import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException;
@ -34,20 +35,22 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.core.ServerStartupObserver; import org.wso2.carbon.core.ServerStartupObserver;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Stack; import java.util.Stack;
public class APIPublisherStartupHandler implements ServerStartupObserver { public class APIPublisherStartupHandler implements ServerStartupObserver {
private static final Log log = LogFactory.getLog(APIPublisherStartupHandler.class); private static final Log log = LogFactory.getLog(APIPublisherStartupHandler.class);
private static int retryTime = 2000;
private static final int CONNECTION_RETRY_FACTOR = 2; private static final int CONNECTION_RETRY_FACTOR = 2;
private static final int MAX_RETRY_COUNT = 5; private static final int MAX_RETRY_COUNT = 5;
private static Stack<APIConfig> failedAPIsStack = new Stack<>();
private static Stack<APIConfig> currentAPIsStack;
private static final Gson gson = new Gson(); private static final Gson gson = new Gson();
private static final Stack<APIConfig> failedAPIsStack = new Stack<>();
private static int retryTime = 2000;
private static Stack<APIConfig> currentAPIsStack;
private final List<String> publishedAPIs = new ArrayList<>();
private APIPublisherService publisher; private APIPublisherService publisher;
@Override @Override
@ -59,71 +62,87 @@ public class APIPublisherStartupHandler implements ServerStartupObserver {
public void completedServerStartup() { public void completedServerStartup() {
APIPublisherDataHolder.getInstance().setServerStarted(true); APIPublisherDataHolder.getInstance().setServerStarted(true);
currentAPIsStack = APIPublisherDataHolder.getInstance().getUnpublishedApis(); currentAPIsStack = APIPublisherDataHolder.getInstance().getUnpublishedApis();
Thread t = new Thread(new Runnable() { Thread t = new Thread(() -> {
@Override if (log.isDebugEnabled()) {
public void run() { log.debug("Server has just started, hence started publishing unpublished APIs");
if (log.isDebugEnabled()) { log.debug("Total number of unpublished APIs: "
log.debug("Server has just started, hence started publishing unpublished APIs"); + APIPublisherDataHolder.getInstance().getUnpublishedApis().size());
log.debug("Total number of unpublished APIs: " }
+ APIPublisherDataHolder.getInstance().getUnpublishedApis().size()); publisher = APIPublisherDataHolder.getInstance().getApiPublisherService();
} int retryCount = 0;
publisher = APIPublisherDataHolder.getInstance().getApiPublisherService(); while (retryCount < MAX_RETRY_COUNT && (!failedAPIsStack.isEmpty() || !currentAPIsStack.isEmpty())) {
int retryCount = 0; if (retryCount > 0) {
while (retryCount < MAX_RETRY_COUNT && (!failedAPIsStack.isEmpty() || !currentAPIsStack.isEmpty())) {
try { try {
retryTime = retryTime * CONNECTION_RETRY_FACTOR; retryTime = retryTime * CONNECTION_RETRY_FACTOR;
Thread.sleep(retryTime); Thread.sleep(retryTime);
} catch (InterruptedException te) { } catch (InterruptedException te) {
//do nothing. //do nothing.
} }
Stack<APIConfig> failedApis; }
if (!APIPublisherDataHolder.getInstance().getUnpublishedApis().isEmpty()) { Stack<APIConfig> failedApis;
publishAPIs(currentAPIsStack, failedAPIsStack); if (!currentAPIsStack.isEmpty()) {
failedApis = failedAPIsStack; publishAPIs(currentAPIsStack, failedAPIsStack);
} else { failedApis = failedAPIsStack;
publishAPIs(failedAPIsStack, currentAPIsStack); } else {
failedApis = currentAPIsStack; publishAPIs(failedAPIsStack, currentAPIsStack);
} failedApis = currentAPIsStack;
retryCount++; }
if (retryCount == MAX_RETRY_COUNT && !failedApis.isEmpty()) { retryCount++;
StringBuilder error = new StringBuilder(); if (retryCount == MAX_RETRY_COUNT && !failedApis.isEmpty()) {
error.append("Error occurred while publishing API ['"); StringBuilder error = new StringBuilder();
while (!failedApis.isEmpty()) { error.append("Error occurred while publishing API ['");
APIConfig api = failedApis.pop(); while (!failedApis.isEmpty()) {
error.append(api.getName() + ","); APIConfig api = failedApis.pop();
} error.append(api.getName() + ",");
error.append("']");
log.error(error.toString());
} }
error.append("']");
log.info(error.toString());
} }
}
try { try {
publisher.updateScopeRoleMapping(); publisher.updateScopeRoleMapping();
publisher.addDefaultScopesIfNotExist(); publisher.addDefaultScopesIfNotExist();
} catch (APIManagerPublisherException e) { } catch (APIManagerPublisherException e) {
log.error("failed to update scope role mapping.", e); log.error("failed to update scope role mapping.", e);
} }
updateScopeMetadataEntryWithDefaultScopes(); updateScopeMetadataEntryWithDefaultScopes();
log.info("Successfully published : [" + publishedAPIs + "]. " +
"and failed : [" + failedAPIsStack + "] " +
"Total successful count : [" + publishedAPIs.size() + "]. " +
"Failed count : [" + failedAPIsStack.size() + "]");
// execute after api publishing // execute after api publishing
for (PostApiPublishingObsever observer : APIPublisherDataHolder.getInstance().getPostApiPublishingObseverList()) { for (PostApiPublishingObsever observer : APIPublisherDataHolder.getInstance().getPostApiPublishingObseverList()) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Executing " + observer.getClass().getName()); log.debug("Executing " + observer.getClass().getName());
}
observer.execute();
} }
log.info("Finish executing PostApiPublishingObsevers"); observer.execute();
} }
log.info("Finish executing PostApiPublishingObsevers");
}); });
t.start(); t.start();
log.info("Starting API publishing procedure");
} }
/**
* Publish apis provided by the API stack, if failed while publishing, then failed API will be added to
* the failed API stack
*
* @param apis Stack of APIs to publish
* @param failedStack Stack to record failed APIs
*/
private void publishAPIs(Stack<APIConfig> apis, Stack<APIConfig> failedStack) { private void publishAPIs(Stack<APIConfig> apis, Stack<APIConfig> failedStack) {
while (!apis.isEmpty()) { while (!apis.isEmpty()) {
APIConfig api = apis.pop(); APIConfig api = apis.pop();
try { try {
publisher.publishAPI(api); publisher.publishAPI(api);
for (ApiScope scope : api.getScopes()) {
APIPublisherDataHolder.getInstance().getPermScopeMapping().putIfAbsent(scope.getPermissions(), scope.getKey());
}
publishedAPIs.add(api.getName());
log.info("Successfully published API [" + api.getName() + "]");
} catch (APIManagerPublisherException e) { } catch (APIManagerPublisherException e) {
log.error("failed to publish api.", e); log.error("failed to publish api.", e);
failedStack.push(api); failedStack.push(api);
@ -136,34 +155,42 @@ public class APIPublisherStartupHandler implements ServerStartupObserver {
* will create that entry and update the value with default permissions. * will create that entry and update the value with default permissions.
*/ */
private void updateScopeMetadataEntryWithDefaultScopes() { private void updateScopeMetadataEntryWithDefaultScopes() {
Map<String, String> permScopeMap = APIPublisherDataHolder.getInstance().getPermScopeMapping();
Metadata permScopeMapping;
MetadataManagementService metadataManagementService = APIPublisherDataHolder.getInstance().getMetadataManagementService(); MetadataManagementService metadataManagementService = APIPublisherDataHolder.getInstance().getMetadataManagementService();
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
DefaultPermissions defaultPermissions = deviceManagementConfig.getDefaultPermissions();
try { try {
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig(); permScopeMapping = metadataManagementService.retrieveMetadata(Constants.PERM_SCOPE_MAPPING_META_KEY);
DefaultPermissions defaultPermissions = deviceManagementConfig.getDefaultPermissions(); boolean entryAlreadyExists = permScopeMapping != null;
Metadata permScopeMapping = metadataManagementService.retrieveMetadata(Constants.PERM_SCOPE_MAPPING_META_KEY); if (permScopeMap == null || permScopeMap.isEmpty()) {
Map<String, String> permScopeMap = (permScopeMapping != null) ? gson.fromJson(permScopeMapping.getMetaValue(), HashMap.class) : permScopeMap = entryAlreadyExists ? gson.fromJson(permScopeMapping.getMetaValue(), HashMap.class) :
new HashMap<>(); new HashMap<>();
for (DefaultPermission defaultPermission : defaultPermissions.getDefaultPermissions()) {
permScopeMap.putIfAbsent(defaultPermission.getName(),
defaultPermission.getScopeMapping().getKey());
} }
APIPublisherDataHolder.getInstance().setPermScopeMapping(permScopeMap); for (DefaultPermission defaultPermission : defaultPermissions.getDefaultPermissions()) {
if (permScopeMapping != null) { permScopeMap.putIfAbsent(defaultPermission.getName(), defaultPermission.getScopeMapping().getKey());
permScopeMapping.setMetaValue(gson.toJson(permScopeMap));
metadataManagementService.updateMetadata(permScopeMapping);
return;
} }
permScopeMapping = new Metadata(); permScopeMapping = new Metadata();
permScopeMapping.setMetaKey(Constants.PERM_SCOPE_MAPPING_META_KEY); permScopeMapping.setMetaKey(Constants.PERM_SCOPE_MAPPING_META_KEY);
permScopeMapping.setMetaValue(gson.toJson(permScopeMap)); permScopeMapping.setMetaValue(gson.toJson(permScopeMap));
metadataManagementService.createMetadata(permScopeMapping);
if (entryAlreadyExists) {
metadataManagementService.updateMetadata(permScopeMapping);
} else {
metadataManagementService.createMetadata(permScopeMapping);
}
APIPublisherDataHolder.getInstance().setPermScopeMapping(permScopeMap);
log.info(Constants.PERM_SCOPE_MAPPING_META_KEY + "entry updated successfully");
} catch (MetadataManagementException e) { } catch (MetadataManagementException e) {
log.error("Error encountered while updating permission scope mapping metadata with default scopes"); log.error("Error encountered while updating permission scope mapping metadata with default scopes");
} catch (MetadataKeyAlreadyExistsException e) { } catch (MetadataKeyAlreadyExistsException e) {
log.error("Metadata entry already exists for " + Constants.PERM_SCOPE_MAPPING_META_KEY); log.error("Metadata entry already exists for " + Constants.PERM_SCOPE_MAPPING_META_KEY);
} }
} }
} }

@ -24,25 +24,33 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import io.entgra.device.mgt.core.apimgt.annotations.Scope; import io.entgra.device.mgt.core.apimgt.annotations.Scope;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.APIResource; import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.APIResource;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.APIResourceConfiguration; import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.APIResourceConfiguration;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.WebappPublisherConfig; import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.WebappPublisherConfig;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiScope; import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiScope;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiUriTemplate; import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiUriTemplate;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.internal.APIPublisherDataHolder;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.lifecycle.util.AnnotationProcessor; import io.entgra.device.mgt.core.apimgt.webapp.publisher.lifecycle.util.AnnotationProcessor;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import org.apache.catalina.core.StandardContext;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.Utils; import org.wso2.carbon.core.util.Utils;
import org.wso2.carbon.user.api.TenantManager;
import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreException;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import java.io.IOException;
import java.util.*; import java.util.*;
public class APIPublisherUtil { public class APIPublisherUtil {
public static final String API_VERSION_PARAM = "{version}"; public static final String API_VERSION_PARAM = "{version}";
public static final String PROPERTY_PROFILE = "profile";
private static final Log log = LogFactory.getLog(APIPublisherUtil.class); private static final Log log = LogFactory.getLog(APIPublisherUtil.class);
private static final String DEFAULT_API_VERSION = "1.0.0"; private static final String DEFAULT_API_VERSION = "1.0.0";
private static final String API_CONFIG_DEFAULT_VERSION = "1.0.0"; private static final String API_CONFIG_DEFAULT_VERSION = "1.0.0";
@ -53,10 +61,10 @@ public class APIPublisherUtil {
private static final String PARAM_MANAGED_API_IS_SECURED = "managed-api-isSecured"; private static final String PARAM_MANAGED_API_IS_SECURED = "managed-api-isSecured";
private static final String PARAM_SHARED_WITH_ALL_TENANTS = "isSharedWithAllTenants"; private static final String PARAM_SHARED_WITH_ALL_TENANTS = "isSharedWithAllTenants";
private static final String PARAM_PROVIDER_TENANT_DOMAIN = "providerTenantDomain"; private static final String PARAM_PROVIDER_TENANT_DOMAIN = "providerTenantDomain";
private static final String NON_SECURED_RESOURCES = "nonSecuredEndPoints"; private static final String NON_SECURED_RESOURCES = "nonSecuredEndPoints";
private static final String AUTH_TYPE_NON_SECURED = "None"; private static final String AUTH_TYPE_NON_SECURED = "None";
private static final String PARAM_IS_DEFAULT = "isDefault"; private static final String PARAM_IS_DEFAULT = "isDefault";
private static final Gson gson = new Gson();
public static String getServerBaseUrl() { public static String getServerBaseUrl() {
WebappPublisherConfig webappPublisherConfig = WebappPublisherConfig.getInstance(); WebappPublisherConfig webappPublisherConfig = WebappPublisherConfig.getInstance();
@ -255,7 +263,7 @@ public class APIPublisherUtil {
policy = null; policy = null;
} }
apiConfig.setPolicy(policy); apiConfig.setPolicy(policy);
setResourceAuthTypes(servletContext, apiConfig);
return apiConfig; return apiConfig;
} }
@ -318,7 +326,7 @@ public class APIPublisherUtil {
} }
} }
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("API swagger definition: " + swaggerDefinition.toString()); log.debug("API swagger definition: " + swaggerDefinition);
} }
return swaggerDefinition.toString(); return swaggerDefinition.toString();
} }
@ -336,8 +344,7 @@ public class APIPublisherUtil {
String fullPaath = ""; String fullPaath = "";
if (!template.getUriTemplate().equals(AnnotationProcessor.WILD_CARD)) { if (!template.getUriTemplate().equals(AnnotationProcessor.WILD_CARD)) {
fullPaath = apiConfig.getContext() + template.getUriTemplate(); fullPaath = apiConfig.getContext() + template.getUriTemplate();
} } else {
else {
fullPaath = apiConfig.getContext(); fullPaath = apiConfig.getContext();
} }
for (String context : resourcesList) { for (String context : resourcesList) {
@ -349,4 +356,73 @@ public class APIPublisherUtil {
} }
apiConfig.setUriTemplates(templates); apiConfig.setUriTemplates(templates);
} }
/**
* This method will extract and retrieve the API resource configuration by processing the API resources
* @param standardContext {@link StandardContext}
* @param servletContext {@link ServletContext}
* @return Extracted {@link APIResourceConfiguration} list describing from the servlet context
* @throws IOException Throws when error occurred while processing the swagger annotations
* @throws ClassNotFoundException Throws when error occurred while extracting api configurations
*/
public static List<APIResourceConfiguration> getAPIResourceConfiguration(StandardContext standardContext, ServletContext servletContext)
throws IOException, ClassNotFoundException {
List<APIResourceConfiguration> apiResourceConfigurations = new ArrayList<>();
String profile = System.getProperty(PROPERTY_PROFILE);
if (WebappPublisherConfig.getInstance().getProfiles().getProfile().contains(profile.toLowerCase())) {
AnnotationProcessor annotationProcessor = new AnnotationProcessor(standardContext);
Set<String> annotatedSwaggerAPIClasses = annotationProcessor.
scanStandardContext(io.swagger.annotations.SwaggerDefinition.class.getName());
apiResourceConfigurations = annotationProcessor.extractAPIInfo(servletContext,
annotatedSwaggerAPIClasses);
}
return apiResourceConfigurations;
}
/**
* This method can use to publish the apis after the server startup complete.
*
* @param apiConfig {@link APIConfig} Contains API definition
*/
public static void publishAPIAfterServerStartup(APIConfig apiConfig) {
APIPublisherDataHolder apiPublisherDataHolder = APIPublisherDataHolder.getInstance();
if (!apiPublisherDataHolder.isServerStarted()) {
if (log.isDebugEnabled()) {
log.debug("Abort publishing the API [" + apiConfig.getName() + "]. Server still starting");
}
throw new IllegalStateException("Server starting procedure is still not completed");
}
TenantManager tenantManager = apiPublisherDataHolder.getTenantManager();
if (tenantManager == null) {
throw new IllegalStateException("Tenant manager service not initialized properly");
}
try {
if (tenantManager.isTenantActive(tenantManager.getTenantId(apiConfig.getTenantDomain()))) {
APIPublisherService apiPublisherService = apiPublisherDataHolder.getApiPublisherService();
if (apiPublisherService == null) {
throw new IllegalStateException("API Publisher service is not initialized properly");
}
apiPublisherService.publishAPI(apiConfig);
for (ApiScope scope : apiConfig.getScopes()) {
apiPublisherDataHolder.getPermScopeMapping().putIfAbsent(scope.getPermissions(), scope.getKey());
}
Metadata permScopeMapping = new Metadata();
permScopeMapping.setMetaKey(Constants.PERM_SCOPE_MAPPING_META_KEY);
permScopeMapping.setMetaValue(gson.toJson(apiPublisherDataHolder.getPermScopeMapping()));
try {
apiPublisherDataHolder.getMetadataManagementService().updateMetadata(permScopeMapping);
} catch (MetadataManagementException e) {
log.error("Error encountered while updating the " + Constants.PERM_SCOPE_MAPPING_META_KEY + "entry");
}
} else {
log.error("Can't find an active tenant under tenant domain " + apiConfig.getTenantDomain());
}
} catch (Throwable e) {
log.error("Error occurred while publishing API '" + apiConfig.getName() + "' with the context '" +
apiConfig.getContext() + "' and version '" + apiConfig.getVersion() + "'", e);
}
}
} }

@ -33,6 +33,7 @@ import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.user.core.tenant.TenantManager; import org.wso2.carbon.user.core.tenant.TenantManager;
import org.wso2.carbon.utils.ConfigurationContextService; import org.wso2.carbon.utils.ConfigurationContextService;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Stack; import java.util.Stack;
import java.util.List; import java.util.List;
@ -48,7 +49,7 @@ public class APIPublisherDataHolder {
private RegistryService registryService; private RegistryService registryService;
private boolean isServerStarted; private boolean isServerStarted;
private Stack<APIConfig> unpublishedApis = new Stack<>(); private Stack<APIConfig> unpublishedApis = new Stack<>();
private Map<String, String> permScopeMapping; private Map<String, String> permScopeMapping = new HashMap<>();
private APIApplicationServices apiApplicationServices; private APIApplicationServices apiApplicationServices;
private PublisherRESTAPIServices publisherRESTAPIServices; private PublisherRESTAPIServices publisherRESTAPIServices;
private MetadataManagementService metadataManagementService; private MetadataManagementService metadataManagementService;

@ -17,24 +17,11 @@
*/ */
package io.entgra.device.mgt.core.apimgt.webapp.publisher.lifecycle.listener; package io.entgra.device.mgt.core.apimgt.webapp.publisher.lifecycle.listener;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiScope;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.core.StandardContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIConfig; import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIConfig;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIPublisherService;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIPublisherUtil; import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIPublisherUtil;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.APIResourceConfiguration; import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.APIResourceConfiguration;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.WebappPublisherConfig; import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.WebappPublisherConfig;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.internal.APIPublisherDataHolder; import io.entgra.device.mgt.core.apimgt.webapp.publisher.internal.APIPublisherDataHolder;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.lifecycle.util.AnnotationProcessor;
import org.apache.catalina.Lifecycle; import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener; import org.apache.catalina.LifecycleListener;
@ -46,104 +33,42 @@ import org.wso2.carbon.user.api.UserStoreException;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class APIPublisherLifecycleListener implements LifecycleListener { public class APIPublisherLifecycleListener implements LifecycleListener {
public static final String PROFILE_DEFAULT = "default";
private static final Log log = LogFactory.getLog(APIPublisherLifecycleListener.class); private static final Log log = LogFactory.getLog(APIPublisherLifecycleListener.class);
private static final String PARAM_MANAGED_API_ENABLED = "managed-api-enabled"; private static final String PARAM_MANAGED_API_ENABLED = "managed-api-enabled";
public static final String PROPERTY_PROFILE = "profile";
public static final String PROFILE_DT_WORKER = "dtWorker";
public static final String PROFILE_DEFAULT = "default";
@Override @Override
public void lifecycleEvent(LifecycleEvent lifecycleEvent) { public void lifecycleEvent(LifecycleEvent lifecycleEvent) {
if (Lifecycle.AFTER_START_EVENT.equals(lifecycleEvent.getType()) ) { if (Lifecycle.AFTER_START_EVENT.equals(lifecycleEvent.getType())) {
if (WebappPublisherConfig.getInstance()
.isPublished()) {
StandardContext context = (StandardContext) lifecycleEvent.getLifecycle();
ServletContext servletContext = context.getServletContext();
String param = servletContext.getInitParameter(PARAM_MANAGED_API_ENABLED);
boolean isManagedApi = (param != null && !param.isEmpty()) && Boolean.parseBoolean(param);
String profile = System.getProperty(PROPERTY_PROFILE); APIPublisherDataHolder apiPublisherDataHolder = APIPublisherDataHolder.getInstance();
if (WebappPublisherConfig.getInstance().getProfiles().getProfile().contains(profile.toLowerCase()) StandardContext context = (StandardContext) lifecycleEvent.getLifecycle();
&& isManagedApi) { ServletContext servletContext = context.getServletContext();
try { String param = servletContext.getInitParameter(PARAM_MANAGED_API_ENABLED);
AnnotationProcessor annotationProcessor = new AnnotationProcessor(context); boolean isManagedApi = (param != null && !param.isEmpty()) && Boolean.parseBoolean(param);
Set<String> annotatedSwaggerAPIClasses = annotationProcessor.
scanStandardContext(io.swagger.annotations.SwaggerDefinition.class.getName());
List<APIResourceConfiguration> apiDefinitions = annotationProcessor.extractAPIInfo(servletContext,
annotatedSwaggerAPIClasses);
APIPublisherDataHolder apiPublisherDataHolder = APIPublisherDataHolder.getInstance(); if (isManagedApi) {
MetadataManagementService metadataManagementService = if (WebappPublisherConfig.getInstance().isPublished() || WebappPublisherConfig.getInstance().isEnabledUpdateApi()) {
apiPublisherDataHolder.getMetadataManagementService();
Metadata metadata = metadataManagementService.retrieveMetadata("perm-scope-mapping");
if (metadata != null) {
HashMap<String, String> permScopeMapping =
new Gson().fromJson(metadata.getMetaValue().toString(), HashMap.class);
apiPublisherDataHolder.setPermScopeMapping(permScopeMapping);
}
Map<String, String> permScopeMap = apiPublisherDataHolder.getPermScopeMapping(); try {
for (APIResourceConfiguration apiDefinition : apiDefinitions) { List<APIResourceConfiguration> apiResourceConfigurations =
APIConfig apiConfig = APIPublisherUtil.buildApiConfig(servletContext, apiDefinition); APIPublisherUtil.getAPIResourceConfiguration(context, servletContext);
for (ApiScope scope : apiConfig.getScopes()) {
permScopeMap.put(scope.getPermissions(), scope.getKey());
}
APIPublisherUtil.setResourceAuthTypes(servletContext,apiConfig);
try {
int tenantId = APIPublisherDataHolder.getInstance().getTenantManager().
getTenantId(apiConfig.getTenantDomain());
boolean isTenantActive = APIPublisherDataHolder.getInstance(). if (WebappPublisherConfig.getInstance().isPublished()) {
getTenantManager().isTenantActive(tenantId); for (APIResourceConfiguration apiDefinition : apiResourceConfigurations) {
if (isTenantActive) { APIConfig apiConfig = APIPublisherUtil.buildApiConfig(servletContext, apiDefinition);
boolean isServerStarted = APIPublisherDataHolder.getInstance().isServerStarted(); if (apiPublisherDataHolder.isServerStarted()) {
if (isServerStarted) { APIPublisherUtil.publishAPIAfterServerStartup(apiConfig);
APIPublisherService apiPublisherService =
APIPublisherDataHolder.getInstance().getApiPublisherService();
if (apiPublisherService == null) {
throw new IllegalStateException(
"API Publisher service is not initialized properly");
}
apiPublisherService.publishAPI(apiConfig);
} else {
if (log.isDebugEnabled()) {
log.debug("Server has not started yet. Hence adding API '" +
apiConfig.getName() + "' to the queue");
}
APIPublisherDataHolder.getInstance().getUnpublishedApis().push(apiConfig);
}
} else { } else {
log.error("No tenant [" + apiConfig.getTenantDomain() + "] " + apiPublisherDataHolder.getUnpublishedApis().push(apiConfig);
"found when publishing the Web app");
} }
} catch (Throwable e) {
log.error("Error occurred while publishing API '" + apiConfig.getName() +
"' with the context '" + apiConfig.getContext() +
"' and version '" + apiConfig.getVersion() + "'", e);
} }
} }
Metadata existingMetaData = metadataManagementService.retrieveMetadata("perm-scope" +
"-mapping");
if (existingMetaData != null) {
existingMetaData.setMetaValue(new Gson().toJson(permScopeMap));
metadataManagementService.updateMetadata(existingMetaData);
} else {
Metadata newMetaData = new Metadata();
newMetaData.setMetaKey("perm-scope-mapping");
newMetaData.setMetaValue(new Gson().toJson(permScopeMap));
metadataManagementService.createMetadata(newMetaData);
}
apiPublisherDataHolder.setPermScopeMapping(permScopeMap);
} catch (IOException e) { } catch (IOException e) {
log.error("Error encountered while discovering annotated classes", e); log.error("Error encountered while discovering annotated classes", e);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
@ -156,24 +81,6 @@ public class APIPublisherLifecycleListener implements LifecycleListener {
log.error("Failed to Publish api from " + servletContext.getContextPath(), e); log.error("Failed to Publish api from " + servletContext.getContextPath(), e);
} }
} }
} else {
APIPublisherDataHolder apiPublisherDataHolder = APIPublisherDataHolder.getInstance();
MetadataManagementService metadataManagementService =
apiPublisherDataHolder.getMetadataManagementService();
try {
Metadata existingMetaData = metadataManagementService.retrieveMetadata("perm-scope" +
"-mapping");
if (existingMetaData != null) {
existingMetaData.setMetaValue(new Gson().toJson(apiPublisherDataHolder.getPermScopeMapping()
));
metadataManagementService.updateMetadata(existingMetaData);
} else {
log.error("Couldn't find 'perm-scope-mapping' Meta entry while API publishing has been turned" +
" off.");
}
} catch (MetadataManagementException e) {
log.error("Failed to Load Meta-Mgt data.", e);
}
} }
} }
} }

Loading…
Cancel
Save