Skip to content

Commit 3439031

Browse files
Merge pull request #23 from SmartPotTech/dev
Dev
2 parents dffe4e4 + fd57284 commit 3439031

12 files changed

Lines changed: 492 additions & 373 deletions

File tree

src/main/java/smartpot/com/api/Commands/Controller/CommandController.java

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import org.springframework.http.ResponseEntity;
1212
import org.springframework.web.bind.annotation.*;
1313
import smartpot.com.api.Commands.Model.DTO.CommandDTO;
14-
import smartpot.com.api.Commands.Model.Entity.Command;
1514
import smartpot.com.api.Commands.Service.SCommandI;
1615
import smartpot.com.api.Crops.Model.DTO.CropDTO;
1716
import smartpot.com.api.Responses.DeleteResponse;
@@ -104,22 +103,8 @@ public ResponseEntity<?> getUserById(@PathVariable String id) {
104103
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)))
105104
})
106105
public ResponseEntity<?> executeCommand(@PathVariable String id, @PathVariable String response) {
107-
/*
108-
Command command = serviceCommand.getCommandById(id);
109-
if (command != null) {
110-
command.setStatus("EXECUTED");
111-
command.setDateExecuted(new Date());
112-
command.setResponse("SUCCESSFUL");
113-
Command updatedCommand = serviceCommand.updateCommand(id, command);
114-
return ResponseEntity.ok(updatedCommand);
115-
} else {
116-
return ResponseEntity.notFound().build();
117-
}
118-
119-
*/
120-
121106
try {
122-
return new ResponseEntity<>(serviceCommand.excuteCommand(id, response), HttpStatus.OK);
107+
return new ResponseEntity<>(serviceCommand.executeCommand(id, response), HttpStatus.OK);
123108
} catch (Exception e) {
124109
return new ResponseEntity<>(new ErrorResponse("Error al actualizar el comando con ID '" + id + "' [" + e.getMessage() + "]", HttpStatus.NOT_FOUND.value()), HttpStatus.NOT_FOUND);
125110
}
@@ -146,8 +131,23 @@ public ResponseEntity<?> deleteCommand(@Parameter(description = "ID único del c
146131
}
147132

148133
@PutMapping("/Update/{id}")
149-
public Command updateCommand(@PathVariable String id, @RequestBody Command updatedCommad) throws Exception {
150-
return serviceCommand.updateCommand(id, updatedCommad);
134+
@Operation(summary = "Eliminar un comando",
135+
description = "Elimina un comando existente utilizando su ID. "
136+
+ "Si el comando no existe o hay un error en el proceso, se devolverá un error con el código HTTP 404.",
137+
responses = {
138+
@ApiResponse(description = "Comando eliminado",
139+
responseCode = "204",
140+
content = @Content(mediaType = "application/json")),
141+
@ApiResponse(responseCode = "404",
142+
description = "Comando no encontrado o error en la eliminación.",
143+
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)))
144+
})
145+
public ResponseEntity<?> updateCommand(@PathVariable String id, @RequestBody CommandDTO updatedCommand) {
146+
try {
147+
return new ResponseEntity<>(new DeleteResponse("Se ha eliminado un recurso [" + serviceCommand.updateCommand(id, updatedCommand) + "]"), HttpStatus.OK);
148+
} catch (Exception e) {
149+
return new ResponseEntity<>(new ErrorResponse("Error al actualizar el comando con ID '" + id + "' [" + e.getMessage() + "]", HttpStatus.NOT_FOUND.value()), HttpStatus.NOT_FOUND);
150+
}
151151
}
152152

153153
}

src/main/java/smartpot/com/api/Commands/Service/SCommand.java

Lines changed: 158 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,60 @@
77
import org.springframework.cache.annotation.CacheEvict;
88
import org.springframework.cache.annotation.CachePut;
99
import org.springframework.cache.annotation.Cacheable;
10-
import org.springframework.http.HttpStatus;
1110
import org.springframework.stereotype.Service;
11+
import org.springframework.transaction.annotation.Transactional;
1212
import smartpot.com.api.Commands.Mapper.MCommand;
1313
import smartpot.com.api.Commands.Model.DTO.CommandDTO;
14-
import smartpot.com.api.Commands.Model.Entity.Command;
1514
import smartpot.com.api.Commands.Repository.RCommand;
1615
import smartpot.com.api.Crops.Service.SCropI;
17-
import smartpot.com.api.Exception.ApiException;
18-
import smartpot.com.api.Exception.ApiResponse;
1916

2017
import java.text.SimpleDateFormat;
2118
import java.util.Date;
2219
import java.util.List;
2320
import java.util.Optional;
24-
21+
import java.util.stream.Collectors;
22+
23+
/**
24+
* Service implementation for managing commands.
25+
*
26+
* <p>
27+
* This class provides the business logic for managing commands, including
28+
* CRUD operations and execution logic. It interacts with the repository,
29+
* a mapper, and additional services to fulfill its responsibilities.
30+
* </p>
31+
*
32+
* <h3>Annotations:</h3>
33+
* <ul>
34+
* <li>{@code @Data} - Generates boilerplate code such as getters, setters, and toString.</li>
35+
* <li>{@code @Builder} - Enables the builder pattern for constructing instances of this class.</li>
36+
* <li>{@code @Service} - Marks this class as a Spring-managed service component.</li>
37+
* </ul>
38+
*
39+
* <h3>Dependencies:</h3>
40+
* <ul>
41+
* <li>{@code RCommand} - Repository for accessing and persisting command entities.</li>
42+
* <li>{@code SCropI} - Service for managing crops, used for operations involving crop data.</li>
43+
* <li>{@code MCommand} - Mapper for converting between entity and DTO representations of commands.</li>
44+
* </ul>
45+
*
46+
* <h3>Responsibilities:</h3>
47+
* <ul>
48+
* <li>Provides methods for creating, retrieving, updating, and deleting commands.</li>
49+
* <li>Implements caching for frequently accessed commands to improve performance.</li>
50+
* <li>Validates and processes business logic for commands before interacting with the repository.</li>
51+
* </ul>
52+
*
53+
* <h3>Usage:</h3>
54+
* <p>
55+
* This service is typically used by controllers to handle HTTP requests related to commands,
56+
* or by other services that depend on command-related operations.
57+
* </p>
58+
*
59+
* @see SCommandI
60+
* @see RCommand
61+
* @see SCropI
62+
* @see MCommand
63+
*/
2564
@Data
2665
@Builder
2766
@Service
@@ -31,18 +70,52 @@ public class SCommand implements SCommandI {
3170
private final SCropI serviceCrop;
3271
private final MCommand mapperCommand;
3372

73+
/**
74+
* Constructs an instance of {@code SCommand} with the required dependencies.
75+
*
76+
* @param repositoryCommand the repository for command-related database operations
77+
* @param serviceCrop the service responsible for crop-related logic
78+
* @param mapperCommand the mapper for converting entities to DTOs and vice versa
79+
*/
3480
@Autowired
3581
public SCommand(RCommand repositoryCommand, SCropI serviceCrop, MCommand mapperCommand) {
3682
this.repositoryCommand = repositoryCommand;
3783
this.serviceCrop = serviceCrop;
3884
this.mapperCommand = mapperCommand;
3985
}
4086

87+
/**
88+
* Retrieves all commands from the repository and maps them to DTOs.
89+
* <p>
90+
* This method is cached to improve performance when retrieving the list of commands.
91+
* The cache is identified by the key 'all_commands' under the 'commands' cache.
92+
* </p>
93+
*
94+
* @return a list of {@code CommandDTO} objects representing all commands
95+
* @throws Exception if no commands exist in the repository
96+
*/
4197
@Override
42-
public List<Command> getAllCommands() {
43-
return repositoryCommand.findAll();
98+
@Cacheable(value = "commands", key = "'all_commands'")
99+
public List<CommandDTO> getAllCommands() throws Exception {
100+
return Optional.of(repositoryCommand.findAll())
101+
.filter(commands -> !commands.isEmpty())
102+
.map(crops -> crops.stream()
103+
.map(mapperCommand::toDTO)
104+
.collect(Collectors.toList()))
105+
.orElseThrow(() -> new Exception("No existe ningún comando"));
44106
}
45107

108+
/**
109+
* Retrieves a command by its unique identifier and maps it to a DTO.
110+
* <p>
111+
* This method is cached to improve performance for retrieving individual commands.
112+
* The cache is identified by the key pattern 'id_{id}' under the 'commands' cache.
113+
* </p>
114+
*
115+
* @param id the unique identifier of the command to retrieve
116+
* @return a {@code CommandDTO} representing the command with the specified ID
117+
* @throws Exception if the command with the specified ID does not exist
118+
*/
46119
@Override
47120
@Cacheable(value = "commands", key = "'id_'+#id")
48121
public CommandDTO getCommandById(String id) throws Exception {
@@ -55,7 +128,21 @@ public CommandDTO getCommandById(String id) throws Exception {
55128
.orElseThrow(() -> new Exception("El Comando no existe"));
56129
}
57130

131+
/**
132+
* Creates a new command based on the provided DTO, sets its creation date and status,
133+
* and persists it in the repository.
134+
*
135+
* <p>
136+
* This method assigns a default status of "PENDING" and records the current timestamp
137+
* as the creation date in the format "yyyy-MM-dd HH:mm:ss".
138+
* </p>
139+
*
140+
* @param commandDTO the {@code CommandDTO} containing the details of the command to create
141+
* @return a {@code CommandDTO} representing the created command
142+
* @throws IllegalStateException if a command with the same details already exists
143+
*/
58144
@Override
145+
@Transactional
59146
public CommandDTO createCommand(CommandDTO commandDTO) throws IllegalStateException {
60147
return Optional.of(commandDTO)
61148
.map(dto -> {
@@ -70,84 +157,22 @@ public CommandDTO createCommand(CommandDTO commandDTO) throws IllegalStateExcept
70157
.orElseThrow(() -> new IllegalStateException("El Comando ya existe"));
71158
}
72159

73-
@Override
74-
public Command updateCommand(String id, Command upCommand) throws Exception {
75-
if (!ObjectId.isValid(id)) {
76-
throw new ApiException(new ApiResponse(
77-
"El ID '" + id + "' no es válido. Asegúrate de que tiene 24 caracteres y solo incluye dígitos hexadecimales (0-9, a-f, A-F).",
78-
HttpStatus.BAD_REQUEST.value()
79-
));
80-
}
81-
Command exCommand = repositoryCommand.findById(new ObjectId(id)).orElseThrow(() -> new ApiException(
82-
new ApiResponse("El Comando con ID '" + id + "' no fue encontrado.",
83-
HttpStatus.NOT_FOUND.value())
84-
));
85-
86-
if (upCommand == null) {
87-
throw new IllegalArgumentException("El comando de actualización no puede ser nulo");
88-
}
89-
90-
if (upCommand.getCrop() == null && serviceCrop.getCropById(upCommand.getCrop().toString()) != null) {
91-
throw new IllegalArgumentException("El campo 'crop' no puede ser nulo");
92-
}
93-
94-
if (upCommand.getDateCreated() == null) {
95-
throw new IllegalArgumentException("El campo 'dateCreated' no puede ser nulo");
96-
}
97-
98-
// Validar y convertir commandType a mayúsculas
99-
if (upCommand.getCommandType() == null || upCommand.getCommandType().isEmpty()) {
100-
throw new IllegalArgumentException("El campo 'commandType' no puede estar vacío");
101-
} else {
102-
exCommand.setCommandType(upCommand.getCommandType().toUpperCase());
103-
}
104-
105-
// Validar y convertir status a mayúsculas
106-
if (upCommand.getStatus() == null || upCommand.getStatus().isEmpty()) {
107-
throw new IllegalArgumentException("El campo 'status' no puede estar vacío");
108-
} else {
109-
exCommand.setStatus(upCommand.getStatus().toUpperCase());
110-
}
111-
112-
// Si se cumplen todas las validaciones, se procede a actualizar el comando
113-
if (exCommand != null) {
114-
exCommand.setCrop(upCommand.getCrop());
115-
exCommand.setResponse(upCommand.getResponse());
116-
exCommand.setDateCreated(upCommand.getDateCreated());
117-
return repositoryCommand.save(exCommand);
118-
} else {
119-
return null;
120-
}
121-
/*
122-
123-
124-
if (!upCommand.getCommandType().matches(exCommand.getCommandType())) {
125-
throw new Exception(new ErrorResponse(
126-
"El nombre '" + upCommand.getCommandType() + "' no es válido.",
127-
HttpStatus.BAD_REQUEST.value()
128-
));
129-
}
130-
if (!upCommand.ge) {
131-
}
132-
*/
133-
134-
135-
}
136-
137-
@Override
138-
@CacheEvict(value = "commands", key = "'id_'+#id")
139-
public String deleteCommand(String id) throws Exception {
140-
return Optional.of(getCommandById(id))
141-
.map(command -> {
142-
repositoryCommand.deleteById(new ObjectId(command.getId()));
143-
return "El Comando con ID '" + id + "' fue eliminado.";
144-
})
145-
.orElseThrow(() -> new Exception("El Comando no existe."));
146-
}
147-
160+
/**
161+
* Executes a command by updating its status to "EXECUTED" and setting a response message.
162+
*
163+
* <p>
164+
* This method updates the specified command with the current timestamp, sets its status to
165+
* "EXECUTED", and records the provided response message.
166+
* </p>
167+
*
168+
* @param id the ID of the command to execute
169+
* @param response the response message to associate with the executed command
170+
* @return a {@code CommandDTO} representing the updated command
171+
* @throws Exception if the command cannot be found or updated
172+
*/
148173
@Override
149174
@CachePut(value = "commands", key = "'id:'+#id")
150-
public CommandDTO excuteCommand(String id, String response) throws Exception {
175+
public CommandDTO executeCommand(String id, String response) throws Exception {
151176
return Optional.of(getCommandById(id))
152177
.map(commandDTO -> {
153178
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -162,31 +187,59 @@ public CommandDTO excuteCommand(String id, String response) throws Exception {
162187
.orElseThrow(() -> new Exception("El Comando no se pudo actualizar"));
163188
}
164189

165-
/*
166-
167-
168-
169-
170-
public Command executeCommand(String id, String response) {
171-
Command command = repositoryCommand.findById(id).orElse(null);
172-
if (command != null) {
173-
command.setStatus("EXECUTED");
174-
command.setDateExecuted(new Date());
175-
command.setResponse(response);
176-
return repositoryCommand.save(command);
177-
}
178-
return null;
190+
/**
191+
* Updates the specified command with new details provided in the update DTO.
192+
*
193+
* <p>
194+
* This method updates fields in the command only if the corresponding fields in the
195+
* update DTO are non-null. The existing values are retained for fields that are null in the update DTO.
196+
* </p>
197+
*
198+
* @param id the ID of the command to update
199+
* @param updateCommand the {@code CommandDTO} containing the updated details
200+
* @return a {@code CommandDTO} representing the updated command
201+
* @throws Exception if the command cannot be found or updated
202+
*/
203+
@Override
204+
@Transactional
205+
@CachePut(value = "commands", key = "'id_'+#id")
206+
public CommandDTO updateCommand(String id, CommandDTO updateCommand) throws Exception {
207+
CommandDTO existingCommand = getCommandById(id);
208+
return Optional.of(updateCommand)
209+
.map(dto -> {
210+
existingCommand.setId(dto.getCommandType() != null ? dto.getCommandType() : existingCommand.getCommandType());
211+
existingCommand.setResponse(dto.getResponse() != null ? dto.getResponse() : existingCommand.getResponse());
212+
existingCommand.setCrop(dto.getCrop() != null ? dto.getCrop() : existingCommand.getCrop());
213+
return existingCommand;
214+
})
215+
.map(mapperCommand::toEntity)
216+
.map(repositoryCommand::save)
217+
.map(mapperCommand::toDTO)
218+
.orElseThrow(() -> new Exception("El Comando no se pudo actualizar"));
179219
}
180220

181-
182-
183-
public List<Command> getCommandsByStatus(String status) {
184-
return repositoryCommand.findByStatus(status);
221+
/**
222+
* Deletes the specified command by its ID.
223+
*
224+
* <p>
225+
* This method removes the command from the repository and evicts the corresponding cache entry.
226+
* </p>
227+
*
228+
* @param id the ID of the command to delete
229+
* @return a confirmation message indicating the successful deletion
230+
* @throws Exception if the command cannot be found
231+
*/
232+
@Override
233+
@Transactional
234+
@CacheEvict(value = "commands", key = "'id_'+#id")
235+
public String deleteCommand(String id) throws Exception {
236+
return Optional.of(getCommandById(id))
237+
.map(command -> {
238+
repositoryCommand.deleteById(new ObjectId(command.getId()));
239+
return "El Comando con ID '" + id + "' fue eliminado.";
240+
})
241+
.orElseThrow(() -> new Exception("El Comando no existe."));
185242
}
186243

187-
public List<Command> getCommandsByCropId(String cropId) {
188-
return repositoryCommand.findByCrop_Id(cropId);
189-
}
190244

191-
*/
192245
}

0 commit comments

Comments
 (0)