Skip to content
Open

lab9 #43

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
55 changes: 55 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.3</version>
<relativePath/>
</parent>

<groupId>com.ironhack</groupId>
<artifactId>lab-java-springboot-rest-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>lab-java-springboot-rest-api</name>
<description>lab-java-springboot-rest-api</description>

<properties>
<java.version>17</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
50 changes: 50 additions & 0 deletions src/main/java/com/ironhack/GlobalExceptionHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.ironhack;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingRequestHeaderException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import jakarta.servlet.ServletException;
import org.springframework.util.MultiValueMap;
import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();

ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage()));

return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(MissingRequestHeaderException.class)
public ResponseEntity<Map<String, String>> handleMissingHeader(MissingRequestHeaderException ex) {
Map<String, String> error = new HashMap<>();
error.put("error", "Missing API-Key header. You must provide the 'API-Key' in your request headers.");
return new ResponseEntity<>(error, HttpStatus.UNAUTHORIZED);
}

@ExceptionHandler(RuntimeException.class)
public ResponseEntity<Map<String, String>> handleRuntimeExceptions(RuntimeException ex) {
Map<String, String> error = new HashMap<>();
String message = ex.getMessage();
error.put("error", message);

if (message.contains("not found")) {
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
} else if (message.contains("Invalid API Key")) {
return new ResponseEntity<>(error, HttpStatus.UNAUTHORIZED);
} else if (message.contains("Invalid price range")) {
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}

return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
12 changes: 12 additions & 0 deletions src/main/java/com/ironhack/SpringbootApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.ironhack;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootApplication {

public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}

}
68 changes: 68 additions & 0 deletions src/main/java/com/ironhack/controllers/CustomerController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.ironhack.controllers;

import com.ironhack.models.Customer;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/customers")
public class CustomerController {


private final List<Customer> customers = new ArrayList<>();

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Customer createCustomer(@Valid @RequestBody Customer customer) {
customers.add(customer);
return customer;
}

@GetMapping
public List<Customer> getAllCustomers() {
return customers;
}

@GetMapping("/{email}")
public Customer getCustomerByEmail(@PathVariable String email) {
Optional<Customer> customer = customers.stream()
.filter(c -> c.getEmail().equalsIgnoreCase(email))
.findFirst();

if (customer.isEmpty()) {
throw new RuntimeException("Customer not found");
}
return customer.get();
}

@PutMapping("/{email}")
public Customer updateCustomer(@PathVariable String email, @Valid @RequestBody Customer updatedCustomer) {
Optional<Customer> existing = customers.stream()
.filter(c -> c.getEmail().equalsIgnoreCase(email))
.findFirst();

if (existing.isEmpty()) {
throw new RuntimeException("Customer not found");
}

Customer c = existing.get();
c.setName(updatedCustomer.getName());
c.setAge(updatedCustomer.getAge());
c.setAddress(updatedCustomer.getAddress());
return c;
}

@DeleteMapping("/{email}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteCustomer(@PathVariable String email) {
boolean deleted = customers.removeIf(c -> c.getEmail().equalsIgnoreCase(email));
if (!deleted) {
throw new RuntimeException("Customer not found");
}
}
}
93 changes: 93 additions & 0 deletions src/main/java/com/ironhack/controllers/ProductController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.ironhack.controllers;

import com.ironhack.models.Product;
import com.ironhack.services.ProductService;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/products")
public class ProductController {

private final ProductService productService;

public ProductController(ProductService productService) {
this.productService = productService;
}

private void validateApiKey(String apiKey) {
if (!"123456".equals(apiKey)) {
throw new RuntimeException("Invalid API Key");
}
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Product createProduct(@RequestHeader("API-Key") String apiKey, @Valid @RequestBody Product product) {
validateApiKey(apiKey);
return productService.addProduct(product);
}

@GetMapping
public List<Product> getAllProducts(@RequestHeader("API-Key") String apiKey) {
validateApiKey(apiKey);
return productService.getAllProducts();
}

@GetMapping("/{name}")
public Product getProductByName(@RequestHeader("API-Key") String apiKey, @PathVariable String name) {
validateApiKey(apiKey);
Optional<Product> product = productService.getProductByName(name);

if (product.isEmpty()) {
throw new RuntimeException("Product not found");
}
return product.get();
}

@PutMapping("/{name}")
public Product updateProduct(@RequestHeader("API-Key") String apiKey, @PathVariable String name, @Valid @RequestBody Product product) {
validateApiKey(apiKey);
Product updated = productService.updateProduct(name, product);

if (updated == null) {
throw new RuntimeException("Product not found");
}
return updated;
}

@DeleteMapping("/{name}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteProduct(@RequestHeader("API-Key") String apiKey, @PathVariable String name) {
validateApiKey(apiKey);
boolean deleted = productService.deleteProduct(name);
if (!deleted) {
throw new RuntimeException("Product not found");
}
}

@GetMapping("/category/{category}")
public List<Product> getProductsByCategory(@RequestHeader("API-Key") String apiKey, @PathVariable String category) {
validateApiKey(apiKey);
return productService.getProductsByCategory(category);
}

@GetMapping("/price")
public List<Product> getProductsByPriceRange(
@RequestHeader("API-Key") String apiKey,
@RequestParam double min,
@RequestParam double max) {

validateApiKey(apiKey);

if (min < 0 || max < 0 || min > max) {
throw new RuntimeException("Invalid price range");
}

return productService.getProductsByPriceRange(min, max);
}
}
47 changes: 47 additions & 0 deletions src/main/java/com/ironhack/models/Customer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.ironhack.models;


import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;

public class Customer {

@NotBlank(message = "Name cannot be blank")
private String name;

@NotBlank(message = "Email is required")
@Email(message = "Must be a valid email fromat")
private String email;

@Min(value = 18, message = "Age must be at least 18")
private int age;

@NotBlank(message = "Adres cannot be blank")
private String address;

public Customer(String name, String email, int age, String address) {
this.name = name;
this.email = email;
this.age = age;
this.address = address;

}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }

public int getAge() { return age; }
public void setAge(int age) { this.age = age; }

public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
}
39 changes: 39 additions & 0 deletions src/main/java/com/ironhack/models/Product.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.ironhack.models;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.Size;

public class Product {
@NotBlank(message = "Name cannot be blank")
@Size(min = 3, message = "Name must be at least 3 caracters long")
private String name;

@Positive(message = "Price must be a positive number")
private double price;

@NotBlank(message = "Quantity must be a positive number")
private String category;

@Positive(message = "Guality must be a positive number")
private int quantity;

public Product(String name, double price, String category, int quantity){
this.name = name;
this.price = price;
this.category = category;
this.quantity =quantity;
}

public String getName() { return name; }
public void setName(String name) { this.name = name; }

public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }

public String getCategory() { return category; }
public void setCategory(String category) { this.category = category; }

public int getQuantity() { return quantity; }
public void setQuantity(int quantity) { this.quantity = quantity; }
}
Loading