package com.sequenceiq.cloudbreak.service.blueprint; import static com.sequenceiq.cloudbreak.common.type.ResourceStatus.DEFAULT_DELETED; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import javax.inject.Inject; import org.hibernate.exception.ConstraintViolationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.convert.ConversionService; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Service; import com.fasterxml.jackson.databind.JsonNode; import com.sequenceiq.cloudbreak.api.model.BlueprintRequest; import com.sequenceiq.cloudbreak.common.type.ResourceStatus; import com.sequenceiq.cloudbreak.domain.Blueprint; import com.sequenceiq.cloudbreak.domain.BlueprintInputParameters; import com.sequenceiq.cloudbreak.domain.CbUser; import com.sequenceiq.cloudbreak.domain.json.Json; import com.sequenceiq.cloudbreak.repository.BlueprintRepository; import com.sequenceiq.cloudbreak.util.NameUtil; @Service public class BlueprintLoaderService { private static final Logger LOGGER = LoggerFactory.getLogger(BlueprintLoaderService.class); @Value("#{'${cb.blueprint.defaults:}'.split(';')}") private List<String> blueprintArray; @Inject @Qualifier("conversionService") private ConversionService conversionService; @Inject private BlueprintRepository blueprintRepository; @Inject private BlueprintUtils blueprintUtils; public Set<Blueprint> loadBlueprints(CbUser user) { Set<Blueprint> blueprints = new HashSet<>(); List<String> blueprintNames = getDefaultBlueprintNames(user); for (String blueprintStrings : blueprintArray) { String[] split = blueprintStrings.split("="); if (blueprintUtils.isBlueprintNamePreConfigured(blueprintStrings, split) && !blueprintNames.contains(blueprintStrings)) { LOGGER.info("Adding default blueprint '{}' for user '{}'", blueprintStrings, user.getUsername()); try { BlueprintRequest blueprintJson = new BlueprintRequest(); blueprintJson.setName(split[0]); blueprintJson.setDescription(split[0]); JsonNode jsonNode = blueprintUtils.convertStringToJsonNode(blueprintUtils.readDefaultBlueprintFromFile(split)); blueprintJson.setAmbariBlueprint(blueprintUtils.convertStringToJsonNode(jsonNode.get("blueprint").toString())); Blueprint bp = conversionService.convert(blueprintJson, Blueprint.class); JsonNode inputs = jsonNode.get("inputs"); BlueprintInputParameters inputParameters = new BlueprintInputParameters(blueprintUtils.prepareInputs(inputs)); bp.setInputParameters(new Json(inputParameters)); bp.setOwner(user.getUserId()); bp.setAccount(user.getAccount()); bp.setPublicInAccount(true); bp.setStatus(ResourceStatus.DEFAULT); blueprintRepository.save(bp); blueprints.add(bp); } catch (ConstraintViolationException | DataIntegrityViolationException e) { LOGGER.info("Blueprint already added with name: '" + split[0] + "' for user: '" + user.getUsername() + "' user."); } catch (Exception e) { LOGGER.error("Blueprint is not available for '" + user.getUsername() + "' user.", e); } } } return blueprints; } private List<String> getDefaultBlueprintNames(CbUser user) { return blueprintRepository.findAllDefaultInAccount(user.getAccount()).stream() .map(bp -> bp.getStatus() == DEFAULT_DELETED ? NameUtil.cutTimestampPostfix(bp.getName()) : bp.getName()) .collect(Collectors.toList()); } }