Skip to content

Commit

Permalink
Add on-demand b2b child org template migration.
Browse files Browse the repository at this point in the history
  • Loading branch information
dhaura committed Dec 5, 2024
1 parent 661105b commit ef0a314
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,31 @@

package org.wso2.carbon.email.mgt.store;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.email.mgt.internal.I18nMgtDataHolder;
import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
import org.wso2.carbon.identity.application.mgt.ApplicationManagementService;
import org.wso2.carbon.identity.core.ThreadLocalAwareExecutors;
import org.wso2.carbon.identity.governance.exceptions.notiification.NotificationTemplateManagerServerException;
import org.wso2.carbon.identity.governance.model.NotificationTemplate;
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
import org.wso2.carbon.identity.organization.management.service.model.BasicOrganization;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

/**
* This class is responsible for on-demand migrating notification templates from the registry to the database.
Expand All @@ -38,6 +53,7 @@
public class HybridTemplateManager implements TemplatePersistenceManager {

private static final Log log = LogFactory.getLog(HybridTemplateManager.class);
private final ExecutorService executorService = ThreadLocalAwareExecutors.newFixedThreadPool(1);

private TemplatePersistenceManager dbBasedTemplateManager = new DBBasedTemplateManager();
private TemplatePersistenceManager registryBasedTemplateManager = new RegistryBasedTemplateManager();
Expand Down Expand Up @@ -137,6 +153,8 @@ public void addOrUpdateNotificationTemplate(NotificationTemplate notificationTem

if (registryBasedTemplateManager.isNotificationTemplateExists(displayName, locale, notificationChannel,
applicationUuid, tenantDomain)) {
NotificationTemplate registryBasedTemplate = registryBasedTemplateManager.getNotificationTemplate(displayName,
locale, notificationChannel, applicationUuid, tenantDomain);

// registryBasedTemplateManager.deleteNotificationTemplate(displayName, locale, notificationChannel,
// applicationUuid, tenantDomain);
Expand All @@ -148,6 +166,12 @@ public void addOrUpdateNotificationTemplate(NotificationTemplate notificationTem
"Moved %s template: %s for locale: %s in tenant: %s from registry to the database.",
notificationChannel, displayName, locale, tenantDomain));
}

String usernameInContext = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
CompletableFuture.runAsync(
() -> migrateChildOrgTemplates(registryBasedTemplate, tenantDomain, applicationUuid,
usernameInContext),
executorService);
}
}

Expand Down Expand Up @@ -277,4 +301,89 @@ private <T> List<T> mergeAndRemoveDuplicates(List<T> list1, List<T> list2) {
uniqueElements.addAll(list2);
return new ArrayList<>(uniqueElements);
}

private void migrateChildOrgTemplates(NotificationTemplate parentTemplate, String parentTenantDomain,
String parentAppId, String usernameInContext) {

String cursor = null;
int pageSize = 100;
try {
String displayName = parentTemplate.getDisplayName();
String locale = parentTemplate.getLocale();
String notificationChannel = parentTemplate.getNotificationChannel();

PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(parentTenantDomain, true);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(usernameInContext);

OrganizationManager organizationManager = I18nMgtDataHolder.getInstance().getOrganizationManager();
ApplicationManagementService applicationManagementService =
I18nMgtDataHolder.getInstance().getApplicationManagementService();
do {
try {
List<BasicOrganization> childOrganizations =
organizationManager.getOrganizations(pageSize, cursor, null, "DESC", "", false);
Map<String, String> childAppIds = new HashMap<>();
if (StringUtils.isNotBlank(parentAppId)) {
childAppIds = applicationManagementService.getChildAppIds(parentAppId, parentTenantDomain,
childOrganizations.stream().map(BasicOrganization::getId).collect(Collectors.toList()));
if (childAppIds.isEmpty()) {
continue;
}
}
for (BasicOrganization childOrganization : childOrganizations) {
String childTenantDomain = organizationManager.resolveTenantDomain(childOrganization.getId());
String childAppId = childAppIds.get(childTenantDomain);

if (StringUtils.isNotBlank(parentAppId) && StringUtils.isBlank(childAppId)) {
continue;
}

NotificationTemplate childNotificationTemplate =
registryBasedTemplateManager.getNotificationTemplate(
displayName, locale, notificationChannel, childAppId, childTenantDomain);
if (childNotificationTemplate != null) {
if (!areNotificationTemplatesEqual(parentTemplate, childNotificationTemplate) &&
!dbBasedTemplateManager.isNotificationTemplateExists(displayName, locale,
notificationChannel, childAppId, childTenantDomain)) {
dbBasedTemplateManager.addOrUpdateNotificationTemplate(childNotificationTemplate,
childAppId, childTenantDomain);
}

registryBasedTemplateManager.deleteNotificationTemplates(displayName, notificationChannel,
childAppId, childTenantDomain);
migrateChildOrgTemplates(childNotificationTemplate, childTenantDomain, childAppId,
usernameInContext);
}
}
cursor = childOrganizations.isEmpty() ? null : Base64.getEncoder().encodeToString(
childOrganizations.get(childOrganizations.size() - 1).getCreated()
.getBytes(StandardCharsets.UTF_8));
} catch (OrganizationManagementException e) {
log.error("Error occurred while retrieving child organizations of organization " +
"with tenant domain: " + parentTenantDomain, e);
} catch (IdentityApplicationManagementException e){
log.error("Error occurred while retrieving child app ids of application with id: " +
parentAppId + " and tenant domain: " + parentTenantDomain, e);
} catch (NotificationTemplateManagerServerException e) {
log.error("Error occurred while migrating child organization templates of parent template: " +
displayName + " for locale: " + locale + " and notification channel: " +
notificationChannel, e);
}
} while (cursor != null);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}

private boolean areNotificationTemplatesEqual(NotificationTemplate template1, NotificationTemplate template2) {

return StringUtils.equals(template1.getDisplayName(), template2.getDisplayName()) &&
StringUtils.equals(template1.getLocale(), template2.getLocale()) &&
StringUtils.equals(template1.getNotificationChannel(), template2.getNotificationChannel()) &&
StringUtils.equals(template1.getContentType(), template2.getContentType()) &&
StringUtils.equals(template1.getBody(), template2.getBody()) &&
StringUtils.equals(template1.getSubject(), template2.getSubject()) &&
StringUtils.equals(template1.getFooter(), template2.getFooter());
}
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@
<org.wso2.carbon.database.utils.version.range>[2.1.0,3.0.0)</org.wso2.carbon.database.utils.version.range>

<!--Carbon Identity Framework Version-->
<carbon.identity.framework.version>7.1.0</carbon.identity.framework.version>
<carbon.identity.framework.version>7.7.2</carbon.identity.framework.version>
<carbon.identity.framework.imp.pkg.version.range>[7.1.0, 8.0.0)</carbon.identity.framework.imp.pkg.version.range>

<!-- Organization management Version -->
Expand Down

0 comments on commit ef0a314

Please sign in to comment.