/**
* Copyright (C) 2015 Orange
* 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.francetelecom.clara.cloud.deployment.logical.service;
import com.francetelecom.clara.cloud.commons.BusinessException;
import com.francetelecom.clara.cloud.commons.InvalidMavenReferenceException;
import com.francetelecom.clara.cloud.commons.MavenReference;
import com.francetelecom.clara.cloud.commons.ValidatorUtil;
import com.francetelecom.clara.cloud.core.service.exception.InvalidReleaseException;
import com.francetelecom.clara.cloud.core.service.exception.ObjectNotFoundException;
import com.francetelecom.clara.cloud.coremodel.Application;
import com.francetelecom.clara.cloud.coremodel.ApplicationRelease;
import com.francetelecom.clara.cloud.coremodel.ApplicationReleaseRepository;
import com.francetelecom.clara.cloud.logicalmodel.*;
import com.francetelecom.clara.cloud.mvn.consumer.MavenReferenceResolutionException;
import com.francetelecom.clara.cloud.mvn.consumer.MvnRepoDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* Business implementation for LogicalDeployment component
*
* All methods are defined as transactional. If no transaction in progress
* during method call, then it will start a new transaction.
*
* Last updated : $LastChangedDate: 2012-06-11 17:23:44 +0200 (lun., 11 juin
* 2012) $ Last author : $Author$
*
* @author Clara
* @version : $Revision$
*/
public class ManageLogicalDeploymentImpl implements ManageLogicalDeployment {
private static final Logger log = LoggerFactory.getLogger(ManageLogicalDeploymentImpl.class);
@Autowired
private LogicalDeploymentRepository logicalDeploymentRepository;
@Autowired
private MvnRepoDao mvnRepoDao;
@Autowired
private ApplicationReleaseRepository applicationReleaseRepository;
@Autowired
private LogicalDeploymentCloner cloner;
@Override
public void checkLogicalSoapServiceConsistency(LogicalSoapService logSoapService, boolean fullValidation) throws BusinessException {
// check soap attachments maven reference
MavenReference serviceAttachmentsMavenRef = logSoapService.getServiceAttachments();
try {
URL accessUrl = checkMavenReference(serviceAttachmentsMavenRef);
serviceAttachmentsMavenRef.setAccessUrl(accessUrl);
} catch (InvalidMavenReferenceException e) {
log.warn("Invalid logical soap service attachments maven reference");
throw e;
}
// assert logical soap service is valid
}
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackForClassName = { "BusinessException" })
public LogicalDeployment checkOverallConsistencyAndUpdateLogicalDeployment(LogicalDeployment logicalDeployment) throws BusinessException {
// First check logical deployment has been persisted
LogicalDeployment persisted = logicalDeploymentRepository.findOne(logicalDeployment.getId());
if (persisted == null) {
String message = "LogicalDeployment[" + logicalDeployment.getName() + "] does not exist";
log.error(message);
throw new ObjectNotFoundException(message);
}
// check consistency and update any model element which might be
// generated/modified during check
// typically resolved maven references are updated on execution nodes
// and logical services
checkOverallConsistency(logicalDeployment, true);
// if no error, then persist our updates
return logicalDeploymentRepository.save(logicalDeployment);
}
@Override
public void checkOverallConsistency(LogicalDeployment logicalDeployment) throws BusinessException {
// check consistency but do not update model elements which might be
// generated/modified during check
// typically resolved maven references are NOT updated on execution
// nodes and logical services
checkOverallConsistency(logicalDeployment, false);
}
/**
* Check that logical model is consistent. Check config sets and maven
* references. Maven references are checked by resolving their access urls.
*
* @param logicalDeployment
* ld
* @param updateModelFlag
* true if model elements such as resolved maven references must
* be updated
* @throws BusinessException
* , the exact exception is LogicalModelNotConsistentException
* which wraps all inconsistency error exceptions raised during
* check
*/
protected void checkOverallConsistency(LogicalDeployment logicalDeployment, boolean updateModelFlag) throws BusinessException {
// Exception is created in case we need to fill it
// We will run a set of checks
// For each check we catch business exception and add it as a unit
// errors to be added to a main LogicalModelNotConsistentException
List<BusinessException> errors = new ArrayList<BusinessException>();
// CHECK MAVEN REFERENCES (check if they can be resolved)
// build the list of all maven references
List<MavenReference> mavenReferences = new ArrayList<MavenReference>();
for (ProcessingNode jeeProcessing : logicalDeployment.listProcessingNodes()) {
if (jeeProcessing.getSoftwareReference() != null){
if (jeeProcessing.isOptionalSoftwareReference()){
log.info("Ignoring optional artifact reference verification for "+ jeeProcessing.toString());
} else
{ mavenReferences.add(jeeProcessing.getSoftwareReference());
}
}
}
// check soap service files (wsdl & xsd) package
for (LogicalSoapService soapService : logicalDeployment.listLogicalServices(LogicalSoapService.class)) {
if (soapService.getServiceAttachments() != null)
mavenReferences.add(soapService.getServiceAttachments());
}
// Check each maven references and update access URL if updateModelFlag
// is true
for (MavenReference mavenRef : mavenReferences) {
URL accessUrl = null;
try {
accessUrl = checkMavenReference(mavenRef);
} catch (InvalidMavenReferenceException e) {
errors.add(e);
}
if (updateModelFlag)
mavenRef.setAccessUrl(accessUrl);
}
try {
logicalDeployment.checkOverallConsistency();
} catch (LogicalModelNotConsistentException e) {
errors.addAll(e.getErrors());
}
// is our list of errors empty ? if not throw exception
if (!errors.isEmpty()) {
for (BusinessException businessException : errors) {
log.warn("Error when validating logical model. Invalid user input ? ", businessException);
}
throw new LogicalModelNotConsistentException(errors);
}
}
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackForClassName = { "BusinessException" })
public LogicalDeployment updateLogicalDeployment(LogicalDeployment logicalDeployment) throws ObjectNotFoundException, InvalidMavenReferenceException {
LogicalDeployment persisted = logicalDeploymentRepository.findOne(logicalDeployment.getId());
if (persisted == null) {
String message = "LogicalDeployment[" + logicalDeployment.getName() + "] does not exist";
log.error(message);
throw new ObjectNotFoundException(message);
}
// Validate model
ValidatorUtil.validate(logicalDeployment);
return logicalDeploymentRepository.save(logicalDeployment);
}
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackForClassName = { "BusinessException" })
public void cloneLogicalDeployment(String applicationReleaseSourceUID, String applicationReleaseTargetUID) throws InvalidReleaseException {
ApplicationRelease sourceAr = applicationReleaseRepository.findByUID(applicationReleaseSourceUID);
if (sourceAr == null) {
throw new InvalidReleaseException("Invalid applicationReleaseSourceInternalName" + applicationReleaseSourceUID);
}
ApplicationRelease targetAr = applicationReleaseRepository.findByUID(applicationReleaseTargetUID);
if (targetAr == null) {
throw new InvalidReleaseException("Invalid applicationReleaseTargetInternalName" + applicationReleaseTargetUID);
}
Application sourceApp = sourceAr.getApplication();
Application targetApp = targetAr.getApplication();
if ((applicationReleaseRepository.findApplicationReleasesByAppUID(targetAr.getUID()).size() > 1) && !targetApp.getUID().equals(sourceApp.getUID())) {
throw new InvalidReleaseException("Invalid applicationReleaseTargetInternalName" + applicationReleaseTargetUID);
}
if (targetAr.isDiscarded()) {
throw new InvalidReleaseException("cannot clone logical deployment to a DISCARDED application release");
}
LogicalDeployment sourceLd = sourceAr.getLogicalDeployment();
LogicalDeployment targetLd = targetAr.getLogicalDeployment();
LogicalDeployment sourceClone = cloner.deepCopy(sourceLd);
targetAr.replaceLd(sourceClone);
// then delete the target Ld to avoid dangling objects in DB
logicalDeploymentRepository.delete(targetLd);
logicalDeploymentRepository.save(sourceClone);
}
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public LogicalDeployment findLogicalDeployment(int logicalDeploymentId) throws ObjectNotFoundException {
LogicalDeployment logicalDeployment = logicalDeploymentRepository.findOne(logicalDeploymentId);
if (logicalDeployment == null) {
String message = "LogicalDeployment[" + logicalDeploymentId + "] does not exist";
log.error(message);
throw new ObjectNotFoundException(message);
}
// TODO verifier strategie de loading des logicalServices et
// processingNodes pour forcer le chargement des LogicalServices
logicalDeployment.listProcessingNodes().size();
logicalDeployment.listLogicalServices().size();
for (LogicalService logicalService : logicalDeployment.listLogicalServices()) {
logicalService.listLogicalServicesAssociations().size();
}
// pour forcer le chargement des NodeClusters
// logicalDeployment.listNodeClusters().size();
for (ProcessingNode jeeProcessing : logicalDeployment.listProcessingNodes()) {
jeeProcessing.listLogicalServicesAssociations().size();
}
// retourne un logical deployment contenant des logicalServices et
// processingNodes charges
return logicalDeployment;
}
@Override
public void resolveMavenURL(ProcessingNode node) {
MavenReference reference = mvnRepoDao.resolveUrl(node.getSoftwareReference());
node.setSoftwareReference(reference);
}
@Override
public URL checkMavenReference(MavenReference mavenReference) throws InvalidMavenReferenceException {
MavenReference updatedMavenReference = null;
try {
updatedMavenReference = mvnRepoDao.resolveUrl(mavenReference);
} catch (MavenReferenceResolutionException e) {
throw new InvalidMavenReferenceException(mavenReference, InvalidMavenReferenceException.ErrorType.ARTIFACT_NOT_FOUND);
}
assert (updatedMavenReference != null) : "updatedMavenReference provided by mvnRepoDao.resolveUrl(...) is null (mvnRepoDao mocked ? cf. wiki)";
return updatedMavenReference.getAccessUrl();
}
public void setLogicalDeploymentRepository(LogicalDeploymentRepository logicalDeploymentRepository) {
this.logicalDeploymentRepository = logicalDeploymentRepository;
}
public void setMvnRepoDao(MvnRepoDao mvnRepoDao) {
this.mvnRepoDao = mvnRepoDao;
}
@Override
public List<String> getQrsApplicationVersions(String domain, String appName) throws ObjectNotFoundException {
List<String> lstApplicationVersions = new ArrayList<String>();
if ("ADV".equalsIgnoreCase(appName)){
lstApplicationVersions.add("G1R0C0");
lstApplicationVersions.add("G2R0C0");
lstApplicationVersions.add("G3R0C0");
} else if ("IODA".equalsIgnoreCase(appName) || "SOFT".equalsIgnoreCase(appName)) {
lstApplicationVersions.add("G1R0C0");
lstApplicationVersions.add("G2R0C0");
} else if ("PtpmFrontOffice".equalsIgnoreCase(appName)) {
lstApplicationVersions.add("G1R1C0");
} else if ("PtpmBackOffice".equalsIgnoreCase(appName)) {
lstApplicationVersions.add("G1R2C0");
} else if ("SEBA IN PAAS".equalsIgnoreCase(appName) || ("SEBA IN CLOUD".equalsIgnoreCase(appName))
|| "SEBA OUT CLOUD".equalsIgnoreCase(appName)){
lstApplicationVersions.add("G6R0C0");
} else if ("Momoo Client".equalsIgnoreCase(appName) || "Momoo Server".equalsIgnoreCase(appName)){
lstApplicationVersions.add("G6R0C0");
}
return lstApplicationVersions;
}
@Override
public List<String> getQrsApplications(String domain) throws ObjectNotFoundException {
List<String> lstApplicationName = new ArrayList<String>();
lstApplicationName.add("ADV");
lstApplicationName.add("IODA");
lstApplicationName.add("DLIS");
lstApplicationName.add("SOFT");
lstApplicationName.add("PtpmFrontOffice");
lstApplicationName.add("PtpmBackOffice");
lstApplicationName.add("SEBA IN PAAS");
lstApplicationName.add("SEBA IN CLOUD");
lstApplicationName.add("SEBA OUT CLOUD");
lstApplicationName.add("Momoo Client");
lstApplicationName.add("Momoo Server");
return lstApplicationName;
}
@Override
public List<String> getQrsServices(String domain, String appName, String appVersion) throws ObjectNotFoundException {
List<String> lstServices = new ArrayList<String>();
if ("ADV".equalsIgnoreCase(appName)) {
lstServices.add("getClient");
lstServices.add("getMISDN");
lstServices.add("getIMSI");
} else if ("IODA".equalsIgnoreCase(appName)) {
lstServices.add("setIMSI");
lstServices.add("setMISDN");
} else if ("DLIS".equalsIgnoreCase(appName)) {
lstServices.add("getDelayLiv");
} else if ("SOFT".equalsIgnoreCase(appName)) {
lstServices.add("setDelayLiv");
} else if ("PtpmFrontOffice".equalsIgnoreCase(appName)) {
lstServices.add("pong");
} else if ("PtpmBackOffice".equalsIgnoreCase(appName)) {
lstServices.add("ping");
} else if ("SEBA IN PAAS".equalsIgnoreCase(appName) || "SEBA IN CLOUD".equalsIgnoreCase(appName)
|| "SEBA OUT CLOUD".equalsIgnoreCase(appName)){
lstServices.add("subscribeLine");
} else if ("Momoo Server".equalsIgnoreCase(appName)){
lstServices.add("createMarket");
lstServices.add("updateMarket");
lstServices.add("deleteMarket");
lstServices.add("createCatalog");
lstServices.add("updateCatalog");
lstServices.add("deleteCatalog");
lstServices.add("createArticle");
lstServices.add("updateArticle");
lstServices.add("deleteArticle");
} else if ("Momoo Client".equalsIgnoreCase(appName)){
lstServices.add("returnMarket");
lstServices.add("returnCatalog");
lstServices.add("returnArticle");
}
return lstServices;
}
@Override
public List<String> getQrsServicesVersions(String domain, String appName, String appVersion, String serviceName) throws ObjectNotFoundException {
List<String> lstServiceVersions = new ArrayList<String>();
if ("getClient".equalsIgnoreCase(serviceName)){
lstServiceVersions.add("G1R0C0");
lstServiceVersions.add("G2R0C0");
} else if ("getMISDN".equalsIgnoreCase(serviceName)) {
lstServiceVersions.add("G1R0C0");
lstServiceVersions.add("G2R0C0");
lstServiceVersions.add("G2R1C0");
} else if ("getIMSI".equalsIgnoreCase(serviceName)) {
lstServiceVersions.add("G1R0C0");
lstServiceVersions.add("G2R0C0");
} else if ("setIMSI".equalsIgnoreCase(serviceName)) {
lstServiceVersions.add("G1R0C0");
lstServiceVersions.add("G2R0C0");
} else if ("setMISDN".equalsIgnoreCase(serviceName)) {
lstServiceVersions.add("G1R0C0");
lstServiceVersions.add("G2R0C0");
} else if ("getDelayLiv".equalsIgnoreCase(serviceName)) {
lstServiceVersions.add("G1R0C0");
} else if ("setDelayLiv".equalsIgnoreCase(serviceName)) {
lstServiceVersions.add("G1R0C0");
} else if ("ping".equalsIgnoreCase(serviceName)) {
lstServiceVersions.add("G1R1C0");
} else if ("pong".equalsIgnoreCase(serviceName)) {
lstServiceVersions.add("G1R1C0");
} else if ("subscribeLine".equalsIgnoreCase(serviceName)) {
lstServiceVersions.add("G1R0C0");
} else {
lstServiceVersions.add("G1R0C0");
}
return lstServiceVersions;
}
}