ResponseEntity> updateStageAndStatus(@PathVariable Long requestId, @Valid @RequestBody StageUpdateDTO stageUpdate) {
try {
// Decrypt the payload
System.out.println("stageUpdate :: ::"+ stageUpdate);
String decryptedData = CryptoUtil.decrypt(String.valueOf(stageUpdate)).toString();
System.out.println("decryptedData"+decryptedData);
// Check if the stageName is a number (index) and map it to the stage name
String stageName = stageUpdate.getStageName();
if (stageName != null && stageName.matches("\\d+")) {
int stageIndex = Integer.parseInt(stageName);
if (stageIndex < 0 || stageIndex >= StageOrder.getStageOrder().size()) {
throw new IllegalArgumentException("Invalid stage index: " + stageIndex);
}
// Map the index to the corresponding stage name
stageUpdate.setStageName(StageOrder.getStageOrder().get(stageIndex));
}
// Validate stage order and process stage update in the service layer
TrackingRequestDto updatedTracking = service.updateStageAndStatus(requestId, stageUpdate, StageOrder.getStageOrder());
// Return success response
return ResponseEntity.ok(ResponseUtil.success(updatedTracking, "Stage updated successfully"));
} catch (IllegalArgumentException e) {
// Return bad request with error response
return ResponseEntity.badRequest().body(ResponseUtil.error(e.getMessage()));
} catch (Exception e) {
// Return internal server error with error response
return ResponseEntity.internalServerError().body(ResponseUtil.error("Error updating stage: " + e.getMessage()));
}
}
/**
* Decrypts the given encrypted data and converts it back to the specified type.
*
* @param encryptedData the Base64 encoded encrypted string
* @param valueType the expected type to convert the decrypted JSON back into
* @param the type parameter
* @return the decrypted object of type T
* @throws Exception if decryption fails
*/
public static T decrypt(String encryptedData, Class valueType) throws Exception {
try {
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decodedBytes = Base64.getDecoder().decode(encryptedData);
byte[] decryptedBytes = cipher.doFinal(decodedBytes);
String decryptedJson = new String(decryptedBytes, StandardCharsets.UTF_8);
return objectMapper.readValue(decryptedJson, valueType);
} catch (Exception e) {
// Log error as needed
throw new Exception("Decryption failed", e);
}
}
/**
* Decrypts the given encrypted data and returns it as a generic Object.
*
* @param encryptedData the Base64 encoded encrypted string
* @return the decrypted object (typically a Map or List, depending on the JSON)
* @throws Exception if decryption fails
*/
public static Object decrypt(String encryptedData) throws Exception {
return decrypt(encryptedData, Object.class);
}
}
package com.infra_automation.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* Data Transfer Object for updating a stage.
*/
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class StageUpdateDTO {
@NotBlank(message = "Hostname preference is required")
@Size(max = 255, message = "Hostname preference must be 255 characters or less")
@Pattern(regexp = "^[a-zA-Z0-9 ]*$", message = "HTML or script tags are not allowed")
private String stageName; // e.g., "HOD_Approval"
@NotBlank(message = "Status is required")
@Pattern(regexp = "^(completed|pending|rejected)$", message = "Invalid status not in this format completed|pending|rejected")
@Pattern(regexp = "^[a-zA-Z0-9 ]*$", message = "HTML or script tags are not allowed")
private String status; // e.g., "Completed"
@Pattern(regexp = "^[a-zA-Z0-9 ]*$", message = "HTML or script tags are not allowed")
@Size(max = 100, message = "Done by must be 100 characters or less")
private String doneBy;
@Size(max = 255, message = "Remarks must be 255 characters or less")
@Pattern(regexp = "^[a-zA-Z0-9 ]*$", message = "HTML or script tags are not allowed")
private String remarks; // e.g., "VM request raised by Admin"
@Pattern(regexp = "^[a-zA-Z0-9 ]*$", message = "HTML or script tags are not allowed")
private String action;
@Size(max = 100, message = "Title must be 100 characters or less")
@Pattern(regexp = "^[a-zA-Z0-9 ]*$", message = "HTML or script tags are not allowed")
private String title; // e.g., "Hod Approval"
}