diff --git a/pom.xml b/pom.xml index df82e78..d83945d 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-thymeleaf + org.springframework.boot spring-boot-configuration-processor diff --git a/src/main/java/cz/sparko/boxitory/controller/BoxController.java b/src/main/java/cz/sparko/boxitory/controller/BoxController.java index e0144bc..977a939 100644 --- a/src/main/java/cz/sparko/boxitory/controller/BoxController.java +++ b/src/main/java/cz/sparko/boxitory/controller/BoxController.java @@ -4,10 +4,11 @@ import cz.sparko.boxitory.domain.Box; import cz.sparko.boxitory.service.BoxRepository; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; -@RestController -@RequestMapping(value = "/", method = RequestMethod.GET) +@Controller public class BoxController { private BoxRepository boxRepository; @@ -16,10 +17,16 @@ public BoxController(BoxRepository boxRepository) { this.boxRepository = boxRepository; } - @RequestMapping("{boxName}") + @RequestMapping(value = "/{boxName}", method = RequestMethod.GET) @ResponseBody - public Box getBoxes(@PathVariable String boxName) { + public Box box(@PathVariable String boxName) { return boxRepository.getBox(boxName) - .orElseThrow(() -> new NotFoundException("[" + boxName + "] does not exist")); + .orElseThrow(() -> new NotFoundException("box [" + boxName + "] does not exist")); + } + + @RequestMapping(value = "/", method = RequestMethod.GET) + public String index(Model model) { + model.addAttribute("boxes", boxRepository.getBoxes()); + return "index"; } } diff --git a/src/main/java/cz/sparko/boxitory/domain/Box.java b/src/main/java/cz/sparko/boxitory/domain/Box.java index d4c686f..75a670b 100644 --- a/src/main/java/cz/sparko/boxitory/domain/Box.java +++ b/src/main/java/cz/sparko/boxitory/domain/Box.java @@ -3,6 +3,9 @@ import java.util.List; import java.util.Objects; +/** + * Full description of Vagrant's box as needed in http API. + */ public class Box { private final String name; private final String description; diff --git a/src/main/java/cz/sparko/boxitory/service/BoxRepository.java b/src/main/java/cz/sparko/boxitory/service/BoxRepository.java index 6b6e061..4171661 100644 --- a/src/main/java/cz/sparko/boxitory/service/BoxRepository.java +++ b/src/main/java/cz/sparko/boxitory/service/BoxRepository.java @@ -2,6 +2,7 @@ import cz.sparko.boxitory.domain.Box; +import java.util.List; import java.util.Optional; public interface BoxRepository { @@ -12,4 +13,12 @@ public interface BoxRepository { * @return {@link Box} when found, {@link Optional#empty()} when not found */ Optional getBox(String boxName); + + /** + * Returns {@link List} of names of available {@link Box}es. Call {@link BoxRepository#getBox(String)} with any of + * returned name should get valid result. + * + * @return names of available {@link Box}es + */ + List getBoxes(); } diff --git a/src/main/java/cz/sparko/boxitory/service/FilesystemBoxRepository.java b/src/main/java/cz/sparko/boxitory/service/FilesystemBoxRepository.java index f7ce1bc..506c802 100644 --- a/src/main/java/cz/sparko/boxitory/service/FilesystemBoxRepository.java +++ b/src/main/java/cz/sparko/boxitory/service/FilesystemBoxRepository.java @@ -8,7 +8,13 @@ import org.slf4j.LoggerFactory; import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; public class FilesystemBoxRepository implements BoxRepository { @@ -27,6 +33,14 @@ public FilesystemBoxRepository(AppProperties appProperties, HashService hashServ LOG.info("setting BOX_HOME as [{}] and HOST_PREFIX as [{}]", boxHome.getAbsolutePath(), hostPrefix); } + @Override + public List getBoxes() { + return Arrays.stream(boxHome.listFiles(File::isDirectory)) + .map(File::getName) + .sorted() + .collect(Collectors.toList()); + } + @Override public Optional getBox(String boxName) { Map> groupedBoxFiles = new HashMap<>(); diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html new file mode 100644 index 0000000..f951981 --- /dev/null +++ b/src/main/resources/templates/index.html @@ -0,0 +1,12 @@ + + + + + + +

Available boxes

+
    +
  • +
+ + \ No newline at end of file diff --git a/src/test/java/cz/sparko/boxitory/service/FilesystemBoxRepositoryTest.java b/src/test/java/cz/sparko/boxitory/service/FilesystemBoxRepositoryTest.java index 1eaba51..1c8022c 100644 --- a/src/test/java/cz/sparko/boxitory/service/FilesystemBoxRepositoryTest.java +++ b/src/test/java/cz/sparko/boxitory/service/FilesystemBoxRepositoryTest.java @@ -19,6 +19,7 @@ import java.util.Optional; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; @SpringBootTest public class FilesystemBoxRepositoryTest { @@ -162,6 +163,14 @@ public void givenSortDescending_whenGetBox_thenVersionsSortedDesc() { assertEquals(versions.get(2).getVersion(), "1"); } + @Test + public void givenValidRepositoryWithBoxes_whenIndex_thenGetValidBoxes() { + BoxRepository boxRepository = new FilesystemBoxRepository(testAppProperties, new NoopHashService()); + + List boxes = boxRepository.getBoxes(); + assertTrue(boxes.containsAll(Arrays.asList("f25", "f26", "f27", "f28", "f29"))); + } + private String composePath(String boxName, String version, String provider) { return String.format("%s%s/%s/%s_%s_%s.box", TEST_BOX_PREFIX, testHomeDir.getAbsolutePath(), boxName, boxName, version, provider);