소스 검색

first apis

Fabien Chéret 5 년 전
부모
커밋
2e81ea47e7

+ 10 - 6
pom.xml

@@ -6,18 +6,14 @@
 		<groupId>org.springframework.boot</groupId>
 		<artifactId>spring-boot-starter-parent</artifactId>
 		<version>2.2.5.RELEASE</version>
-		<relativePath/> <!-- lookup parent from repository -->
+		<relativePath/>
 	</parent>
 	<groupId>eu.fibane</groupId>
 	<artifactId>parkingtoll</artifactId>
 	<version>0.0.1-SNAPSHOT</version>
-	<name>parkingtoll</name>
+	<name>parking-toll</name>
 	<description>Demo project for Spring Boot</description>
 
-	<properties>
-		<java.version>1.8</java.version>
-	</properties>
-
 	<dependencies>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
@@ -46,6 +42,14 @@
 				<groupId>org.springframework.boot</groupId>
 				<artifactId>spring-boot-maven-plugin</artifactId>
 			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>11</source>
+					<target>11</target>
+				</configuration>
+			</plugin>
 		</plugins>
 	</build>
 

+ 3 - 2
src/main/java/eu/fibane/parkingtoll/ParkingtollApplication.java → src/main/java/eu/fibane/parkingtoll/ParkingTollApplication.java

@@ -6,11 +6,12 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 @SpringBootApplication
-public class ParkingtollApplication {
+public class ParkingTollApplication {
+
 	protected final Log logger = LogFactory.getLog(getClass());
 
 	public static void main(String[] args) {
-		SpringApplication.run(ParkingtollApplication.class, args);
+		SpringApplication.run(ParkingTollApplication.class, args);
 	}
 
 }

+ 18 - 34
src/main/java/eu/fibane/parkingtoll/api/ParkingLotApi.java

@@ -3,56 +3,40 @@ package eu.fibane.parkingtoll.api;
 import eu.fibane.parkingtoll.model.CarSlot;
 import eu.fibane.parkingtoll.model.ParkingLot;
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
+import java.util.Collection;
 import java.util.List;
 
+@RequestMapping(produces = { "application/json" },
+        consumes = { "application/json" })
 public interface ParkingLotApi {
 
-    @RequestMapping(value = "/parking_lot",
-            produces = { "application/json" },
-            consumes = { "application/json" },
-            method = RequestMethod.POST)
-    ResponseEntity<Void> addParkingLot(@Valid @RequestBody ParkingLot parkingLotItem);
+    @PostMapping(value = "/parking_lot")
+    ResponseEntity<ParkingLot> addParkingLot(@Valid @RequestBody ParkingLot parkingLotItem);
 
 
-    @RequestMapping(value = "/parking_lot/{parkingLotId}",
-            method = RequestMethod.DELETE)
-    ResponseEntity<Void> parkingLotParkingLotIdDelete(@PathVariable("parkingLotId") Long parkingLotId);
+    @DeleteMapping(value = "/parking_lot/{parkingLotId}")
+    ResponseEntity<ParkingLot> parkingLotDeleteById(@PathVariable("parkingLotId") Long parkingLotId);
 
-    @RequestMapping(value = "/parking_lot/{parkingLotId}",
-            produces = { "application/json" },
-            method = RequestMethod.GET)
-    ResponseEntity<ParkingLot> parkingLotParkingLotIdGet(@PathVariable("parkingLotId") Long parkingLotId);
+    @GetMapping(value = "/parking_lot/{parkingLotId}")
+    ResponseEntity<ParkingLot> parkingLotGetById(@PathVariable("parkingLotId") Long parkingLotId);
 
 
-    @RequestMapping(value = "/parking_lot/{parkingLotId}/park",
-            method = RequestMethod.DELETE)
-    ResponseEntity<CarSlot> parkingLotParkingLotIdParkDelete(@PathVariable("parkingLotId") Long parkingLotId, @Valid @RequestBody CarSlot carSlotItem);
+    @DeleteMapping(value = "/parking_lot/{parkingLotId}/park")
+    ResponseEntity<CarSlot> leaveParkingLot(@PathVariable("parkingLotId") Long parkingLotId, @Valid @RequestBody CarSlot carSlotItem);
 
 
-    @RequestMapping(value = "/parking_lot/{parkingLotId}/park",
-            produces = { "application/json" },
-            consumes = { "application/json" },
-            method = RequestMethod.POST)
-    ResponseEntity<CarSlot> parkingLotParkingLotIdParkPost(@PathVariable("parkingLotId") Long parkingLotId, @Valid @RequestBody CarSlot carSlotItem);
+    @PostMapping(value = "/parking_lot/{parkingLotId}/park")
+    ResponseEntity<CarSlot> parkParkingLot(@PathVariable("parkingLotId") Long parkingLotId, @Valid @RequestBody CarSlot carSlotItem);
 
 
-    @RequestMapping(value = "/parking_lot",
-            produces = { "application/json" },
-            consumes = { "application/json" },
-            method = RequestMethod.PUT)
-    ResponseEntity<ParkingLot> parkingLotPut(@Valid @RequestBody ParkingLot parkingLotItem);
+    @PutMapping(value = "/parking_lot")
+    ResponseEntity<ParkingLot> updateParkingLot(@PathVariable("parkingLotId") Long parkingLotId, @Valid @RequestBody ParkingLot parkingLotItem);
 
 
-    @RequestMapping(value = "/parking_lot",
-            produces = { "application/json" },
-            method = RequestMethod.GET)
-    ResponseEntity<List<ParkingLot>> searchParkingLot(@Valid @RequestParam(value = "searchString", required = false) String searchString);
+    @GetMapping(value = "/parking_lot")
+    ResponseEntity<Collection<ParkingLot>> searchParkingLot(@Valid @RequestParam(value = "searchString", required = false) String searchString);
 
 }

+ 34 - 43
src/main/java/eu/fibane/parkingtoll/api/ParkingLotApiController.java

@@ -1,21 +1,27 @@
 package eu.fibane.parkingtoll.api;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
+import eu.fibane.parkingtoll.core.PersistenceManager;
 import eu.fibane.parkingtoll.model.CarSlot;
 import eu.fibane.parkingtoll.model.ParkingLot;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.Valid;
 import java.io.IOException;
-import java.util.List;
+import java.net.URI;
+import java.util.Collection;
+import java.util.stream.Collectors;
 
+@RestController
 public class ParkingLotApiController implements ParkingLotApi {
 
     private static final Logger log = LoggerFactory.getLogger(ParkingLotApiController.class);
@@ -24,37 +30,37 @@ public class ParkingLotApiController implements ParkingLotApi {
 
     private final HttpServletRequest request;
 
+    @Autowired
+    private PersistenceManager persistenceManager;
+
     @org.springframework.beans.factory.annotation.Autowired
     public ParkingLotApiController(ObjectMapper objectMapper, HttpServletRequest request) {
         this.objectMapper = objectMapper;
         this.request = request;
     }
 
-    public ResponseEntity<Void> addParkingLot(@Valid @RequestBody ParkingLot parkingLotItem) {
-        String accept = request.getHeader("Accept");
-        return new ResponseEntity<Void>(HttpStatus.NOT_IMPLEMENTED);
+    public ResponseEntity<ParkingLot> addParkingLot(@Valid @RequestBody ParkingLot parkingLotItem) {
+        persistenceManager.addParkingLot(parkingLotItem);
+        return ResponseEntity.created(URI.create("/parking_lot/" + parkingLotItem.getId())).body(parkingLotItem);
     }
 
-    public ResponseEntity<Void> parkingLotParkingLotIdDelete(@PathVariable("parkingLotId") Long parkingLotId) {
-        String accept = request.getHeader("Accept");
-        return new ResponseEntity<Void>(HttpStatus.NOT_IMPLEMENTED);
+    public ResponseEntity<ParkingLot> parkingLotDeleteById(@PathVariable("parkingLotId") Long parkingLotId) {
+        ParkingLot parkingLot = persistenceManager.deleteParkingLotById(parkingLotId);
+        if(parkingLot == null){
+            return ResponseEntity.notFound().build();
+        }
+        return ResponseEntity.ok(parkingLot);
     }
 
-    public ResponseEntity<ParkingLot> parkingLotParkingLotIdGet(@PathVariable("parkingLotId") Long parkingLotId) {
-        String accept = request.getHeader("Accept");
-        if (accept != null && accept.contains("application/json")) {
-            try {
-                return new ResponseEntity<ParkingLot>(objectMapper.readValue("{  \"layout\" : [ {    \"name\" : \"name\",    \"available\" : 0  }, {    \"name\" : \"name\",    \"available\" : 0  } ],  \"pricing_policy\" : {    \"per_hour_fare\" : 2.1,    \"flat_fee\" : 1.1  },  \"name\" : \"Victoria 1 Parking Lot\",  \"id\" : 5}", ParkingLot.class), HttpStatus.NOT_IMPLEMENTED);
-            } catch (IOException e) {
-                log.error("Couldn't serialize response for content type application/json", e);
-                return new ResponseEntity<ParkingLot>(HttpStatus.INTERNAL_SERVER_ERROR);
-            }
+    public ResponseEntity<ParkingLot> parkingLotGetById(@PathVariable("parkingLotId") Long parkingLotId) {
+        ParkingLot parkingLot = persistenceManager.getParkingLotById(parkingLotId);
+        if(parkingLot == null){
+            return ResponseEntity.notFound().build();
         }
-
-        return new ResponseEntity<ParkingLot>(HttpStatus.NOT_IMPLEMENTED);
+        return ResponseEntity.ok(parkingLot);
     }
 
-    public ResponseEntity<CarSlot> parkingLotParkingLotIdParkDelete(@PathVariable("parkingLotId") Long parkingLotId, @Valid @RequestBody CarSlot carSlotItem) {
+    public ResponseEntity<CarSlot> leaveParkingLot(@PathVariable("parkingLotId") Long parkingLotId, @Valid @RequestBody CarSlot carSlotItem) {
         String accept = request.getHeader("Accept");
         if (accept != null && accept.contains("application/json")) {
             try {
@@ -68,7 +74,7 @@ public class ParkingLotApiController implements ParkingLotApi {
         return new ResponseEntity<CarSlot>(HttpStatus.NOT_IMPLEMENTED);
     }
 
-    public ResponseEntity<CarSlot> parkingLotParkingLotIdParkPost(@PathVariable("parkingLotId") Long parkingLotId, @Valid @RequestBody CarSlot carSlotItem) {
+    public ResponseEntity<CarSlot> parkParkingLot(@PathVariable("parkingLotId") Long parkingLotId, @Valid @RequestBody CarSlot carSlotItem) {
         String accept = request.getHeader("Accept");
         if (accept != null && accept.contains("application/json")) {
             try {
@@ -82,32 +88,17 @@ public class ParkingLotApiController implements ParkingLotApi {
         return new ResponseEntity<CarSlot>(HttpStatus.NOT_IMPLEMENTED);
     }
 
-    public ResponseEntity<ParkingLot> parkingLotPut(@Valid @RequestBody ParkingLot parkingLotItem) {
-        String accept = request.getHeader("Accept");
-        if (accept != null && accept.contains("application/json")) {
-            try {
-                return new ResponseEntity<ParkingLot>(objectMapper.readValue("{  \"layout\" : [ {    \"name\" : \"name\",    \"available\" : 0  }, {    \"name\" : \"name\",    \"available\" : 0  } ],  \"pricing_policy\" : {    \"per_hour_fare\" : 2.1,    \"flat_fee\" : 1.1  },  \"name\" : \"Victoria 1 Parking Lot\",  \"id\" : 5}", ParkingLot.class), HttpStatus.NOT_IMPLEMENTED);
-            } catch (IOException e) {
-                log.error("Couldn't serialize response for content type application/json", e);
-                return new ResponseEntity<ParkingLot>(HttpStatus.INTERNAL_SERVER_ERROR);
-            }
-        }
-
-        return new ResponseEntity<ParkingLot>(HttpStatus.NOT_IMPLEMENTED);
+    public ResponseEntity<ParkingLot> updateParkingLot(@PathVariable("parkingLotId") Long parkingLotId, @Valid @RequestBody ParkingLot parkingLotItem) {
+        ParkingLot parkingLot = persistenceManager.updateParkingLot(parkingLotId, parkingLotItem);
+        return  ResponseEntity.ok(parkingLot);
     }
 
-    public ResponseEntity<List<ParkingLot>> searchParkingLot(@Valid @RequestParam(value = "searchString", required = false) String searchString) {
-        String accept = request.getHeader("Accept");
-        if (accept != null && accept.contains("application/json")) {
-            try {
-                return new ResponseEntity<List<ParkingLot>>(objectMapper.readValue("[ {  \"layout\" : [ {    \"name\" : \"name\",    \"available\" : 0  }, {    \"name\" : \"name\",    \"available\" : 0  } ],  \"pricing_policy\" : {    \"per_hour_fare\" : 2.1,    \"flat_fee\" : 1.1  },  \"name\" : \"Victoria 1 Parking Lot\",  \"id\" : 5}, {  \"layout\" : [ {    \"name\" : \"name\",    \"available\" : 0  }, {    \"name\" : \"name\",    \"available\" : 0  } ],  \"pricing_policy\" : {    \"per_hour_fare\" : 2.1,    \"flat_fee\" : 1.1  },  \"name\" : \"Victoria 1 Parking Lot\",  \"id\" : 5} ]", List.class), HttpStatus.NOT_IMPLEMENTED);
-            } catch (IOException e) {
-                log.error("Couldn't serialize response for content type application/json", e);
-                return new ResponseEntity<List<ParkingLot>>(HttpStatus.INTERNAL_SERVER_ERROR);
-            }
+    public ResponseEntity<Collection<ParkingLot>> searchParkingLot(@Valid @RequestParam(value = "searchString", required = false) String searchString) {
+        Collection<ParkingLot> parkingLots = persistenceManager.getAllParkingLots();
+        if(searchString != null && !searchString.isBlank()) {
+            parkingLots = parkingLots.stream().filter(a -> a.getName().toUpperCase().contains(searchString.toUpperCase())).collect(Collectors.toList());
         }
-
-        return new ResponseEntity<List<ParkingLot>>(HttpStatus.NOT_IMPLEMENTED);
+        return ResponseEntity.ok(parkingLots);
     }
 
 }

+ 11 - 4
src/main/java/eu/fibane/parkingtoll/core/InMemoryPersistanceManager.java → src/main/java/eu/fibane/parkingtoll/core/InMemoryPersistenceManager.java

@@ -1,11 +1,13 @@
 package eu.fibane.parkingtoll.core;
 
 import eu.fibane.parkingtoll.model.ParkingLot;
+import org.springframework.stereotype.Repository;
 
 import java.util.*;
 import java.util.concurrent.atomic.AtomicLong;
 
-public class InMemoryPersistanceManager implements PersistanceManager {
+@Repository
+public class InMemoryPersistenceManager implements PersistenceManager {
 
     private static final Map<Long, ParkingLot> parkingLotMap = new HashMap<>();
     private static AtomicLong idCounter = new AtomicLong();
@@ -31,21 +33,26 @@ public class InMemoryPersistanceManager implements PersistanceManager {
     }
 
     @Override
-    public ParkingLot updateParkingLot(ParkingLot parkingLot) {
+    public ParkingLot updateParkingLot(Long id, ParkingLot parkingLot) {
+        //TODO concurrent updates
         ParkingLot response;
         if(parkingLot.getId() == null){
             response = addParkingLot(parkingLot);
         } else {
+            //secure case where user puts wrong ID
+            parkingLot.setId(id);
             response = parkingLotMap.put(parkingLot.getId(), parkingLot);
         }
         return response;
     }
 
     @Override
-    public ParkingLot deleteParkingLot(ParkingLot parkingLot) {
-        return parkingLotMap.remove(parkingLot.getId());
+    public ParkingLot deleteParkingLotById(Long id) {
+        return parkingLotMap.remove(id);
     }
 
+
+
     @Override
     public void clearDatabase() {
         parkingLotMap.clear();

+ 6 - 4
src/main/java/eu/fibane/parkingtoll/core/PersistanceManager.java → src/main/java/eu/fibane/parkingtoll/core/PersistenceManager.java

@@ -5,7 +5,7 @@ import eu.fibane.parkingtoll.model.ParkingLot;
 import java.math.BigInteger;
 import java.util.Collection;
 
-interface PersistanceManager {
+public interface PersistenceManager {
 
     /**
      * Get all currently stored parking lots
@@ -32,14 +32,16 @@ interface PersistanceManager {
      * @param parkingLot the new value of parkingLot
      * @return the previous representation of parkingLot
      */
-    public ParkingLot updateParkingLot(ParkingLot parkingLot);
+    public ParkingLot updateParkingLot(Long id, ParkingLot parkingLot);
+
+    //public void parkCarAtParking(Long id);
 
     /**
      * Delete parking lot by id
-     * @param parkingLot parking lot to delete - id has to be filled
+     * @param id parking lot id to delete
      * @return the ParkingLot that was deleted, null if the parking lot was not found in the database
      */
-    public ParkingLot deleteParkingLot(ParkingLot parkingLot);
+    public ParkingLot deleteParkingLotById(Long id);
 
     /**
      * Clear all data stored in the database

+ 4 - 7
src/main/java/eu/fibane/parkingtoll/model/Layout.java

@@ -67,13 +67,10 @@ public class Layout   {
 
   @Override
   public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class Layout {\n");
-
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    available: ").append(toIndentedString(available)).append("\n");
-    sb.append("}");
-    return sb.toString();
+    return "Layout{" +
+            "name='" + name + '\'' +
+            ", available=" + available +
+            '}';
   }
 
   /**

+ 2 - 1
src/main/java/eu/fibane/parkingtoll/model/ParkingLot.java

@@ -5,6 +5,7 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Null;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -32,7 +33,7 @@ public class ParkingLot   {
     return this;
   }
 
-  @NotNull
+  @Null
   public Long getId() {
     return id;
   }

+ 1 - 1
src/test/java/eu/fibane/parkingtoll/ParkingtollApplicationTests.java → src/test/java/eu/fibane/parkingtoll/ParkingTollApplicationTests.java

@@ -4,7 +4,7 @@ import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 
 @SpringBootTest
-class ParkingtollApplicationTests {
+class ParkingTollApplicationTests {
 
 	@Test
 	void contextLoads() {

+ 8 - 10
src/test/java/eu/fibane/parkingtoll/core/InMemoryPersistanceManagerTest.java → src/test/java/eu/fibane/parkingtoll/core/InMemoryPersistenceManagerTest.java

@@ -1,12 +1,10 @@
 package eu.fibane.parkingtoll.core;
 
-import eu.fibane.parkingtoll.model.CarSlot;
 import eu.fibane.parkingtoll.model.Layout;
 import eu.fibane.parkingtoll.model.ParkingLot;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
-import javax.swing.*;
 import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -17,9 +15,9 @@ import java.util.stream.Collectors;
 
 import static org.junit.jupiter.api.Assertions.*;
 
-class InMemoryPersistanceManagerTest {
+class InMemoryPersistenceManagerTest {
     private long ids = 0;
-    private final PersistanceManager manager = new InMemoryPersistanceManager();
+    private final PersistenceManager manager = new InMemoryPersistenceManager();
     private final SecureRandom random = new SecureRandom();
     @BeforeEach
     void clearDatabase() {
@@ -30,7 +28,7 @@ class InMemoryPersistanceManagerTest {
     void testEmptyDatabase() {
         assertEquals(0, manager.getAllParkingLots().size());
         assertNull(manager.getParkingLotById(0L));
-        assertNull(manager.deleteParkingLot(getNewParkingLot()));
+        assertNull(manager.deleteParkingLotById(getNewParkingLot().getId()));
     }
 
     @Test
@@ -109,14 +107,14 @@ class InMemoryPersistanceManagerTest {
         ParkingLot parkingLot = getNewParkingLot();
         assertEquals(0, manager.getAllParkingLots().size());
         assertNull(parkingLot.getId());
-        parkingLot = manager.updateParkingLot(parkingLot);
+        parkingLot = manager.updateParkingLot(parkingLot.getId(), parkingLot);
         assertEquals(1, manager.getAllParkingLots().size());
         assertNotNull(parkingLot.getId());
 
         ParkingLot parkingLot2 = getNewParkingLot();
         //set the id of parking 1
         parkingLot2.setId(parkingLot.getId());
-        ParkingLot parkingLotUpdated = manager.updateParkingLot(parkingLot2);
+        ParkingLot parkingLotUpdated = manager.updateParkingLot(parkingLot2.getId(), parkingLot2);
         assertEquals(1, manager.getAllParkingLots().size());
         assertEquals(parkingLotUpdated, parkingLot);
 
@@ -130,11 +128,11 @@ class InMemoryPersistanceManagerTest {
         assertEquals(1, manager.getAllParkingLots().size());
 
         //call the service
-        ParkingLot result = manager.deleteParkingLot(parkingLot);
+        ParkingLot result = manager.deleteParkingLotById(parkingLot.getId());
         assertEquals(result,parkingLot);
         assertEquals(0, manager.getAllParkingLots().size());
 
-        result = manager.deleteParkingLot(parkingLot);
+        result = manager.deleteParkingLotById(parkingLot.getId());
         assertNull(result);
         assertEquals(0, manager.getAllParkingLots().size());
 
@@ -143,7 +141,7 @@ class InMemoryPersistanceManagerTest {
         //now try to delete something else
         ParkingLot parkingLot1 = new ParkingLot();
         parkingLot1.setId(parkingLot.getId() + 1);
-        result = manager.deleteParkingLot(parkingLot1);
+        result = manager.deleteParkingLotById(parkingLot1.getId());
         assertEquals(1, manager.getAllParkingLots().size());
         assertNull(result);
     }

+ 0 - 8
src/test/java/eu/fibane/parkingtoll/core/TestUtils.java

@@ -1,8 +0,0 @@
-package eu.fibane.parkingtoll.core;
-
-import eu.fibane.parkingtoll.model.ParkingLot;
-import net.bytebuddy.utility.RandomString;
-
-public class TestUtils {
-
-}