/* * Copyright (c) 2010-2015 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.evolveum.midpoint.report.impl; import com.evolveum.midpoint.audit.api.AuditEventRecord; import com.evolveum.midpoint.audit.api.AuditEventStage; import com.evolveum.midpoint.audit.api.AuditEventType; import com.evolveum.midpoint.audit.api.AuditService; import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.Item; import com.evolveum.midpoint.prism.PrismConstants; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.RetrieveOption; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.task.api.TaskManager; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventStageType; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventTypeType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignStateType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDefinitionForReportType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDefinitionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import javax.xml.namespace.QName; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignStateType.CLOSED; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType.F_STATE; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_OBJECT_REF; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_TARGET_REF; import static com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType.F_NAME; public class ReportFunctions { private static final Trace LOGGER = TraceManager.getTrace(ReportFunctions.class); private PrismContext prismContext; private ModelService model; private TaskManager taskManager; private AuditService auditService; public ReportFunctions(PrismContext prismContext, ModelService modelService, TaskManager taskManager, AuditService auditService) { this.prismContext = prismContext; this.model = modelService; this.taskManager = taskManager; this.auditService = auditService; } public <O extends ObjectType> O resolveObject(ObjectReferenceType ref) { Validate.notNull(ref.getOid(), "Object oid must not be null"); Validate.notNull(ref.getType(), "Object type must not be null"); Class type = prismContext.getSchemaRegistry().determineCompileTimeClass(ref.getType()); return resolveObject(type, ref.getOid()); } public <O extends ObjectType> O resolveObject(Class type, String oid) { Task task = taskManager.createTaskInstance(); OperationResult parentResult = task.getResult(); PrismObject<O> obj; try { obj = model.getObject(type, oid, SelectorOptions.createCollection(GetOperationOptions.createResolveNames()), task, parentResult); return obj.asObjectable(); } catch (ObjectNotFoundException | SchemaException | SecurityViolationException | CommunicationException | ConfigurationException e) { // TODO Auto-generated catch block LOGGER.error("Could not get object with oid " + oid + ". Reason: " + e.getMessage()); } return null; } public <O extends ObjectType> List<PrismObject<O>> resolveLinkRefs(Collection<ObjectReferenceType> refs, Class type) { List<PrismObject<O>> objects = new ArrayList<>(); for (ObjectReferenceType ref : refs) { Class clazz = getClassForType(ref.getType()); if (!clazz.equals(type)) { continue; } Task task = taskManager.createTaskInstance(); OperationResult parentResult = task.getResult(); try { PrismObject<O> obj = model.getObject(type, ref.getOid(), SelectorOptions.createCollection(GetOperationOptions.createResolveNames()), task, parentResult); objects.add(obj); } catch (ObjectNotFoundException | SchemaException | SecurityViolationException | CommunicationException | ConfigurationException e) { // TODO Auto-generated catch block LOGGER.error("Could not get object with oid " + ref.getOid() + ". Reason: " + e.getMessage()); } } return objects; } public String resolveRefName(ObjectReferenceType ref) { if (ref == null) { return null; } PrismReferenceValue refValue = ref.asReferenceValue(); Object name = refValue.getTargetName() != null ? ref.getTargetName().getOrig() : null; if (!(name instanceof String)) { LOGGER.error("Couldn't resolve object name"); } return (String) name; } public List<PrismObject<RoleType>> resolveRoles(Collection<AssignmentType> assignments) { return resolveAssignments(assignments, RoleType.class); } public List<PrismObject<OrgType>> resolveOrgs(Collection<AssignmentType> assignments) { return resolveAssignments(assignments, OrgType.class); } public List<PrismObject<RoleType>> resolveRoles(AssignmentType assignments) { return resolveAssignments(assignments, RoleType.class); } public List<PrismObject<OrgType>> resolveOrgs(AssignmentType assignments) { return resolveAssignments(assignments, OrgType.class); } public <O extends ObjectType> List<PrismObject<O>> resolveAssignments(AssignmentType assignment, Class<O> type) { List<AssignmentType> assignments = new ArrayList<>(); assignments.add(assignment); return resolveAssignments(assignments, type); } public <O extends ObjectType> List<PrismObject<O>> resolveAssignments(Collection<AssignmentType> assignments, Class<O> type) { List<PrismObject<O>> resolvedAssignments = new ArrayList<>(); if (assignments == null) { return resolvedAssignments; } for (AssignmentType assignment : assignments) { Class clazz = null; String oid = null; if (assignment.getTargetRef() != null) { clazz = getClassForType(assignment.getTargetRef().getType()); oid = assignment.getTargetRef().getOid(); } else if (assignment.getTarget() != null) { clazz = assignment.getTarget().getClass(); } else if (assignment.getTenantRef() != null) { clazz = getClassForType(assignment.getTenantRef().getType()); oid = assignment.getTenantRef().getOid(); } if (clazz == null && assignment.getConstruction() != null) { continue; } else { LOGGER.debug("Could not resolve assignment for type {}. No target type defined.", type); } if (!clazz.equals(type)) { continue; } if (assignment.getTarget() != null) { resolvedAssignments.add((PrismObject<O>) assignment.getTarget().asPrismObject()); continue; } Task task = taskManager.createTaskInstance(); try { PrismObject<O> obj = model.getObject(type, oid, null, task, task.getResult()); resolvedAssignments.add(obj); } catch (ObjectNotFoundException | SchemaException | SecurityViolationException | CommunicationException | ConfigurationException e) { LOGGER.error("Could not get object with oid " + oid + ". Reason: " + e.getMessage()); } } return resolvedAssignments; } public List<AuditEventRecord> searchAuditRecords(String query, Map<String, Object> params) { if (StringUtils.isBlank(query)) { return new ArrayList<>(); } Map<String, Object> resultSet = new HashMap<String, Object>(); Set<Entry<String, Object>> paramSet = params.entrySet(); for (Entry<String, Object> p : paramSet) { if (p.getValue() instanceof AuditEventTypeType) { resultSet.put(p.getKey(), AuditEventType.toAuditEventType((AuditEventTypeType) p.getValue())); } else if (p.getValue() instanceof AuditEventStageType) { resultSet.put(p.getKey(), AuditEventStage.toAuditEventStage((AuditEventStageType) p.getValue())); } else { resultSet.put(p.getKey(), p.getValue()); } } return auditService.listRecords(query, resultSet); } public UserType getShadowOwner(String shadowOid) { Task task = taskManager.createTaskInstance(); try { PrismObject<UserType> owner = model.findShadowOwner(shadowOid, task, task.getResult()); return owner.asObjectable(); } catch (ObjectNotFoundException | SecurityViolationException | SchemaException | ConfigurationException e) { // TODO Auto-generated catch block LOGGER.error("Could not find owner for shadow with oid " + shadowOid + ". Reason: " + e.getMessage()); } return null; } private Class getClassForType(QName type) { return prismContext.getSchemaRegistry().determineCompileTimeClass(type); } <T extends ObjectType> List<T> searchObjects(Class<T> type, ObjectQuery query) { List<T> ret = new ArrayList(); Task task = taskManager.createTaskInstance(); try { List<PrismObject<T>> list = model.searchObjects(type, query, null, task, task.getResult()).getList(); for (PrismObject<T> po : list) { ret.add(po.asObjectable()); } } catch (SchemaException | ObjectNotFoundException | SecurityViolationException | CommunicationException | ConfigurationException e) { LOGGER.error("Could not search objects of type: " + type + " with query " + query + ". Reason: " + e.getMessage()); } return ret; } <C extends Containerable, T> ObjectFilter createEqualFilter(QName propertyName, Class<C> type, T realValue) throws SchemaException { return QueryBuilder.queryFor(type, prismContext) .item(propertyName).eq(realValue) .buildFilter(); } <C extends Containerable, T> ObjectFilter createEqualFilter(ItemPath propertyPath, Class<C> type, T realValue) throws SchemaException { return QueryBuilder.queryFor(type, prismContext) .item(propertyPath).eq(realValue) .buildFilter(); } // TODO implement if needed // <O extends Containerable> RefFilter createReferenceEqualFilter(QName propertyName, Class<O> type, String... oids) { // return RefFilter.createReferenceEqual(propertyName, type, prismContext, oids); // } // <O extends Containerable> RefFilter createReferenceEqualFilter(ItemPath propertyPath, Class<O> type, String... oids) throws SchemaException { // return RefFilter.createReferenceEqual(propertyPath, type, prismContext, oids); // } // Object parseObjectFromXML (String xml) throws SchemaException { // return prismContext.parserFor(xml).xml().parseAnyData(); // } /** * Retrieves all definitions. * Augments them by count of campaigns (all + open ones). * * TODO query parameters, customizable sorting * definitions and campaigns counts are expected to be low, so we can afford to go through all of them here */ public Collection<PrismObject<AccessCertificationDefinitionForReportType>> searchCertificationDefinitions() throws ConfigurationException, SchemaException, ObjectNotFoundException, CommunicationException, SecurityViolationException { Task task = taskManager.createTaskInstance(); OperationResult result = task.getResult(); Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createResolveNames()); List<PrismObject<AccessCertificationDefinitionType>> definitions = model.searchObjects(AccessCertificationDefinitionType.class, null, options, task, result); final Map<String,PrismObject<AccessCertificationDefinitionForReportType>> definitionsForReportMap = new HashMap<>(); for (PrismObject<AccessCertificationDefinitionType> definition : definitions) { // create subclass with the values copied from the superclass PrismObject<AccessCertificationDefinitionForReportType> definitionForReport = prismContext.createObjectable(AccessCertificationDefinitionForReportType.class).asPrismObject(); for (Item<?,?> item : definition.getValue().getItems()) { definitionForReport.getValue().add(item.clone()); } definitionsForReportMap.put(definition.getOid(), definitionForReport); } ResultHandler<AccessCertificationCampaignType> handler = new ResultHandler<AccessCertificationCampaignType>() { @Override public boolean handle(PrismObject<AccessCertificationCampaignType> campaignObject, OperationResult parentResult) { AccessCertificationCampaignType campaign = campaignObject.asObjectable(); if (campaign.getDefinitionRef() != null) { String definitionOid = campaign.getDefinitionRef().getOid(); PrismObject<AccessCertificationDefinitionForReportType> definitionObject = definitionsForReportMap.get(definitionOid); if (definitionObject != null) { AccessCertificationDefinitionForReportType definition = definitionObject.asObjectable(); int campaigns = definition.getCampaigns() != null ? definition.getCampaigns() : 0; definition.setCampaigns(campaigns+1); AccessCertificationCampaignStateType state = campaign.getState(); if (state != AccessCertificationCampaignStateType.CREATED && state != CLOSED) { int openCampaigns = definition.getOpenCampaigns() != null ? definition.getOpenCampaigns() : 0; definition.setOpenCampaigns(openCampaigns+1); } } } return true; } }; model.searchObjectsIterative(AccessCertificationCampaignType.class, null, handler, null, task, result); List<PrismObject<AccessCertificationDefinitionForReportType>> rv = new ArrayList<>(definitionsForReportMap.values()); Collections.sort(rv, new Comparator<PrismObject<AccessCertificationDefinitionForReportType>>() { @Override public int compare(PrismObject<AccessCertificationDefinitionForReportType> o1, PrismObject<AccessCertificationDefinitionForReportType> o2) { String n1 = o1.asObjectable().getName().getOrig(); String n2 = o2.asObjectable().getName().getOrig(); if (n1 == null) { n1 = ""; } return n1.compareTo(n2); } }); for (PrismObject<AccessCertificationDefinitionForReportType> defObject : rv) { AccessCertificationDefinitionForReportType def = defObject.asObjectable(); if (def.getCampaigns() == null) { def.setCampaigns(0); } if (def.getOpenCampaigns() == null) { def.setOpenCampaigns(0); } } return rv; } public List<PrismContainerValue<AccessCertificationCaseType>> getCertificationCampaignCases(String campaignName) throws SchemaException, SecurityViolationException, ConfigurationException, ObjectNotFoundException { List<AccessCertificationCaseType> cases = getCertificationCampaignCasesAsBeans(campaignName); return PrismContainerValue.toPcvList(cases); } private List<AccessCertificationCaseType> getCertificationCampaignCasesAsBeans(String campaignName) throws SchemaException, SecurityViolationException, ConfigurationException, ObjectNotFoundException { Task task = taskManager.createTaskInstance(); ObjectQuery query; if (StringUtils.isEmpty(campaignName)) { //query = null; return new ArrayList<>(); } else { query = QueryBuilder.queryFor(AccessCertificationCaseType.class, prismContext) .item(PrismConstants.T_PARENT, F_NAME).eqPoly(campaignName, "").matchingOrig() // TODO first by object/target type then by name (not supported by the repository as of now) .asc(AccessCertificationCaseType.F_OBJECT_REF, PrismConstants.T_OBJECT_REFERENCE, ObjectType.F_NAME) .asc(AccessCertificationCaseType.F_TARGET_REF, PrismConstants.T_OBJECT_REFERENCE, ObjectType.F_NAME) .build(); } Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createResolveNames()); return model.searchContainers(AccessCertificationCaseType.class, query, options, task, task.getResult()); } // public List<PrismContainerValue<AccessCertificationDecisionType>> getCertificationCampaignDecisions(String campaignName, Integer stageNumber) throws SchemaException, SecurityViolationException, ConfigurationException, ObjectNotFoundException { // List<AccessCertificationCaseType> cases = getCertificationCampaignCasesAsBeans(campaignName); // List<AccessCertificationDecisionType> decisions = new ArrayList<>(); // for (AccessCertificationCaseType aCase : cases) { // for (AccessCertificationDecisionType decision : aCase.getDecision()) { // if (stageNumber == null || decision.getStageNumber() == stageNumber) { // decisions.add(decision); // } // } // } // return PrismContainerValue.toPcvList(decisions); // } public List<PrismObject<AccessCertificationCampaignType>> getCertificationCampaigns(Boolean alsoClosedCampaigns) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, SecurityViolationException { Task task = taskManager.createTaskInstance(); ObjectQuery query = QueryBuilder.queryFor(AccessCertificationCampaignType.class, prismContext) .asc(F_NAME) .build(); if (!Boolean.TRUE.equals(alsoClosedCampaigns)) { query.addFilter( QueryBuilder.queryFor(AccessCertificationCampaignType.class, prismContext) .not().item(F_STATE).eq(CLOSED) .buildFilter() ); } Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createResolveNames()); options.add(SelectorOptions.create(AccessCertificationCampaignType.F_CASE, GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE))); return model.searchObjects(AccessCertificationCampaignType.class, query, options, task, task.getResult()); } }