Skip to content

Commit

Permalink
Feature/disable jobs via api (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
saschadoemer committed Jan 3, 2024
1 parent 283885f commit 21520a0
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 8 deletions.
45 changes: 45 additions & 0 deletions openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,33 @@
]
}
},
"/v1/job": {
"patch": {
"tags": [
"Job"
],
"description": "Disables a job for a manufacturer.",
"operationId": "job.disable",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DisableJobRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "The job has been disabled successfully."
},
"400": {
"description": "The request is invalid."
}
}
}
},
"/v1/mica-sense/images/{transactionId}/oids": {
"get": {
"tags": [
Expand Down Expand Up @@ -1042,6 +1069,24 @@
},
"description": "Represents a value for a specific time in a time series."
},
"DisableJobRequest": {
"type": "object",
"properties": {
"manufacturer": {
"type": "string",
"enum": [
"SOILSCOUT",
"AGRANIMO",
"FARM21",
"MICA_SENSE",
"AGVOLUTION",
"SENSOTERRA",
"SENTEK",
"WEENAT"
]
}
}
},
"OidsForTransactionResponse": {
"type": "object",
"properties": {
Expand Down
51 changes: 51 additions & 0 deletions src/main/java/de/app/fivegla/controller/JobController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package de.app.fivegla.controller;

import de.app.fivegla.controller.api.BaseMappings;
import de.app.fivegla.controller.api.swagger.OperationTags;
import de.app.fivegla.controller.dto.request.DisableJobRequest;
import de.app.fivegla.persistence.ApplicationDataRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

/**
* The JobController class handles requests related to job operations.
*/
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping(BaseMappings.JOB)
public class JobController {

private final ApplicationDataRepository applicationDataRepository;

/**
* Disables a job for a manufacturer.
*
* @param request The request to disable a job.
* @return A ResponseEntity indicating the success of the job disabling.
*/
@Operation(
operationId = "job.disable",
description = "Disables a job for a manufacturer.",
tags = OperationTags.JOB
)
@ApiResponse(
responseCode = "200",
description = "The job has been disabled successfully."
)
@ApiResponse(
responseCode = "400",
description = "The request is invalid."
)
@PatchMapping
public ResponseEntity<Void> disable(@RequestBody DisableJobRequest request) {
log.debug("Disabling job for manufacturer: {}", request.getManufacturer());
applicationDataRepository.disableJob(request.getManufacturer());
return ResponseEntity.ok().build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ public class BaseMappings {

public static final String DEVICE = API_V1 + "/device";
public static final String AGRI_CROP = API_V1 + "/agri-crop";
public static final String JOB = API_V1 + "/job";
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public interface OperationTags {
String DEVICE_MEASUREMENT = "Device Measurement";
String DEVICE = "Device";
String AGRI_CROP = "Agri Crop";
String JOB = "Job";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package de.app.fivegla.controller.dto.request;

import de.app.fivegla.api.Manufacturer;
import lombok.Getter;
import lombok.Setter;

/**
* Represents a request to disable a job.
*/
@Getter
@Setter
public class DisableJobRequest {

/**
* Represents the manufacturer of a sensor or device.
*/
private Manufacturer manufacturer;

}
37 changes: 37 additions & 0 deletions src/main/java/de/app/fivegla/persistence/ApplicationData.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import de.app.fivegla.api.Manufacturer;
import de.app.fivegla.integration.micasense.model.MicaSenseImage;
import de.app.fivegla.persistence.entity.DisabledJob;
import lombok.Getter;
import one.microstream.integrations.spring.boot.types.Storage;
import one.microstream.storage.types.StorageManager;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.Instant;
Expand All @@ -25,6 +27,8 @@ public class ApplicationData {

private List<MicaSenseImage> micaSenseImages;

private List<DisabledJob> disabledJobs;

/**
* Update the last run.
*
Expand Down Expand Up @@ -77,4 +81,37 @@ protected List<MicaSenseImage> getMicaSenseImages() {
return micaSenseImages;
}

/**
* Adds a disabled job for a specific manufacturer.
*
* @param manufacturer The manufacturer for which the job is disabled.
* @see Manufacturer
* @see DisabledJob
*/
protected void disableJob(Manufacturer manufacturer) {
if (null == disabledJobs) {
disabledJobs = new ArrayList<>();
}
var disabledJob = new DisabledJob();
disabledJob.setDisabledAt(Instant.now());
disabledJob.setDisabledManufacturers(manufacturer);
disabledJobs.add(disabledJob);
storageManager.store(this);
}

/**
* Checks if the specified job is disabled for the given manufacturer.
*
* @param manufacturer The manufacturer for which to check the job status.
* @return True if the job is disabled for the manufacturer, false otherwise.
* @see Manufacturer
*/
public boolean isTheJobDisabled(Manufacturer manufacturer) {
if (CollectionUtils.isEmpty(disabledJobs)) {
return false;
} else {
return disabledJobs.stream()
.anyMatch(disabledJob -> disabledJob.getDisabledManufacturers().equals(manufacturer));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,33 @@ public List<String> getImageOidsForTransaction(String transactionId) {
.filter(id -> id.equals(transactionId))
.toList();
}

/**
* Disables a job for a specific manufacturer.
*
* @param manufacturer The manufacturer for which the job is disabled.
* Possible values are:
* - SOILSCOUT
* - AGRANIMO
* - FARM21
* - MICA_SENSE
* - AGVOLUTION
* - SENSOTERRA
* - SENTEK
* - WEENAT
*/
public void disableJob(Manufacturer manufacturer) {
applicationData.disableJob(manufacturer);
}

/**
* Checks if the specified job is enabled for the given manufacturer.
*
* @param manufacturer The manufacturer for which to check the job status.
* @return True if the job is enabled for the manufacturer, false otherwise.
* @see Manufacturer
*/
public boolean isTheJobEnabled(Manufacturer manufacturer) {
return !applicationData.isTheJobDisabled(manufacturer);
}
}
43 changes: 43 additions & 0 deletions src/main/java/de/app/fivegla/persistence/entity/DisabledJob.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package de.app.fivegla.persistence.entity;

import de.app.fivegla.api.Manufacturer;
import lombok.Getter;
import lombok.Setter;

import java.time.Instant;

/**
* Represents a job disabled for a specific manufacturer.
*/
@Getter
@Setter
public class DisabledJob {

/**
* Represents the timestamp when a job is disabled for a specific manufacturer.
* <p>
* The disabledAt variable is of type Instant. It represents the exact moment when the job is disabled for the manufacturer.
* Instant is a class in Java that represents a moment on the timeline, measured in milliseconds from the Unix epoch of 1970-01-01T00:00:00Z.
* <p>
* The value of disabledAt can be set and retrieved using getter and setter methods. The getter method is named "getDisabledAt" and returns an Instant object.
* The setter method is named "setDisabledAt" and accepts an Instant object as a parameter.
* <p>
* Example usage:
* DisabledJob job = new DisabledJob();
* Instant disabledAt = Instant.now(); // Get current timestamp
* job.setDisabledAt(disabledAt); // Set disabledAt to the current timestamp
* Instant retrievedDisabledAt = job.getDisabledAt(); // Get the disabledAt value
* <p>
* Note: This documentation assumes that you have the necessary imports and declarations for the Instant and DisabledJob classes.
*
* @see DisabledJob
* @see Instant
*/
private Instant disabledAt;

/**
* Represents a disabled manufacturer.
*/
private Manufacturer disabledManufacturers;

}
16 changes: 8 additions & 8 deletions src/main/java/de/app/fivegla/scheduled/DataImportScheduler.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import de.app.fivegla.api.Manufacturer;
import de.app.fivegla.config.ApplicationConfiguration;
import de.app.fivegla.event.DataImportEvent;
import de.app.fivegla.persistence.ApplicationDataRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.annotation.Scheduled;
Expand All @@ -15,16 +17,12 @@
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class DataImportScheduler {

private final ApplicationEventPublisher applicationEventPublisher;
private final ApplicationConfiguration applicationConfiguration;

public DataImportScheduler(ApplicationEventPublisher applicationEventPublisher,
ApplicationConfiguration applicationConfiguration) {
this.applicationEventPublisher = applicationEventPublisher;
this.applicationConfiguration = applicationConfiguration;
}
private final ApplicationDataRepository applicationDataRepository;

/**
* Schedule data import for all manufacturer.
Expand All @@ -33,9 +31,11 @@ public DataImportScheduler(ApplicationEventPublisher applicationEventPublisher,
public void scheduleDataImport() {
Arrays.stream(Manufacturer.values())
.forEach(manufacturer -> {
if (applicationConfiguration.isEnabled(manufacturer))
if (applicationConfiguration.isEnabled(manufacturer) && applicationDataRepository.isTheJobEnabled(manufacturer)) {
applicationEventPublisher.publishEvent(new DataImportEvent(manufacturer));
else log.warn("Skipping data import for manufacturer: {}", manufacturer);
} else {
log.warn("Skipping data import for manufacturer since the job is enabled by configuration or manually: {}", manufacturer);
}
})
;
}
Expand Down

0 comments on commit 21520a0

Please sign in to comment.