Add performance enhancement for permission updating procedure

pull/268/head
Rajitha Kumara 1 year ago
parent 95b2750d8b
commit 0736559283

@ -80,6 +80,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Phaser;
/**
* This class represents the concrete implementation of the APIPublisherService that corresponds to providing all
@ -98,8 +102,43 @@ public class APIPublisherServiceImpl implements APIPublisherService {
public static final String API_GLOBAL_VISIBILITY = "PUBLIC";
public static final String API_PRIVATE_VISIBILITY = "PRIVATE";
private static final String ADMIN_ROLE_KEY = "admin";
private static final ExecutorService scopeRoleExecutorService = Executors.newCachedThreadPool();
private static final Log log = LogFactory.getLog(APIPublisherServiceImpl.class);
public static class ScopeUpdaterTask implements Runnable {
private final Phaser phaser;
private final PublisherRESTAPIServices publisherRESTAPIServices;
private final APIApplicationKey apiApplicationKey;
private final AccessTokenInfo accessTokenInfo;
private final Scope scope;
public ScopeUpdaterTask(Phaser phaser, PublisherRESTAPIServices publisherRESTAPIServices,
APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope) {
this.phaser = phaser;
this.publisherRESTAPIServices = publisherRESTAPIServices;
this.apiApplicationKey = apiApplicationKey;
this.accessTokenInfo = accessTokenInfo;
this.scope = scope;
}
@Override
public void run() {
phaser.register();
try {
if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, scope.getName())) {
publisherRESTAPIServices.updateSharedScope(apiApplicationKey, accessTokenInfo, scope);
} else {
// todo: come to this level means, that scope is removed from API, but haven't removed from the scope-role-permission-mappings list
log.warn(scope.getName() + " not available as shared scope");
}
} catch (Exception e) {
log.info("Error occurred while updating role scope mapping via APIM REST endpoint.", e);
} finally {
if (log.isDebugEnabled()) {
log.debug("Role binding is completed for scope" + scope.getName());
}
phaser.arriveAndDeregister();
}
}
}
@Override
public void publishAPI(APIConfig apiConfig) throws APIManagerPublisherException {
@ -635,18 +674,12 @@ public class APIPublisherServiceImpl implements APIPublisherService {
Map<String, String> permScopeMap = APIPublisherDataHolder.getInstance().getPermScopeMapping();
if (permissions.length != 0) {
updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList, permissions, permScopeMap, false);
updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList,
permissions, permissions, permScopeMap, false);
}
if (removedPermissions.length != 0) {
updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList, removedPermissions, permScopeMap, true);
}
try {
updatePermissions(roleName, Arrays.asList(permissions));
} catch (UserStoreException e) {
String errorMsg = "Error occurred when adding permissions to role: " + roleName;
log.error(errorMsg, e);
throw new APIManagerPublisherException(errorMsg, e);
updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList,
removedPermissions, permissions, permScopeMap, true);
}
} catch (APIServicesException e) {
String errorMsg = "Error while processing Publisher REST API response";
@ -677,9 +710,11 @@ public class APIPublisherServiceImpl implements APIPublisherService {
* @throws APIManagerPublisherException If the method receives invalid permission to update.
*/
private void updateScopes (String roleName, PublisherRESTAPIServices publisherRESTAPIServices,
APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
Scope[] scopeList, String[] permissions, Map<String, String> permScopeMap, boolean removingPermissions )
APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope[] scopeList,
String[] permissions, String[] allowedPermissions,
Map<String, String> permScopeMap, boolean removingPermissions)
throws APIManagerPublisherException {
Phaser phaser = new Phaser(1);
for (String permission : permissions) {
String scopeValue = permScopeMap.get(permission);
if (scopeValue == null) {
@ -714,21 +749,21 @@ public class APIPublisherServiceImpl implements APIPublisherService {
}
}
scope.setBindings(existingRoleList);
try {
if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, scope.getName())) {
publisherRESTAPIServices.updateSharedScope(apiApplicationKey, accessTokenInfo, scope);
} else {
// todo: come to this level means, that scope is removed from API, but haven't removed from the scope-role-permission-mappings list
log.warn(scope.getName() + " not available as shared scope");
}
} catch (APIServicesException | BadRequestException | UnexpectedResponseException e) {
log.error("Error occurred while updating role scope mapping via APIM REST endpoint.", e);
}
scopeRoleExecutorService.submit(new ScopeUpdaterTask(phaser, publisherRESTAPIServices,
apiApplicationKey, accessTokenInfo, scope));
break;
}
}
}
try {
updatePermissions(roleName, Arrays.asList(allowedPermissions));
} catch (UserStoreException e) {
String errorMsg = "Error occurred when adding permissions to role: " + roleName;
log.error(errorMsg, e);
throw new APIManagerPublisherException(errorMsg, e);
}
phaser.arriveAndAwaitAdvance();
log.info("Permission and scope updating is successfully completed for role : " + roleName);
}
private void updatePermissions(String role, List<String> permissions) throws UserStoreException {

@ -724,23 +724,17 @@ public class RoleManagementServiceImpl implements RoleManagementService {
*/
private void updatePermissions(String roleName, RoleInfo roleInfo, UserRealm userRealm) {
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
DeviceMgtAPIUtils.getApiPublisher().updateScopeRoleMapping(roleName,
RoleManagementServiceImpl.this.getPlatformUIPermissions(roleName, userRealm,
roleInfo.getPermissions()), RoleManagementServiceImpl.this.getPlatformUIPermissions(roleName, userRealm,
roleInfo.getRemovedPermissions()));
} catch (APIManagerPublisherException | UserAdminException e) {
log.error("Error Occurred while updating role scope mapping. ", e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
});
thread.start();
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
DeviceMgtAPIUtils.getApiPublisher().updateScopeRoleMapping(roleName,
RoleManagementServiceImpl.this.getPlatformUIPermissions(roleName, userRealm,
roleInfo.getPermissions()), RoleManagementServiceImpl.this.getPlatformUIPermissions(roleName, userRealm,
roleInfo.getRemovedPermissions()));
} catch (APIManagerPublisherException | UserAdminException e) {
log.error("Error Occurred while updating role scope mapping. ", e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}

Loading…
Cancel
Save