added HTTP cache and package size
This commit is contained in:
@@ -8,12 +8,13 @@ import com.oggio88.jpacrepo.model.PkgList;
|
||||
import com.oggio88.jpacrepo.model.PkgName;
|
||||
import com.oggio88.jpacrepo.model.StringList;
|
||||
import com.oggio88.jpacrepo.pacbase.Parser;
|
||||
import com.oggio88.jpacrepo.persistence.QueryEngine;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.ejb.*;
|
||||
import javax.ejb.Singleton;
|
||||
import javax.ejb.TransactionManagement;
|
||||
import javax.ejb.TransactionManagementType;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.*;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
@@ -24,6 +25,7 @@ import javax.transaction.Status;
|
||||
import javax.transaction.UserTransaction;
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.*;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
@@ -33,6 +35,14 @@ import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@XmlRootElement
|
||||
class PkgTuple
|
||||
{
|
||||
String md5sum;
|
||||
public String filename;
|
||||
public long size;
|
||||
}
|
||||
|
||||
@CORSManaged
|
||||
@Singleton
|
||||
@Path("/pkg")
|
||||
@@ -41,7 +51,7 @@ import java.util.logging.Logger;
|
||||
@TransactionManagement(TransactionManagementType.BEAN)
|
||||
public class PacmanWebService
|
||||
{
|
||||
private SortedMap<String, SortedMap<String, SortedMap<String, String>>> cachedMap = null;
|
||||
private SortedMap<String, SortedMap<String, SortedMap<String, PkgTuple>>> cachedMap = null;
|
||||
|
||||
@PersistenceContext(unitName = "jpacrepo_pu")
|
||||
private EntityManager em;
|
||||
@@ -63,6 +73,42 @@ public class PacmanWebService
|
||||
@DefaultConfiguration
|
||||
private ApplicationContext ctx;
|
||||
|
||||
|
||||
private SortedMap<String, SortedMap<String, SortedMap<String, PkgTuple>>> getCachedMap()
|
||||
{
|
||||
SortedMap<String, SortedMap<String, SortedMap<String, PkgTuple>>> result;
|
||||
if (ctx.invalidateCache)
|
||||
{
|
||||
result = new TreeMap<>();
|
||||
TypedQuery<Object[]> query = em.createQuery("SELECT pkg.name.id, pkg.version, pkg.arch, pkg.fileName, pkg.size, pkg.md5sum FROM PkgData pkg", Object[].class);
|
||||
for (Object[] pkg : query.getResultList())
|
||||
{
|
||||
String name = (String) pkg[0];
|
||||
String version = (String) pkg[1];
|
||||
String arch = (String) pkg[2];
|
||||
String filename = (String) pkg[3];
|
||||
long size = (long) pkg[4];
|
||||
String md5sum = (String) pkg[5];
|
||||
result.putIfAbsent(name, new TreeMap<>());
|
||||
SortedMap<String, SortedMap<String, PkgTuple>> map = result.get(name);
|
||||
map.putIfAbsent(version, new TreeMap<>());
|
||||
SortedMap<String, PkgTuple> map2 = map.get(version);
|
||||
|
||||
PkgTuple tuple = new PkgTuple();
|
||||
tuple.filename = filename;
|
||||
tuple.size = size;
|
||||
tuple.md5sum = md5sum;
|
||||
map2.putIfAbsent(arch, tuple);
|
||||
}
|
||||
cachedMap = result;
|
||||
ctx.invalidateCache = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = cachedMap;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@GET
|
||||
@Path("searchByName/{name}")
|
||||
public Response searchByName(@PathParam("name") String name)
|
||||
@@ -116,33 +162,22 @@ public class PacmanWebService
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("map")
|
||||
public Response getPackageMap()
|
||||
public Response getPackageMap(@Context Request request)
|
||||
{
|
||||
SortedMap<String, SortedMap<String, SortedMap<String, String>>> result;
|
||||
if (ctx.invalidateCache)
|
||||
CacheControl cc = new CacheControl();
|
||||
cc.setMaxAge(86400);
|
||||
cc.setMustRevalidate(true);
|
||||
cc.setNoCache(true);
|
||||
SortedMap<String, SortedMap<String, SortedMap<String, PkgTuple>>> result = getCachedMap();
|
||||
EntityTag etag = new EntityTag(Integer.toString(result.hashCode()));
|
||||
Response.ResponseBuilder builder = request.evaluatePreconditions(etag);
|
||||
if (builder == null)
|
||||
{
|
||||
result = new TreeMap<>();
|
||||
TypedQuery<Object[]> query = em.createQuery("SELECT pkg.name.id, pkg.version, pkg.arch, pkg.fileName FROM PkgData pkg", Object[].class);
|
||||
for (Object[] pkg : query.getResultList())
|
||||
{
|
||||
String name = (String) pkg[0];
|
||||
String version = (String) pkg[1];
|
||||
String arch = (String) pkg[2];
|
||||
String filename = (String) pkg[3];
|
||||
result.putIfAbsent(name, new TreeMap<>());
|
||||
SortedMap<String, SortedMap<String, String>> map = result.get(name);
|
||||
map.putIfAbsent(version, new TreeMap<>());
|
||||
SortedMap<String, String> map2 = map.get(version);
|
||||
map2.putIfAbsent(arch, filename);
|
||||
}
|
||||
cachedMap = result;
|
||||
ctx.invalidateCache = false;
|
||||
builder = Response.ok(result);
|
||||
builder.tag(etag);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = cachedMap;
|
||||
}
|
||||
return Response.ok(result).build();
|
||||
builder.cacheControl(cc);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@@ -179,6 +214,27 @@ public class PacmanWebService
|
||||
return manageQueryResult(fnquery.getResultList(), true);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("filesize/{filename}")
|
||||
public Response getFileSize(@PathParam("filename") String fileName, @Context Request request)
|
||||
{
|
||||
CacheControl cc = new CacheControl();
|
||||
cc.setMaxAge(86400);
|
||||
cc.setMustRevalidate(true);
|
||||
cc.setNoCache(true);
|
||||
EntityTag etag = new EntityTag(Integer.toString(getCachedMap().hashCode()));
|
||||
Response.ResponseBuilder builder = request.evaluatePreconditions(etag);
|
||||
if (builder == null)
|
||||
{
|
||||
File res = ctx.getFile(fileName);
|
||||
if (!res.exists()) throw new NotFoundException(String.format("File '%s' was not found", fileName));
|
||||
builder = Response.ok(res.length());
|
||||
builder.tag(etag);
|
||||
}
|
||||
builder.cacheControl(cc);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("download/{filename}")
|
||||
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||
@@ -356,7 +412,8 @@ public class PacmanWebService
|
||||
@OPTIONS
|
||||
@Path("/downloadTar")
|
||||
@Produces("text/plain; charset=UTF-8")
|
||||
public Response options() {
|
||||
public Response options()
|
||||
{
|
||||
return Response.ok("POST, OPTIONS").build();
|
||||
}
|
||||
|
||||
@@ -367,9 +424,10 @@ public class PacmanWebService
|
||||
public Response downloadTar(@FormParam("pkgs") String formData)
|
||||
{
|
||||
String[] files = formData.split(" ");
|
||||
for(String fname : files)
|
||||
for (String fname : files)
|
||||
{
|
||||
if(!ctx.getFile(fname).exists()) throw new NotFoundException(String.format("Package file '%s' does not exist", fname));
|
||||
if (!ctx.getFile(fname).exists())
|
||||
throw new NotFoundException(String.format("Package file '%s' does not exist", fname));
|
||||
}
|
||||
StreamingOutput stream = new StreamingOutput()
|
||||
{
|
||||
|
Reference in New Issue
Block a user