Skip to content
Snippets Groups Projects
Commit f5302d45 authored by kbeyro's avatar kbeyro
Browse files

Merge branch 'release/1.6.5-fix' into 1.6.5-fix-processing-bulk

# Conflicts:
#	build.gradle
#	src/test/java/net/geant/nmaas/portal/service/impl/BulkApplicationServiceImplTest.java
#	src/test/java/net/geant/nmaas/portal/service/impl/InternationalizationServiceTest.java
parents 33a21813 df228deb
No related branches found
No related tags found
2 merge requests!65Resolve "Prevent users from adding an existing SSH key",!601.6.5 fix processing bulk
Pipeline #91072 failed
This commit is part of merge request !65. Comments created here will be created in the context of that merge request.
Showing
with 275 additions and 46 deletions
......@@ -13,7 +13,7 @@ repositories {
mavenCentral()
}
version = '1.7.0-SNAPSHOT'
version = '1.6.5-SNAPSHOT'
group = 'net.geant.nmaas'
java {
......@@ -95,8 +95,6 @@ dependencies {
implementation('org.springframework.boot:spring-boot-starter-quartz')
implementation('org.springframework.boot:spring-boot-starter-log4j2')
implementation('org.springframework.boot:spring-boot-starter-validation')
implementation 'org.springframework.boot:spring-boot-starter-cache'
implementation('org.springdoc:springdoc-openapi-ui:1.6.15')
......@@ -116,7 +114,6 @@ dependencies {
implementation('com.vdurmont:semver4j:3.1.0')
implementation('io.micrometer:micrometer-registry-prometheus:1.11.2')
// SSH library
implementation('com.hierynomus:sshj:0.32.0')
......
......@@ -74,7 +74,9 @@ nmaas.service.deployment.check.interval=${DEPLOYMENT_CHECK_INTERVAL}
nmaas.service.deployment.max.duration=${DEPLOYMENT_CHECK_TIMEOUT}
nmaas.service.upgrade.cron=${APP_UPGRADE_CRON}
nmaas.service.upgrade-summary.cron=${APP_UPGRADE_SUMMARY_CRON}
nmaas.service.bulk-deployment.cron=0 */1 * * * ?
nmaas.service.upgrade-summary.interval=${APP_UPGRADE_SUMMARY_INTERVAL}
nmaas.service.deployment.parallel.limit=2
nmaas.portal.domains.codename.pattern=[a-z0-9-]{2,12}
nmaas.portal.domains.codename.length=12
......
......@@ -65,7 +65,7 @@ public class ConfigurationControllerTest extends BaseControllerTestSetup {
@Test
void shouldAddNewConfiguration() throws Exception {
repository.deleteAll();
ConfigurationView configuration = new ConfigurationView(true, false, "en", false, false, new ArrayList<>(), true, true);
ConfigurationView configuration = new ConfigurationView(1L, true, false, "en", false, false, new ArrayList<>(), true, true, true, "0 */1 * * * ?", 2);
mvc.perform(post(URL_PREFIX)
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization","Bearer " + getValidTokenForUser(user))
......@@ -81,7 +81,7 @@ public class ConfigurationControllerTest extends BaseControllerTestSetup {
@Test
void shouldUpdateConfiguration() throws Exception {
Long id = repository.findAll().get(0).getId();
ConfigurationView configuration = new ConfigurationView(true, false, "en", false, false, new ArrayList<>(), true, true);
ConfigurationView configuration = new ConfigurationView(1L, true, false, "en", false, false, new ArrayList<>(), true, true, true, "0 */1 * * * ?", 2);
configuration.setId(id);
mvc.perform(put(URL_PREFIX+"/{id}",id)
.contentType(MediaType.APPLICATION_JSON)
......
......@@ -94,7 +94,7 @@ public class BulkDomainServiceIntTest {
CsvDomain csvDomain2 = new CsvDomain("test5", "user2", "user2@test.com", null, "group1", false);
List<CsvDomain> input = List.of(csvDomain1, csvDomain2);
configurationRepository.save(modelMapper.map(
ConfigurationView.builder().id(1L).defaultLanguage("en").bulkDomainsAllowForSsoAccounts(false).build(), Configuration.class));
ConfigurationView.builder().id(1L).defaultLanguage("en").bulkDomainsAllowForSsoAccounts(false).parallelDeploymentsLimit(2).bulkDeploymentJobCron("* * * *").build(), Configuration.class));
UserViewMinimal creator = new UserViewMinimal();
creator.setId(1L);
creator.setUsername("admin");
......
......@@ -50,7 +50,9 @@ nmaas.service.deployment.check.interval=10
nmaas.service.deployment.max.duration=30
nmaas.service.upgrade.cron=0 */5 * * * ?
nmaas.service.upgrade-summary.cron=0 0 * * * ?
nmaas.service.bulk-deployment.cron=0 */1 * * * ?
nmaas.service.upgrade-summary.interval=1
nmaas.service.deployment.parallel.limit=2
nmaas.portal.domains.codename.pattern=[a-z0-9-]{2,12}
nmaas.portal.domains.codename.length=12
......
package net.geant.nmaas.nmservice.deployment.bulks;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Service;
@Slf4j
@RequiredArgsConstructor
@Service
public class BulkDeploymentJob implements Job {
private final BulkDeploymentQueueService service;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.debug("Triggering bulk deployment job...");
service.handleQueue();
}
}
package net.geant.nmaas.nmservice.deployment.bulks;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.geant.nmaas.orchestration.Identifier;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BulkDeploymentQueueEntry {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Identifier deploymentId;
private Long bulkEntryId;
@JsonProperty("appConfigurationJson")
private String appConfigurationJson;
@Enumerated(EnumType.STRING)
private QueryEntryState state;
public enum QueryEntryState {
WAITING,
IN_PROGRESS
}
}
package net.geant.nmaas.nmservice.deployment.bulks;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface BulkDeploymentQueueRepository extends JpaRepository<BulkDeploymentQueueEntry, Long> {
}
\ No newline at end of file
package net.geant.nmaas.nmservice.deployment.bulks;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.geant.nmaas.nmservice.deployment.bulks.BulkDeploymentQueueEntry.QueryEntryState;
import net.geant.nmaas.orchestration.AppDeploymentMonitor;
import net.geant.nmaas.orchestration.AppDeploymentRepositoryManager;
import net.geant.nmaas.orchestration.AppLifecycleManager;
import net.geant.nmaas.orchestration.AppLifecycleState;
import net.geant.nmaas.orchestration.api.model.AppConfigurationView;
import net.geant.nmaas.orchestration.entities.AppDeploymentState;
import net.geant.nmaas.orchestration.events.app.AppVerifyRequestActionEvent;
import net.geant.nmaas.portal.service.BulkApplicationService;
import net.geant.nmaas.portal.service.ConfigurationManager;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
@Slf4j
public class BulkDeploymentQueueService {
private final AppDeploymentMonitor appDeploymentMonitor;
private final AppDeploymentRepositoryManager appDeploymentRepositoryManager;
private final BulkDeploymentQueueRepository queueRepository;
private final ApplicationEventPublisher eventPublisher;
private final BulkApplicationService bulkApplicationService;
private final AppLifecycleManager appLifecycleManager;
private final ConfigurationManager configurationManager;
public void handleQueue() {
List<BulkDeploymentQueueEntry> queue = queueRepository.findAll();
log.debug("Handling bulk queue (total entries {})", queue.size());
if (queue.isEmpty()) {
return;
}
updateBulkStatusForCompletedOrFailedAndRemoveThemFromQueue();
triggerConfiguration();
triggerNewDeploymentsFromQueue();
}
private void updateBulkStatusForCompletedOrFailedAndRemoveThemFromQueue() {
List<BulkDeploymentQueueEntry> queue = queueRepository.findAll();
queue.stream()
.filter(e -> {
AppDeploymentState state = appDeploymentRepositoryManager.loadState(e.getDeploymentId());
return state.isInRunningState() || state.isInFailedState();
})
.forEach(e -> {
bulkApplicationService.updateEntryStateById(e.getBulkEntryId());
log.debug("Removing entry for {}", e.getDeploymentId());
queueRepository.delete(e);
});
}
private void triggerConfiguration() {
List<BulkDeploymentQueueEntry> queue = queueRepository.findAll();
queue.stream()
.filter(deployment -> appDeploymentMonitor.state(deployment.getDeploymentId()).equals(AppLifecycleState.MANAGEMENT_VPN_CONFIGURED))
.forEach(e -> {
log.debug("Configuration task triggered for {}", e.getDeploymentId());
appLifecycleManager.applyConfiguration(e.getDeploymentId(), AppConfigurationView.builder()
.jsonInput(e.getAppConfigurationJson())
.mandatoryParameters(e.getAppConfigurationJson()).build(), null);
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
});
}
private void triggerNewDeploymentsFromQueue() {
List<BulkDeploymentQueueEntry> queue = queueRepository.findAll();
long parallelDeploymentsLimit = configurationManager.getConfiguration().getParallelDeploymentsLimit();
long ongoingDeployments = queue.stream().filter(e -> e.getState().equals(QueryEntryState.IN_PROGRESS)).count();
long freeCapacity = parallelDeploymentsLimit - ongoingDeployments;
log.debug("Number of instances that can be triggered right away: {}", freeCapacity);
queue.stream()
.filter(e -> appDeploymentMonitor.state(e.getDeploymentId()).equals(AppLifecycleState.REQUESTED)
|| e.getState().equals(QueryEntryState.WAITING))
.limit(freeCapacity)
.forEach(e -> {
log.debug("Triggering deployment for {}", e.getDeploymentId());
eventPublisher.publishEvent(new AppVerifyRequestActionEvent(this, e.getDeploymentId()));
e.setState(QueryEntryState.IN_PROGRESS);
bulkApplicationService.setBulkEntryToProcessing(e.getBulkEntryId());
queueRepository.save(e);
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
});
}
}
......@@ -2,6 +2,7 @@ package net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes;
import lombok.RequiredArgsConstructor;
import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.helm.HelmKServiceManager;
import net.geant.nmaas.portal.api.configuration.InitScriptsController;
import net.geant.nmaas.portal.events.ApplicationActivatedEvent;
import net.geant.nmaas.utils.logging.LogLevel;
import net.geant.nmaas.utils.logging.Loggable;
......@@ -15,10 +16,15 @@ public class HelmRepoUpdateListener {
private final HelmKServiceManager helmKServiceManager;
private final InitScriptsController initScriptsController;
@EventListener
@Loggable(LogLevel.INFO)
public ApplicationEvent trigger(ApplicationActivatedEvent event) {
helmKServiceManager.updateHelmRepo();
if(!initScriptsController.isScriptRunning) {
helmKServiceManager.updateHelmRepo();
}
return null;
}
......
package net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.helm;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.geant.nmaas.portal.api.configuration.InitScriptsController;
import net.geant.nmaas.portal.events.ApplicationListUpdatedEvent;
import net.geant.nmaas.utils.logging.LogLevel;
import net.geant.nmaas.utils.logging.Loggable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
......@@ -17,13 +17,14 @@ import static net.geant.nmaas.portal.events.ApplicationListUpdatedEvent.Applicat
import static net.geant.nmaas.portal.events.ApplicationListUpdatedEvent.ApplicationAction.UPDATED;
@Component
@AllArgsConstructor
@RequiredArgsConstructor
@Slf4j
public class HelmChartUpdateListener {
@Autowired
private final HelmCommandExecutor helmCommandExecutor;
private final InitScriptsController initScriptsController;
@EventListener
@Loggable(LogLevel.INFO)
public ApplicationEvent trigger(ApplicationListUpdatedEvent event) {
......@@ -34,8 +35,11 @@ public class HelmChartUpdateListener {
if (StringUtils.hasText(repoName) && StringUtils.hasText(repoUrl)) {
helmCommandExecutor.executeHelmRepoAddCommand(repoName, repoUrl);
}
if (!initScriptsController.isScriptRunning) {
helmCommandExecutor.executeHelmRepoUpdateCommand();
}
}
helmCommandExecutor.executeHelmRepoUpdateCommand();
return null;
}
......
......@@ -189,7 +189,7 @@ public class HelmCommandExecutor {
singleCommandExecutor().executeSingleCommand(
HelmVersionCommand.command(helmVersion, enableTls)
);
} catch(SshConnectionException e) {
} catch (SshConnectionException e) {
throw new CommandExecutionException("Failed to execute helm version command -> " + e.getMessage());
}
}
......@@ -201,7 +201,7 @@ public class HelmCommandExecutor {
void executeHelmRepoUpdateCommand() {
try{
singleCommandExecutor().executeSingleCommand(HelmRepoUpdateCommand.command());
} catch(SshConnectionException e) {
} catch (SshConnectionException e) {
throw new CommandExecutionException("Failed to execute helm repository update command -> " + e.getMessage());
}
}
......@@ -209,7 +209,7 @@ public class HelmCommandExecutor {
void executeHelmRepoAddCommand(String repoName, String repoUrl) {
try{
singleCommandExecutor().executeSingleCommand(HelmRepoAddCommand.command(repoName, repoUrl));
} catch(SshConnectionException e) {
} catch (SshConnectionException e) {
throw new CommandExecutionException("Failed to execute helm repository add command -> " + e.getMessage());
}
}
......
......@@ -56,7 +56,7 @@ public class HelmKServiceManager implements KServiceLifecycleManager {
private boolean helmRepoUpdateAsyncEnabled;
@Override
@Loggable(LogLevel.DEBUG)
@Loggable(LogLevel.TRACE)
public void deployService(Identifier deploymentId) {
try {
if (!helmRepoUpdateAsyncEnabled) {
......@@ -143,7 +143,7 @@ public class HelmKServiceManager implements KServiceLifecycleManager {
}
@Override
@Loggable(LogLevel.DEBUG)
@Loggable(LogLevel.TRACE)
public boolean checkServiceDeployed(Identifier deploymentId) {
try {
HelmPackageStatus status = helmCommandExecutor.executeHelmStatusCommand(
......@@ -157,12 +157,12 @@ public class HelmKServiceManager implements KServiceLifecycleManager {
}
@Override
@Loggable(LogLevel.DEBUG)
@Loggable(LogLevel.TRACE)
public void deleteServiceIfExists(Identifier deploymentId) {
String namespace = namespaceService.namespace(repositoryManager.loadDomain(deploymentId));
Identifier descriptiveDeploymentId = repositoryManager.loadDescriptiveDeploymentId(deploymentId);
try {
if(checkIfServiceExists(namespace, descriptiveDeploymentId)){
if (checkIfServiceExists(namespace, descriptiveDeploymentId)) {
helmCommandExecutor.executeHelmDeleteCommand(
namespace,
descriptiveDeploymentId.getValue()
......@@ -173,12 +173,12 @@ public class HelmKServiceManager implements KServiceLifecycleManager {
}
}
private boolean checkIfServiceExists(String namespace, Identifier deploymentId){
private boolean checkIfServiceExists(String namespace, Identifier deploymentId) {
return helmCommandExecutor.executeHelmListCommand(namespace).contains(deploymentId.value());
}
@Override
@Loggable(LogLevel.DEBUG)
@Loggable(LogLevel.TRACE)
public void upgradeService(Identifier deploymentId, KubernetesTemplate targetVersion) {
KubernetesNmServiceInfo serviceInfo = repositoryManager.loadService(deploymentId);
try {
......
package net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.helm;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class InitScriptsStateService {
private final HelmCommandExecutor helmCommandExecutor;
public void executeHelmRepoUpdate() {
helmCommandExecutor.executeHelmRepoUpdateCommand();
}
}
......@@ -84,35 +84,35 @@ public class JanitorService {
}
public void createOrReplaceConfigMap(Identifier deploymentId, String domain) {
log.info(String.format("Creating or replacing configMap(s) for deployment %s in domain %s", deploymentId.value(), domain));
log.info("Creating or replacing configMap(s) for deployment {} in domain {}", deploymentId.value(), domain);
ConfigServiceGrpc.ConfigServiceBlockingStub stub = ConfigServiceGrpc.newBlockingStub(channel);
JanitorManager.ServiceResponse response = stub.createOrReplace(buildInstanceRequest(deploymentId, domain));
throwExceptionIfExecutionFailed(response);
}
public void deleteConfigMapIfExists(Identifier deploymentId, String domain) {
log.info(String.format("Deleting configMap(s) for deployment %s in domain %s", deploymentId.value(), domain));
log.info("Deleting configMap(s) for deployment {} in domain {}", deploymentId.value(), domain);
ConfigServiceGrpc.ConfigServiceBlockingStub stub = ConfigServiceGrpc.newBlockingStub(channel);
JanitorManager.ServiceResponse response = stub.deleteIfExists(buildInstanceRequest(deploymentId, domain));
throwExceptionIfExecutionFailed(response);
}
public void createOrReplaceBasicAuth(Identifier deploymentId, String domain, String user, String password) {
log.info(String.format("Configuring basic auth for deployment %s in domain %s", deploymentId.value(), domain));
log.info("Configuring basic auth for deployment {} in domain {}", deploymentId.value(), domain);
BasicAuthServiceGrpc.BasicAuthServiceBlockingStub stub = BasicAuthServiceGrpc.newBlockingStub(channel);
JanitorManager.ServiceResponse response = stub.createOrReplace(buildInstanceCredentialsRequest(deploymentId, domain, user, password));
throwExceptionIfExecutionFailed(response);
}
public void deleteBasicAuthIfExists(Identifier deploymentId, String domain) {
log.info(String.format("Deleting basic auth for deployment %s in domain %s", deploymentId.value(), domain));
log.info("Deleting basic auth for deployment {} in domain {}", deploymentId.value(), domain);
BasicAuthServiceGrpc.BasicAuthServiceBlockingStub stub = BasicAuthServiceGrpc.newBlockingStub(channel);
JanitorManager.ServiceResponse response = stub.deleteIfExists(buildInstanceRequest(deploymentId, domain));
throwExceptionIfExecutionFailed(response);
}
public void deleteTlsIfExists(Identifier deploymentId, String domain) {
log.info(String.format("Deleting TLS for deployment %s in domain %s", deploymentId.value(), domain));
log.info("Deleting TLS for deployment {} in domain {}", deploymentId.value(), domain);
CertManagerServiceGrpc.CertManagerServiceBlockingStub stub = CertManagerServiceGrpc.newBlockingStub(channel);
JanitorManager.ServiceResponse response = stub.deleteIfExists(buildInstanceRequest(deploymentId, domain));
throwExceptionIfExecutionFailed(response);
......@@ -129,7 +129,7 @@ public class JanitorService {
}
public boolean checkIfReady(Identifier deploymentId, String domain) {
log.info(String.format("Checking if deployment %s in domain %s is ready", deploymentId.value(), domain));
log.trace("Checking if deployment {} in domain {} is ready", deploymentId.value(), domain);
ReadinessServiceGrpc.ReadinessServiceBlockingStub stub = ReadinessServiceGrpc.newBlockingStub(channel);
JanitorManager.ServiceResponse response = stub.checkIfReady(buildInstanceRequest(deploymentId, domain));
switch (response.getStatus()) {
......@@ -145,7 +145,7 @@ public class JanitorService {
}
public String retrieveServiceIp(Identifier serviceId, String domain) {
log.info(String.format("Retrieving service IP for %s in domain %s", serviceId.value(), domain));
log.info("Retrieving service IP for {} in domain {}", serviceId.value(), domain);
InformationServiceGrpc.InformationServiceBlockingStub stub = InformationServiceGrpc.newBlockingStub(channel);
JanitorManager.InfoServiceResponse response = stub.retrieveServiceIp(buildInstanceRequest(serviceId, domain));
switch (response.getStatus()) {
......@@ -158,7 +158,7 @@ public class JanitorService {
}
public void checkServiceExists(Identifier serviceId, String domain) {
log.info(String.format("Verifying if provided service %s exists in domain %s", serviceId.value(), domain));
log.info("Verifying if provided service {} exists in domain {}", serviceId.value(), domain);
InformationServiceGrpc.InformationServiceBlockingStub stub = InformationServiceGrpc.newBlockingStub(channel);
JanitorManager.InfoServiceResponse response = stub.checkServiceExists(buildInstanceRequest(serviceId, domain));
switch (response.getStatus()) {
......@@ -171,7 +171,7 @@ public class JanitorService {
}
public List<JanitorManager.PodInfo> getPodNames(Identifier deploymentId, String domain) {
log.info(String.format("Retrieving list of pods for %s in domain %s", deploymentId.value(), domain));
log.debug("Retrieving list of pods for {} in domain {}", deploymentId.value(), domain);
PodServiceGrpc.PodServiceBlockingStub stub = PodServiceGrpc.newBlockingStub(channel);
JanitorManager.PodListResponse response = stub.retrievePodList(buildInstanceRequest(deploymentId, domain));
switch (response.getStatus()) {
......@@ -209,7 +209,7 @@ public class JanitorService {
}
public void createNameSpace(String domainNameSpace, List<KeyValueView> annotations) {
log.info(String.format("Request domain namespace creation for domain %s with %s annotations", domainNameSpace, annotations.size()));
log.info("Request domain namespace creation for domain {} with {} annotations", domainNameSpace, annotations.size());
NamespaceServiceGrpc.NamespaceServiceBlockingStub stub = NamespaceServiceGrpc.newBlockingStub(channel);
JanitorManager.ServiceResponse response = stub.createNamespace(
buildNamespaceRequest(domainNameSpace, annotations));
......
......@@ -47,4 +47,5 @@ public interface AppDeploymentRepositoryManager {
Map<String, Long> getDeploymentStatistics();
Boolean isFirstTimeDeployment(Identifier deploymentId);
}
package net.geant.nmaas.orchestration;
import com.google.common.collect.ImmutableMap;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import net.geant.nmaas.nmservice.NmServiceDeploymentStateChangeEvent;
......@@ -49,13 +48,13 @@ public class AppDeploymentStateChangeManager {
try {
AppDeploymentState newDeploymentState = deploymentRepositoryManager.loadState(event.getDeploymentId()).nextState(event.getState());
deploymentRepositoryManager.updateState(event.getDeploymentId(), newDeploymentState);
if(newDeploymentState.isInFailedState()) {
log.warn("Application deployment failed state detected. Saving error message: " + event.getErrorMessage());
if (newDeploymentState.isInFailedState()) {
log.warn("Application deployment failed state detected. Saving error message: {}", event.getErrorMessage());
deploymentRepositoryManager.updateErrorMessage(event.getDeploymentId(), event.getErrorMessage());
eventPublisher.publishEvent(
new NotificationEvent(this, getMailAttributes(deploymentRepositoryManager.load(event.getDeploymentId()), event.getErrorMessage()))
);
if(newDeploymentState == AppDeploymentState.APPLICATION_UPGRADE_FAILED) {
if (newDeploymentState == AppDeploymentState.APPLICATION_UPGRADE_FAILED) {
eventPublisher.publishEvent(
new AppUpgradeFailedEvent(this,
event.getDeploymentId(),
......@@ -65,7 +64,7 @@ public class AppDeploymentStateChangeManager {
);
}
}
if(newDeploymentState == AppDeploymentState.APPLICATION_UPGRADED) {
if (newDeploymentState == AppDeploymentState.APPLICATION_UPGRADED) {
Identifier previousApplicationId = deploymentRepositoryManager.loadApplicationId(event.getDeploymentId());
Identifier newApplicationId = Identifier.newInstance(event.getDetail(EventDetailType.NEW_APPLICATION_ID));
deploymentRepositoryManager.updateApplicationId(event.getDeploymentId(), newApplicationId);
......@@ -77,16 +76,16 @@ public class AppDeploymentStateChangeManager {
AppUpgradeMode.valueOf(event.getDetail(EventDetailType.UPGRADE_TRIGGER_TYPE)))
);
}
if(newDeploymentState == AppDeploymentState.APPLICATION_DEPLOYMENT_VERIFIED) {
eventPublisher.publishEvent(
new NotificationEvent(this, getMailAttributes(deploymentRepositoryManager.load(event.getDeploymentId()))));
if (newDeploymentState == AppDeploymentState.APPLICATION_DEPLOYMENT_VERIFIED
&& deploymentRepositoryManager.isFirstTimeDeployment(event.getDeploymentId())) {
eventPublisher.publishEvent(
new NotificationEvent(this, getMailAttributes(deploymentRepositoryManager.load(event.getDeploymentId()))));
}
return triggerActionEventIfRequired(event.getDeploymentId(), newDeploymentState).orElse(null);
} catch (InvalidAppStateException e) {
log.warn("State notification failure -> " + e.getMessage());
log.warn("State notification failure -> {}", e.getMessage());
deploymentRepositoryManager.updateErrorMessage(event.getDeploymentId(), e.getMessage());
deploymentRepositoryManager.updateState(event.getDeploymentId(), AppDeploymentState.INTERNAL_ERROR);
eventPublisher.publishEvent(
new NotificationEvent(this, getMailAttributes(deploymentRepositoryManager.load(event.getDeploymentId()), e.getMessage()))
);
......@@ -119,19 +118,19 @@ public class AppDeploymentStateChangeManager {
@EventListener
@Loggable(LogLevel.INFO)
public synchronized void notifyDcnDeployed(DcnDeployedEvent event) {
try{
try {
deploymentRepositoryManager.loadAllWaitingForDcn(event.getRelatedTo())
.forEach(d -> eventPublisher.publishEvent(
new NmServiceDeploymentStateChangeEvent(this, d.getDeploymentId(), NmServiceDeploymentState.READY_FOR_DEPLOYMENT, "")));
}catch(Exception ex){
} catch(Exception ex) {
long timestamp = System.currentTimeMillis();
log.error("Error reported at " + timestamp, ex);
log.error("Error reported at {}", timestamp, ex);
}
}
private MailAttributes getMailAttributes(AppDeployment appDeployment){
return MailAttributes.builder()
.otherAttributes(ImmutableMap.of(
.otherAttributes(Map.of(
"accessURL", deploymentMonitor.userAccessDetails(appDeployment.getDeploymentId())
.getServiceAccessMethods().stream()
.filter(m -> !Arrays.asList(ServiceAccessMethodType.INTERNAL, ServiceAccessMethodType.LOCAL).contains(m.getType()))
......
......@@ -20,6 +20,14 @@ public interface AppLifecycleManager {
*/
Identifier deployApplication(AppDeployment appDeployment);
/**
* Initializes application deployment without triggering the process itself.
*
* @param appDeployment App deployment
* @return unique identifier of the deployed user application
*/
Identifier initApplicationDeployment(AppDeployment appDeployment);
/**
* Triggers the nmaas application redeployment process which may take some time.This process is executed asynchronously
* and {@link AppDeploymentState} for this deployment is updated once particular deployment phases
......
......@@ -157,6 +157,12 @@ public class DefaultAppDeploymentRepositoryManager implements AppDeploymentRepos
return this.repository.countAllRunningByAppName().stream().collect(Collectors.toMap(AppDeploymentCount::getApplicationName, AppDeploymentCount::getCount));
}
@Override
@Transactional
public Boolean isFirstTimeDeployment(Identifier deploymentId) {
return loadStateHistory(deploymentId).stream().filter(state -> state.getCurrentState().isInRunningState()).count() <= 1;
}
private String deploymentNotFoundMessage(Identifier deploymentId) {
return "Deployment with id " + deploymentId + " not found in the repository. ";
}
......
......@@ -66,6 +66,16 @@ public class DefaultAppLifecycleManager implements AppLifecycleManager {
return deploymentId;
}
@Override
@Loggable(LogLevel.INFO)
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Identifier initApplicationDeployment(AppDeployment appDeployment) {
Identifier deploymentId = generateDeploymentId();
appDeployment.setDeploymentId(deploymentId);
deploymentRepositoryManager.store(appDeployment);
return deploymentId;
}
Identifier generateDeploymentId() {
Identifier generatedId;
do {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment