Skip to content

Commit

Permalink
Enhanced shadow integrity checker. Fixed bug in repo iterative search…
Browse files Browse the repository at this point in the history
… by paging.
  • Loading branch information
mederly committed Sep 3, 2015
1 parent 7fcc6d1 commit 3c2e441
Show file tree
Hide file tree
Showing 10 changed files with 558 additions and 69 deletions.
Expand Up @@ -191,6 +191,7 @@ public abstract class SchemaConstants {

public static final QName MODEL_EXTENSION_DIAGNOSE = new QName(NS_MODEL_EXTENSION, "diagnose");
public static final QName MODEL_EXTENSION_FIX = new QName(NS_MODEL_EXTENSION, "fix");
public static final QName MODEL_EXTENSION_DUPLICATE_SHADOWS_RESOLVER = new QName(NS_MODEL_EXTENSION, "duplicateShadowsResolver");

public static final String NS_GUI = NS_MIDPOINT_PUBLIC + "/gui";
public static final String NS_GUI_CHANNEL = NS_GUI + "/channels-3";
Expand Down
Expand Up @@ -224,7 +224,19 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:element>


<xsd:element name="duplicateShadowsResolver" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Class that is used to resolve duplicate shadows in ShadowIntegrityCheck task.
If not specified, a default implementation is used.
</xsd:documentation>
<xsd:appinfo>
<a:maxOccurs>1</a:maxOccurs>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>

</xsd:schema>


@@ -0,0 +1,78 @@
/*
* 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.model.impl.integrity;

import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationSituationType;

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

/**
* @author Pavol Mederly
*/
public class DefaultDuplicateShadowsResolver implements DuplicateShadowsResolver {

static final Trace LOGGER = TraceManager.getTrace(DefaultDuplicateShadowsResolver.class);

@Override
public DuplicateShadowsTreatmentInstruction determineDuplicateShadowsTreatment(Collection<PrismObject<ShadowType>> shadows) {
if (shadows.size() <= 1) {
return null;
}
LOGGER.trace("Determining duplicate shadows treatment: conflicting set with {} members", shadows.size());
// prefer shadows with intent and linked ones
int bestScore = 0;
PrismObject<ShadowType> bestShadow = null;
for (PrismObject<ShadowType> shadow : shadows) {
ShadowType shadowType = shadow.asObjectable();
int score = 0;
if (shadowType.getSynchronizationSituation() == SynchronizationSituationType.LINKED) {
score += 10;
}
List owners = (List) shadow.getUserData(ShadowIntegrityCheckResultHandler.KEY_OWNERS);
if (owners != null && !owners.isEmpty()) {
score += 10;
}
if (shadowType.getIntent() != null && !shadowType.getIntent().isEmpty()) {
score += 8;
}
if (shadow.getUserData(ShadowIntegrityCheckResultHandler.KEY_EXISTS_ON_RESOURCE) != null) { // filled in only if checkFetch is true
score += 50;
}
LOGGER.trace("Shadow {} has score of {}; best is {}", ObjectTypeUtil.toShortString(shadow), score, bestScore);
if (bestShadow == null || score > bestScore) {
bestScore = score;
bestShadow = shadow;
}
}
DuplicateShadowsTreatmentInstruction instruction = new DuplicateShadowsTreatmentInstruction();
instruction.setShadowOidToReplaceDeletedOnes(bestShadow.getOid());
instruction.setShadowsToDelete(new ArrayList<PrismObject<ShadowType>>());
for (PrismObject<ShadowType> shadow : shadows) {
if (!shadow.getOid().equals(bestShadow.getOid())) {
instruction.getShadowsToDelete().add(shadow);
}
}
return instruction;
}
}
@@ -0,0 +1,37 @@
/*
* 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.model.impl.integrity;

import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;

import java.util.Collection;

/**
* @author Pavol Mederly
*/
public interface DuplicateShadowsResolver {

/**
* Takes a collection of duplicate shadows - i.e. shadows pointing to (presumably) one resource object,
* and returns a treatment instruction: a collection of shadows that have to be deleted + which OID to use in owner object as a replacement.
*
* @param shadows
* @return
*/
DuplicateShadowsTreatmentInstruction determineDuplicateShadowsTreatment(Collection<PrismObject<ShadowType>> shadows);
}
@@ -0,0 +1,55 @@
/*
* 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.model.impl.integrity;

import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;

import java.util.Collection;

/**
* @author Pavol Mederly
*/
public class DuplicateShadowsTreatmentInstruction {

private Collection<PrismObject<ShadowType>> shadowsToDelete;
private String shadowOidToReplaceDeletedOnes;

public Collection<PrismObject<ShadowType>> getShadowsToDelete() {
return shadowsToDelete;
}

public void setShadowsToDelete(Collection<PrismObject<ShadowType>> shadowsToDelete) {
this.shadowsToDelete = shadowsToDelete;
}

public String getShadowOidToReplaceDeletedOnes() {
return shadowOidToReplaceDeletedOnes;
}

public void setShadowOidToReplaceDeletedOnes(String shadowOidToReplaceDeletedOnes) {
this.shadowOidToReplaceDeletedOnes = shadowOidToReplaceDeletedOnes;
}

@Override
public String toString() {
return "DuplicateShadowsTreatmentInstruction{" +
"shadowsToDelete=" + shadowsToDelete +
", shadowOidToReplaceDeletedOnes='" + shadowOidToReplaceDeletedOnes + '\'' +
'}';
}
}
Expand Up @@ -53,15 +53,19 @@ public ShadowCheckResult(PrismObject<ShadowType> shadow) {
}

public ShadowCheckResult recordError(String problemCode, Exception e) {
problemCodes.add(problemCode);
if (problemCode != null) {
problemCodes.add(problemCode);
}
LoggingUtils.logException(LOGGER, "{} - for shadow {} on resource {}",
e, e.getMessage(), ObjectTypeUtil.toShortString(shadow), ObjectTypeUtil.toShortString(resource));
errors.add(e);
return this;
}

public ShadowCheckResult recordWarning(String problemCode, String message) {
problemCodes.add(problemCode);
if (problemCode != null) {
problemCodes.add(problemCode);
}
LOGGER.warn("{} - for shadow {} on resource {}",
message, ObjectTypeUtil.toShortString(shadow), ObjectTypeUtil.toShortString(resource));
warnings.add(message);
Expand Down

0 comments on commit 3c2e441

Please sign in to comment.