Skip to content

Commit

Permalink
Merge pull request #805 from janakamarasena/bfix-is7
Browse files Browse the repository at this point in the history
Load super tenant publishers at server startup
  • Loading branch information
janakamarasena authored Feb 13, 2024
2 parents 7ea5f44 + 84d8078 commit 70315aa
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
org.osgi.framework; version="${osgi.framework.imp.pkg.version.range}",
org.osgi.service.component; version="${osgi.service.component.imp.pkg.version.range}",
org.wso2.carbon.context; version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.core; version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.core.util; version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.databridge.commons; version="${carbon.analytics.common.version.range}",
org.wso2.carbon.event.publisher.core; version="${carbon.analytics.common.version.range}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,14 @@
import org.wso2.carbon.event.publisher.core.config.EventPublisherConfiguration;
import org.wso2.carbon.event.stream.core.EventStreamConfiguration;
import org.wso2.carbon.event.stream.core.exception.EventStreamConfigurationException;
import org.wso2.carbon.identity.configuration.mgt.core.constant.ConfigurationConstants;
import org.wso2.carbon.identity.configuration.mgt.core.exception.ConfigurationManagementException;
import org.wso2.carbon.identity.configuration.mgt.core.model.Resource;
import org.wso2.carbon.identity.configuration.mgt.core.model.ResourceFile;
import org.wso2.carbon.identity.tenant.resource.manager.constants.TenantResourceConstants;
import org.wso2.carbon.identity.tenant.resource.manager.exception.TenantResourceManagementException;
import org.wso2.carbon.identity.tenant.resource.manager.internal.TenantResourceManagerDataHolder;
import org.wso2.carbon.identity.tenant.resource.manager.util.ResourceUtils;
import org.wso2.carbon.utils.AbstractAxis2ConfigurationContextObserver;

import java.util.List;

import static org.wso2.carbon.identity.tenant.resource.manager.constants.TenantResourceConstants.ErrorMessages.ERROR_CODE_ERROR_WHEN_ADDING_EVENT_PUBLISHER_CONFIGURATION;
import static org.wso2.carbon.identity.tenant.resource.manager.constants.TenantResourceConstants.ErrorMessages.ERROR_CODE_ERROR_WHEN_CREATING_TENANT_EVENT_STREAM_CONFIGURATION;
import static org.wso2.carbon.identity.tenant.resource.manager.constants.TenantResourceConstants.ErrorMessages.ERROR_CODE_ERROR_WHEN_FETCHING_TENANT_SPECIFIC_PUBLISHER_FILES;
import static org.wso2.carbon.identity.tenant.resource.manager.constants.TenantResourceConstants.PUBLISHER;
import static org.wso2.carbon.identity.tenant.resource.manager.util.ResourceUtils.populateMessageWithData;

/**
Expand Down Expand Up @@ -81,7 +73,7 @@ private void loadEventStreamAndPublisherConfigurations(int tenantId) {
try {
ResourceUtils.startTenantFlow(tenantId);
loadTenantEventStreams(eventStreamConfigurationList);
loadTenantPublisherConfigurationFromConfigStore();
ResourceUtils.loadTenantPublisherConfigurationFromConfigStore();

if (activeEventPublisherConfigurations != null) {
ResourceUtils.loadTenantPublisherConfigurationFromSuperTenantConfig(activeEventPublisherConfigurations);
Expand All @@ -91,52 +83,6 @@ private void loadEventStreamAndPublisherConfigurations(int tenantId) {
}
}

/**
* This method loads publisher configurations tenant wise by fetching them from configuration store.
*/
private void loadTenantPublisherConfigurationFromConfigStore() {

try {
List<Resource> resourcesByTypePublisher = TenantResourceManagerDataHolder.getInstance()
.getConfigurationManager().getResourcesByType(PUBLISHER).getResources();
for (Resource resource : resourcesByTypePublisher) {
if (!resource.getFiles().isEmpty()) {
ResourceFile tenantSpecificPublisherFile = resource.getFiles().get(0);
if (tenantSpecificPublisherFile != null) {
if (log.isDebugEnabled()) {
log.debug("File for publisher name: " + tenantSpecificPublisherFile.getName()
+ " is available in the configuration store.");
}
TenantResourceManagerDataHolder.getInstance().getResourceManager()
.addEventPublisherConfiguration(tenantSpecificPublisherFile);
}
}
}
} catch (ConfigurationManagementException e) {
if (e.getErrorCode()
.equals(ConfigurationConstants.ErrorMessages.ERROR_CODE_FEATURE_NOT_ENABLED.getCode())) {
log.warn("Configuration store is disabled. Super tenant configuration will be used for the tenant "
+ "domain: " + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain());
} else if (e.getErrorCode()
.equals(ConfigurationConstants.ErrorMessages.ERROR_CODE_RESOURCES_DOES_NOT_EXISTS.getCode())) {
log.warn("Configuration store does not contain any resources under resource type publisher. Super "
+ "tenant configurations will be used for the tenant domain: " + PrivilegedCarbonContext
.getThreadLocalCarbonContext().getTenantDomain());
} else if (e.getErrorCode()
.equals(ConfigurationConstants.ErrorMessages.ERROR_CODE_RESOURCE_TYPE_DOES_NOT_EXISTS.getCode())) {
log.warn("Configuration store does not contain publisher resource type. Super "
+ "tenant configurations will be used for the tenant domain: " + PrivilegedCarbonContext
.getThreadLocalCarbonContext().getTenantDomain());
} else {
log.error(populateMessageWithData(ERROR_CODE_ERROR_WHEN_FETCHING_TENANT_SPECIFIC_PUBLISHER_FILES,
PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()), e);
}
} catch (TenantResourceManagementException e) {
log.error(populateMessageWithData(ERROR_CODE_ERROR_WHEN_ADDING_EVENT_PUBLISHER_CONFIGURATION,
PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()), e);
}
}

/**
* This method returns super tenant event stream configurations.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.tenant.resource.manager.internal;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.core.ServerStartupObserver;
import org.wso2.carbon.identity.tenant.resource.manager.util.ResourceUtils;

/**
* Server startup observer for tenant resource management component.
*/
public class TenantResourceManagementServerStartupObserver implements ServerStartupObserver {

private static final Log LOG = LogFactory.getLog(TenantResourceManagementServerStartupObserver.class);

@Override
public void completingServerStartup() {

// Do nothing.
}

@Override
public void completedServerStartup() {

if (LOG.isDebugEnabled()) {
LOG.debug("Attempting to load super tenant event publisher configurations from the configuration store.");
}

/*
Load the super tenant publisher configuration from the config store. This is required if there are
super tenant event publishers configured in the config store (ex: Custom SMS Provider).
This way of loading configurations is not optimal as it is called after the server startup
completion. These configurations should be loaded before the server startup completion event. Before we can
add the publishers the event streams need to be loaded to the server, current event streams are file based,
and it's loading is triggered using a server startup observer which runs on completingServerStartup
method (org.wso2.carbon.core.internal.DeploymentServerStartupObserver). There is currently no way to make
sure the calling order, therefore this is the only way to guarantee the publishers are loaded after the
event streams are loaded.
*/
ResourceUtils.loadTenantPublisherConfigurationFromConfigStore();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.wso2.carbon.core.ServerStartupObserver;
import org.wso2.carbon.event.publisher.core.EventPublisherService;
import org.wso2.carbon.event.stream.core.EventStreamService;
import org.wso2.carbon.identity.configuration.mgt.core.ConfigurationManager;
Expand Down Expand Up @@ -60,6 +61,8 @@ protected void activate(ComponentContext context) {
context.getBundleContext()
.registerService(ResourceManager.class.getName(), resourceManager, null);
TenantResourceManagerDataHolder.getInstance().setResourceManager(resourceManager);
context.getBundleContext().registerService(ServerStartupObserver.class.getName(),
new TenantResourceManagementServerStartupObserver(), null);
if (log.isDebugEnabled()) {
log.debug("Successfully deployed the tenant resource manager service.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,23 @@
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.event.publisher.core.config.EventPublisherConfiguration;
import org.wso2.carbon.event.publisher.core.exception.EventPublisherConfigurationException;
import org.wso2.carbon.event.stream.core.EventStreamConfiguration;
import org.wso2.carbon.event.stream.core.exception.EventStreamConfigurationException;
import org.wso2.carbon.identity.configuration.mgt.core.constant.ConfigurationConstants;
import org.wso2.carbon.identity.configuration.mgt.core.exception.ConfigurationManagementException;
import org.wso2.carbon.identity.configuration.mgt.core.model.Resource;
import org.wso2.carbon.identity.configuration.mgt.core.model.ResourceFile;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.tenant.resource.manager.constants.TenantResourceConstants;
import org.wso2.carbon.identity.tenant.resource.manager.exception.TenantResourceManagementException;
import org.wso2.carbon.identity.tenant.resource.manager.exception.TenantResourceManagementServerException;
import org.wso2.carbon.identity.tenant.resource.manager.internal.TenantResourceManagerDataHolder;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;

import java.util.List;

import static org.wso2.carbon.identity.tenant.resource.manager.constants.TenantResourceConstants.ErrorMessages.ERROR_CODE_ERROR_WHEN_ADDING_EVENT_PUBLISHER_CONFIGURATION;
import static org.wso2.carbon.identity.tenant.resource.manager.constants.TenantResourceConstants.ErrorMessages.ERROR_CODE_ERROR_WHEN_CREATING_TENANT_EVENT_PUBLISHER_CONFIGURATION_USING_SUPER_TENANT_CONFIG;
import static org.wso2.carbon.identity.tenant.resource.manager.constants.TenantResourceConstants.ErrorMessages.ERROR_CODE_ERROR_WHEN_FETCHING_TENANT_SPECIFIC_PUBLISHER_FILES;
import static org.wso2.carbon.identity.tenant.resource.manager.constants.TenantResourceConstants.PUBLISHER;

/**
* Utility methods for tenant resource management.
Expand Down Expand Up @@ -139,4 +145,50 @@ public static void startSuperTenantFlow() {
carbonContext.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
carbonContext.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
}

/**
* This method loads publisher configurations tenant wise by fetching them from configuration store.
*/
public static void loadTenantPublisherConfigurationFromConfigStore() {

try {
List<Resource> resourcesByTypePublisher = TenantResourceManagerDataHolder.getInstance()
.getConfigurationManager().getResourcesByType(PUBLISHER).getResources();
for (Resource resource : resourcesByTypePublisher) {
if (!resource.getFiles().isEmpty()) {
ResourceFile tenantSpecificPublisherFile = resource.getFiles().get(0);
if (tenantSpecificPublisherFile != null) {
if (log.isDebugEnabled()) {
log.debug("File for publisher name: " + tenantSpecificPublisherFile.getName()
+ " is available in the configuration store.");
}
TenantResourceManagerDataHolder.getInstance().getResourceManager()
.addEventPublisherConfiguration(tenantSpecificPublisherFile);
}
}
}
} catch (ConfigurationManagementException e) {
if (e.getErrorCode()
.equals(ConfigurationConstants.ErrorMessages.ERROR_CODE_FEATURE_NOT_ENABLED.getCode())) {
log.warn("Configuration store is disabled. Super tenant configuration will be used for the tenant "
+ "domain: " + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain());
} else if (e.getErrorCode()
.equals(ConfigurationConstants.ErrorMessages.ERROR_CODE_RESOURCES_DOES_NOT_EXISTS.getCode())) {
log.warn("Configuration store does not contain any resources under resource type publisher. Super "
+ "tenant configurations will be used for the tenant domain: " + PrivilegedCarbonContext
.getThreadLocalCarbonContext().getTenantDomain());
} else if (e.getErrorCode()
.equals(ConfigurationConstants.ErrorMessages.ERROR_CODE_RESOURCE_TYPE_DOES_NOT_EXISTS.getCode())) {
log.warn("Configuration store does not contain publisher resource type. Super "
+ "tenant configurations will be used for the tenant domain: " + PrivilegedCarbonContext
.getThreadLocalCarbonContext().getTenantDomain());
} else {
log.error(populateMessageWithData(ERROR_CODE_ERROR_WHEN_FETCHING_TENANT_SPECIFIC_PUBLISHER_FILES,
PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()), e);
}
} catch (TenantResourceManagementException e) {
log.error(populateMessageWithData(ERROR_CODE_ERROR_WHEN_ADDING_EVENT_PUBLISHER_CONFIGURATION,
PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ private void prepareConfigs() throws Exception {
Mockito.when(tenantResourceManagerDataHolder.getConfigurationManager()).thenReturn(configurationManager);
Mockito.when(tenantResourceManagerDataHolder.getCarbonEventPublisherService())
.thenReturn(carbonEventPublisherService);
mockedResourceUtils.when(ResourceUtils::loadTenantPublisherConfigurationFromConfigStore).thenCallRealMethod();

File sampleResourceFile = new File(getSamplesPath());
InputStream fileStream = FileUtils.openInputStream(sampleResourceFile);
Expand Down

0 comments on commit 70315aa

Please sign in to comment.