From 423ee87b189deae80273c357ff9d8d63d360cfe2 Mon Sep 17 00:00:00 2001 From: Josh Stark Date: Mon, 5 Aug 2019 13:09:02 +0100 Subject: [PATCH] Refactored model classes to use a key rather than direct ID. --- .../linuxserver/fleet/cache/ImageCache.java | 43 ++++++------ .../fleet/db/dao/DefaultImageDAO.java | 43 ++++++------ .../fleet/db/dao/DefaultRepositoryDAO.java | 15 ++-- .../fleet/db/dao/DefaultUserDAO.java | 4 +- .../io/linuxserver/fleet/db/dao/ImageDAO.java | 12 ++-- .../fleet/db/dao/RepositoryDAO.java | 3 +- .../fleet/delegate/ImageDelegate.java | 30 ++++---- .../fleet/delegate/RepositoryDelegate.java | 5 +- .../dockerhub/queue/DockerHubSyncRequest.java | 15 ++-- .../queue/DockerHubSyncResponse.java | 7 +- .../fleet/model/api/ApiImagePullHistory.java | 2 +- .../fleet/model/internal/Image.java | 70 ++++++++++--------- .../fleet/model/internal/Repository.java | 58 ++++++++------- .../fleet/model/internal/User.java | 40 +++++++++-- .../fleet/model/key/AbstractHasKey.java | 52 ++++++++++++++ .../AbstractKey.java} | 52 ++++++++------ .../linuxserver/fleet/model/key/HasKey.java | 23 ++++++ .../linuxserver/fleet/model/key/ImageKey.java | 56 +++++++++++++++ .../io/linuxserver/fleet/model/key/Key.java | 23 ++++++ .../fleet/model/key/RepositoryKey.java | 49 +++++++++++++ .../linuxserver/fleet/model/key/UserKey.java | 29 ++++++++ .../sync/DefaultSynchronisationState.java | 15 ++-- .../linuxserver/fleet/web/pages/HomePage.java | 2 +- .../fleet/web/routes/AllImagesApi.java | 2 +- .../fleet/web/routes/GetImageApi.java | 3 +- .../web/routes/GetImagePullHistoryApi.java | 7 +- .../fleet/web/routes/ManageImageApi.java | 3 +- .../fleet/web/routes/ManageRepositoryApi.java | 3 +- .../spark/template/freemarker/admin.ftl | 2 +- .../spark/template/freemarker/home.ftl | 18 ++--- 30 files changed, 492 insertions(+), 194 deletions(-) create mode 100644 src/main/java/io/linuxserver/fleet/model/key/AbstractHasKey.java rename src/main/java/io/linuxserver/fleet/model/{internal/PersistableItem.java => key/AbstractKey.java} (52%) create mode 100644 src/main/java/io/linuxserver/fleet/model/key/HasKey.java create mode 100644 src/main/java/io/linuxserver/fleet/model/key/ImageKey.java create mode 100644 src/main/java/io/linuxserver/fleet/model/key/Key.java create mode 100644 src/main/java/io/linuxserver/fleet/model/key/RepositoryKey.java create mode 100644 src/main/java/io/linuxserver/fleet/model/key/UserKey.java diff --git a/src/main/java/io/linuxserver/fleet/cache/ImageCache.java b/src/main/java/io/linuxserver/fleet/cache/ImageCache.java index f6f15bf..0041212 100644 --- a/src/main/java/io/linuxserver/fleet/cache/ImageCache.java +++ b/src/main/java/io/linuxserver/fleet/cache/ImageCache.java @@ -18,20 +18,19 @@ package io.linuxserver.fleet.cache; import io.linuxserver.fleet.model.internal.Image; +import io.linuxserver.fleet.model.key.ImageKey; +import io.linuxserver.fleet.model.key.RepositoryKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; public class ImageCache { private static final Logger LOGGER = LoggerFactory.getLogger(ImageCache.class); - private final Map> cachedImages; + private final Map> cachedImages; public ImageCache() { this.cachedImages = new HashMap<>(); @@ -41,19 +40,19 @@ public class ImageCache { Image updatedImage = Image.copyOf(image); - if (cachedImages.containsKey(updatedImage.getRepositoryId())) { + if (cachedImages.containsKey(updatedImage.getKey().getRepositoryKey())) { - List images = cachedImages.get(updatedImage.getRepositoryId()); + List images = cachedImages.get(updatedImage.getKey().getRepositoryKey()); int cachedImageLocation = images.indexOf(updatedImage); if (cachedImageLocation > -1) { - LOGGER.info("updateCache({}) Updating existing cached image.", updatedImage.getName()); + LOGGER.info("updateCache({}) Updating existing cached image.", updatedImage); images.set(cachedImageLocation, updatedImage); } else { - LOGGER.info("updateCache({}) Adding image to cache", updatedImage.getName()); + LOGGER.info("updateCache({}) Adding image to cache", updatedImage); images.add(updatedImage); } @@ -62,33 +61,37 @@ public class ImageCache { List images = new ArrayList<>(); images.add(updatedImage); - LOGGER.info("updateCache({}:{}) Creating new cache for repository {}", updatedImage.getName(), updatedImage.getRepositoryId()); - cachedImages.put(updatedImage.getRepositoryId(), images); + LOGGER.info("updateCache({}) Creating new cache for repository {}", updatedImage, updatedImage.getRepositoryId()); + cachedImages.put(updatedImage.getKey().getRepositoryKey(), images); } } - public List getAll(int repositoryId) { + public List getAll(RepositoryKey repositoryKey) { - if (cachedImages.containsKey(repositoryId)) { - return cachedImages.get(repositoryId).stream().map(Image::copyOf).collect(Collectors.toList()); + if (cachedImages.containsKey(repositoryKey)) { + return cachedImages.get(repositoryKey).stream().map(Image::copyOf).collect(Collectors.toList()); } return new ArrayList<>(); } - public Image get(int repositoryId, String imageName) { + public Image get(ImageKey imageKey) { - if (cachedImages.containsKey(repositoryId)) { - return cachedImages.get(repositoryId).stream().filter(i -> i.getName().equals(imageName)).findFirst().orElse(null); + final RepositoryKey repositoryKey = imageKey.getRepositoryKey(); + + if (cachedImages.containsKey(repositoryKey)) { + return cachedImages.get(repositoryKey).stream().filter(i -> i.getName().equals(imageKey.getName())).findFirst().orElse(null); } return null; } - public void remove(Image image) { + public void remove(ImageKey imageKey) { - if (cachedImages.containsKey(image.getRepositoryId())) { - cachedImages.get(image.getRepositoryId()).remove(image); + final RepositoryKey repositoryKey = imageKey.getRepositoryKey(); + + if (cachedImages.containsKey(repositoryKey)) { + cachedImages.get(repositoryKey).removeIf(image -> image.getKey().equals(imageKey)); } } } diff --git a/src/main/java/io/linuxserver/fleet/db/dao/DefaultImageDAO.java b/src/main/java/io/linuxserver/fleet/db/dao/DefaultImageDAO.java index a01b45b..caeb904 100644 --- a/src/main/java/io/linuxserver/fleet/db/dao/DefaultImageDAO.java +++ b/src/main/java/io/linuxserver/fleet/db/dao/DefaultImageDAO.java @@ -23,8 +23,9 @@ import io.linuxserver.fleet.db.query.InsertUpdateStatus; import io.linuxserver.fleet.db.query.LimitedResult; import io.linuxserver.fleet.model.internal.Image; import io.linuxserver.fleet.model.internal.ImagePullStat; -import io.linuxserver.fleet.model.internal.Repository; import io.linuxserver.fleet.model.internal.Tag; +import io.linuxserver.fleet.model.key.ImageKey; +import io.linuxserver.fleet.model.key.RepositoryKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,15 +47,15 @@ public class DefaultImageDAO implements ImageDAO { } @Override - public Image findImageByRepositoryAndImageName(int repositoryId, String imageName) { + public Image findImageByRepositoryAndImageName(ImageKey imageKey) { CallableStatement call = null; try (Connection connection = databaseConnection.getConnection()) { call = connection.prepareCall("{CALL Image_GetByName(?,?)}"); - call.setInt(1, repositoryId); - call.setString(2, imageName); + call.setInt(1, imageKey.getRepositoryKey().getId()); + call.setString(2, imageKey.getName()); ResultSet results = call.executeQuery(); if (results.next()) @@ -70,16 +71,16 @@ public class DefaultImageDAO implements ImageDAO { } @Override - public Image fetchImage(Integer id) { + public Image fetchImage(ImageKey imageKey) { - LOGGER.debug("Fetching image by ID: " + id); + LOGGER.debug("Fetching image by ID: " + imageKey); CallableStatement call = null; try (Connection connection = databaseConnection.getConnection()) { call = connection.prepareCall("{CALL Image_Get(?)}"); - call.setInt(1, id); + call.setInt(1, imageKey.getId()); ResultSet results = call.executeQuery(); if (results.next()) @@ -95,7 +96,7 @@ public class DefaultImageDAO implements ImageDAO { } @Override - public LimitedResult fetchImagesByRepository(int repositoryId) { + public LimitedResult fetchImagesByRepository(final RepositoryKey repositoryKey) { List images = new ArrayList<>(); @@ -104,7 +105,7 @@ public class DefaultImageDAO implements ImageDAO { try (Connection connection = databaseConnection.getConnection()) { call = connection.prepareCall("{CALL Image_GetAll(?,?)}"); - call.setInt(1, repositoryId); + call.setInt(1, repositoryKey.getId()); call.registerOutParameter(2, Types.INTEGER); ResultSet results = call.executeQuery(); @@ -131,7 +132,7 @@ public class DefaultImageDAO implements ImageDAO { try (Connection connection = databaseConnection.getConnection()) { call = connection.prepareCall("{CALL Image_Save(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); - setNullableInt(call, 1, image.getId()); + setNullableInt(call, 1, image.getKey().getId()); call.setInt(2, image.getRepositoryId()); call.setString(3, image.getName()); setNullableLong(call, 4, image.getPullCount()); @@ -155,7 +156,7 @@ public class DefaultImageDAO implements ImageDAO { String statusMessage = call.getString(15); if (InsertUpdateStatus.OK == status) - return new InsertUpdateResult<>(fetchImage(imageId), status, statusMessage); + return new InsertUpdateResult<>(fetchImage(image.getKey().cloneWithId(imageId)), status, statusMessage); return new InsertUpdateResult<>(status, statusMessage); @@ -170,14 +171,14 @@ public class DefaultImageDAO implements ImageDAO { } @Override - public void removeImage(Integer id) { + public void removeImage(final ImageKey imageKey) { CallableStatement call = null; try (Connection connection = databaseConnection.getConnection()) { call = connection.prepareCall("{CALL Image_Delete(?)}"); - call.setInt(1, id); + call.setInt(1, imageKey.getId()); call.executeUpdate(); call.close(); @@ -190,7 +191,7 @@ public class DefaultImageDAO implements ImageDAO { } @Override - public List fetchImagePullHistory(Integer imageId, ImagePullStat.GroupMode groupMode) { + public List fetchImagePullHistory(final ImageKey imageKey, ImagePullStat.GroupMode groupMode) { List pullHistory = new ArrayList<>(); @@ -199,7 +200,7 @@ public class DefaultImageDAO implements ImageDAO { try (Connection connection = databaseConnection.getConnection()) { call = connection.prepareCall("CALL Image_GetPullHistory(?, ?)"); - call.setInt(1, imageId); + call.setInt(1, imageKey.getId()); call.setString(2, groupMode.toString()); ResultSet results = call.executeQuery(); @@ -230,12 +231,14 @@ public class DefaultImageDAO implements ImageDAO { private Image parseImageFromResultSet(ResultSet results) throws SQLException { Image image = new Image( - results.getInt("ImageId"), - new Repository( - results.getInt("RepositoryId"), - results.getString("RepositoryName") + new ImageKey( + results.getInt("ImageId"), + results.getString("ImageName"), + new RepositoryKey( + results.getInt("RepositoryId"), + results.getString("RepositoryName") + ) ), - results.getString("ImageName"), new Tag( results.getString("LatestTagVersion"), results.getString("LatestMaskedTagVersion"), diff --git a/src/main/java/io/linuxserver/fleet/db/dao/DefaultRepositoryDAO.java b/src/main/java/io/linuxserver/fleet/db/dao/DefaultRepositoryDAO.java index 366fb68..eb46389 100644 --- a/src/main/java/io/linuxserver/fleet/db/dao/DefaultRepositoryDAO.java +++ b/src/main/java/io/linuxserver/fleet/db/dao/DefaultRepositoryDAO.java @@ -21,6 +21,7 @@ import io.linuxserver.fleet.db.PoolingDatabaseConnection; import io.linuxserver.fleet.db.query.InsertUpdateResult; import io.linuxserver.fleet.db.query.InsertUpdateStatus; import io.linuxserver.fleet.model.internal.Repository; +import io.linuxserver.fleet.model.key.RepositoryKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,9 +29,7 @@ import java.sql.*; import java.util.ArrayList; import java.util.List; -import static io.linuxserver.fleet.db.dao.Utils.safeClose; -import static io.linuxserver.fleet.db.dao.Utils.setNullableInt; -import static io.linuxserver.fleet.db.dao.Utils.setNullableString; +import static io.linuxserver.fleet.db.dao.Utils.*; public class DefaultRepositoryDAO implements RepositoryDAO { @@ -43,14 +42,14 @@ public class DefaultRepositoryDAO implements RepositoryDAO { } @Override - public Repository fetchRepository(int id) { + public Repository fetchRepository(RepositoryKey repositoryKey) { CallableStatement call = null; try (Connection connection = databaseConnection.getConnection()) { call = connection.prepareCall("{CALL Repository_Get(?)}"); - call.setInt(1, id); + call.setInt(1, repositoryKey.getId()); ResultSet results = call.executeQuery(); if (results.next()) @@ -73,7 +72,7 @@ public class DefaultRepositoryDAO implements RepositoryDAO { try (Connection connection = databaseConnection.getConnection()) { call = connection.prepareCall("{CALL Repository_Save(?,?,?,?,?,?,?)}"); - setNullableInt(call, 1, repository.getId()); + setNullableInt(call, 1, repository.getKey().getId()); call.setString(2, repository.getName()); setNullableString(call, 3, repository.getVersionMask()); call.setBoolean(4, repository.isSyncEnabled()); @@ -89,7 +88,7 @@ public class DefaultRepositoryDAO implements RepositoryDAO { String statusMessage = call.getString(7); if (InsertUpdateStatus.OK == status) - return new InsertUpdateResult<>(fetchRepository(repositoryId), status, statusMessage); + return new InsertUpdateResult<>(fetchRepository(repository.getKey().cloneWithId(repositoryId)), status, statusMessage); return new InsertUpdateResult<>(status, statusMessage); @@ -171,7 +170,7 @@ public class DefaultRepositoryDAO implements RepositoryDAO { private Repository parseRepositoryFromResultSet(ResultSet results) throws SQLException { - Repository repository = new Repository(results.getInt("RepositoryId"), results.getString("RepositoryName")) + Repository repository = new Repository(new RepositoryKey(results.getInt("RepositoryId"), results.getString("RepositoryName"))) .withSyncEnabled(results.getBoolean("SyncEnabled")) .withVersionMask(results.getString("RepositoryVersionMask")) .withModifiedTime(results.getTimestamp("ModifiedTime").toLocalDateTime()); diff --git a/src/main/java/io/linuxserver/fleet/db/dao/DefaultUserDAO.java b/src/main/java/io/linuxserver/fleet/db/dao/DefaultUserDAO.java index 64e4136..32b7d19 100644 --- a/src/main/java/io/linuxserver/fleet/db/dao/DefaultUserDAO.java +++ b/src/main/java/io/linuxserver/fleet/db/dao/DefaultUserDAO.java @@ -85,7 +85,7 @@ public class DefaultUserDAO implements UserDAO { try (Connection connection = databaseConnection.getConnection()) { CallableStatement call = connection.prepareCall("{CALL User_Save(?,?,?,?,?,?)}"); - setNullableInt(call, 1, user.getId()); + setNullableInt(call, 1, user.getKey().getId()); call.setString(2, user.getUsername()); setNullableString(call, 3, user.getPassword()); @@ -137,7 +137,7 @@ public class DefaultUserDAO implements UserDAO { try (Connection connection = databaseConnection.getConnection()) { CallableStatement call = connection.prepareCall("{CALL User_Delete(?)}"); - call.setInt(1, user.getId()); + call.setInt(1, user.getKey().getId()); call.executeUpdate(); diff --git a/src/main/java/io/linuxserver/fleet/db/dao/ImageDAO.java b/src/main/java/io/linuxserver/fleet/db/dao/ImageDAO.java index 1125b86..efdd004 100644 --- a/src/main/java/io/linuxserver/fleet/db/dao/ImageDAO.java +++ b/src/main/java/io/linuxserver/fleet/db/dao/ImageDAO.java @@ -4,20 +4,22 @@ import io.linuxserver.fleet.db.query.InsertUpdateResult; import io.linuxserver.fleet.db.query.LimitedResult; import io.linuxserver.fleet.model.internal.Image; import io.linuxserver.fleet.model.internal.ImagePullStat; +import io.linuxserver.fleet.model.key.ImageKey; +import io.linuxserver.fleet.model.key.RepositoryKey; import java.util.List; public interface ImageDAO { - Image findImageByRepositoryAndImageName(int repositoryId, String imageName); + Image findImageByRepositoryAndImageName(ImageKey imageKey); - Image fetchImage(Integer id); + Image fetchImage(ImageKey imageKey); - LimitedResult fetchImagesByRepository(int repositoryId); + LimitedResult fetchImagesByRepository(RepositoryKey repositoryKey); InsertUpdateResult saveImage(Image image); - void removeImage(Integer id); + void removeImage(ImageKey imageKey); - List fetchImagePullHistory(Integer imageId, ImagePullStat.GroupMode groupMode); + List fetchImagePullHistory(ImageKey imageKey, ImagePullStat.GroupMode groupMode); } diff --git a/src/main/java/io/linuxserver/fleet/db/dao/RepositoryDAO.java b/src/main/java/io/linuxserver/fleet/db/dao/RepositoryDAO.java index 512e07e..ca5cc56 100644 --- a/src/main/java/io/linuxserver/fleet/db/dao/RepositoryDAO.java +++ b/src/main/java/io/linuxserver/fleet/db/dao/RepositoryDAO.java @@ -2,12 +2,13 @@ package io.linuxserver.fleet.db.dao; import io.linuxserver.fleet.db.query.InsertUpdateResult; import io.linuxserver.fleet.model.internal.Repository; +import io.linuxserver.fleet.model.key.RepositoryKey; import java.util.List; public interface RepositoryDAO { - Repository fetchRepository(int id); + Repository fetchRepository(RepositoryKey repositoryKey); InsertUpdateResult saveRepository(Repository repository); diff --git a/src/main/java/io/linuxserver/fleet/delegate/ImageDelegate.java b/src/main/java/io/linuxserver/fleet/delegate/ImageDelegate.java index e0a12ea..2c27bb3 100644 --- a/src/main/java/io/linuxserver/fleet/delegate/ImageDelegate.java +++ b/src/main/java/io/linuxserver/fleet/delegate/ImageDelegate.java @@ -24,6 +24,8 @@ import io.linuxserver.fleet.db.query.InsertUpdateStatus; import io.linuxserver.fleet.exception.SaveException; import io.linuxserver.fleet.model.internal.Image; import io.linuxserver.fleet.model.internal.ImagePullStat; +import io.linuxserver.fleet.model.key.ImageKey; +import io.linuxserver.fleet.model.key.RepositoryKey; import java.util.List; @@ -45,13 +47,13 @@ public class ImageDelegate { * already has the image stored against the repository. *

*/ - public Image findImageByRepositoryAndImageName(int repositoryId, String imageName) { + public Image findImageByRepositoryAndImageName(final ImageKey imageKey) { - Image cachedImage = imageCache.get(repositoryId, imageName); + Image cachedImage = imageCache.get(imageKey); if (null == cachedImage) { - Image image = imageDAO.findImageByRepositoryAndImageName(repositoryId, imageName); + Image image = imageDAO.findImageByRepositoryAndImageName(imageKey); if (null != image) { imageCache.updateCache(image); @@ -63,16 +65,16 @@ public class ImageDelegate { return cachedImage; } - public Image fetchImage(int id) { - return imageDAO.fetchImage(id); + public Image fetchImage(ImageKey imageKey) { + return imageDAO.fetchImage(imageKey); } - public List fetchImagesByRepository(int repositoryId) { + public List fetchImagesByRepository(final RepositoryKey repositoryKey) { - List cachedImages = imageCache.getAll(repositoryId); + List cachedImages = imageCache.getAll(repositoryKey); if (cachedImages.isEmpty()) { - List images = imageDAO.fetchImagesByRepository(repositoryId).getResults(); + List images = imageDAO.fetchImagesByRepository(repositoryKey).getResults(); images.forEach(imageCache::updateCache); return images; @@ -81,13 +83,13 @@ public class ImageDelegate { return cachedImages; } - public void removeImage(Integer id) { + public void removeImage(ImageKey imageKey) { - Image existingImage = imageDAO.fetchImage(id); + Image existingImage = imageDAO.fetchImage(imageKey); if (null != existingImage) { - imageDAO.removeImage(id); - imageCache.remove(existingImage); + imageDAO.removeImage(imageKey); + imageCache.remove(imageKey); } } @@ -106,7 +108,7 @@ public class ImageDelegate { throw new SaveException(result.getStatusMessage()); } - public List fetchImagePullHistory(int id, ImagePullStat.GroupMode groupMode) { - return imageDAO.fetchImagePullHistory(id, groupMode); + public List fetchImagePullHistory(ImageKey imageKey, ImagePullStat.GroupMode groupMode) { + return imageDAO.fetchImagePullHistory(imageKey, groupMode); } } diff --git a/src/main/java/io/linuxserver/fleet/delegate/RepositoryDelegate.java b/src/main/java/io/linuxserver/fleet/delegate/RepositoryDelegate.java index d3971bb..e955c95 100644 --- a/src/main/java/io/linuxserver/fleet/delegate/RepositoryDelegate.java +++ b/src/main/java/io/linuxserver/fleet/delegate/RepositoryDelegate.java @@ -22,6 +22,7 @@ import io.linuxserver.fleet.db.query.InsertUpdateResult; import io.linuxserver.fleet.db.query.InsertUpdateStatus; import io.linuxserver.fleet.exception.SaveException; import io.linuxserver.fleet.model.internal.Repository; +import io.linuxserver.fleet.model.key.RepositoryKey; import java.util.List; @@ -33,8 +34,8 @@ public class RepositoryDelegate { this.repositoryDAO = repositoryDAO; } - public Repository fetchRepository(int id) { - return repositoryDAO.fetchRepository(id); + public Repository fetchRepository(RepositoryKey repositoryKey) { + return repositoryDAO.fetchRepository(repositoryKey); } public Repository saveRepository(Repository repository) throws SaveException { diff --git a/src/main/java/io/linuxserver/fleet/dockerhub/queue/DockerHubSyncRequest.java b/src/main/java/io/linuxserver/fleet/dockerhub/queue/DockerHubSyncRequest.java index 3b1b89d..f1dc4f1 100644 --- a/src/main/java/io/linuxserver/fleet/dockerhub/queue/DockerHubSyncRequest.java +++ b/src/main/java/io/linuxserver/fleet/dockerhub/queue/DockerHubSyncRequest.java @@ -20,8 +20,8 @@ package io.linuxserver.fleet.dockerhub.queue; import io.linuxserver.fleet.delegate.DockerHubDelegate; import io.linuxserver.fleet.model.internal.Image; import io.linuxserver.fleet.queue.FleetRequest; - -import java.util.Objects; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; public class DockerHubSyncRequest implements FleetRequest { @@ -41,14 +41,15 @@ public class DockerHubSyncRequest implements FleetRequest @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - DockerHubSyncRequest that = (DockerHubSyncRequest) o; - return Objects.equals(image, that.image); + + if (!(o instanceof DockerHubSyncRequest)) + return false; + + return EqualsBuilder.reflectionEquals(this, "dockerHubDelegate"); } @Override public int hashCode() { - return Objects.hash(image); + return HashCodeBuilder.reflectionHashCode(this, "dockerHubDelegate"); } } diff --git a/src/main/java/io/linuxserver/fleet/dockerhub/queue/DockerHubSyncResponse.java b/src/main/java/io/linuxserver/fleet/dockerhub/queue/DockerHubSyncResponse.java index f3f84d1..9b74520 100644 --- a/src/main/java/io/linuxserver/fleet/dockerhub/queue/DockerHubSyncResponse.java +++ b/src/main/java/io/linuxserver/fleet/dockerhub/queue/DockerHubSyncResponse.java @@ -41,8 +41,9 @@ public class DockerHubSyncResponse implements FleetResponse { @Override public void handle() { - DockerImage dockerImage = dockerHubDelegate.fetchImageFromRepository(image.getRepository().getName(), image.getName()); - String versionMask = getVersionMask(image.getRepository().getVersionMask(), image.getVersionMask()); + DockerImage dockerImage = dockerHubDelegate.fetchImageFromRepository(image.getKey().getRepositoryKey().getName(), image.getName()); + + String versionMask = getVersionMask(null, image.getVersionMask()); Tag maskedVersion = getLatestTagAndCreateMaskedVersion(versionMask); image.withPullCount(dockerImage.getPullCount()); @@ -59,7 +60,7 @@ public class DockerHubSyncResponse implements FleetResponse { private Tag getLatestTagAndCreateMaskedVersion(String versionMask) { - DockerTag tag = dockerHubDelegate.fetchLatestImageTag(image.getRepository().getName(), image.getName()); + DockerTag tag = dockerHubDelegate.fetchLatestImageTag(image.getKey().getRepositoryKey().getName(), image.getName()); if (null == tag) return Tag.NONE; diff --git a/src/main/java/io/linuxserver/fleet/model/api/ApiImagePullHistory.java b/src/main/java/io/linuxserver/fleet/model/api/ApiImagePullHistory.java index ba33c9d..a5a98d9 100644 --- a/src/main/java/io/linuxserver/fleet/model/api/ApiImagePullHistory.java +++ b/src/main/java/io/linuxserver/fleet/model/api/ApiImagePullHistory.java @@ -49,7 +49,7 @@ public class ApiImagePullHistory { public static ApiImagePullHistory fromPullStats(Image image, List stats) { ApiImagePullHistory history = new ApiImagePullHistory(); - history.imageId = image.getId(); + history.imageId = image.getKey().getId(); history.imageName = image.getName(); history.groupMode = stats.get(0).getGroupMode().toString(); diff --git a/src/main/java/io/linuxserver/fleet/model/internal/Image.java b/src/main/java/io/linuxserver/fleet/model/internal/Image.java index 4a85650..f472779 100644 --- a/src/main/java/io/linuxserver/fleet/model/internal/Image.java +++ b/src/main/java/io/linuxserver/fleet/model/internal/Image.java @@ -17,9 +17,11 @@ package io.linuxserver.fleet.model.internal; +import io.linuxserver.fleet.model.key.AbstractHasKey; +import io.linuxserver.fleet.model.key.ImageKey; + import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.Objects; /** *

@@ -27,36 +29,35 @@ import java.util.Objects; * specific information regarding its build status and pull count. *

*/ -public class Image extends PersistableItem { +public class Image extends AbstractHasKey { - private final Repository repository; - private final String name; + private static final DateTimeFormatter DATE_PATTERN = DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm:ss"); private Tag tag; private long pullCount; private String versionMask; private boolean unstable; private boolean hidden; - + private LocalDateTime modifiedTime; private boolean deprecated; private String deprecationReason; - public Image(Integer id, Repository repository, String name, Tag latestVersion) { - - super(id); - - this.name = name; - this.repository = repository; - this.tag = new Tag(latestVersion.getVersion(), latestVersion.getMaskedVersion(), latestVersion.getBuildDate()); + public Image(final ImageKey imageKey, final Tag latestVersion) { + super(imageKey); + this.tag = new Tag(latestVersion.getVersion(), latestVersion.getMaskedVersion(), latestVersion.getBuildDate()); } - public Image(Repository repository, String name) { - this(null, repository, name, Tag.NONE); + public Image(final ImageKey imageKey) { + this(imageKey, Tag.NONE); + } + + public static Image makeFromKey(ImageKey imageKey) { + return new Image(imageKey); } public static Image copyOf(Image image) { - Image cloned = new Image(image.getId(), Repository.copyOf(image.repository), image.name, image.tag); + Image cloned = new Image(image.getKey(), image.tag); cloned.pullCount = image.pullCount; cloned.versionMask = image.versionMask; cloned.unstable = image.unstable; @@ -103,20 +104,22 @@ public class Image extends PersistableItem { return this; } + public Image withModifiedTime(final LocalDateTime modifiedTime) { + + this.modifiedTime = modifiedTime; + return this; + } + public void updateTag(Tag maskedVersion) { this.tag = new Tag(maskedVersion.getVersion(), maskedVersion.getMaskedVersion(), maskedVersion.getBuildDate()); } public int getRepositoryId() { - return repository.getId(); - } - - public Repository getRepository() { - return repository; + return getKey().getRepositoryKey().getId(); } public String getName() { - return name; + return getKey().getName(); } public long getPullCount() { @@ -138,7 +141,7 @@ public class Image extends PersistableItem { public String getBuildDateAsString() { if (getBuildDate() != null) { - return getBuildDate().format(DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm:ss")); + return getBuildDate().format(DATE_PATTERN); } return null; @@ -164,17 +167,20 @@ public class Image extends PersistableItem { return deprecationReason; } - @Override - public boolean equals(Object o) { + public LocalDateTime getModifiedTime() { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Image image = (Image) o; - return Objects.equals(repository, image.repository) && Objects.equals(name, image.name); - } + if (null != modifiedTime) { - @Override - public int hashCode() { - return Objects.hash(repository, name); + return LocalDateTime.of( + modifiedTime.getYear(), + modifiedTime.getMonth(), + modifiedTime.getDayOfMonth(), + modifiedTime.getHour(), + modifiedTime.getMinute(), + modifiedTime.getSecond() + ); + } + + return null; } } diff --git a/src/main/java/io/linuxserver/fleet/model/internal/Repository.java b/src/main/java/io/linuxserver/fleet/model/internal/Repository.java index a8262e4..e3ff9e5 100644 --- a/src/main/java/io/linuxserver/fleet/model/internal/Repository.java +++ b/src/main/java/io/linuxserver/fleet/model/internal/Repository.java @@ -17,29 +17,23 @@ package io.linuxserver.fleet.model.internal; -import java.util.Objects; +import io.linuxserver.fleet.model.key.AbstractHasKey; +import io.linuxserver.fleet.model.key.RepositoryKey; -public class Repository extends PersistableItem { +import java.time.LocalDateTime; - private final String name; +public class Repository extends AbstractHasKey { - private String versionMask; - private boolean syncEnabled; + private String versionMask; + private boolean syncEnabled; + private LocalDateTime modifiedTime; - public Repository(Integer id, String name) { - super(id); - - this.name = name; - } - - public Repository(String name) { - super(); - - this.name = name; + public Repository(final RepositoryKey repositoryKey) { + super(repositoryKey); } public static Repository copyOf(Repository repository) { - return new Repository(repository.getId(), repository.name).withVersionMask(repository.versionMask).withSyncEnabled(repository.syncEnabled); + return new Repository(repository.getKey()).withVersionMask(repository.versionMask).withSyncEnabled(repository.syncEnabled); } public Repository withVersionMask(String versionMask) { @@ -54,8 +48,14 @@ public class Repository extends PersistableItem { return this; } + public Repository withModifiedTime(LocalDateTime modifiedTime) { + + this.modifiedTime = modifiedTime; + return this; + } + public String getName() { - return name; + return getKey().getName(); } public String getVersionMask() { @@ -66,16 +66,20 @@ public class Repository extends PersistableItem { return syncEnabled; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Repository that = (Repository) o; - return Objects.equals(name, that.name); - } + public LocalDateTime getModifiedTime() { - @Override - public int hashCode() { - return Objects.hash(name); + if (null != modifiedTime) { + + return LocalDateTime.of( + modifiedTime.getYear(), + modifiedTime.getMonth(), + modifiedTime.getDayOfMonth(), + modifiedTime.getHour(), + modifiedTime.getMinute(), + modifiedTime.getSecond() + ); + } + + return null; } } diff --git a/src/main/java/io/linuxserver/fleet/model/internal/User.java b/src/main/java/io/linuxserver/fleet/model/internal/User.java index 026d127..1af541f 100644 --- a/src/main/java/io/linuxserver/fleet/model/internal/User.java +++ b/src/main/java/io/linuxserver/fleet/model/internal/User.java @@ -17,20 +17,27 @@ package io.linuxserver.fleet.model.internal; -public class User extends PersistableItem { +import io.linuxserver.fleet.model.key.AbstractHasKey; +import io.linuxserver.fleet.model.key.UserKey; - private final String username; - private final String password; +import java.time.LocalDateTime; + +public class User extends AbstractHasKey { + + private final String username; + private final String password; + + private LocalDateTime modifiedTime; public User(String username, String password) { - super(); + super(new UserKey()); this.username = username; this.password = password; } public User(Integer id, String username, String password) { - super(id); + super(new UserKey(id)); this.username = username; this.password = password; @@ -43,4 +50,27 @@ public class User extends PersistableItem { public String getPassword() { return password; } + + public User withModifiedTime(LocalDateTime modifiedTime) { + + this.modifiedTime = modifiedTime; + return this; + } + + public LocalDateTime getModifiedTime() { + + if (null != modifiedTime) { + + return LocalDateTime.of( + modifiedTime.getYear(), + modifiedTime.getMonth(), + modifiedTime.getDayOfMonth(), + modifiedTime.getHour(), + modifiedTime.getMinute(), + modifiedTime.getSecond() + ); + } + + return null; + } } diff --git a/src/main/java/io/linuxserver/fleet/model/key/AbstractHasKey.java b/src/main/java/io/linuxserver/fleet/model/key/AbstractHasKey.java new file mode 100644 index 0000000..db52b59 --- /dev/null +++ b/src/main/java/io/linuxserver/fleet/model/key/AbstractHasKey.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019 LinuxServer.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.linuxserver.fleet.model.key; + +public abstract class AbstractHasKey implements HasKey { + + private final KEY key; + + public AbstractHasKey(final KEY key) { + this.key = key; + } + + @Override + public final KEY getKey() { + return key; + } + + @Override + public int hashCode() { + return key.hashCode(); + } + + @Override + public boolean equals(Object o) { + + if (!(o instanceof HasKey)) { + return false; + } + + return key.equals(((HasKey) o).getKey()); + } + + @Override + public final String toString() { + return key.toString(); + } +} diff --git a/src/main/java/io/linuxserver/fleet/model/internal/PersistableItem.java b/src/main/java/io/linuxserver/fleet/model/key/AbstractKey.java similarity index 52% rename from src/main/java/io/linuxserver/fleet/model/internal/PersistableItem.java rename to src/main/java/io/linuxserver/fleet/model/key/AbstractKey.java index c92f510..21cdcf4 100644 --- a/src/main/java/io/linuxserver/fleet/model/internal/PersistableItem.java +++ b/src/main/java/io/linuxserver/fleet/model/key/AbstractKey.java @@ -15,41 +15,47 @@ * along with this program. If not, see . */ -package io.linuxserver.fleet.model.internal; +package io.linuxserver.fleet.model.key; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; +public abstract class AbstractKey implements Key { -import java.time.LocalDateTime; + private final Integer id; -public abstract class PersistableItem { - - private Integer id; - private LocalDateTime modifiedTime; - - PersistableItem() { } - - PersistableItem(Integer id) { + public AbstractKey(final Integer id) { this.id = id; } - @SuppressWarnings("unchecked") - public T withModifiedTime(LocalDateTime modifiedTime) { - - this.modifiedTime = modifiedTime; - return (T) this; - } - - public Integer getId() { + @Override + public final Integer getId() { return id; } - public LocalDateTime getModifiedTime() { - return modifiedTime; + @Override + public boolean equals(Object o) { + + if (!(o instanceof Key)) { + return false; + } + + if (null == id) { + return ((Key) o).getId() == null; + } + + return ((Key) o).getId().equals(id); + } + + @Override + public int hashCode() { + + if (null == id) { + return -1; + } + + return id.hashCode(); } @Override public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); + return null == id ? "" : String.valueOf(id); } } diff --git a/src/main/java/io/linuxserver/fleet/model/key/HasKey.java b/src/main/java/io/linuxserver/fleet/model/key/HasKey.java new file mode 100644 index 0000000..8ef0801 --- /dev/null +++ b/src/main/java/io/linuxserver/fleet/model/key/HasKey.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019 LinuxServer.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.linuxserver.fleet.model.key; + +public interface HasKey { + + KEY getKey(); +} diff --git a/src/main/java/io/linuxserver/fleet/model/key/ImageKey.java b/src/main/java/io/linuxserver/fleet/model/key/ImageKey.java new file mode 100644 index 0000000..d631925 --- /dev/null +++ b/src/main/java/io/linuxserver/fleet/model/key/ImageKey.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019 LinuxServer.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.linuxserver.fleet.model.key; + +public class ImageKey extends AbstractKey { + + private final RepositoryKey repositoryKey; + private final String name; + + public ImageKey(final String name, final RepositoryKey repositoryKey) { + this(null, name, repositoryKey); + } + + public ImageKey(final Integer id, final String name, final RepositoryKey repositoryKey) { + super(id); + + this.repositoryKey = repositoryKey; + this.name = name; + } + + public static ImageKey makeForLookup(final int imageId) { + return new ImageKey(imageId, "", null); + } + + public ImageKey cloneWithId(int id) { + return new ImageKey(id, name, repositoryKey); + } + + public final RepositoryKey getRepositoryKey() { + return repositoryKey; + } + + public final String getName() { + return name; + } + + @Override + public String toString() { + return super.toString() + ":" + (repositoryKey == null ? "" : repositoryKey.getName()) + "/" + name; + } +} diff --git a/src/main/java/io/linuxserver/fleet/model/key/Key.java b/src/main/java/io/linuxserver/fleet/model/key/Key.java new file mode 100644 index 0000000..5311e6d --- /dev/null +++ b/src/main/java/io/linuxserver/fleet/model/key/Key.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019 LinuxServer.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.linuxserver.fleet.model.key; + +public interface Key { + + Integer getId(); +} diff --git a/src/main/java/io/linuxserver/fleet/model/key/RepositoryKey.java b/src/main/java/io/linuxserver/fleet/model/key/RepositoryKey.java new file mode 100644 index 0000000..20d8e64 --- /dev/null +++ b/src/main/java/io/linuxserver/fleet/model/key/RepositoryKey.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019 LinuxServer.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.linuxserver.fleet.model.key; + +public class RepositoryKey extends AbstractKey { + + private final String name; + + public RepositoryKey(final int id) { + this(id, ""); + } + + public RepositoryKey(final String name) { + this(null, name); + } + + public RepositoryKey(final Integer id, final String name) { + super(id); + this.name = name; + } + + public RepositoryKey cloneWithId(int id) { + return new RepositoryKey(id, name); + } + + public final String getName() { + return name; + } + + @Override + public String toString() { + return super.toString() + ":" + name; + } +} diff --git a/src/main/java/io/linuxserver/fleet/model/key/UserKey.java b/src/main/java/io/linuxserver/fleet/model/key/UserKey.java new file mode 100644 index 0000000..30bea6c --- /dev/null +++ b/src/main/java/io/linuxserver/fleet/model/key/UserKey.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019 LinuxServer.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.linuxserver.fleet.model.key; + +public class UserKey extends AbstractKey { + + public UserKey() { + this(null); + } + + public UserKey(Integer id) { + super(id); + } +} diff --git a/src/main/java/io/linuxserver/fleet/sync/DefaultSynchronisationState.java b/src/main/java/io/linuxserver/fleet/sync/DefaultSynchronisationState.java index ab05aa8..694f778 100644 --- a/src/main/java/io/linuxserver/fleet/sync/DefaultSynchronisationState.java +++ b/src/main/java/io/linuxserver/fleet/sync/DefaultSynchronisationState.java @@ -24,6 +24,8 @@ import io.linuxserver.fleet.model.docker.DockerTag; import io.linuxserver.fleet.model.internal.Image; import io.linuxserver.fleet.model.internal.Repository; import io.linuxserver.fleet.model.internal.Tag; +import io.linuxserver.fleet.model.key.ImageKey; +import io.linuxserver.fleet.model.key.RepositoryKey; import io.linuxserver.fleet.sync.event.ImageUpdateEvent; import io.linuxserver.fleet.sync.event.RepositoriesScannedEvent; import org.slf4j.Logger; @@ -167,7 +169,7 @@ public class DefaultSynchronisationState implements SynchronisationState { if (!repositories.contains(storedRepository.getName())) { LOGGER.info("Found repository which no longer exists in Docker Hub. Removing {}", storedRepository.getName()); - context.getRepositoryDelegate().removeRepository(storedRepository.getId()); + context.getRepositoryDelegate().removeRepository(storedRepository.getKey().getId()); } } } @@ -177,12 +179,12 @@ public class DefaultSynchronisationState implements SynchronisationState { List dockerHubImageNames = images.stream().map(DockerImage::getName).collect(Collectors.toList()); LOGGER.info("Checking for any removed images under {}", repository.getName()); - for (Image storedImage : context.getImageDelegate().fetchImagesByRepository(repository.getId())) { + for (Image storedImage : context.getImageDelegate().fetchImagesByRepository(repository.getKey())) { if (!dockerHubImageNames.contains(storedImage.getName())) { LOGGER.info("Found image which no longer exists in Docker Hub. Removing {}", storedImage.getName()); - context.getImageDelegate().removeImage(storedImage.getId()); + context.getImageDelegate().removeImage(storedImage.getKey()); } } } @@ -216,7 +218,7 @@ public class DefaultSynchronisationState implements SynchronisationState { try { - return context.getRepositoryDelegate().saveRepository(new Repository(repositoryName)); + return context.getRepositoryDelegate().saveRepository(new Repository(new RepositoryKey(repositoryName))); } catch (SaveException e) { LOGGER.error("Tried to save new repository during sync but failed", e); @@ -232,13 +234,14 @@ public class DefaultSynchronisationState implements SynchronisationState { */ private Image configureImage(Repository repository, DockerImage dockerHubImage, SynchronisationContext context) { - Image image = context.getImageDelegate().findImageByRepositoryAndImageName(repository.getId(), dockerHubImage.getName()); + final ImageKey baseImageKey = new ImageKey(dockerHubImage.getName(), repository.getKey()); + final Image image = context.getImageDelegate().findImageByRepositoryAndImageName(baseImageKey); if (isImageNew(image)) { try { - return context.getImageDelegate().saveImage(new Image(repository, dockerHubImage.getName())); + return context.getImageDelegate().saveImage(Image.makeFromKey(baseImageKey)); } catch (SaveException e) { LOGGER.error("Tried to save new image during sync but failed", e); diff --git a/src/main/java/io/linuxserver/fleet/web/pages/HomePage.java b/src/main/java/io/linuxserver/fleet/web/pages/HomePage.java index 4845ea9..711f589 100644 --- a/src/main/java/io/linuxserver/fleet/web/pages/HomePage.java +++ b/src/main/java/io/linuxserver/fleet/web/pages/HomePage.java @@ -51,7 +51,7 @@ public class HomePage extends WebPage { for (Repository repository : repositories) { if (repository.isSyncEnabled()) - populatedRepositories.add(new RepositoryWithImages(repository, imageDelegate.fetchImagesByRepository(repository.getId()))); + populatedRepositories.add(new RepositoryWithImages(repository, imageDelegate.fetchImagesByRepository(repository.getKey()))); } model.put("populatedRepositories", populatedRepositories); diff --git a/src/main/java/io/linuxserver/fleet/web/routes/AllImagesApi.java b/src/main/java/io/linuxserver/fleet/web/routes/AllImagesApi.java index e2345e8..5e5e4b3 100644 --- a/src/main/java/io/linuxserver/fleet/web/routes/AllImagesApi.java +++ b/src/main/java/io/linuxserver/fleet/web/routes/AllImagesApi.java @@ -55,7 +55,7 @@ public class AllImagesApi implements Route { if (repository.isSyncEnabled()) { - List savedImages = imageDelegate.fetchImagesByRepository(repository.getId()); + List savedImages = imageDelegate.fetchImagesByRepository(repository.getKey()); List apiImages = new ArrayList<>(); for (Image savedImage : savedImages) { diff --git a/src/main/java/io/linuxserver/fleet/web/routes/GetImageApi.java b/src/main/java/io/linuxserver/fleet/web/routes/GetImageApi.java index 20994a2..486034b 100644 --- a/src/main/java/io/linuxserver/fleet/web/routes/GetImageApi.java +++ b/src/main/java/io/linuxserver/fleet/web/routes/GetImageApi.java @@ -21,6 +21,7 @@ import io.linuxserver.fleet.delegate.ImageDelegate; import io.linuxserver.fleet.model.internal.Image; import io.linuxserver.fleet.model.api.ApiResponse; import io.linuxserver.fleet.model.api.FleetApiException; +import io.linuxserver.fleet.model.key.ImageKey; import spark.Request; import spark.Response; import spark.Route; @@ -41,7 +42,7 @@ public class GetImageApi implements Route { throw new FleetApiException(400, "Missing imageId param"); } - Image image = imageDelegate.fetchImage(Integer.parseInt(imageIdParam)); + Image image = imageDelegate.fetchImage(ImageKey.makeForLookup(Integer.parseInt(imageIdParam))); if (null == image) { throw new FleetApiException(404, "Image not found"); } diff --git a/src/main/java/io/linuxserver/fleet/web/routes/GetImagePullHistoryApi.java b/src/main/java/io/linuxserver/fleet/web/routes/GetImagePullHistoryApi.java index 708a8e7..f71deb9 100644 --- a/src/main/java/io/linuxserver/fleet/web/routes/GetImagePullHistoryApi.java +++ b/src/main/java/io/linuxserver/fleet/web/routes/GetImagePullHistoryApi.java @@ -23,6 +23,7 @@ import io.linuxserver.fleet.model.internal.ImagePullStat; import io.linuxserver.fleet.model.api.ApiImagePullHistory; import io.linuxserver.fleet.model.api.ApiResponse; import io.linuxserver.fleet.model.api.FleetApiException; +import io.linuxserver.fleet.model.key.ImageKey; import spark.Request; import spark.Response; import spark.Route; @@ -45,10 +46,10 @@ public class GetImagePullHistoryApi implements Route { throw new FleetApiException(400, "Missing imageId param"); } - int imageId = Integer.parseInt(imageIdParam); - List imagePullStats = imageDelegate.fetchImagePullHistory(imageId, getGroupMode(request)); + final ImageKey lookupKey = ImageKey.makeForLookup(Integer.parseInt(imageIdParam)); + List imagePullStats = imageDelegate.fetchImagePullHistory(lookupKey, getGroupMode(request)); - Image image = imageDelegate.fetchImage(imageId); + Image image = imageDelegate.fetchImage(lookupKey); return new ApiResponse<>("OK", ApiImagePullHistory.fromPullStats(image, imagePullStats)); } diff --git a/src/main/java/io/linuxserver/fleet/web/routes/ManageImageApi.java b/src/main/java/io/linuxserver/fleet/web/routes/ManageImageApi.java index 00c4b7a..339f5a3 100644 --- a/src/main/java/io/linuxserver/fleet/web/routes/ManageImageApi.java +++ b/src/main/java/io/linuxserver/fleet/web/routes/ManageImageApi.java @@ -21,6 +21,7 @@ import io.linuxserver.fleet.delegate.ImageDelegate; import io.linuxserver.fleet.model.internal.Image; import io.linuxserver.fleet.model.api.ApiResponse; import io.linuxserver.fleet.model.api.FleetApiException; +import io.linuxserver.fleet.model.key.ImageKey; import spark.Request; import spark.Response; import spark.Route; @@ -40,7 +41,7 @@ public class ManageImageApi implements Route { int imageId = Integer.parseInt(request.queryParams("imageId")); - Image image = imageDelegate.fetchImage(imageId); + Image image = imageDelegate.fetchImage(ImageKey.makeForLookup(imageId)); if (null == image) { response.status(404); diff --git a/src/main/java/io/linuxserver/fleet/web/routes/ManageRepositoryApi.java b/src/main/java/io/linuxserver/fleet/web/routes/ManageRepositoryApi.java index 682c4b3..c3762fa 100644 --- a/src/main/java/io/linuxserver/fleet/web/routes/ManageRepositoryApi.java +++ b/src/main/java/io/linuxserver/fleet/web/routes/ManageRepositoryApi.java @@ -21,6 +21,7 @@ import io.linuxserver.fleet.delegate.RepositoryDelegate; import io.linuxserver.fleet.model.internal.Repository; import io.linuxserver.fleet.model.api.ApiResponse; import io.linuxserver.fleet.model.api.FleetApiException; +import io.linuxserver.fleet.model.key.RepositoryKey; import spark.Request; import spark.Response; import spark.Route; @@ -40,7 +41,7 @@ public class ManageRepositoryApi implements Route { int repositoryId = Integer.parseInt(request.queryParams("repositoryId")); - Repository repository = repositoryDelegate.fetchRepository(repositoryId); + Repository repository = repositoryDelegate.fetchRepository(new RepositoryKey(repositoryId)); if (null == repository) { response.status(404); diff --git a/src/main/resources/spark/template/freemarker/admin.ftl b/src/main/resources/spark/template/freemarker/admin.ftl index 8e1ea10..65ca1db 100644 --- a/src/main/resources/spark/template/freemarker/admin.ftl +++ b/src/main/resources/spark/template/freemarker/admin.ftl @@ -34,7 +34,7 @@ <#list repositories as repository> - + ${repository.name} diff --git a/src/main/resources/spark/template/freemarker/home.ftl b/src/main/resources/spark/template/freemarker/home.ftl index 855f0cd..e454539 100644 --- a/src/main/resources/spark/template/freemarker/home.ftl +++ b/src/main/resources/spark/template/freemarker/home.ftl @@ -10,7 +10,7 @@ @@ -21,7 +21,7 @@
<#list populatedRepositories as populatedRepository> -
+
<#if populatedRepository.everyImageStable> @@ -48,15 +48,15 @@
- Search ${populatedRepository.repository.name} + Search ${populatedRepository.repository.name}
- +
-
+
@@ -73,7 +73,7 @@ <#list populatedRepository.images as image> <#if !image.hidden || __AUTHENTICATED_USER?has_content> - +
${populatedRepository.repository.name} / ${image.name} <#if image.deprecated> @@ -105,10 +105,10 @@ <#if __AUTHENTICATED_USER?has_content>