Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package fr.insee.genesis.controller.rest;

import fr.insee.genesis.domain.model.rundeck.RundeckExecution;
import fr.insee.genesis.domain.ports.api.RundeckExecutionApiPort;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping(path = "/rundeck-execution")
@Controller
@Slf4j
public class RundeckExecutionController {

private final RundeckExecutionApiPort rundeckExecutionApiPort;

@Autowired
public RundeckExecutionController(RundeckExecutionApiPort rundeckExecutionApiPort) {
this.rundeckExecutionApiPort = rundeckExecutionApiPort;
}

@Operation(summary = "Register a Rundeck execution")
@PostMapping(path = "/save")
public ResponseEntity<Object> addRundeckExecution(
@Parameter(description = "JSON response from Rundeck API /run endpoint") @RequestBody RundeckExecution rundeckExecution
){
try{
rundeckExecutionApiPort.addExecution(rundeckExecution);
log.info("{} job saved", rundeckExecution.getJob().getName());
} catch(Exception e){
log.info("Rundeck execution was not saved in database");
return ResponseEntity.internalServerError().build();
}
return ResponseEntity.ok().build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package fr.insee.genesis.domain.model.rundeck;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class DateStarted {

private long unixtime;
private String date;

}
20 changes: 20 additions & 0 deletions src/main/java/fr/insee/genesis/domain/model/rundeck/Job.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package fr.insee.genesis.domain.model.rundeck;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Job {

@JsonProperty("id")
private String idJob;
private long averageDuration;
private String name;
private String group;
private String project;
private String description;
private String href;
private String permalink;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package fr.insee.genesis.domain.model.rundeck;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class RundeckExecution {

@JsonProperty("id")
private long idExecution;
private String href;
private String permalink;
private String status;
private String project;
private String executionType;
private String user;

@JsonProperty("date-started")
private DateStarted dateStarted;

private Job job;
private String description;
private String argstring;
private String serverUUID;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package fr.insee.genesis.domain.ports.api;

import fr.insee.genesis.domain.model.rundeck.RundeckExecution;

public interface RundeckExecutionApiPort {

void addExecution(RundeckExecution rundeckExecution);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package fr.insee.genesis.domain.ports.spi;

import fr.insee.genesis.domain.model.rundeck.RundeckExecution;

public interface RundeckExecutionPersistencePort {

void save(RundeckExecution rundeckExecution);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package fr.insee.genesis.domain.service.rundeck;

import fr.insee.genesis.domain.model.rundeck.RundeckExecution;
import fr.insee.genesis.domain.ports.api.RundeckExecutionApiPort;
import fr.insee.genesis.domain.ports.spi.RundeckExecutionPersistencePort;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class RundeckExecutionService implements RundeckExecutionApiPort {
@Qualifier("rundeckExecutionMongoAdapter")
private final RundeckExecutionPersistencePort rundeckExecutionPersistencePort;

@Autowired
public RundeckExecutionService(RundeckExecutionPersistencePort rundeckExecutionPersistencePort) {
this.rundeckExecutionPersistencePort = rundeckExecutionPersistencePort;
}

@Override
public void addExecution(RundeckExecution rundeckExecution) {
rundeckExecutionPersistencePort.save(rundeckExecution);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package fr.insee.genesis.infrastructure.adapter;

import fr.insee.genesis.domain.model.rundeck.RundeckExecution;
import fr.insee.genesis.domain.ports.spi.RundeckExecutionPersistencePort;
import fr.insee.genesis.infrastructure.mappers.RundeckExecutionDocumentMapper;
import fr.insee.genesis.infrastructure.repository.RundeckExecutionDBRepository;
import fr.insee.genesis.infrastructure.repository.ScheduleMongoDBRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

@Service
@Qualifier("rundeckExecutionMongoAdapter")
@Slf4j
public class RundeckExecutionMongoAdapter implements RundeckExecutionPersistencePort {

private final RundeckExecutionDBRepository rundeckExecutionDBRepository;

@Autowired
public RundeckExecutionMongoAdapter(RundeckExecutionDBRepository rundeckExecutionDBRepository) {
this.rundeckExecutionDBRepository = rundeckExecutionDBRepository;
}

@Override
public void save(RundeckExecution rundeckExecution) {
rundeckExecutionDBRepository.insert(RundeckExecutionDocumentMapper.INSTANCE.modelToDocument(rundeckExecution));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package fr.insee.genesis.infrastructure.document.rundeck;

import lombok.Data;

@Data
public class Job {

private String idJob;
private long averageDuration;
private String name;
private String project;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package fr.insee.genesis.infrastructure.document.rundeck;

import com.fasterxml.jackson.annotation.JsonProperty;
import fr.insee.genesis.domain.model.rundeck.DateStarted;
import lombok.*;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection= "rundeckExecutions")
public class RundeckExecutionDocument {

private long idExecution;
private String status;
private String project;
private String user;

@JsonProperty("date-started")
private DateStarted dateStarted;

private Job job;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package fr.insee.genesis.infrastructure.mappers;

import fr.insee.genesis.domain.model.rundeck.RundeckExecution;
import fr.insee.genesis.infrastructure.document.rundeck.RundeckExecutionDocument;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

@Mapper
public interface RundeckExecutionDocumentMapper {

RundeckExecutionDocumentMapper INSTANCE = Mappers.getMapper(RundeckExecutionDocumentMapper.class);

RundeckExecution documentToModel(RundeckExecutionDocument rundeckExecutionDocument);

RundeckExecutionDocument modelToDocument(RundeckExecution rundeckExecution);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package fr.insee.genesis.infrastructure.repository;

import fr.insee.genesis.infrastructure.document.rundeck.RundeckExecutionDocument;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface RundeckExecutionDBRepository extends MongoRepository<RundeckExecutionDocument, String> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package fr.insee.genesis.controller.rest;

import fr.insee.genesis.domain.model.rundeck.Job;
import fr.insee.genesis.domain.model.rundeck.RundeckExecution;
import fr.insee.genesis.stubs.RundeckExecutionApiPortStub;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.http.ResponseEntity;

import static org.junit.jupiter.api.Assertions.assertEquals;

class RundeckExecutionControllerTest {

private static RundeckExecutionController rundeckExecutionController;
private static RundeckExecutionApiPortStub rundeckExecutionApiPortStub;

@BeforeAll
static void init(){
rundeckExecutionApiPortStub = new RundeckExecutionApiPortStub();
rundeckExecutionController = new RundeckExecutionController(rundeckExecutionApiPortStub);
}

@Test
void testAddRundeckExecution_Success() {

RundeckExecution rundeckExecution = new RundeckExecution();
Job job = new Job();
job.setName("TEST");
rundeckExecution.setJob(job);

// WHEN
ResponseEntity<Object> response = rundeckExecutionController.addRundeckExecution(rundeckExecution);

// THEN
assertEquals(ResponseEntity.ok().build(), response);
}

@Test
void testAddRundeckExecution_Failure() {
// GIVEN
rundeckExecutionApiPortStub.setShouldThrowException(true);

RundeckExecution rundeckExecution = new RundeckExecution();
Job job = new Job();
job.setName("TEST");

rundeckExecution.setJob(job);

// WHEN
ResponseEntity<Object> response = rundeckExecutionController.addRundeckExecution(rundeckExecution);

// THEN
assertEquals(ResponseEntity.internalServerError().build(), response);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package fr.insee.genesis.domain.service.rundeck;

import fr.insee.genesis.domain.model.rundeck.DateStarted;
import fr.insee.genesis.domain.model.rundeck.Job;
import fr.insee.genesis.domain.model.rundeck.RundeckExecution;
import fr.insee.genesis.stubs.RundeckExecutionPersistencePortStub;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

class RundeckExecutionServiceTest {

static RundeckExecutionPersistencePortStub rundeckPersistencePortStub;

static RundeckExecutionService rundeckExecutionService;

@BeforeAll
static void init(){
rundeckPersistencePortStub = new RundeckExecutionPersistencePortStub();
rundeckExecutionService = new RundeckExecutionService(rundeckPersistencePortStub);
}

@Test
void addRundeckExecution_test() {
//GIVEN
DateStarted dateStarted = new DateStarted();
dateStarted.setUnixtime(1737643070029L);
dateStarted.setDate("2025-01-23T14:37:50Z");

Job job = new Job();
job.setIdJob("9506a45d-79e3-42d9-afb4-c8f59652c676");
job.setAverageDuration(8817);
job.setName("TEST");
job.setGroup("");
job.setProject("project-test");
job.setDescription("job de test qui attend 8 s et retourne OK");
job.setHref("https://example-url");
job.setPermalink("https://example-url");

// Création de l'objet RundeckExecution
RundeckExecution execution = new RundeckExecution();
execution.setIdExecution(1747563);
execution.setHref("https://example-url");
execution.setPermalink("https://example-url");
execution.setStatus("running");
execution.setProject("project-test");
execution.setExecutionType("user");
execution.setUser("project-test");
execution.setDateStarted(dateStarted);
execution.setJob(job);
execution.setDescription("A very usefull description");
execution.setArgstring(null);
execution.setServerUUID("e9ff62c2-b621-4b31-827e-9d47f0c34310");

//WHEN
rundeckExecutionService.addExecution(execution);

//THEN
Assertions.assertThat(rundeckPersistencePortStub.getMongoStub()).hasSize(1);
Assertions.assertThat(rundeckPersistencePortStub.getMongoStub().getFirst().getIdExecution()).isEqualTo(1747563);
Assertions.assertThat(rundeckPersistencePortStub.getMongoStub().getFirst().getStatus()).isEqualTo("running");

Assertions.assertThat(rundeckPersistencePortStub.getMongoStub().getFirst().getUser()).isEqualTo("project-test");
Assertions.assertThat(rundeckPersistencePortStub.getMongoStub().getFirst().getProject()).isEqualTo("project-test");
Assertions.assertThat(rundeckPersistencePortStub.getMongoStub().getFirst().getDateStarted().getUnixtime()).isEqualTo(1737643070029L);
Assertions.assertThat(rundeckPersistencePortStub.getMongoStub().getFirst().getJob().getIdJob()).isEqualTo("9506a45d-79e3-42d9-afb4-c8f59652c676");

}


}
Loading
Loading