Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/main/java/com/provedcode/handlers/ApiError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.provedcode.handlers;

import lombok.Getter;
import org.springframework.http.HttpStatus;

import java.util.Arrays;
import java.util.List;

@Getter
public class ApiError {
private HttpStatus status;
private String message;
private List<String> errors;

public ApiError(HttpStatus status, String message, List<String> errors) {
super();
this.status = status;
this.message = message;
this.errors = errors;
}

public ApiError(HttpStatus status, String message, String error) {
super();
this.status = status;
this.message = message;
errors = Arrays.asList(error);
}
}
90 changes: 90 additions & 0 deletions src/main/java/com/provedcode/handlers/TalentExceptionHandler.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,104 @@
package com.provedcode.handlers;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.server.ResponseStatusException;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@ControllerAdvice
public class TalentExceptionHandler {
@ExceptionHandler(ResponseStatusException.class)
private ResponseEntity<?> responseStatusExceptionHandler(ResponseStatusException exception) {
return ResponseEntity.status(exception.getStatusCode()).body(exception.getBody());
}

@ExceptionHandler({SQLException.class})
public void printSQLException(SQLException ex) {
for (Throwable e : ex) {
if (e instanceof SQLException) {
if (ignoreSQLException(((SQLException) e).getSQLState()) == false) {

e.printStackTrace(System.err);
System.err.println("SQLState: " +
((SQLException) e).getSQLState());

System.err.println("Error Code: " +
((SQLException) e).getErrorCode());

System.err.println("Message: " + e.getMessage());

Throwable t = ex.getCause();
while (t != null) {
System.out.println("Cause: " + t);
t = t.getCause();
}
}
}
}
}

public static boolean ignoreSQLException(String sqlState) {

if (sqlState == null) {
System.out.println("The SQL state is not defined!");
return false;
}

// X0Y32: Jar file already exists in schema
if (sqlState.equalsIgnoreCase("X0Y32"))
return true;

// 42Y55: Table already exists in schema
if (sqlState.equalsIgnoreCase("42Y55"))
return true;

return false;
}

@ExceptionHandler({ Exception.class })
public ResponseEntity<Object> handleAll(Exception ex, WebRequest request) {
ApiError apiError = new ApiError(
HttpStatus.INTERNAL_SERVER_ERROR, ex.getLocalizedMessage(), "error occurred");
return new ResponseEntity<Object>(
apiError, new HttpHeaders(), apiError.getStatus());
}

//MethodArgumentNotValidException – This exception is thrown
// when an argument annotated with @Valid failed validation:
// @ResponseStatus(HttpStatus.BAD_REQUEST)
// @ExceptionHandler(MethodArgumentNotValidException.class)
// public Map<String, String> handleValidationExceptions(
// MethodArgumentNotValidException ex) {
// Map<String, String> errors = new HashMap<>();
// ex.getBindingResult().getAllErrors().forEach((error) -> {
// String fieldName = ((FieldError) error).getField();
// String errorMessage = error.getDefaultMessage();
// errors.put(fieldName, errorMessage);
// });
// return errors;
// }

@ExceptionHandler({ ConstraintViolationException.class })
public ResponseEntity<Object> handleConstraintViolation(
ConstraintViolationException ex, WebRequest request) {
List<String> errors = new ArrayList<>();
for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
errors.add(violation.getRootBeanClass().getName() + " " +
violation.getPropertyPath() + ": " + violation.getMessage());
}

ApiError apiError =
new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors);
return new ResponseEntity<Object>(
apiError, new HttpHeaders(), apiError.getStatus());
}
}
113 changes: 94 additions & 19 deletions src/main/java/com/provedcode/kudos/controller/KudosController.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,107 @@
package com.provedcode.kudos.controller;

import com.provedcode.kudos.model.response.KudosAmountWithSponsor;
import com.provedcode.kudos.service.KudosService;
import com.provedcode.kudos.model.response.KudosAmount;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import lombok.AllArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

@RestController
@AllArgsConstructor
@RequestMapping("/api/v3/talent")
@RequestMapping("/api/v3/")
public class KudosController {
// KudosService kudosService;
//
// @GetMapping("/proofs/{proof-id}/kudos")
// KudosAmount getKudosProof(@PathVariable("proof-id") long id) {
// return kudosService.getAmountKudosProof(id);
// }
//
// @PreAuthorize("hasRole('TALENT')")
// @PostMapping("/proofs/{proof-id}/kudos")
// void addKudosToProof(@PathVariable("proof-id") long id, Authentication authentication) {
// kudosService.addKudosToProof(id, authentication);
// }
//
// @PreAuthorize("hasRole('TALENT')")
// @DeleteMapping("/proofs/{proof-id}/kudos")
// void deleteKudosFromProof(@PathVariable("proof-id") long id, Authentication authentication) {
// kudosService.deleteKudosFromProof(id, authentication);
// }
KudosService kudosService;

@Operation(summary = "Get all available kudos from a sponsor")
@ApiResponses(value = {
@ApiResponse(responseCode = "200",
description = "SUCCESS",
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = @Schema(implementation = KudosAmount.class))),
@ApiResponse(responseCode = "404",
description = "NOT FOUND",
content = @Content),
@ApiResponse(
responseCode = "401",
description = "UNAUTHORIZED",
content = @Content),
@ApiResponse(
responseCode = "403",
description = "FORBIDDEN (if not the owner wants to see other sponsor kudos)",
content = @Content),
@ApiResponse(
responseCode = "400",
description = "BAD REQUEST",
content = @Content)
})
@PreAuthorize("hasRole('SPONSOR')")
@GetMapping("/sponsors/{sponsor-id}/kudos")
KudosAmount getKudosForSponsor(@PathVariable("sponsor-id") long id, Authentication authentication) {
return kudosService.getKudosForSponsor(id, authentication);
}

@Operation(summary = "As a sponsor I want to estimate talent proof by giving kudos")
@ApiResponses(value = {
@ApiResponse(responseCode = "200",
description = "SUCCESS",
content = @Content),
@ApiResponse(responseCode = "404",
description = "NOT FOUND",
content = @Content),
@ApiResponse(
responseCode = "401",
description = "UNAUTHORIZED",
content = @Content),
@ApiResponse(
responseCode = "403",
description = "FORBIDDEN (if sponsor does not have enough kudos)",
content = @Content),
@ApiResponse(
responseCode = "400",
description = "BAD REQUEST",
content = @Content)
})
@PreAuthorize("hasRole('SPONSOR')")
@PostMapping("/proofs/{proof-id}/kudos/{amount}")
void addKudosToProof(@PathVariable("proof-id") long id,
@PathVariable("amount") Long amount,
Authentication authentication) {
kudosService.addKudosToProof(id, amount, authentication);
}

@Operation(summary = "Amount of “kudos” given by sponsors and who gave the “kudos” on proof")
@ApiResponses(value = {
@ApiResponse(responseCode = "200",
description = "SUCCESS",
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = @Schema(implementation = KudosAmountWithSponsor.class))),
@ApiResponse(responseCode = "404",
description = "NOT FOUND",
content = @Content),
@ApiResponse(
responseCode = "401",
description = "UNAUTHORIZED",
content = @Content),
@ApiResponse(
responseCode = "403",
description = "FORBIDDEN (if not the talent wants to see)",
content = @Content),
@ApiResponse(
responseCode = "400",
description = "BAD REQUEST",
content = @Content)
})
@PreAuthorize("hasRole('TALENT')")
@GetMapping("/proofs/{proof-id}/kudos")
KudosAmountWithSponsor getProofKudos(@PathVariable("proof-id") long id, Authentication authentication) {
return kudosService.getProofKudos(id, authentication);
}
}
2 changes: 2 additions & 0 deletions src/main/java/com/provedcode/kudos/model/entity/Kudos.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class Kudos {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Column(name = "amount_kudos")
private Long amountKudos;
@ManyToOne
@JoinColumn(name = "sponsor_id")
private Sponsor sponsor;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.provedcode.kudos.model.response;

import com.provedcode.sponsor.model.dto.SponsorDTO;
import lombok.Builder;

import java.util.Map;

@Builder
public record KudosAmountWithSponsor(
Long allKudosOnProof,
Map<SponsorDTO, Long> kudosFromSponsor
) {
}
Loading