From 1b03220adb20c86530e983a6cda78e1732cc05d7 Mon Sep 17 00:00:00 2001 From: talig Date: Wed, 28 Feb 2018 10:53:11 +0200 Subject: Healing manager logic enhancements Check whether healers need to run before running them. Heal private: if there's at least one structure healer - force sync (instead of running data healers). Change-Id: I5cc5ce43d61a59d5cfd6a1db717d6e3e4be1119a Issue-ID: SDC-1066 Signed-off-by: talig --- .../sdc/healing/impl/HealingManagerImpl.java | 248 ++++++++++++--------- .../main/resources/entityHealingConfiguration.json | 18 +- 2 files changed, 146 insertions(+), 120 deletions(-) (limited to 'openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core') diff --git a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerImpl.java b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerImpl.java index 4a0bf13f41..eef8c3cd44 100644 --- a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerImpl.java +++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerImpl.java @@ -7,9 +7,9 @@ * 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. @@ -24,33 +24,29 @@ import org.openecomp.core.utilities.CommonMethods; import org.openecomp.core.utilities.file.FileUtils; import org.openecomp.core.utilities.json.JsonUtil; import org.openecomp.sdc.common.errors.CoreException; +import org.openecomp.sdc.common.errors.ErrorCategory; import org.openecomp.sdc.common.errors.ErrorCode; import org.openecomp.sdc.common.errors.Messages; -import org.openecomp.sdc.common.session.SessionContext; import org.openecomp.sdc.common.session.SessionContextProviderFactory; import org.openecomp.sdc.datatypes.model.ItemType; import org.openecomp.sdc.healing.api.HealingManager; import org.openecomp.sdc.healing.dao.HealingDao; import org.openecomp.sdc.healing.interfaces.Healer; -import org.openecomp.sdc.healing.types.HealCode; import org.openecomp.sdc.healing.types.HealerType; import org.openecomp.sdc.versioning.VersioningManager; import org.openecomp.sdc.versioning.dao.types.Version; import org.openecomp.sdc.versioning.dao.types.VersionStatus; import org.openecomp.sdc.versioning.types.VersionCreationMethod; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; import java.util.Collection; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; -/** - * Created by Talio on 11/29/2016. - */ public class HealingManagerImpl implements HealingManager { private static final String HEALERS_BY_ENTITY_TYPE_FILE = "entityHealingConfiguration.json"; @@ -66,134 +62,142 @@ public class HealingManagerImpl implements HealingManager { } @Override - public Optional healItemVersion(String itemId, Version version, ItemType itemType, - boolean force) { + public Optional healItemVersion(final String itemId, final Version version, + final ItemType itemType, final boolean force) { String user = getUser(); if (force || isPrivateHealingNeededByFlag(itemId, version.getId(), user)) { - version = versioningManager.get(itemId, version); - Version origVersion = version; - if (version.getStatus() == VersionStatus.Certified) { - Optional newVersion = createNewVersion(itemId, version); - if (!newVersion.isPresent()) { - // do NOT turn off flag here (in thought of saving version calculate performance next - // time) because maybe next time the next version will be available (due to deletion of - // the taken one) - return Optional.empty(); - } - version = newVersion.get(); + + Map> healersByType = getItemHealers(itemType); + List failureMessages = new LinkedList<>(); + List structureHealersToRun = + getHealersToRun(healersByType.get(HealerType.structure.name()), itemId, version, + failureMessages); + List dataHealersToRun = + getHealersToRun(healersByType.get(HealerType.data.name()), itemId, version, + failureMessages); + + if (structureHealersToRun.isEmpty() && dataHealersToRun.isEmpty()) { + markAsHealed(itemId, version.getId(), user); + markAsHealed(itemId, version.getId(), PUBLIC_USER); + return Optional.empty(); + } + + Optional healVersion = getHealVersion(itemId, version); + if (!healVersion.isPresent()) { + // do NOT turn off flag here (in thought of saving version calculate performance next + // time) because maybe next time the next version will be available (due to deletion of + // the taken one) + return Optional.empty(); } - doHeal(itemId, version, origVersion, itemType, user, force); - return Optional.of(version); + failureMessages.addAll( + doHeal(itemId, healVersion.get(), version, structureHealersToRun, dataHealersToRun, user, + force)); + + handleFailures(failureMessages); + return healVersion; } return Optional.empty(); } - private void doHeal(String itemId, Version version, Version origVersion, - ItemType itemType, String user, boolean force) { - Optional privateFailureMessages = - healPrivate(itemId, version, origVersion, getItemHealers(itemType), user); + private Optional getHealVersion(String itemId, Version version) { + version.setStatus(versioningManager.get(itemId, version).getStatus()); + return version.getStatus() == VersionStatus.Certified + ? createNewVersion(itemId, version.getId()) + : Optional.of(version); + } + + private Optional createNewVersion(String itemId, String versionId) { + Version newVersion = new Version(); + newVersion.setBaseId(versionId); + try { + return Optional.of(versioningManager.create(itemId, newVersion, VersionCreationMethod.major)); + } catch (Exception e) { + return Optional.empty(); + } + } - Optional publicFailureMessages = + private List doHeal(String itemId, Version version, Version origVersion, + List structureHealersToRun, + List dataHealersToRun, String user, + boolean force) { + List failureMessages = force || origVersion.getStatus() == VersionStatus.Certified || isPublicHealingNeededByFlag(itemId, origVersion.getId()) - ? healPublic(itemId, version, origVersion, getItemHealers(itemType), user) - : Optional.empty(); + ? healPublic(itemId, version, origVersion, structureHealersToRun, dataHealersToRun, + user) + : new LinkedList<>(); - if (privateFailureMessages.isPresent() || publicFailureMessages.isPresent()) { - throw new CoreException(new ErrorCode.ErrorCodeBuilder().withMessage( - publicFailureMessages.orElse("") + " " + privateFailureMessages.orElse("")) - .build()); - } + failureMessages.addAll( + healPrivate(itemId, version, origVersion, structureHealersToRun, dataHealersToRun, user)); + + return failureMessages; } - private Optional healPrivate(String itemId, Version version, Version origVersion, - Map> itemHealers, String user) { - if (origVersion.getStatus() != VersionStatus.Certified) { - itemHealers.remove(HealerType.structure.name()); + private List healPrivate(String itemId, Version version, Version origVersion, + List structureHealersToRun, + List dataHealersToRun, String user) { + List failureMessages; + if (origVersion.getStatus() == VersionStatus.Certified) { + failureMessages = executeHealers(itemId, version, + Stream.concat(structureHealersToRun.stream(), dataHealersToRun.stream()) + .collect(Collectors.toList())); + } else { + if (structureHealersToRun.isEmpty()) { + failureMessages = executeHealers(itemId, version, dataHealersToRun); + } else { + versioningManager.forceSync(itemId, version); + failureMessages = new LinkedList<>(); + } } - - Optional privateHealingFailureMessages = executeHealers(itemId, version, itemHealers); markAsHealed(itemId, origVersion.getId(), user); - return privateHealingFailureMessages; + return failureMessages; } - private Optional healPublic(String itemId, Version version, Version origVersion, - Map> itemHealers, String user) { - Optional healingFailureMessages = origVersion.getStatus() == VersionStatus.Certified - ? Optional.empty() - : healPublic(itemId, version, itemHealers, user); + private List healPublic(String itemId, Version version, Version origVersion, + List structureHealersToRun, + List dataHealersToRun, String user) { + List failureMessages = origVersion.getStatus() == VersionStatus.Certified + ? new LinkedList<>() + : healPublic(itemId, version, + Stream.concat(structureHealersToRun.stream(), dataHealersToRun.stream()) + .collect(Collectors.toList()), user); markAsHealed(itemId, origVersion.getId(), PUBLIC_USER); - return healingFailureMessages; + return failureMessages; } - private Optional healPublic(String itemId, Version version, - Map> itemHealers, String user) { - SessionContext context = - SessionContextProviderFactory.getInstance().createInterface().get(); - SessionContextProviderFactory.getInstance().createInterface().create(user - + HEALING_USER_SUFFIX,context.getTenant()); + private List healPublic(String itemId, Version version, List healers, + String user) { + String tenant = SessionContextProviderFactory.getInstance().createInterface().get().getTenant(); + SessionContextProviderFactory.getInstance().createInterface() + .create(user + HEALING_USER_SUFFIX, tenant); - versioningManager.sync(itemId, version); + versioningManager.forceSync(itemId, version); - Optional healingFailureMessages = executeHealers(itemId, version, itemHealers); + List failureMessages = executeHealers(itemId, version, healers); Version publicVersion = versioningManager.get(itemId, version); if (Objects.nonNull(publicVersion.getState()) && publicVersion.getState().isDirty()) { versioningManager.publish(itemId, version, "Healing vsp"); } - SessionContextProviderFactory.getInstance().createInterface().create(user, context.getTenant()); - return healingFailureMessages; + SessionContextProviderFactory.getInstance().createInterface().create(user, tenant); + return failureMessages; } - private Optional createNewVersion(String itemId, Version version) { - Version newVersion = new Version(); - newVersion.setBaseId(version.getId()); - try { - return Optional.of(versioningManager.create(itemId, newVersion, VersionCreationMethod.major)); - } catch (Exception e) { - return Optional.empty(); - } - } - - private Optional executeHealers(String itemId, Version version, - Map> itemHealers) { - List healers = itemHealers.values().stream() - .map(Map::values) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - - List healingFailureMessages = new ArrayList<>(); - for (String implClassName : healers) { - executeHealer(itemId, version, implClassName, healingFailureMessages); - } - - return healingFailureMessages.isEmpty() - ? Optional.empty() - : Optional.of(CommonMethods.listToSeparatedString(healingFailureMessages, '\n')); - } - - - private Object executeHealer(String itemId, Version version, String healerClassName, - List healingFailureMessages) { - Healer healer; - try { - healer = getHealerImplInstance(healerClassName); - } catch (Exception e) { - healingFailureMessages - .add(String.format(Messages.CANT_LOAD_HEALING_CLASS.getErrorMessage(), - healerClassName)); - return null; + private List executeHealers(String itemId, Version version, List healers) { + List failureMessages = new LinkedList<>(); + for (Healer healer : healers) { + try { + healer.heal(itemId, version); + } catch (Exception e) { + failureMessages.add( + String.format("Failure in healer %s: %s", healer.getClass().getName(), e.getMessage())); + } } - try { - return healer.heal(itemId, version); - } catch (Exception e) { - healingFailureMessages.add(e.getMessage() + " ,healer name :" + healerClassName); - } - return null; + return failureMessages; } private boolean isPrivateHealingNeededByFlag(String itemId, String version, String user) { @@ -214,17 +218,39 @@ public class HealingManagerImpl implements HealingManager { healingDao.setItemHealingFlag(false, user, itemId, versionId); } - private Map> getItemHealers(ItemType itemType) { + private void handleFailures(List failureMessages) { + if (!failureMessages.isEmpty()) { + throw new CoreException(new ErrorCode.ErrorCodeBuilder() + .withCategory(ErrorCategory.APPLICATION) + .withMessage(CommonMethods.listToSeparatedString(failureMessages, '\n')).build()); + } + } + + private List getHealersToRun(Collection healersClassNames, String itemId, + Version version, List failureMessages) { + return healersClassNames.stream() + .map(healerClassName -> getHealerInstance(healerClassName, failureMessages)) + .filter(Optional::isPresent) + .map(Optional::get) + .filter(healer -> healer.isHealingNeeded(itemId, version)) + .collect(Collectors.toList()); + } + + private Optional getHealerInstance(String healerClassName, List failureMessages) { + try { + return Optional.of((Healer) Class.forName(healerClassName).getConstructor().newInstance()); + } catch (Exception e) { + failureMessages + .add(String.format(Messages.CANT_LOAD_HEALING_CLASS.getErrorMessage(), healerClassName)); + return Optional.empty(); + } + } + + private Map> getItemHealers(ItemType itemType) { Map healingConfig = FileUtils .readViaInputStream(HEALERS_BY_ENTITY_TYPE_FILE, stream -> JsonUtil.json2Object(stream, Map.class)); - return (Map>) healingConfig.get(itemType.name()); - } - - private Healer getHealerImplInstance(String implClassName) - throws InstantiationException, IllegalAccessException, InvocationTargetException, - NoSuchMethodException, ClassNotFoundException { - return (Healer) Class.forName(implClassName).getConstructor().newInstance(); + return (Map>) healingConfig.get(itemType.name()); } private String getUser() { diff --git a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/entityHealingConfiguration.json b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/entityHealingConfiguration.json index 64f43a6625..2fc23372de 100644 --- a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/entityHealingConfiguration.json +++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/entityHealingConfiguration.json @@ -1,15 +1,15 @@ { "vsp": { - "structure": { - "ownerHealer": "org.openecomp.sdc.healing.healers.OwnerHealer" - }, - "data": { - "toscaServiceModelHealer": "org.openecomp.sdc.healing.healers.ToscaServiceModelHealer" - } + "structure": [ + "org.openecomp.sdc.healing.healers.OwnerHealer" + ], + "data": [ + "org.openecomp.sdc.healing.healers.ToscaServiceModelHealer" + ] }, "vlm": { - "structure": { - "ownerHealer": "org.openecomp.sdc.healing.healers.OwnerHealer" - } + "structure": [ + "org.openecomp.sdc.healing.healers.OwnerHealer" + ] } } \ No newline at end of file -- cgit 1.2.3-korg