Skip to content

Commit

Permalink
Update role mining feature
Browse files Browse the repository at this point in the history
  • Loading branch information
tchrapovic committed Aug 10, 2023
1 parent 675baa7 commit a83ec2c
Show file tree
Hide file tree
Showing 12 changed files with 287 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@

import java.util.List;

import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.object.ClusterOptions;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleAnalysisClusterType;

public interface Clusterable {
List<PrismObject<RoleAnalysisClusterType>> executeClustering(ClusterOptions clusterOptions);
List<PrismObject<RoleAnalysisClusterType>> executeClustering(ClusterOptions clusterOptions,
OperationResult result, PageBase pageBase);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,24 @@

package com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.cluster;

import java.util.ArrayList;
import java.util.List;

import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.object.ClusterOptions;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleAnalysisClusterType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleAnalysisProcessModeType;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.jetbrains.annotations.NotNull;

import javax.xml.namespace.QName;

import static com.evolveum.midpoint.gui.impl.page.admin.role.mining.utils.ClusterObjectUtils.importRoleAnalysisClusterObject;
import static com.evolveum.midpoint.gui.impl.page.admin.role.mining.utils.ClusterObjectUtils.importRoleAnalysisSessionObject;
import static com.evolveum.midpoint.gui.impl.page.admin.role.mining.utils.Tools.endTimer;
import static com.evolveum.midpoint.gui.impl.page.admin.role.mining.utils.Tools.startTimer;

public class ClusteringAction {

Expand All @@ -26,7 +38,100 @@ public ClusteringAction(RoleAnalysisProcessModeType mode) {
}
}

public List<PrismObject<RoleAnalysisClusterType>> execute(ClusterOptions clusterOptions) {
return clusterable.executeClustering(clusterOptions);
public void execute(@NotNull PageBase pageBase, @NotNull ClusterOptions clusterOptions,
@NotNull OperationResult operationResult, @NotNull Task task) {

RoleAnalysisSessionOptionType roleAnalysisSessionClusterOption = getRoleAnalysisSessionFilterOption(clusterOptions);

RoleAnalysisDetectionOptionType roleAnalysisSessionDetectionOption = getRoleAnalysisSessionDetectionOption(clusterOptions);

List<PrismObject<RoleAnalysisClusterType>> clusterObjects = clusterable.executeClustering(clusterOptions,
operationResult, pageBase);

importObjects(clusterObjects, clusterOptions,
roleAnalysisSessionClusterOption, roleAnalysisSessionDetectionOption, pageBase, operationResult, task);

}

@NotNull
private RoleAnalysisDetectionOptionType getRoleAnalysisSessionDetectionOption(ClusterOptions clusterOptions) {
RoleAnalysisDetectionOptionType roleAnalysisSessionDetectionOption = new RoleAnalysisDetectionOptionType();
roleAnalysisSessionDetectionOption.setDetectionMode(clusterOptions.getSearchMode());
roleAnalysisSessionDetectionOption.setMinFrequencyThreshold(clusterOptions.getDefaultMinFrequency());
roleAnalysisSessionDetectionOption.setMaxFrequencyThreshold(clusterOptions.getDefaultMaxFrequency());
roleAnalysisSessionDetectionOption.setMinMembersOccupancy(clusterOptions.getDefaultOccupancySearch());
roleAnalysisSessionDetectionOption.setMinPropertiesOccupancy(clusterOptions.getDefaultIntersectionSearch());
roleAnalysisSessionDetectionOption.setJaccardSimilarityThreshold(clusterOptions.getDefaultJaccardThreshold());

return roleAnalysisSessionDetectionOption;
}

@NotNull
private RoleAnalysisSessionOptionType getRoleAnalysisSessionFilterOption(ClusterOptions clusterOptions) {
RoleAnalysisSessionOptionType roleAnalysisSessionClusterOption = new RoleAnalysisSessionOptionType();
if (clusterOptions.getQuery() != null) {
roleAnalysisSessionClusterOption.setFilter(clusterOptions.getQuery().toString());
}

roleAnalysisSessionClusterOption.setProcessMode(clusterOptions.getMode());
roleAnalysisSessionClusterOption.setSimilarityThreshold(clusterOptions.getSimilarity());
roleAnalysisSessionClusterOption.setMinUniqueMembersCount(clusterOptions.getMinGroupSize());
roleAnalysisSessionClusterOption.setMinMembersCount(clusterOptions.getMinMembers());
roleAnalysisSessionClusterOption.setMinPropertiesCount(clusterOptions.getMinProperties());
roleAnalysisSessionClusterOption.setMaxPropertiesCount(clusterOptions.getMaxProperties());
roleAnalysisSessionClusterOption.setMinPropertiesOverlap(clusterOptions.getMinIntersections());
return roleAnalysisSessionClusterOption;
}

private void importObjects(List<PrismObject<RoleAnalysisClusterType>> clusters, ClusterOptions clusterOptions,
RoleAnalysisSessionOptionType roleAnalysisSessionClusterOption,
RoleAnalysisDetectionOptionType roleAnalysisSessionDetectionOption,
PageBase pageBase, OperationResult result, Task task) {

List<ObjectReferenceType> roleAnalysisClusterRef = new ArrayList<>();

int processedObjectCount = 0;

QName complexType;
if (clusterOptions.getMode().equals(RoleAnalysisProcessModeType.ROLE)) {
complexType = RoleType.COMPLEX_TYPE;
} else {complexType = UserType.COMPLEX_TYPE;}

double meanDensity = 0;
for (PrismObject<RoleAnalysisClusterType> clusterTypePrismObject : clusters) {
RoleAnalysisClusterStatisticType clusterStatistic = clusterTypePrismObject.asObjectable().getClusterStatistic();
meanDensity += clusterStatistic.getPropertiesDensity();
processedObjectCount += clusterStatistic.getMemberCount();

ObjectReferenceType objectReferenceType = new ObjectReferenceType();
objectReferenceType.setOid(clusterTypePrismObject.getOid());
objectReferenceType.setType(complexType);
roleAnalysisClusterRef.add(objectReferenceType);
}

meanDensity = meanDensity / clusters.size();

RoleAnalysisSessionStatisticType roleAnalysisSessionStatisticType = new RoleAnalysisSessionStatisticType();
roleAnalysisSessionStatisticType.setProcessedObjectCount(processedObjectCount);
roleAnalysisSessionStatisticType.setMeanDensity(meanDensity);

System.out.println("IMPORT SESSION");

ObjectReferenceType parentRef = importRoleAnalysisSessionObject(result, pageBase, roleAnalysisSessionClusterOption,
roleAnalysisSessionStatisticType, roleAnalysisClusterRef, clusterOptions.getName());
System.out.println("SESSION IMPORTED");
try {
int counter = 1;
for (PrismObject<RoleAnalysisClusterType> clusterTypePrismObject : clusters) {
System.out.println("IMPORT CLUSTER: "+counter+"/"+clusters.size());
importRoleAnalysisClusterObject(result, task, pageBase, clusterTypePrismObject, parentRef,
roleAnalysisSessionDetectionOption);
System.out.println("END IMPORTING CLUSTER: "+counter+"/"+clusters.size());
counter++;

}
} catch (NumberFormatException e) {
throw new RuntimeException("Import RoleAnalysisCluster object failed" + e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@
package com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.cluster;

import static com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.cluster.MiningDataUtils.*;
import static com.evolveum.midpoint.gui.impl.page.admin.role.mining.utils.ClusterObjectUtils.importRoleAnalysisClusterObject;
import static com.evolveum.midpoint.gui.impl.page.admin.role.mining.utils.ClusterObjectUtils.importRoleAnalysisSessionObject;
import static com.evolveum.midpoint.gui.impl.page.admin.role.mining.utils.Tools.endTimer;
import static com.evolveum.midpoint.gui.impl.page.admin.role.mining.utils.Tools.startTimer;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.object.ClusterOptions;
import com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.object.DataPoint;
import com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.utils.ClusterAlgorithmUtils;
import com.evolveum.midpoint.model.api.ActivitySubmissionOptions;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import com.google.common.collect.ListMultimap;
Expand All @@ -34,22 +34,22 @@
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.schema.result.OperationResult;

import javax.xml.namespace.QName;

public class RoleBasedClustering implements Clusterable {

@Override
public List<PrismObject<RoleAnalysisClusterType>> executeClustering(ClusterOptions clusterOptions) {
PageBase pageBase = clusterOptions.getPageBase();
public List<PrismObject<RoleAnalysisClusterType>> executeClustering(ClusterOptions clusterOptions,
OperationResult result, PageBase pageBase) {

// ts2(clusterOptions.getPageBase());
long start = startTimer(" prepare clustering object");
int assignThreshold = clusterOptions.getMinProperties();
int minIntersections = clusterOptions.getMinIntersections();
int threshold = Math.max(assignThreshold, minIntersections);
int maxProperties = Math.max(clusterOptions.getMaxProperties(), threshold);

ObjectFilter query = clusterOptions.getQuery();
OperationResult operationResult = new OperationResult("ExecuteRoleBasedClustering");
ListMultimap<List<String>, String> chunkMap = loadData(operationResult, pageBase,
ListMultimap<List<String>, String> chunkMap = loadData(result, pageBase,
threshold, maxProperties, query);
List<DataPoint> dataPoints = ClusterAlgorithmUtils.prepareDataPoints(chunkMap);
endTimer(start, "prepare clustering object. Objects count: " + dataPoints.size());
Expand All @@ -60,15 +60,16 @@ public List<PrismObject<RoleAnalysisClusterType>> executeClustering(ClusterOptio

//TODO
if (eps == 0.0) {
return new ClusterAlgorithmUtils().processExactMatch(pageBase, dataPoints, clusterOptions);
return new ClusterAlgorithmUtils().processExactMatch(pageBase, result, dataPoints, clusterOptions);
}

int minGroupSize = clusterOptions.getMinGroupSize();
DBSCANClusterer<DataPoint> dbscan = new DBSCANClusterer<>(eps, minGroupSize, distanceMeasure);
List<Cluster<DataPoint>> clusters = dbscan.cluster(dataPoints);
endTimer(start, "clustering");

return new ClusterAlgorithmUtils().processClusters(pageBase, dataPoints, clusters, clusterOptions);
return new ClusterAlgorithmUtils().processClusters(pageBase, result, dataPoints, clusters, clusterOptions);

}

private ListMultimap<List<String>, String> loadData(OperationResult result, @NotNull PageBase pageBase,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.List;
import java.util.Set;

import com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.cluster.test.DBSCANClusterer2;
import com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.object.ClusterOptions;
import com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.object.DataPoint;
import com.evolveum.midpoint.gui.impl.page.admin.role.mining.algorithm.utils.ClusterAlgorithmUtils;
Expand All @@ -33,7 +34,8 @@
public class UserBasedClustering implements Clusterable {

@Override
public List<PrismObject<RoleAnalysisClusterType>> executeClustering(ClusterOptions clusterOptions) {
public List<PrismObject<RoleAnalysisClusterType>> executeClustering(ClusterOptions clusterOptions,
OperationResult result, PageBase pageBase) {

long start = startTimer(" prepare clustering object");
int minIntersections = clusterOptions.getMinIntersections();
Expand All @@ -43,10 +45,8 @@ public List<PrismObject<RoleAnalysisClusterType>> executeClustering(ClusterOptio
clusterOptions.setMinProperties(threshold);
clusterOptions.setMinIntersections(minIntersections);

PageBase pageBase = clusterOptions.getPageBase();
//roles //users
OperationResult operationResult = new OperationResult("ExecuteUserBasedClustering");
ListMultimap<List<String>, String> chunkMap = loadData(operationResult, pageBase,
ListMultimap<List<String>, String> chunkMap = loadData(result, pageBase,
threshold, maxProperties, clusterOptions.getQuery());
List<DataPoint> dataPoints = ClusterAlgorithmUtils.prepareDataPoints(chunkMap);
endTimer(start, "prepare clustering object. Objects count: " + dataPoints.size());
Expand All @@ -56,15 +56,18 @@ public List<PrismObject<RoleAnalysisClusterType>> executeClustering(ClusterOptio

//TODO
if (eps == 0.0) {
return new ClusterAlgorithmUtils().processExactMatch(pageBase, dataPoints, clusterOptions);
return new ClusterAlgorithmUtils().processExactMatch(pageBase, result, dataPoints, clusterOptions);
}
start = startTimer("clustering");
DistanceMeasure distanceMeasure = new JaccardDistancesMeasure(minIntersections);
// DBSCANClusterer<DataPoint> dbscan = new DBSCANClusterer<>(eps, minGroupSize, distanceMeasure);
// List<Cluster<DataPoint>> clusters = dbscan.cluster(dataPoints);

DBSCANClusterer<DataPoint> dbscan = new DBSCANClusterer<>(eps, minGroupSize, distanceMeasure);
List<Cluster<DataPoint>> clusters = dbscan.cluster(dataPoints);
endTimer(start, "clustering");

return new ClusterAlgorithmUtils().processClusters(pageBase, dataPoints, clusters, clusterOptions);
return new ClusterAlgorithmUtils().processClusters(pageBase, result, dataPoints, clusters, clusterOptions);
}

private ListMultimap<List<String>, String> loadData(OperationResult result, PageBase pageBase,
Expand Down

0 comments on commit a83ec2c

Please sign in to comment.