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.Map;
import java.util.Set; import java.util.Set;
import java.util.Date; 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 * 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_GLOBAL_VISIBILITY = "PUBLIC";
public static final String API_PRIVATE_VISIBILITY = "PRIVATE"; public static final String API_PRIVATE_VISIBILITY = "PRIVATE";
private static final String ADMIN_ROLE_KEY = "admin"; private static final String ADMIN_ROLE_KEY = "admin";
private static final ExecutorService scopeRoleExecutorService = Executors.newCachedThreadPool();
private static final Log log = LogFactory.getLog(APIPublisherServiceImpl.class); 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 @Override
public void publishAPI(APIConfig apiConfig) throws APIManagerPublisherException { public void publishAPI(APIConfig apiConfig) throws APIManagerPublisherException {
@ -635,18 +674,12 @@ public class APIPublisherServiceImpl implements APIPublisherService {
Map<String, String> permScopeMap = APIPublisherDataHolder.getInstance().getPermScopeMapping(); Map<String, String> permScopeMap = APIPublisherDataHolder.getInstance().getPermScopeMapping();
if (permissions.length != 0) { 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) { if (removedPermissions.length != 0) {
updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList, removedPermissions, permScopeMap, true); updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList,
} removedPermissions, permissions, 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);
} }
} catch (APIServicesException e) { } catch (APIServicesException e) {
String errorMsg = "Error while processing Publisher REST API response"; 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. * @throws APIManagerPublisherException If the method receives invalid permission to update.
*/ */
private void updateScopes (String roleName, PublisherRESTAPIServices publisherRESTAPIServices, private void updateScopes (String roleName, PublisherRESTAPIServices publisherRESTAPIServices,
APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope[] scopeList,
Scope[] scopeList, String[] permissions, Map<String, String> permScopeMap, boolean removingPermissions ) String[] permissions, String[] allowedPermissions,
Map<String, String> permScopeMap, boolean removingPermissions)
throws APIManagerPublisherException { throws APIManagerPublisherException {
Phaser phaser = new Phaser(1);
for (String permission : permissions) { for (String permission : permissions) {
String scopeValue = permScopeMap.get(permission); String scopeValue = permScopeMap.get(permission);
if (scopeValue == null) { if (scopeValue == null) {
@ -714,21 +749,21 @@ public class APIPublisherServiceImpl implements APIPublisherService {
} }
} }
scope.setBindings(existingRoleList); scope.setBindings(existingRoleList);
scopeRoleExecutorService.submit(new ScopeUpdaterTask(phaser, publisherRESTAPIServices,
try { apiApplicationKey, accessTokenInfo, scope));
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);
}
break; 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 { private void updatePermissions(String role, List<String> permissions) throws UserStoreException {

@ -724,9 +724,6 @@ public class RoleManagementServiceImpl implements RoleManagementService {
*/ */
private void updatePermissions(String roleName, RoleInfo roleInfo, UserRealm userRealm) { private void updatePermissions(String roleName, RoleInfo roleInfo, UserRealm userRealm) {
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true); String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try { try {
PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
@ -740,7 +737,4 @@ public class RoleManagementServiceImpl implements RoleManagementService {
PrivilegedCarbonContext.endTenantFlow(); PrivilegedCarbonContext.endTenantFlow();
} }
} }
});
thread.start();
}
} }

Loading…
Cancel
Save