bugfix
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
jpacrepo.version=2023.07
|
jpacrepo.version=2023.07
|
||||||
|
|
||||||
lys.version=2023.07.20
|
lys.version=2023.07.28
|
||||||
|
@@ -8,6 +8,7 @@ import net.woggioni.jpacrepo.api.model.PkgData;
|
|||||||
import net.woggioni.jpacrepo.api.model.PkgId;
|
import net.woggioni.jpacrepo.api.model.PkgId;
|
||||||
import net.woggioni.jpacrepo.api.wire.PkgTuple;
|
import net.woggioni.jpacrepo.api.wire.PkgTuple;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NavigableMap;
|
import java.util.NavigableMap;
|
||||||
@@ -44,4 +45,6 @@ public interface PacmanServiceRemote {
|
|||||||
Set<String> missingFiles(Collection<String> fileNames);
|
Set<String> missingFiles(Collection<String> fileNames);
|
||||||
|
|
||||||
NavigableMap<PkgId, PkgTuple> getPkgMap();
|
NavigableMap<PkgId, PkgTuple> getPkgMap();
|
||||||
|
|
||||||
|
boolean addPackage(String fileName, InputStream inputStream);
|
||||||
}
|
}
|
@@ -1,11 +1,5 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal {
|
|
||||||
content {
|
|
||||||
includeGroup 'net.woggioni.gradle'
|
|
||||||
includeGroup 'net.woggioni.gradle.lombok'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
maven {
|
maven {
|
||||||
url = 'https://woggioni.net/mvn/'
|
url = 'https://woggioni.net/mvn/'
|
||||||
content {
|
content {
|
||||||
|
37
src/main/java/net/woggioni/jpacrepo/cache/PackageCache.java
vendored
Normal file
37
src/main/java/net/woggioni/jpacrepo/cache/PackageCache.java
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package net.woggioni.jpacrepo.cache;
|
||||||
|
|
||||||
|
import net.woggioni.jpacrepo.api.model.PkgId;
|
||||||
|
import net.woggioni.jpacrepo.api.wire.PkgTuple;
|
||||||
|
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class PackageCache {
|
||||||
|
private NavigableMap<PkgId, PkgTuple> cachedMap;
|
||||||
|
private final AtomicBoolean invalidateCache = new AtomicBoolean(true);
|
||||||
|
|
||||||
|
public NavigableMap<PkgId, PkgTuple> getCachedMap(Supplier<NavigableMap<PkgId, PkgTuple>> mapSupplier) {
|
||||||
|
NavigableMap<PkgId, PkgTuple> result = null;
|
||||||
|
if (!invalidateCache.get()) {
|
||||||
|
result = cachedMap;
|
||||||
|
}
|
||||||
|
if (result == null) {
|
||||||
|
synchronized(this) {
|
||||||
|
if (!invalidateCache.get()) {
|
||||||
|
result = cachedMap;
|
||||||
|
}
|
||||||
|
if (result == null) {
|
||||||
|
cachedMap = mapSupplier.get();
|
||||||
|
invalidateCache.set(false);
|
||||||
|
result = cachedMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void invalidateCache() {
|
||||||
|
invalidateCache.set(true);
|
||||||
|
}
|
||||||
|
}
|
@@ -12,7 +12,6 @@ import java.io.InputStream;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor(access = AccessLevel.PUBLIC)
|
@RequiredArgsConstructor(access = AccessLevel.PUBLIC)
|
||||||
public class AppConfig {
|
public class AppConfig {
|
||||||
@@ -26,9 +25,6 @@ public class AppConfig {
|
|||||||
@Getter
|
@Getter
|
||||||
private final String dataSourceJndi;
|
private final String dataSourceJndi;
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final AtomicBoolean invalidateCache = new AtomicBoolean(true);
|
|
||||||
|
|
||||||
public Path getFile(PkgData pkg) {
|
public Path getFile(PkgData pkg) {
|
||||||
return repoFolder.resolve(pkg.getFileName());
|
return repoFolder.resolve(pkg.getFileName());
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@ package net.woggioni.jpacrepo.factory;
|
|||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import jakarta.enterprise.inject.Produces;
|
import jakarta.enterprise.inject.Produces;
|
||||||
import jakarta.enterprise.inject.spi.InjectionPoint;
|
import jakarta.enterprise.inject.spi.InjectionPoint;
|
||||||
|
import net.woggioni.jpacrepo.cache.PackageCache;
|
||||||
import net.woggioni.jpacrepo.config.AppConfig;
|
import net.woggioni.jpacrepo.config.AppConfig;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -22,4 +23,9 @@ public class BeanFactory {
|
|||||||
public Logger createLogger(InjectionPoint injectionPoint) {
|
public Logger createLogger(InjectionPoint injectionPoint) {
|
||||||
return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
|
return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
|
||||||
}
|
}
|
||||||
|
@Produces
|
||||||
|
@ApplicationScoped
|
||||||
|
public PackageCache createCache() {
|
||||||
|
return new PackageCache();
|
||||||
|
}
|
||||||
}
|
}
|
@@ -11,7 +11,7 @@ import jakarta.ejb.Lock;
|
|||||||
import jakarta.ejb.LockType;
|
import jakarta.ejb.LockType;
|
||||||
import jakarta.ejb.Remote;
|
import jakarta.ejb.Remote;
|
||||||
import jakarta.ejb.Schedule;
|
import jakarta.ejb.Schedule;
|
||||||
import jakarta.ejb.Singleton;
|
import jakarta.ejb.Stateless;
|
||||||
import jakarta.ejb.TransactionAttribute;
|
import jakarta.ejb.TransactionAttribute;
|
||||||
import jakarta.ejb.TransactionAttributeType;
|
import jakarta.ejb.TransactionAttributeType;
|
||||||
import jakarta.ejb.TransactionManagement;
|
import jakarta.ejb.TransactionManagement;
|
||||||
@@ -19,20 +19,20 @@ import jakarta.ejb.TransactionManagementType;
|
|||||||
import jakarta.enterprise.concurrent.ManagedExecutorService;
|
import jakarta.enterprise.concurrent.ManagedExecutorService;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.EntityManagerFactory;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import jakarta.persistence.TypedQuery;
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import net.woggioni.jpacrepo.api.model.CompressionFormat;
|
import net.woggioni.jpacrepo.api.model.CompressionFormat;
|
||||||
import net.woggioni.jpacrepo.api.model.PkgData;
|
import net.woggioni.jpacrepo.api.model.PkgData;
|
||||||
import net.woggioni.jpacrepo.api.model.PkgId;
|
import net.woggioni.jpacrepo.api.model.PkgId;
|
||||||
import net.woggioni.jpacrepo.api.service.PacmanServiceLocal;
|
import net.woggioni.jpacrepo.api.service.PacmanServiceLocal;
|
||||||
import net.woggioni.jpacrepo.api.service.PacmanServiceRemote;
|
import net.woggioni.jpacrepo.api.service.PacmanServiceRemote;
|
||||||
|
import net.woggioni.jpacrepo.api.wire.PkgTuple;
|
||||||
|
import net.woggioni.jpacrepo.cache.PackageCache;
|
||||||
import net.woggioni.jpacrepo.config.AppConfig;
|
import net.woggioni.jpacrepo.config.AppConfig;
|
||||||
import net.woggioni.jpacrepo.impl.model.CompressionFormatImpl;
|
import net.woggioni.jpacrepo.impl.model.CompressionFormatImpl;
|
||||||
import net.woggioni.jpacrepo.impl.model.PkgDataImpl;
|
import net.woggioni.jpacrepo.impl.model.PkgDataImpl;
|
||||||
import net.woggioni.jpacrepo.persistence.QueryEngine;
|
import net.woggioni.jpacrepo.persistence.QueryEngine;
|
||||||
import net.woggioni.jpacrepo.service.jpa.Queries;
|
import net.woggioni.jpacrepo.service.jpa.Queries;
|
||||||
import net.woggioni.jpacrepo.api.wire.PkgTuple;
|
|
||||||
import net.woggioni.jpacrepo.version.PkgIdComparator;
|
import net.woggioni.jpacrepo.version.PkgIdComparator;
|
||||||
import net.woggioni.jwo.CollectionUtils;
|
import net.woggioni.jwo.CollectionUtils;
|
||||||
import net.woggioni.jwo.Con;
|
import net.woggioni.jwo.Con;
|
||||||
@@ -41,8 +41,12 @@ import net.woggioni.jwo.Sup;
|
|||||||
import net.woggioni.jwo.Tuple2;
|
import net.woggioni.jwo.Tuple2;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -59,15 +63,15 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Singleton
|
@Stateless
|
||||||
@Lock(LockType.READ)
|
@Lock(LockType.READ)
|
||||||
@TransactionManagement(TransactionManagementType.CONTAINER)
|
@TransactionManagement(TransactionManagementType.CONTAINER)
|
||||||
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
|
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
|
||||||
@Local({PacmanServiceLocal.class})
|
@Local({PacmanServiceLocal.class})
|
||||||
@Remote({PacmanServiceRemote.class})
|
@Remote({PacmanServiceRemote.class})
|
||||||
public class PacmanServiceEJB implements PacmanServiceLocal {
|
public class PacmanServiceEJB implements PacmanServiceLocal {
|
||||||
@Inject
|
@PersistenceContext
|
||||||
private EntityManagerFactory emf;
|
private EntityManager em;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AppConfig ctx;
|
private AppConfig ctx;
|
||||||
@@ -78,6 +82,9 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
|||||||
@Resource(name = "DefaultManagedExecutorService")
|
@Resource(name = "DefaultManagedExecutorService")
|
||||||
private ManagedExecutorService executor;
|
private ManagedExecutorService executor;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PackageCache packageCache;
|
||||||
|
|
||||||
private void deletePkgData(EntityManager em, PkgData pkgData) {
|
private void deletePkgData(EntityManager em, PkgData pkgData) {
|
||||||
em.remove(pkgData);
|
em.remove(pkgData);
|
||||||
}
|
}
|
||||||
@@ -88,7 +95,6 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
|||||||
@TransactionAttribute(TransactionAttributeType.REQUIRED)
|
@TransactionAttribute(TransactionAttributeType.REQUIRED)
|
||||||
@Schedule(hour = "4", minute = "00", persistent = false)
|
@Schedule(hour = "4", minute = "00", persistent = false)
|
||||||
public void syncDB() {
|
public void syncDB() {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
try {
|
try {
|
||||||
logger.info("Starting repository cleanup");
|
logger.info("Starting repository cleanup");
|
||||||
//Removes from DB the packages that have been deleted from filesystem
|
//Removes from DB the packages that have been deleted from filesystem
|
||||||
@@ -153,7 +159,7 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
|||||||
logger.info("Removing obsolete packages");
|
logger.info("Removing obsolete packages");
|
||||||
deleteOld(em);
|
deleteOld(em);
|
||||||
logger.info("Repository cleanup completed successfully");
|
logger.info("Repository cleanup completed successfully");
|
||||||
ctx.getInvalidateCache().set(true);
|
packageCache.invalidateCache();
|
||||||
} finally {
|
} finally {
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
@@ -173,7 +179,6 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
|||||||
@Override
|
@Override
|
||||||
@TransactionAttribute(TransactionAttributeType.REQUIRED)
|
@TransactionAttribute(TransactionAttributeType.REQUIRED)
|
||||||
public void deletePackage(String filename) {
|
public void deletePackage(String filename) {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
deletePackage(em, filename);
|
deletePackage(em, filename);
|
||||||
logger.info("Package {} has been deleted", filename);
|
logger.info("Package {} has been deleted", filename);
|
||||||
}
|
}
|
||||||
@@ -198,7 +203,6 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
|||||||
@Override
|
@Override
|
||||||
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
|
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
|
||||||
public long countResults(String name, String version, String arch) {
|
public long countResults(String name, String version, String arch) {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
return QueryEngine.countResults(em, name, version, arch);
|
return QueryEngine.countResults(em, name, version, arch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +215,6 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
|||||||
String fileName,
|
String fileName,
|
||||||
int pageNumber,
|
int pageNumber,
|
||||||
int pageSize) {
|
int pageSize) {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
return Queries.searchPackage(em, name, version, arch, compressionFormat, fileName)
|
return Queries.searchPackage(em, name, version, arch, compressionFormat, fileName)
|
||||||
.setMaxResults(pageSize)
|
.setMaxResults(pageSize)
|
||||||
.setFirstResult(pageNumber * pageSize)
|
.setFirstResult(pageNumber * pageSize)
|
||||||
@@ -220,31 +223,26 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> searchName(@Nonnull String name) {
|
public List<String> searchName(@Nonnull String name) {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
return Queries.searchPackageName(em, name).getResultList();
|
return Queries.searchPackageName(em, name).getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PkgData> searchByFileName(@Nonnull String fileName) {
|
public List<PkgData> searchByFileName(@Nonnull String fileName) {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
return Queries.searchPackagesByFileName(em, fileName).getResultList();
|
return Queries.searchPackagesByFileName(em, fileName).getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PkgData> searchByHash(@Nonnull String hash) {
|
public List<PkgData> searchByHash(@Nonnull String hash) {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
return Queries.searchPackagesByHash(em, hash).getResultList();
|
return Queries.searchPackagesByHash(em, hash).getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> listFiles() {
|
public List<String> listFiles() {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
return Queries.listFiles(em).getResultList();
|
return Queries.listFiles(em).getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> listHashes() {
|
public List<String> listHashes() {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
return Queries.listHashes(em).getResultList();
|
return Queries.listHashes(em).getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +250,6 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
|||||||
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
|
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
|
||||||
public List<PkgId> searchPkgId(
|
public List<PkgId> searchPkgId(
|
||||||
String name, String version, String arch, CompressionFormat compressionFormat) {
|
String name, String version, String arch, CompressionFormat compressionFormat) {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
return Queries.searchPackages(em, name, version, arch, compressionFormat).getResultList();
|
return Queries.searchPackages(em, name, version, arch, compressionFormat).getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +263,6 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> missingFiles(Collection<String> fileNames) {
|
public Set<String> missingFiles(Collection<String> fileNames) {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
Stream<String> result = fileNames.stream();
|
Stream<String> result = fileNames.stream();
|
||||||
Set<String> existing = Queries.getExistingFiles(em, fileNames)
|
Set<String> existing = Queries.getExistingFiles(em, fileNames)
|
||||||
.getResultStream().collect(CollectionUtils.toUnmodifiableTreeSet());
|
.getResultStream().collect(CollectionUtils.toUnmodifiableTreeSet());
|
||||||
@@ -274,8 +270,12 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
|||||||
.collect(CollectionUtils.toUnmodifiableTreeSet());
|
.collect(CollectionUtils.toUnmodifiableTreeSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public NavigableMap<PkgId, PkgTuple> getPkgMap() {
|
public NavigableMap<PkgId, PkgTuple> getPkgMap() {
|
||||||
EntityManager em = emf.createEntityManager();
|
return packageCache.getCachedMap(this::computePackageMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NavigableMap<PkgId, PkgTuple> computePackageMap() {
|
||||||
return Queries.getPkgMap(em).getResultStream().map(tuple -> {
|
return Queries.getPkgMap(em).getResultStream().map(tuple -> {
|
||||||
PkgId pkgId = tuple.get(0, PkgId.class);
|
PkgId pkgId = tuple.get(0, PkgId.class);
|
||||||
String filename = tuple.get(1, String.class);
|
String filename = tuple.get(1, String.class);
|
||||||
@@ -298,7 +298,33 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public PkgData getPackage(PkgId pkgId) {
|
public PkgData getPackage(PkgId pkgId) {
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
return em.find(PkgData.class, pkgId);
|
return em.find(PkgData.class, pkgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public boolean addPackage(String fileName, InputStream input) {
|
||||||
|
java.nio.file.Path file = Files.createTempFile(ctx.getRepoFolder(), fileName, null);
|
||||||
|
List<PkgData> savedFiles = searchByFileName(fileName);
|
||||||
|
if (savedFiles.size() > 0) return false;
|
||||||
|
else {
|
||||||
|
try(OutputStream output = Files.newOutputStream(file)) {
|
||||||
|
JWO.copy(input, output, 0x10000);
|
||||||
|
PkgData pkg = PkgDataImpl.parseFile(file,
|
||||||
|
CompressionFormatImpl.guess(Paths.get(fileName)));
|
||||||
|
pkg.setFileName(fileName);
|
||||||
|
Optional.ofNullable(em.find(PkgData.class, pkg.getId())).ifPresent((Con<PkgData>) (pkgData -> {
|
||||||
|
em.remove(pkgData);
|
||||||
|
Files.delete(ctx.getRepoFolder().resolve(pkgData.getFileName()));
|
||||||
|
}));
|
||||||
|
logger.info("Persisting package {}", pkg.getFileName());
|
||||||
|
em.persist(pkg);
|
||||||
|
Files.move(file, ctx.getRepoFolder().resolve(fileName), StandardCopyOption.ATOMIC_MOVE);
|
||||||
|
packageCache.invalidateCache();
|
||||||
|
return true;
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Files.delete(file);
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -78,9 +78,6 @@ import java.util.stream.Collectors;
|
|||||||
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
||||||
@TransactionManagement(TransactionManagementType.CONTAINER)
|
@TransactionManagement(TransactionManagementType.CONTAINER)
|
||||||
public class PacmanWebService {
|
public class PacmanWebService {
|
||||||
|
|
||||||
private NavigableMap<PkgId, PkgTuple> cachedMap;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private EntityManagerFactory emf;
|
private EntityManagerFactory emf;
|
||||||
|
|
||||||
@@ -93,24 +90,6 @@ public class PacmanWebService {
|
|||||||
@Inject
|
@Inject
|
||||||
private AppConfig ctx;
|
private AppConfig ctx;
|
||||||
|
|
||||||
private NavigableMap<PkgId, PkgTuple> getCachedMap() {
|
|
||||||
NavigableMap<PkgId, PkgTuple> result = null;
|
|
||||||
if (!ctx.getInvalidateCache().get()) {
|
|
||||||
result = cachedMap;
|
|
||||||
}
|
|
||||||
if (result == null) {
|
|
||||||
synchronized(this) {
|
|
||||||
result = cachedMap;
|
|
||||||
if (result == null) {
|
|
||||||
cachedMap = service.getPkgMap();
|
|
||||||
ctx.getInvalidateCache().set(false);
|
|
||||||
result = cachedMap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response manageQueryResult(List<PkgData> list) {
|
private Response manageQueryResult(List<PkgData> list) {
|
||||||
return manageQueryResult(list, false);
|
return manageQueryResult(list, false);
|
||||||
}
|
}
|
||||||
@@ -163,6 +142,7 @@ public class PacmanWebService {
|
|||||||
EntityTag etag = new EntityTag(Integer.toString(cachedMap.hashCode()), false);
|
EntityTag etag = new EntityTag(Integer.toString(cachedMap.hashCode()), false);
|
||||||
Response.ResponseBuilder builder = request.evaluatePreconditions(etag);
|
Response.ResponseBuilder builder = request.evaluatePreconditions(etag);
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
|
|
||||||
TreeMap<String, TreeMap<String, Map<String, NavigableSet<PkgTuple>>>> result = cachedMap.entrySet().stream().collect(
|
TreeMap<String, TreeMap<String, Map<String, NavigableSet<PkgTuple>>>> result = cachedMap.entrySet().stream().collect(
|
||||||
Collectors.groupingBy((Map.Entry<PkgId, PkgTuple> entry) -> entry.getKey().getArch(),
|
Collectors.groupingBy((Map.Entry<PkgId, PkgTuple> entry) -> entry.getKey().getArch(),
|
||||||
TreeMap::new,
|
TreeMap::new,
|
||||||
@@ -221,7 +201,8 @@ public class PacmanWebService {
|
|||||||
cc.setMaxAge(86400);
|
cc.setMaxAge(86400);
|
||||||
cc.setMustRevalidate(true);
|
cc.setMustRevalidate(true);
|
||||||
cc.setNoCache(true);
|
cc.setNoCache(true);
|
||||||
EntityTag etag = new EntityTag(Integer.toString(getCachedMap().hashCode()));
|
NavigableMap<PkgId, PkgTuple> cachedMap = service.getPkgMap();
|
||||||
|
EntityTag etag = new EntityTag(Integer.toString(cachedMap.hashCode()));
|
||||||
Response.ResponseBuilder builder = request.evaluatePreconditions(etag);
|
Response.ResponseBuilder builder = request.evaluatePreconditions(etag);
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
Long size = service.getFileSize(fileName);
|
Long size = service.getFileSize(fileName);
|
||||||
@@ -277,31 +258,13 @@ public class PacmanWebService {
|
|||||||
@Context UriInfo uriInfo) {
|
@Context UriInfo uriInfo) {
|
||||||
EntityManager em = emf.createEntityManager();
|
EntityManager em = emf.createEntityManager();
|
||||||
if (filename == null) throw new BadRequestException();
|
if (filename == null) throw new BadRequestException();
|
||||||
java.nio.file.Path file = Files.createTempFile(ctx.getRepoFolder(), filename, null);
|
|
||||||
List<PkgData> savedFiles = service.searchByFileName(filename);
|
|
||||||
Response result;
|
Response result;
|
||||||
if (savedFiles.size() > 0) result = Response.notModified().build();
|
boolean added = service.addPackage(filename, input);
|
||||||
else {
|
if(!added) {
|
||||||
try(OutputStream output = Files.newOutputStream(file)) {
|
result = Response.notModified().build();
|
||||||
JWO.copy(input, output, 0x10000);
|
} else {
|
||||||
PkgData pkg = PkgDataImpl.parseFile(file,
|
URI pkgUri = uriInfo.getAbsolutePathBuilder().path(filename).build();
|
||||||
CompressionFormatImpl.guess(Paths.get(filename)));
|
result = Response.created(pkgUri).build();
|
||||||
pkg.setFileName(filename);
|
|
||||||
Optional.ofNullable(em.find(PkgData.class, pkg.getId())).ifPresent((Con<PkgData>) (pkgData -> {
|
|
||||||
em.remove(pkgData);
|
|
||||||
Files.delete(ctx.getRepoFolder().resolve(pkgData.getFileName()));
|
|
||||||
}));
|
|
||||||
log.info("Persisting package {}", pkg.getFileName());
|
|
||||||
em.persist(pkg);
|
|
||||||
URI pkgUri = uriInfo.getAbsolutePathBuilder().path(pkg.getFileName()).build();
|
|
||||||
Files.move(file, ctx.getRepoFolder().resolve(filename), StandardCopyOption.ATOMIC_MOVE);
|
|
||||||
ctx.getInvalidateCache().set(true);
|
|
||||||
cachedMap = null;
|
|
||||||
result = Response.created(pkgUri).build();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
Files.delete(file);
|
|
||||||
throw t;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user