From 8e9c0653dd6c6862123c9609ae34e1206d86456e Mon Sep 17 00:00:00 2001 From: talig Date: Wed, 20 Dec 2017 14:30:43 +0200 Subject: Add collaboration feature Issue-ID: SDC-767 Change-Id: I14fb4c1f54086ed03a56a7ff7fab9ecd40381795 Signed-off-by: talig --- .../sdc/healing/dao/impl/HealingDaoImpl.java | 46 +++++ .../healing/impl/HealingManagerFactoryImpl.java | 6 +- .../sdc/healing/impl/HealingManagerImpl.java | 189 ++++++++++++++++++--- .../main/resources/entityHealingConfiguration.json | 12 ++ .../src/main/resources/healingConfiguration.json | 28 +-- 5 files changed, 248 insertions(+), 33 deletions(-) create mode 100644 openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/dao/impl/HealingDaoImpl.java create mode 100644 openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/entityHealingConfiguration.json (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/dao/impl/HealingDaoImpl.java b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/dao/impl/HealingDaoImpl.java new file mode 100644 index 0000000000..921f418118 --- /dev/null +++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/dao/impl/HealingDaoImpl.java @@ -0,0 +1,46 @@ +package org.openecomp.sdc.healing.dao.impl; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.mapping.annotations.Accessor; +import com.datastax.driver.mapping.annotations.Query; +import org.openecomp.core.nosqldb.api.NoSqlDb; +import org.openecomp.core.nosqldb.factory.NoSqlDbFactory; +import org.openecomp.sdc.healing.dao.HealingDao; + +import java.util.Optional; + +/** + * Created by ayalaben on 10/17/2017 + */ +public class HealingDaoImpl implements HealingDao { + + private static final NoSqlDb noSqlDb = NoSqlDbFactory.getInstance().createInterface(); + private static HealingAccessor accessor = + noSqlDb.getMappingManager().createAccessor(HealingAccessor.class); + + @Override + public Optional getItemHealingFlag(String space, String itemId, String versionId) { + ResultSet result = accessor.getItemHealingFlag(space, itemId, versionId); + return result.getAvailableWithoutFetching() < 1 + ? Optional.empty() + : Optional.of(result.one().getBool("healing_needed")); + } + + @Override + public void setItemHealingFlag(boolean healingNeededFlag, String space, String itemId, + String versionId) { + accessor.setItemHealingFlag(healingNeededFlag, space, itemId, versionId); + } + + + @Accessor + interface HealingAccessor { + + @Query("SELECT healing_needed FROM healing WHERE space=? AND item_id=? AND version_id=?") + ResultSet getItemHealingFlag(String space, String itemId, String versionId); + + @Query("UPDATE healing SET healing_needed=? WHERE space=? AND item_id=? AND version_id=?") + void setItemHealingFlag(boolean flag, String space, String itemId, String versionId); + + } +} diff --git a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerFactoryImpl.java b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerFactoryImpl.java index 84aff4327d..5a283f954b 100644 --- a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerFactoryImpl.java +++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerFactoryImpl.java @@ -21,15 +21,17 @@ package org.openecomp.sdc.healing.impl; import org.openecomp.sdc.healing.api.HealingManager; +import org.openecomp.sdc.healing.dao.impl.HealingDaoImpl; import org.openecomp.sdc.healing.factory.HealingManagerFactory; +import org.openecomp.sdc.versioning.VersioningManagerFactory; /** * Created by Talio on 11/29/2016. */ public class HealingManagerFactoryImpl extends HealingManagerFactory { - @Override public HealingManager createInterface() { - return new HealingManagerImpl(); + return new HealingManagerImpl( + VersioningManagerFactory.getInstance().createInterface(), new HealingDaoImpl()); } } 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 1c895ffc6f..59c6732cab 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 @@ -24,34 +24,147 @@ 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.Messages; +import org.openecomp.sdc.common.session.SessionContextProviderFactory; import org.openecomp.sdc.datatypes.error.ErrorLevel; +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.logging.context.impl.MdcDataErrorMessage; import org.openecomp.sdc.logging.types.LoggerConstants; import org.openecomp.sdc.logging.types.LoggerErrorCode; import org.openecomp.sdc.logging.types.LoggerErrorDescription; import org.openecomp.sdc.logging.types.LoggerTragetServiceName; +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.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; /** * Created by Talio on 11/29/2016. */ public class HealingManagerImpl implements HealingManager { - private static String HEALING_CONF_FILE = "healingConfiguration.json"; - private static Map healerCodeToImplClass = initHealers(); + + private static final String HEALERS_BY_ENTITY_TYPE_FILE = "entityHealingConfiguration.json"; + private static final String HEALING_USER_SUFFIX = "_healer"; + private static final String PUBLIC_USER = "public"; + + private HealingDao healingDao; + private VersioningManager versioningManager; + + public HealingManagerImpl(VersioningManager versioningManager, HealingDao healingDao) { + this.versioningManager = versioningManager; + this.healingDao = healingDao; + } + + @Override + public Optional healItemVersion(String itemId, Version version, ItemType itemType, + 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(); + } + + doHeal(itemId, version, origVersion, itemType, user, force); + return Optional.of(version); + } + 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); + + Optional publicFailureMessages = + force || origVersion.getStatus() == VersionStatus.Certified || + isPublicHealingNeededByFlag(itemId, origVersion.getId()) + ? healPublic(itemId, version, origVersion, getItemHealers(itemType), user) + : Optional.empty(); + + if (privateFailureMessages.isPresent() || publicFailureMessages.isPresent()) { + throw new RuntimeException( + publicFailureMessages.orElse("") + " " + privateFailureMessages.orElse("")); + } + } + + private Optional healPrivate(String itemId, Version version, Version origVersion, + Map> itemHealers, String user) { + if (origVersion.getStatus() != VersionStatus.Certified) { + itemHealers.remove(HealerType.structure.name()); + } + + Optional privateHealingFailureMessages = executeHealers(itemId, version, itemHealers); + markAsHealed(itemId, origVersion.getId(), user); + return privateHealingFailureMessages; + } + + 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); + + markAsHealed(itemId, origVersion.getId(), PUBLIC_USER); + return healingFailureMessages; + } + + private Optional healPublic(String itemId, Version version, + Map> itemHealers, String user) { + SessionContextProviderFactory.getInstance().createInterface() + .create(user + HEALING_USER_SUFFIX); + + versioningManager.sync(itemId, version); + + Optional healingFailureMessages = executeHealers(itemId, version, itemHealers); + 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); + return healingFailureMessages; + } + + 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(); + } + } @Override - public Object heal(HealCode code, Map healParameters) { + public Object heal(String itemId, Version version, HealerType healerType, HealCode code, + ItemType itemType) { + String healerClassName = getItemHealers(itemType).get(healerType.name()).get(code.name()); ArrayList healingFailureMessages = new ArrayList<>(); - Object result = - heal(healParameters, healerCodeToImplClass.get(code.name()), healingFailureMessages); + Object result = executeHealer(itemId, version, healerClassName, healingFailureMessages); if (!healingFailureMessages.isEmpty()) { throw new RuntimeException(CommonMethods.listToSeparatedString(healingFailureMessages, '\n')); @@ -59,46 +172,77 @@ public class HealingManagerImpl implements HealingManager { return result; } - @Override - public Optional healAll(Map healParameters) { - ArrayList healingFailureMessages = new ArrayList<>(); + private Optional executeHealers(String itemId, Version version, + Map> itemHealers) { + List healers = itemHealers.values().stream() + .map(Map::values) + .flatMap(Collection::stream) + .collect(Collectors.toList()); - for (String implClassName : healerCodeToImplClass.values()) { - heal(healParameters, implClassName, healingFailureMessages); + List healingFailureMessages = new ArrayList<>(); + for (String implClassName : healers) { + executeHealer(itemId, version, implClassName, healingFailureMessages); } - return healingFailureMessages.isEmpty() ? Optional.empty() + return healingFailureMessages.isEmpty() + ? Optional.empty() : Optional.of(CommonMethods.listToSeparatedString(healingFailureMessages, '\n')); } - private Object heal(Map healParameters, String healerImplClassName, - ArrayList healingFailureMessages) { - Healer healerImpl; + + private Object executeHealer(String itemId, Version version, String healerClassName, + List healingFailureMessages) { + Healer healer; try { - healerImpl = getHealerImplInstance(healerImplClassName); + healer = getHealerImplInstance(healerClassName); } catch (Exception e) { MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB, LoggerTragetServiceName.SELF_HEALING, ErrorLevel.ERROR.name(), LoggerErrorCode .DATA_ERROR.getErrorCode(), LoggerErrorDescription.CANT_HEAL); healingFailureMessages .add(String.format(Messages.CANT_LOAD_HEALING_CLASS.getErrorMessage(), - healerImplClassName)); + healerClassName)); return null; } try { - return healerImpl.heal(healParameters); + return healer.heal(itemId, version); } catch (Exception e) { MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB, LoggerTragetServiceName.SELF_HEALING, ErrorLevel.ERROR.name(), LoggerErrorCode .DATA_ERROR.getErrorCode(), LoggerErrorDescription.CANT_HEAL); - healingFailureMessages.add(e.getMessage() + " ,healer name :" + healerImplClassName); + healingFailureMessages.add(e.getMessage() + " ,healer name :" + healerClassName); } return null; } - private static Map initHealers() { - return FileUtils.readViaInputStream(HEALING_CONF_FILE, stream -> JsonUtil.json2Object(stream, Map.class)); + private boolean isPrivateHealingNeededByFlag(String itemId, String version, String user) { + Optional userHealingFlag = getHealingFlag(itemId, version, user); + return userHealingFlag.isPresent() + ? userHealingFlag.get() + : isPublicHealingNeededByFlag(itemId, version); + } + + private boolean isPublicHealingNeededByFlag(String itemId, String versionId) { + Optional publicHealingFlag = getHealingFlag(itemId, versionId, PUBLIC_USER); + return publicHealingFlag.isPresent() && publicHealingFlag.get(); + } + + private Optional getHealingFlag(String itemId, String version, String user) { + return healingDao.getItemHealingFlag(user, itemId, version); + } + + private void markAsHealed(String itemId, String versionId, String user) { + healingDao.setItemHealingFlag(false, user, itemId, versionId); + } + + private Map> getItemHealers(ItemType itemType) { + // TODO: 11/29/2017 create objects to hold this configuration + + // load once from the json file and use the relevant healers (by itemType, healerType) as needed. + 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) @@ -106,4 +250,9 @@ public class HealingManagerImpl implements HealingManager { NoSuchMethodException, ClassNotFoundException { return (Healer) Class.forName(implClassName).getConstructor().newInstance(); } + + private String getUser() { + return SessionContextProviderFactory.getInstance().createInterface().get().getUser() + .getUserId(); + } } 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 new file mode 100644 index 0000000000..ab8a1dfb4f --- /dev/null +++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/entityHealingConfiguration.json @@ -0,0 +1,12 @@ +{ + "vsp": { + "structure": { + "ownerHealer": "org.openecomp.sdc.healing.healers.OwnerHealer" + } + }, + "vlm": { + "structure": { + "ownerHealer": "org.openecomp.sdc.healing.healers.OwnerHealer" + } + } +} \ No newline at end of file diff --git a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/healingConfiguration.json b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/healingConfiguration.json index 4e1b0df97a..85eec77c56 100644 --- a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/healingConfiguration.json +++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/healingConfiguration.json @@ -1,13 +1,19 @@ { - "FILE_DATA_STRUCTURE_HEALER" : "org.openecomp.sdc.healing.healers.FileDataStructureHealer", - "QUESTIONNAIRE_HEALER" : "org.openecomp.sdc.healing.healers.VspQuestionnaireHealer", - "COMPOSITION_DATA_HEALER" : "org.openecomp.sdc.healing.healers.CompositionDataHealer", - "SUB_ENTITIES_HEALER" : "org.openecomp.sdc.healing.healers.SubEntitiesQuestionnaireHealer", - "ONBOARDING_METHOD_HEALER" : "org.openecomp.sdc.healing.healers.VspOnboardingMethodHealer", - "NIC_DATA_HEALER" : "org.openecomp.sdc.healing.healers.NicDataHealer", - "COMPONENT_QUESTIONNAIRE_HEALER" : "org.openecomp.sdc.healing.healers.ComponentQuestionnaireHealer", - "HEAT_TOSCA_TRANSLATION_HEALER" : "org.openecomp.sdc.healing.healers.HeatToToscaTranslationHealer", - "VLM_VERSION_HEALER" : "org.openecomp.sdc.healing.healers.VlmVersionHealer", - "VALIDATION_STRUCTURE_HEALER" : "org.openecomp.sdc.healing.healers.ValidationStructureHealer", - "FORWARDER_CAPABILITY_HEALER" : "org.openecomp.sdc.healing.healers.ForwarderCapabilityHealer" + "VendorSoftwareProduct" : { + "VSP_OWNER_HEALER" : "org.openecomp.sdc.healing.healers.VspOwnerHealer", + "FILE_DATA_STRUCTURE_HEALER" : "org.openecomp.sdc.healing.healers.FileDataStructureHealer", + "QUESTIONNAIRE_HEALER" : "org.openecomp.sdc.healing.healers.VspQuestionnaireHealer", + "COMPOSITION_DATA_HEALER" : "org.openecomp.sdc.healing.healers.CompositionDataHealer", + "SUB_ENTITIES_HEALER" : "org.openecomp.sdc.healing.healers.SubEntitiesQuestionnaireHealer", + "ONBOARDING_METHOD_HEALER" : "org.openecomp.sdc.healing.healers.VspOnboardingMethodHealer", + "NIC_DATA_HEALER" : "org.openecomp.sdc.healing.healers.NicDataHealer", + "COMPONENT_QUESTIONNAIRE_HEALER" : "org.openecomp.sdc.healing.healers.ComponentQuestionnaireHealer", + "HEAT_TOSCA_TRANSLATION_HEALER" : "org.openecomp.sdc.healing.healers.HeatToToscaTranslationHealer", + "VLM_VERSION_HEALER" : "org.openecomp.sdc.healing.healers.VlmVersionHealer", + "VALIDATION_STRUCTURE_HEALER" : "org.openecomp.sdc.healing.healers.ValidationStructureHealer", + "FORWARDER_CAPABILITY_HEALER" : "org.openecomp.sdc.healing.healers.ForwarderCapabilityHealer" + }, + "VendorLicenseModel" : { + "VLM_OWNER_HEALER" : "org.openecomp.sdc.healing.healers.VlmOwnerHealer" + } } \ No newline at end of file -- cgit 1.2.3-korg