Skip to content

Commit

Permalink
Merge pull request #12446 from msm1992/master-healthcheck-improvement
Browse files Browse the repository at this point in the history
Improve Server Startup Health Check API
  • Loading branch information
msm1992 authored May 27, 2024
2 parents 01f3d5a + b909cad commit 27b6ffe
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.api.gateway.GatewayAPIDTO;
import org.wso2.carbon.apimgt.api.gateway.GraphQLSchemaDTO;
import org.wso2.carbon.apimgt.gateway.utils.GatewayUtils;
import org.wso2.carbon.apimgt.gateway.webhooks.SubscriptionDataStore;
import org.wso2.carbon.apimgt.impl.notifier.events.APIEvent;
import org.wso2.carbon.apimgt.impl.notifier.events.DeployAPIInGatewayEvent;
Expand All @@ -32,6 +34,7 @@
import org.wso2.carbon.apimgt.keymgt.model.impl.SubscriptionDataLoaderImpl;

import java.util.*;
import java.util.stream.Collectors;

public class DataHolder {
private static final Log log = LogFactory.getLog(DataHolder.class);
Expand All @@ -41,11 +44,11 @@ public class DataHolder {
private Map<String, GraphQLSchemaDTO> apiToGraphQLSchemaDTOMap = new HashMap<>();
private Map<String, List<String>> apiToKeyManagersMap = new HashMap<>();
private Map<String,Map<String, API>> tenantAPIMap = new HashMap<>();
private boolean isAllApisDeployed = false;
private Map<String, Boolean> tenantDeployStatus = new HashMap<>();
private boolean isAllGatewayPoliciesDeployed = false;

private DataHolder() {

initializeTenantDeploymentStatusMap();
}

public Map<String, List<String>> getApiToCertificatesMap() {
Expand Down Expand Up @@ -104,13 +107,15 @@ public void addApiToGraphQLSchemaDTO(String apiId, GraphQLSchemaDTO graphQLSchem
}

public boolean isAllApisDeployed() {

return isAllApisDeployed;
return tenantDeployStatus.values().stream().allMatch(Boolean::booleanValue);
}

public void setAllApisDeployed(boolean allApisDeployed) {
public Map<String, Boolean> getTenantDeployStatus() {
return tenantDeployStatus;
}

isAllApisDeployed = allApisDeployed;
public void setTenantDeployStatus(String tenant) {
tenantDeployStatus.put(tenant, true);
}

public void addKeyManagerToAPIMapping(String uuid, List<String> keyManagers) {
Expand Down Expand Up @@ -227,4 +232,13 @@ public void markApisAsUnDeployedInTenant(String tenantDomain) {
apiMap.values().forEach(api -> api.setDeployed(false));
}
}

private void initializeTenantDeploymentStatusMap() {
try {
List<String> tenants = GatewayUtils.getTenantsToBeDeployed();
tenantDeployStatus = tenants.stream().collect(Collectors.toMap(str -> str, str -> false));
} catch (APIManagementException e) {
log.error("Error while initializing tenant deployment status map", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,6 @@ private void deployAPIsInSyncMode(String tenantDomain) throws ArtifactSynchroniz
}
syncModeDeploymentCount++;
isAPIsDeployedInSyncMode = deployArtifactsAtStartup(tenantDomain);
DataHolder.getInstance().setAllApisDeployed(isAPIsDeployedInSyncMode);
if (!isAPIsDeployedInSyncMode) {
log.error("Deployment attempt : " + syncModeDeploymentCount + " was unsuccessful");
if (!(syncModeDeploymentCount > retryCount)) {
Expand All @@ -301,6 +300,7 @@ private void deployAPIsInSyncMode(String tenantDomain) throws ArtifactSynchroniz
log.error("Maximum retry limit exceeded. Server is starting without deploying all synapse artifacts");
}
} else {
DataHolder.getInstance().setTenantDeployStatus(tenantDomain);
log.info("Deployment attempt : " + syncModeDeploymentCount + " was successful");
}
}
Expand Down Expand Up @@ -370,8 +370,8 @@ private void deployArtifactsInGateway(String tenantDomain) throws ArtifactSynchr
while (retry) {
try {
boolean isArtifactsDeployed = deployArtifactsAtStartup(tenantDomain);
DataHolder.getInstance().setAllApisDeployed(isArtifactsDeployed);
if (isArtifactsDeployed) {
DataHolder.getInstance().setTenantDeployStatus(tenantDomain);
log.info("Synapse Artifacts deployed Successfully in the Gateway");
retry = false;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,16 @@
import org.wso2.carbon.apimgt.tracing.telemetry.TelemetrySpan;
import org.wso2.carbon.apimgt.tracing.telemetry.TelemetryTracer;
import org.wso2.carbon.apimgt.tracing.telemetry.TelemetryUtil;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration;
import org.wso2.carbon.mediation.registry.RegistryServiceHolder;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.session.UserRegistry;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.core.UserCoreConstants;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;

Expand Down Expand Up @@ -1716,4 +1719,68 @@ public static boolean isOnDemandLoading() {
.getGatewayArtifactSynchronizerProperties();
return gatewayArtifactSynchronizerProperties.isOnDemandLoading();
}

/**
* This method return the carbon.xml config value for tenant eager loading
*
* @return config string
*/
public static String getEagerLoadingEnabledTenantsConfig() {
ServerConfiguration carbonConfig = CarbonUtils.getServerConfiguration();
return carbonConfig.getFirstProperty(APIConstants.EAGER_LOADING_ENABLED_TENANTS);
}

/**
* This method returns the list of tenants for which eager loading is enabled
*
* @return List of eager loading enabled tenants
*/
public static List<String> getTenantsToBeDeployed() throws APIManagementException {
List<String> tenantsToBeDeployed = new ArrayList<>();
tenantsToBeDeployed.add(APIConstants.SUPER_TENANT_DOMAIN);

//Read eager loading config from carbon server config, and extract include and exclude tenant lists
String eagerLoadingConfig = getEagerLoadingEnabledTenantsConfig();
if (StringUtils.isNotEmpty(eagerLoadingConfig)) {
boolean includeAllTenants = false;
List<String> includeTenantList = new ArrayList<>();
List<String> excludeTenantList = new ArrayList<>();


if (StringUtils.isNotEmpty(eagerLoadingConfig)) {
String[] tenants = eagerLoadingConfig.split(",");
for (String tenant : tenants) {
tenant = tenant.trim();
if (tenant.equals("*")) {
includeAllTenants = true;
} else if (tenant.contains("!")) {
if (tenant.contains("*")) {
// "!*" is not a valid config
throw new IllegalArgumentException(tenant + " is not a valid tenant domain");
}
excludeTenantList.add(tenant.replace("!", ""));
} else {
includeTenantList.add(tenant);
}
}
}

//Fetch all active tenant domains
try {
Set<String> allTenants = APIUtil.getTenantDomainsByState(APIConstants.TENANT_STATE_ACTIVE);
if (includeAllTenants) {
tenantsToBeDeployed.addAll(allTenants);
// Now that we have included all tenants, let's see whether any tenant have been excluded
if (!excludeTenantList.isEmpty()) {
tenantsToBeDeployed.removeAll(excludeTenantList);
}
} else {
tenantsToBeDeployed.addAll(includeTenantList);
}
} catch (UserStoreException e) {
throw new APIManagementException("Error while fetching active tenants list.", e);
}
}
return tenantsToBeDeployed;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3144,6 +3144,7 @@ public static class APILogHandler {

// Constants related to basic health check APIs
public static final String WEB_SOCKET_HEALTH_CHECK_PATH = "/health";
public static final String EAGER_LOADING_ENABLED_TENANTS = "Tenant.LoadingPolicy.EagerLoading.Include";

public static final String CASE_SENSITIVE_CHECK_PATH = "caseSensitiveRoleValidation";
public static final String SOAP_TO_REST_PRESERVE_ELEMENT_ORDER = "soapToRestPreserveElementOrder";
Expand Down

0 comments on commit 27b6ffe

Please sign in to comment.