use of cz.metacentrum.perun.core.api.CandidateGroup in project perun by CESNET.
the class GroupsManagerBlImpl method specifyParentForUpdatedGroup.
/**
* Specify parent group for group which is updated by synchronization
*
* Method is used by group structure synchronization.
*
* @param groupToUpdate for which will be parent specified
* @param baseGroup under which may be new parent
* @param candidateGroup with potential new parent group
* @param loginAttributeName attribute name for login of group
* @return updated parent group (if null, parent group hasn't changed)
* @throws InternalErrorException
*/
private Group specifyParentForUpdatedGroup(PerunSession sess, Group groupToUpdate, Group baseGroup, CandidateGroup candidateGroup, String loginAttributeName) {
// get current parent of updated group, if there is no group (null), it means the group is under the base group
String oldParentGroupLogin = getOldParentGroupLogin(sess, groupToUpdate, baseGroup, loginAttributeName);
// check if there is difference between parents of current and new group, if not, return null
if (Objects.equals(oldParentGroupLogin, candidateGroup.getParentGroupLogin()))
return null;
// if there is difference, we need to find a new parent group
Group newParentGroup = getNewParentGroup(sess, candidateGroup, baseGroup, loginAttributeName);
// check if the new parent group is also under the base group somewhere (if not, set base group as new parent group)
if (!newParentGroup.equals(baseGroup) && !getAllSubGroups(sess, baseGroup).contains(newParentGroup)) {
newParentGroup = baseGroup;
}
// check situation, where group is already under base group and the destination parent group is now base group too
if (oldParentGroupLogin == null && newParentGroup.equals(baseGroup)) {
return null;
}
return newParentGroup;
}
use of cz.metacentrum.perun.core.api.CandidateGroup in project perun by CESNET.
the class GroupsManagerBlImpl method updateExistingGroupsWhileSynchronization.
/**
* Get Map groupsToUpdate and update their parent group and description.
* We don't have to update short name, because if short name has changed, group will be removed and created with new name.
*
* If some problem occurs, add groupToUpdate to skippedGroups and skip it.
*
* Method is used by group structure synchronization.
*
* @param sess
* @param baseGroup under which will be group structure synchronized
* @param groupsToUpdate list of groups for updating in Perun by information from extSource
* @param removedGroupsIds list of ids already removed groups (these groups not exists in Perun anymore)
* @param loginAttributeDefinition attribute definition for login of group
* @param skippedGroups groups to be skipped because of any expected problem
*
* @throws InternalErrorException if some internal error occurs
*/
private void updateExistingGroupsWhileSynchronization(PerunSession sess, Group baseGroup, Map<CandidateGroup, Group> groupsToUpdate, List<Integer> removedGroupsIds, AttributeDefinition loginAttributeDefinition, List<String> skippedGroups, List<String> mergeAttributes) {
for (CandidateGroup candidateGroup : groupsToUpdate.keySet()) {
Group groupToUpdate = groupsToUpdate.get(candidateGroup);
// If group had parent which was already removed from perun, it was moved under base group, change it's parent group id properly for updating
if (removedGroupsIds.contains(groupToUpdate.getParentGroupId()))
groupToUpdate.setParentGroupId(baseGroup.getId());
setUpAdditionalAttributes(sess, groupToUpdate, candidateGroup.getAdditionalAttributes(), mergeAttributes);
Group newParentGroup = specifyParentForUpdatedGroup(sess, groupToUpdate, baseGroup, candidateGroup, loginAttributeDefinition.getName());
if (newParentGroup != null) {
try {
moveGroup(sess, newParentGroup, groupToUpdate);
log.trace("Group structure synchronization {}: value of the parentGroupId for groupId {} changed. Original value {}, new value {}.", baseGroup, groupToUpdate.getId(), groupToUpdate.getParentGroupId(), newParentGroup.getId());
} catch (GroupMoveNotAllowedException e) {
log.warn("Can't update group {} due to group move not allowed exception {}.", groupToUpdate, e);
skippedGroups.add("GroupEntry:[" + groupToUpdate + "] was skipped because group move is not allowed: Exception: " + e.getName() + " => " + e.getMessage() + "]");
continue;
} catch (WrongAttributeValueException e) {
log.warn("Can't update group {} from baseGroup {} due to wrong attribute value exception {}.", groupToUpdate, e);
skippedGroups.add("GroupEntry:[" + groupToUpdate + "] was skipped because of wrong attribute value: Exception: " + e.getName() + " => " + e.getMessage() + "]");
continue;
} catch (WrongReferenceAttributeValueException e) {
log.warn("Can't update group {} from baseGroup {} due to wrong reference attribute value exception {}.", groupToUpdate, e);
skippedGroups.add("GroupEntry:[" + groupToUpdate + "] was skipped because of wrong reference attribute value: Exception: " + e.getName() + " => " + e.getMessage() + "]");
continue;
}
}
boolean changed = updateGroupDescription(sess, groupToUpdate, candidateGroup);
if (changed) {
log.trace("Group structure synchronization {}: value of the group description for groupId {} changed. Original value {}, new value {}.", baseGroup, groupToUpdate.getId(), groupToUpdate.getDescription(), candidateGroup.asGroup().getDescription());
}
}
}
use of cz.metacentrum.perun.core.api.CandidateGroup in project perun by CESNET.
the class GroupsManagerBlImpl method getNewParentGroup.
/**
* Return parent group for the candidate group
*
* @param sess perun session
* @param candidateGroup candidate group
* @param baseGroup base group in structure
* @param loginAttributeName attribute name of login in the structure
* @return parent group of candidate group, if there is none, return base group
*/
private Group getNewParentGroup(PerunSession sess, CandidateGroup candidateGroup, Group baseGroup, String loginAttributeName) {
Group newParentGroup = baseGroup;
// if parent group login is not null, we need to find this new parent group (otherwise it is base group)
if (candidateGroup.getParentGroupLogin() != null) {
try {
// we need to have vo to filter groups, base group has to be from the same vo as new parent of candidate group
Vo baseGroupVo = getPerunBl().getVosManagerBl().getVoById(sess, baseGroup.getVoId());
List<Group> groupsWithLogin = getPerunBl().getSearcherBl().getGroups(sess, baseGroupVo, Collections.singletonMap(loginAttributeName, candidateGroup.getParentGroupLogin()));
// if there is missing the destination parent group, set base group as parent, there could be missing parent group in the extSource data
if (!groupsWithLogin.isEmpty()) {
// if there are more than one group with login, there is no way how to choose correct behavior
if (groupsWithLogin.size() > 1)
throw new InternalErrorException("More than 1 group has login attribute '" + loginAttributeName + "' set with the same login " + candidateGroup.getParentGroupLogin());
// our new parent group is exactly the one with the login set
return groupsWithLogin.get(0);
}
} catch (VoNotExistsException ex) {
throw new InternalErrorException("Vo of base group: " + baseGroup + " can't be found. Unexpected situation, can't continue.");
} catch (AttributeNotExistsException ex) {
throw new InternalErrorException("Can't find attribute definition for '" + loginAttributeName + "'.");
}
}
return newParentGroup;
}
use of cz.metacentrum.perun.core.api.CandidateGroup in project perun by CESNET.
the class GroupsManagerBlImpl method synchronizeGroupStructure.
@Override
public List<String> synchronizeGroupStructure(PerunSession sess, Group baseGroup) throws AttributeNotExistsException, WrongAttributeAssignmentException, ExtSourceNotExistsException, WrongAttributeValueException, WrongReferenceAttributeValueException {
List<String> skippedGroups = new ArrayList<>();
log.info("Group structure synchronization {}: started.", baseGroup);
// get extSource for group structure
ExtSource source = getGroupExtSourceForSynchronization(sess, baseGroup);
try {
// get login attribute for structure
AttributeDefinition loginAttributeDefinition = getLoginAttributeForGroupStructure(sess, baseGroup);
// get login prefix if exists
String loginPrefix = getLoginPrefixForGroupStructure(sess, baseGroup);
List<CandidateGroup> candidateGroupsToAdd = new ArrayList<>();
Map<CandidateGroup, Group> groupsToUpdate = new HashMap<>();
List<Group> groupsToRemove = new ArrayList<>();
Map<String, Group> actualGroups = getAllSubGroupsWithLogins(sess, baseGroup, loginAttributeDefinition);
List<Map<String, String>> subjectGroups = getSubjectGroupsFromExtSource(sess, source, baseGroup);
if (isThisFlatSynchronization(sess, baseGroup)) {
for (Map<String, String> subjectGroup : subjectGroups) {
subjectGroup.put(PARENT_GROUP_LOGIN, null);
}
}
List<String> mergeAttributes = getAttributesListFromExtSource(source, MERGE_GROUP_ATTRIBUTES);
List<CandidateGroup> candidateGroups = getPerunBl().getExtSourcesManagerBl().generateCandidateGroups(sess, subjectGroups, source, loginPrefix);
categorizeGroupsForSynchronization(actualGroups, candidateGroups, candidateGroupsToAdd, groupsToUpdate, groupsToRemove);
// order of operations is important here
// removing need to go first to be able to replace groups with same name but different login
// updating need to be last to set right order of groups again
List<Integer> removedGroupsIds = removeFormerGroupsWhileSynchronization(sess, baseGroup, groupsToRemove, skippedGroups);
addMissingGroupsWhileSynchronization(sess, baseGroup, candidateGroupsToAdd, loginAttributeDefinition, skippedGroups, mergeAttributes);
updateExistingGroupsWhileSynchronization(sess, baseGroup, groupsToUpdate, removedGroupsIds, loginAttributeDefinition, skippedGroups, mergeAttributes);
setUpSynchronizationAttributesForAllSubGroups(sess, baseGroup, source, loginAttributeDefinition, loginPrefix);
syncResourcesForSynchronization(sess, baseGroup, loginAttributeDefinition, skippedGroups);
log.info("Group structure synchronization {}: ended.", baseGroup);
return skippedGroups;
} finally {
if (source instanceof ExtSourceSimpleApi) {
try {
((ExtSourceSimpleApi) source).close();
} catch (ExtSourceUnsupportedOperationException e) {
// silently skip
} catch (Exception e) {
log.error("Failed to close extsource after structure synchronization.", e);
}
}
}
}
use of cz.metacentrum.perun.core.api.CandidateGroup in project perun by CESNET.
the class GroupsManagerBlImpl method categorizeGroupsForSynchronization.
/**
* This method categorize candidate groups to groups to add, update and remove
*
* Method used by group structure synchronization
*
* @param currentGroups current groups
* @param candidateGroups to be synchronized from extSource
* @param groupsToUpdate Candidate groups with equivalent Groups from Perun for purpose of updating attributes
* @param candidateGroupsToAdd New groups
* @param groupsToRemove Former groups which are not in synchronized ExtSource now
*/
private void categorizeGroupsForSynchronization(Map<String, Group> currentGroups, List<CandidateGroup> candidateGroups, List<CandidateGroup> candidateGroupsToAdd, Map<CandidateGroup, Group> groupsToUpdate, List<Group> groupsToRemove) {
candidateGroupsToAdd.addAll(candidateGroups);
groupsToRemove.addAll(currentGroups.values());
for (CandidateGroup candidateGroup : candidateGroups) {
String loginOfCandidateGroup = candidateGroup.getLogin();
if (currentGroups.containsKey(loginOfCandidateGroup)) {
groupsToUpdate.put(candidateGroup, currentGroups.get(loginOfCandidateGroup));
candidateGroupsToAdd.remove(candidateGroup);
groupsToRemove.remove(currentGroups.get(loginOfCandidateGroup));
}
}
}
Aggregations