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);