added client and server REST support
This commit is contained in:
32
build.gradle
32
build.gradle
@@ -1,14 +1,24 @@
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'war'
|
||||
|
||||
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
version = '1.0'
|
||||
|
||||
logging.captureStandardOutput LogLevel.INFO
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
test {
|
||||
testLogging {
|
||||
exceptionFormat = 'full'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile group: 'junit', name: 'junit', version: '4.11'
|
||||
compile 'org.apache.commons:commons-compress:1.9'
|
||||
@@ -16,8 +26,30 @@ dependencies {
|
||||
compile 'javax:javaee-api:7.0'
|
||||
compile 'commons-io:commons-io:2.4'
|
||||
testCompile 'com.thoughtworks.xstream:xstream:1.4.8'
|
||||
testCompile 'org.jboss.resteasy:resteasy-jaxrs:3.0.11.Final'
|
||||
testCompile 'org.jboss.resteasy:resteasy-client:3.0.11.Final'
|
||||
testCompile 'org.jboss.resteasy:resteasy-jackson-provider:3.0.11.Final'
|
||||
testCompile 'org.jboss.resteasy:resteasy-jaxb-provider:3.0.11.Final'
|
||||
|
||||
testCompile files('/opt/wildfly/bin/client/jboss-client.jar')
|
||||
|
||||
}
|
||||
|
||||
task deployWildfly(dependsOn: 'war') << {
|
||||
'/opt/wildfly/bin/jboss-cli.sh --connect --user=admin --password=qwerty --command="deploy build/libs/jpacrepo-1.0.war --force"'.execute().waitFor()
|
||||
}
|
||||
|
||||
// client.jar
|
||||
task clientJar(type: Jar) {
|
||||
from(sourceSets.main.output) {
|
||||
archiveName project.name + "-client.jar"
|
||||
include "model/**"
|
||||
include "pacbase/**"
|
||||
}
|
||||
}
|
||||
|
||||
// server.jar
|
||||
task serverJar(type: Jar) {
|
||||
from(sourceSets.main.output) {
|
||||
}
|
||||
}
|
26
jpacrepo.iml
26
jpacrepo.iml
@@ -25,5 +25,31 @@
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: xmlpull:xmlpull:1.1.3.1" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: xpp3:xpp3_min:1.1.4c" level="project" />
|
||||
<orderEntry type="library" exported="" name="Gradle: commons-io:commons-io:2.4" level="project" />
|
||||
<orderEntry type="module-library" scope="TEST">
|
||||
<library name="Gradle: jboss-client">
|
||||
<CLASSES>
|
||||
<root url="jar:///opt/wildfly/bin/client/jboss-client.jar!/" />
|
||||
<root url="jar:///opt/wildfly/bin/client/jboss-client.jar!/" />
|
||||
<root url="jar:///opt/wildfly/bin/client/jboss-client.jar!/" />
|
||||
<root url="jar:///opt/wildfly/bin/client/jboss-client.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: org.jboss.resteasy:resteasy-jaxrs:3.0.11.Final" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: org.jboss.resteasy:resteasy-client:3.0.11.Final" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: org.jboss.resteasy:resteasy-jackson-provider:3.0.11.Final" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: org.jboss.resteasy:jaxrs-api:3.0.11.Final" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: org.jboss.spec.javax.annotation:jboss-annotations-api_1.1_spec:1.0.1.Final" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: org.apache.httpcomponents:httpclient:4.2.6" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: net.jcip:jcip-annotations:1.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: org.codehaus.jackson:jackson-core-asl:1.9.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: org.codehaus.jackson:jackson-mapper-asl:1.9.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: org.codehaus.jackson:jackson-jaxrs:1.9.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: org.codehaus.jackson:jackson-xc:1.9.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: org.apache.httpcomponents:httpcore:4.2.5" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: commons-logging:commons-logging:1.1.1" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Gradle: commons-codec:commons-codec:1.6" level="project" />
|
||||
</component>
|
||||
</module>
|
17
src/main/java/client/MainClient.java
Normal file
17
src/main/java/client/MainClient.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package client;
|
||||
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
|
||||
/**
|
||||
* Created by walter on 29/03/15.
|
||||
*/
|
||||
public class MainClient
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Client client = ClientBuilder.newClient();
|
||||
WebTarget target = client.target("http://www.myserver.com/book");
|
||||
}
|
||||
}
|
48
src/main/java/model/PkgList.java
Normal file
48
src/main/java/model/PkgList.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package model;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by walter on 29/03/15.
|
||||
*/
|
||||
|
||||
@XmlRootElement
|
||||
@XmlSeeAlso(PkgData.class)
|
||||
public class PkgList extends ArrayList<PkgData>
|
||||
{
|
||||
|
||||
// ======================================
|
||||
// = Constructors =
|
||||
// ======================================
|
||||
|
||||
public PkgList()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public PkgList(Collection<? extends PkgData> c)
|
||||
{
|
||||
super(c);
|
||||
}
|
||||
|
||||
// ======================================
|
||||
// = Getters & Setters =
|
||||
// ======================================
|
||||
|
||||
@XmlElement(name = "PkgData")
|
||||
public List<PkgData> getPackages()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setPackages(List<PkgData> pkgs)
|
||||
{
|
||||
this.clear();
|
||||
this.addAll(pkgs);
|
||||
}
|
||||
}
|
55
src/main/java/persistence/QueryEngine.java
Normal file
55
src/main/java/persistence/QueryEngine.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package persistence;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by walter on 29/03/15.
|
||||
*/
|
||||
public class QueryEngine
|
||||
{
|
||||
private String entityName;
|
||||
private String query;
|
||||
private List<String> where;
|
||||
|
||||
public QueryEngine(Class<?> cls)
|
||||
{
|
||||
query = String.format("SELECT e FROM %s e", cls.getSimpleName());
|
||||
this.entityName = cls.getSimpleName();
|
||||
where = new ArrayList<>();
|
||||
}
|
||||
|
||||
public QueryEngine(String entityName)
|
||||
{
|
||||
query = String.format("SELECT e FROM %s e", entityName);
|
||||
where = new ArrayList<>();
|
||||
}
|
||||
|
||||
public QueryEngine select(String... fields)
|
||||
{
|
||||
String[] strarr = new String[fields.length];
|
||||
for(int i=0; i<fields.length; i++)
|
||||
{
|
||||
strarr[i] = "e." + fields[i];
|
||||
}
|
||||
query = "SELECT " + String.join(",", strarr) + " FROM " + entityName + " e";
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryEngine select()
|
||||
{
|
||||
query = String.format("SELECT e FROM %s e", entityName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryEngine where(String field, String operator, String value)
|
||||
{
|
||||
where.add(String.format("e.%s %s '%s'", field, operator, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public String build()
|
||||
{
|
||||
return query + " WHERE " + String.join(" AND ", where);
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@ import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@ApplicationPath("rs")
|
||||
@ApplicationPath("rest")
|
||||
public class ApplicationConfig extends Application
|
||||
{
|
||||
|
||||
@@ -20,10 +20,10 @@ public class ApplicationConfig extends Application
|
||||
// = Constructors =
|
||||
// ======================================
|
||||
|
||||
public ApplicationConfig() {
|
||||
public ApplicationConfig()
|
||||
{
|
||||
HashSet<Class<?>> c = new HashSet<>();
|
||||
c.add(PacmanService.class);
|
||||
|
||||
c.add(PacmanWebService.class);
|
||||
classes = Collections.unmodifiableSet(c);
|
||||
}
|
||||
|
||||
|
51
src/main/java/service/ApplicationContext.java
Normal file
51
src/main/java/service/ApplicationContext.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package service;
|
||||
|
||||
import javax.enterprise.context.ApplicationScoped;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Created by walter on 29/03/15.
|
||||
*/
|
||||
|
||||
@ApplicationScoped
|
||||
public class ApplicationContext
|
||||
{
|
||||
private Properties systemProperties;
|
||||
|
||||
public ApplicationContext()
|
||||
{
|
||||
systemProperties = new Properties();
|
||||
InputStream input = null;
|
||||
|
||||
try
|
||||
{
|
||||
input = new FileInputStream("/etc/jpacrepo/config.properties");
|
||||
// load a properties file
|
||||
systemProperties.load(input);
|
||||
// get the property value and print it out
|
||||
} catch (IOException ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
} finally
|
||||
{
|
||||
if (input != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
input.close();
|
||||
} catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Properties getSystemProperties()
|
||||
{
|
||||
return systemProperties;
|
||||
}
|
||||
}
|
@@ -1,273 +1,14 @@
|
||||
package service;
|
||||
|
||||
import model.PkgData;
|
||||
import model.PkgName;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.filefilter.DirectoryFileFilter;
|
||||
import org.apache.commons.io.filefilter.RegexFileFilter;
|
||||
import pacbase.Parser;
|
||||
import javax.ejb.Remote;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.ejb.Singleton;
|
||||
import javax.ejb.Startup;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
/**
|
||||
* Created by walter on 28/03/15.
|
||||
*/
|
||||
|
||||
@Startup
|
||||
@Path("/pkg")
|
||||
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
||||
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
||||
@Singleton
|
||||
public class PacmanService
|
||||
@Remote
|
||||
public interface PacmanService
|
||||
{
|
||||
private Properties prop;
|
||||
|
||||
@PersistenceContext(unitName = "jpacrepo_pu")
|
||||
private EntityManager em;
|
||||
|
||||
|
||||
@Context
|
||||
private UriInfo uriInfo;
|
||||
|
||||
private Logger log = Logger.getLogger(PacmanService.class.getName());
|
||||
|
||||
|
||||
private String nameQuery = "SELECT pname FROM PkgName pname WHERE id = :name";
|
||||
private String fileQuery = "SELECT pdata FROM PkgData pdata WHERE name.id = :name AND version = :version AND arch = :arch";
|
||||
private String fileNameQuery = "SELECT pdata FROM PkgData pdata WHERE fileName = :fileName";
|
||||
private String hashQuery = "SELECT pdata FROM PkgData pdata WHERE md5sum = :md5sum";
|
||||
private String idQuery = "SELECT pdata FROM PkgData pdata WHERE id = :id";
|
||||
|
||||
@PostConstruct
|
||||
public void syncDB()
|
||||
{
|
||||
loadProperties();
|
||||
|
||||
//Elimina i pacchetti sul DB che non esistono più nel filesystem
|
||||
List<PkgData> listaDB = em.createQuery("SELECT p FROM PkgData p", PkgData.class).getResultList();
|
||||
for (PkgData p : listaDB)
|
||||
{
|
||||
File file = new File(p.filePath);
|
||||
if (!file.exists())
|
||||
{
|
||||
log.log(Level.INFO, String.format("Removing package %s", file.getName()));
|
||||
em.remove(p);
|
||||
}
|
||||
}
|
||||
|
||||
//Aggiunge sul DB i pacchetti presenti nel filesystem
|
||||
Collection<File> ls = FileUtils.listFiles(new File(prop.getProperty("RepoFolder")), new RegexFileFilter(".*\\.pkg\\.tar\\.xz"), DirectoryFileFilter.DIRECTORY);
|
||||
int i = 0;
|
||||
|
||||
TypedQuery<PkgData> fquery = em.createQuery(fileQuery, PkgData.class);
|
||||
TypedQuery<PkgName> nquery = em.createQuery(nameQuery, PkgName.class);
|
||||
|
||||
for (File file : ls)
|
||||
{
|
||||
try
|
||||
{
|
||||
PkgData data = Parser.parseFile(file);
|
||||
|
||||
fquery.setParameter("name", data.name.id);
|
||||
fquery.setParameter("version", data.version);
|
||||
fquery.setParameter("arch", data.arch);
|
||||
|
||||
List<PkgData> savedFiles = fquery.getResultList();
|
||||
|
||||
if (savedFiles.size() > 0) continue;
|
||||
|
||||
nquery.setParameter("name", data.name.id);
|
||||
List<PkgName> savedName = nquery.getResultList();
|
||||
if (savedName.size() > 0)
|
||||
{
|
||||
data.name = savedName.get(0);
|
||||
}
|
||||
em.persist(data);
|
||||
log.log(Level.INFO, String.format("Persisting package %s", file.getName()));
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void loadProperties()
|
||||
{
|
||||
prop = new Properties();
|
||||
InputStream input = null;
|
||||
|
||||
try
|
||||
{
|
||||
input = new FileInputStream("/etc/jpacrepo/config.properties");
|
||||
// load a properties file
|
||||
prop.load(input);
|
||||
// get the property value and print it out
|
||||
} catch (IOException ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
} finally
|
||||
{
|
||||
if (input != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
input.close();
|
||||
} catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON : curl -X GET -H "Accept: application/json" http://localhost:8080/chapter15-service-1.0/rs/book/1 -v
|
||||
* XML : curl -X GET -H "Accept: application/xml" http://localhost:8080/chapter15-service-1.0/rs/book/1 -v
|
||||
*/
|
||||
@GET
|
||||
@Path("search")
|
||||
public Response getPackage(@QueryParam("name") String name, @QueryParam("version") String version, @QueryParam("arch") String arch)
|
||||
{
|
||||
TypedQuery<PkgData> fquery = em.createQuery(fileQuery, PkgData.class);
|
||||
if(name != null) fquery.setParameter("name", name);
|
||||
if(version != null) fquery.setParameter("version", version);
|
||||
if(arch != null) fquery.setParameter("arch", arch);
|
||||
|
||||
PkgData pkg = fquery.getSingleResult();
|
||||
if (pkg == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
return Response.ok(pkg).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("searchHash")
|
||||
public Response getPackageByHash(@QueryParam("md5") String md5sum)
|
||||
{
|
||||
TypedQuery<PkgData> hquery = em.createQuery(hashQuery, PkgData.class);
|
||||
if(md5sum != null) hquery.setParameter("md5sum", md5sum);
|
||||
|
||||
PkgData pkg = hquery.getSingleResult();
|
||||
if (pkg == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
return Response.ok(pkg).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("searchFilename")
|
||||
public Response getPackageByFileName(@QueryParam("file") String file)
|
||||
{
|
||||
TypedQuery<PkgData> fnquery = em.createQuery(fileNameQuery, PkgData.class);
|
||||
fnquery.setParameter("fileName", file);
|
||||
PkgData pkg = fnquery.getSingleResult();
|
||||
if (pkg == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
return Response.ok(pkg).build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/pkg/upload")
|
||||
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
|
||||
public Response createPackage(byte[] input, @MatrixParam("filename") String filename) throws Exception
|
||||
{
|
||||
if (filename == null)
|
||||
throw new BadRequestException();
|
||||
|
||||
String hash = Parser.computeMD5(new ByteArrayInputStream(input));
|
||||
TypedQuery<PkgData> hquery = em.createQuery(hashQuery, PkgData.class);
|
||||
hquery.setParameter("md5sum", hash);
|
||||
|
||||
List<PkgData> savedFiles = hquery.getResultList();
|
||||
|
||||
if (savedFiles.size() > 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
File file = new File(prop.getProperty("RepoFolder"), filename);
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
fos.write(input);
|
||||
fos.close();
|
||||
PkgData pkg = Parser.parseFile(file);
|
||||
em.persist(pkg);
|
||||
URI pkgUri = uriInfo.getAbsolutePathBuilder().path(pkg.filePath).build();
|
||||
return Response.created(pkgUri).build();
|
||||
}
|
||||
}
|
||||
public void syncDB();
|
||||
|
||||
}
|
||||
|
||||
// ======================================
|
||||
// = Public Methods =
|
||||
// ======================================
|
||||
|
||||
/**
|
||||
* curl -X POST --data-binary "<book><description>Science fiction comedy book</description><illustrations>false</illustrations><isbn>1-84023-742-2</isbn><nbOfPage>354</nbOfPage><price>12.5</price><title>The Hitchhiker's Guide to the Galaxy</title></book>" -H "Content-Type: application/xml" http://localhost:8080/chapter15-service-1.0/rs/book -v
|
||||
* curl -X POST --data-binary "{\"description\":\"Science fiction comedy book\",\"illustrations\":false,\"isbn\":\"1-84023-742-2\",\"nbOfPage\":354,\"price\":12.5,\"title\":\"The Hitchhiker's Guide to the Galaxy\"}" -H "Content-Type: application/json" http://localhost:8080/chapter15-service-1.0/rs/book -v
|
||||
*/
|
||||
// @POST
|
||||
// public Response createBook(Book book) {
|
||||
// if (book == null)
|
||||
// throw new BadRequestException();
|
||||
//
|
||||
// em.persist(book);
|
||||
// URI bookUri = uriInfo.getAbsolutePathBuilder().path(book.getId()).build();
|
||||
// return Response.created(bookUri).build();
|
||||
// }
|
||||
|
||||
// @PUT
|
||||
// public Response updateBook(Book book) {
|
||||
// if (book == null)
|
||||
// throw new BadRequestException();
|
||||
//
|
||||
// em.merge(book);
|
||||
// return Response.ok().build();
|
||||
// }
|
||||
|
||||
/**
|
||||
* curl -X DELETE http://localhost:8080/chapter15-service-1.0/rs/book/1 -v
|
||||
*/
|
||||
// @DELETE
|
||||
// @Path("{id}")
|
||||
// public Response deleteBook(@PathParam("id") String id) {
|
||||
// Book book = em.find(Book.class, id);
|
||||
//
|
||||
// if (book == null)
|
||||
// throw new NotFoundException();
|
||||
//
|
||||
// em.remove(book);
|
||||
//
|
||||
// return Response.noContent().build();
|
||||
// }
|
||||
|
||||
/**
|
||||
* JSON : curl -X GET -H "Accept: application/json" http://localhost:8080/chapter15-service-1.0/rs/book -v
|
||||
* XML : curl -X GET -H "Accept: application/xml" http://localhost:8080/chapter15-service-1.0/rs/book -v
|
||||
*/
|
||||
// @GET
|
||||
// public Response getAllBooks() {
|
||||
// TypedQuery<Book> query = em.createNamedQuery(Book.FIND_ALL, Book.class);
|
||||
// Books books = new Books(query.getResultList());
|
||||
// return Response.ok(books).build();
|
||||
// }
|
128
src/main/java/service/PacmanServiceEJB.java
Normal file
128
src/main/java/service/PacmanServiceEJB.java
Normal file
@@ -0,0 +1,128 @@
|
||||
package service;
|
||||
|
||||
import model.PkgData;
|
||||
import model.PkgName;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.filefilter.DirectoryFileFilter;
|
||||
import org.apache.commons.io.filefilter.RegexFileFilter;
|
||||
import pacbase.Parser;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import javax.ejb.Singleton;
|
||||
import javax.ejb.Startup;
|
||||
import javax.ejb.TransactionManagement;
|
||||
import javax.ejb.TransactionManagementType;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.transaction.*;
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@Startup
|
||||
@Singleton
|
||||
@TransactionManagement(TransactionManagementType.BEAN)
|
||||
public class PacmanServiceEJB implements PacmanService
|
||||
{
|
||||
@PersistenceContext(unitName = "jpacrepo_pu")
|
||||
private EntityManager em;
|
||||
|
||||
@Inject
|
||||
private ApplicationContext ctx;
|
||||
|
||||
private Logger log = Logger.getLogger(PacmanServiceEJB.class.getName());
|
||||
|
||||
|
||||
private String nameQuery = "SELECT pname FROM PkgName pname WHERE id = :name";
|
||||
private String fileQuery = "SELECT pdata FROM PkgData pdata WHERE name.id = :name AND version = :version AND arch = :arch";
|
||||
private String fileNameQuery = "SELECT pdata FROM PkgData pdata WHERE fileName = :fileName";
|
||||
private String hashQuery = "SELECT pdata FROM PkgData pdata WHERE md5sum = :md5sum";
|
||||
private String idQuery = "SELECT pdata FROM PkgData pdata WHERE id = :id";
|
||||
|
||||
@PostConstruct
|
||||
public void syncDB()
|
||||
{
|
||||
Set<String> knownPkg = new HashSet<>();
|
||||
//Elimina i pacchetti sul DB che non esistono più nel filesystem
|
||||
List<PkgData> listaDB = em.createQuery("SELECT p FROM PkgData p", PkgData.class).getResultList();
|
||||
try
|
||||
{
|
||||
ut.setTransactionTimeout(1000);
|
||||
for (PkgData p : listaDB)
|
||||
{
|
||||
knownPkg.add(p.filePath);
|
||||
File file = new File(p.filePath);
|
||||
if (!file.exists())
|
||||
{
|
||||
ut.begin();
|
||||
log.log(Level.INFO, String.format("Removing package %s", file.getName()));
|
||||
em.remove(p);
|
||||
ut.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NotSupportedException | SystemException | HeuristicMixedException | RollbackException | HeuristicRollbackException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
//Aggiunge sul DB i pacchetti presenti nel filesystem
|
||||
Collection<File> ls = FileUtils.listFiles(new File(ctx.getSystemProperties().getProperty("RepoFolder")), new RegexFileFilter(".*\\.pkg\\.tar\\.xz"), DirectoryFileFilter.DIRECTORY);
|
||||
|
||||
for (File file : ls)
|
||||
{
|
||||
if(!knownPkg.contains(file.getAbsolutePath()))
|
||||
{
|
||||
try
|
||||
{
|
||||
ut.setTransactionTimeout(1000);
|
||||
ut.begin();
|
||||
parseFile(file);
|
||||
ut.commit();
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Resource
|
||||
private UserTransaction ut;
|
||||
|
||||
private void parseFile(File file) throws Exception
|
||||
{
|
||||
TypedQuery<PkgData> fquery = em.createQuery(fileQuery, PkgData.class);
|
||||
TypedQuery<PkgName> nquery = em.createQuery(nameQuery, PkgName.class);
|
||||
|
||||
PkgData data = Parser.parseFile(file);
|
||||
|
||||
fquery.setParameter("name", data.name.id);
|
||||
fquery.setParameter("version", data.version);
|
||||
fquery.setParameter("arch", data.arch);
|
||||
|
||||
List<PkgData> savedFiles = fquery.getResultList();
|
||||
|
||||
if (savedFiles.size() > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
nquery.setParameter("name", data.name.id);
|
||||
List<PkgName> savedName = nquery.getResultList();
|
||||
if (savedName.size() > 0)
|
||||
{
|
||||
data.name = savedName.get(0);
|
||||
}
|
||||
em.persist(data);
|
||||
log.log(Level.INFO, String.format("Persisting package %s", file.getName()));
|
||||
}
|
||||
|
||||
}
|
206
src/main/java/service/PacmanWebService.java
Normal file
206
src/main/java/service/PacmanWebService.java
Normal file
@@ -0,0 +1,206 @@
|
||||
package service;
|
||||
|
||||
import model.PkgData;
|
||||
import model.PkgList;
|
||||
import pacbase.Parser;
|
||||
import persistence.QueryEngine;
|
||||
|
||||
import javax.ejb.Singleton;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@Path("/pkg")
|
||||
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
||||
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
||||
@Singleton
|
||||
public class PacmanWebService
|
||||
{
|
||||
@PersistenceContext(unitName = "jpacrepo_pu")
|
||||
private EntityManager em;
|
||||
|
||||
|
||||
@Context
|
||||
private UriInfo uriInfo;
|
||||
|
||||
private Logger log = Logger.getLogger(PacmanWebService.class.getName());
|
||||
|
||||
|
||||
private String nameQuery = "SELECT pname FROM PkgName pname WHERE id = :name";
|
||||
private String fileQuery = "SELECT pdata FROM PkgData pdata";
|
||||
private String fileNameQuery = "SELECT pdata FROM PkgData pdata WHERE fileName = :fileName";
|
||||
private String hashQuery = "SELECT pdata FROM PkgData pdata WHERE md5sum = :md5sum";
|
||||
private String idQuery = "SELECT pdata FROM PkgData pdata WHERE id = :id";
|
||||
|
||||
@Inject
|
||||
private ApplicationContext ctx;
|
||||
|
||||
/**
|
||||
* JSON : curl -X GET -H "Accept: application/json" http://localhost:8080/chapter15-service-1.0/rs/book/1 -v
|
||||
* XML : curl -X GET -H "Accept: application/xml" http://localhost:8080/chapter15-service-1.0/rs/book/1 -v
|
||||
*/
|
||||
@GET
|
||||
@Path("search")
|
||||
public Response getPackage(@QueryParam("name") String name,
|
||||
@QueryParam("version") String version,
|
||||
@QueryParam("arch") String arch,
|
||||
@QueryParam("filename") String filename,
|
||||
@QueryParam("md5sum") String md5sum)
|
||||
{
|
||||
if(md5sum != null)
|
||||
{
|
||||
return getPackageByHash(md5sum);
|
||||
}
|
||||
else if(filename != null)
|
||||
{
|
||||
return getPackageByFileName(filename);
|
||||
}
|
||||
else if( name != null || arch != null || version != null)
|
||||
{
|
||||
QueryEngine qe = new QueryEngine(PkgData.class);
|
||||
qe.select();
|
||||
TypedQuery<PkgData> fquery = em.createQuery(fileQuery, PkgData.class);
|
||||
if (name != null) qe.where("name", "=", name);
|
||||
if (version != null) qe.where("version", "=", version);
|
||||
if (arch != null) qe.where("arch", "=", arch);
|
||||
String query = qe.build();
|
||||
// log.log(Level.INFO, query);
|
||||
return manageQueryResult(em.createQuery(query).getResultList());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
private Response getPackageByHash(String md5sum)
|
||||
{
|
||||
TypedQuery<PkgData> hquery = em.createQuery(hashQuery, PkgData.class);
|
||||
if(md5sum != null) hquery.setParameter("md5sum", md5sum);
|
||||
return manageQueryResult(hquery.getResultList());
|
||||
}
|
||||
|
||||
private Response getPackageByFileName(String file)
|
||||
{
|
||||
TypedQuery<PkgData> fnquery = em.createQuery(fileNameQuery, PkgData.class);
|
||||
fnquery.setParameter("fileName", file);
|
||||
return manageQueryResult(fnquery.getResultList());
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/pkg/upload")
|
||||
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
|
||||
public Response createPackage(byte[] input, @MatrixParam("filename") String filename) throws Exception
|
||||
{
|
||||
if (filename == null)
|
||||
throw new BadRequestException();
|
||||
|
||||
String hash = Parser.computeMD5(new ByteArrayInputStream(input));
|
||||
TypedQuery<PkgData> hquery = em.createQuery(hashQuery, PkgData.class);
|
||||
hquery.setParameter("md5sum", hash);
|
||||
|
||||
List<PkgData> savedFiles = hquery.getResultList();
|
||||
|
||||
if (savedFiles.size() > 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
File file = new File(ctx.getSystemProperties().getProperty("RepoFolder"), filename);
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
fos.write(input);
|
||||
fos.close();
|
||||
PkgData pkg = Parser.parseFile(file);
|
||||
em.persist(pkg);
|
||||
URI pkgUri = uriInfo.getAbsolutePathBuilder().path(pkg.filePath).build();
|
||||
return Response.created(pkgUri).build();
|
||||
}
|
||||
}
|
||||
|
||||
private Response manageQueryResult(List<PkgData> list)
|
||||
{
|
||||
// log.log(Level.INFO, "size: " + list.size());
|
||||
PkgList pkgList = new PkgList(list);
|
||||
if (pkgList.size() == 0)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
else if(pkgList.size()==1)
|
||||
{
|
||||
return Response.ok(pkgList.get(0)).build();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Response.ok(pkgList).build();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ======================================
|
||||
// = Public Methods =
|
||||
// ======================================
|
||||
|
||||
/**
|
||||
* curl -X POST --data-binary "<book><description>Science fiction comedy book</description><illustrations>false</illustrations><isbn>1-84023-742-2</isbn><nbOfPage>354</nbOfPage><price>12.5</price><title>The Hitchhiker's Guide to the Galaxy</title></book>" -H "Content-Type: application/xml" http://localhost:8080/chapter15-service-1.0/rs/book -v
|
||||
* curl -X POST --data-binary "{\"description\":\"Science fiction comedy book\",\"illustrations\":false,\"isbn\":\"1-84023-742-2\",\"nbOfPage\":354,\"price\":12.5,\"title\":\"The Hitchhiker's Guide to the Galaxy\"}" -H "Content-Type: application/json" http://localhost:8080/chapter15-service-1.0/rs/book -v
|
||||
*/
|
||||
// @POST
|
||||
// public Response createBook(Book book) {
|
||||
// if (book == null)
|
||||
// throw new BadRequestException();
|
||||
//
|
||||
// em.persist(book);
|
||||
// URI bookUri = uriInfo.getAbsolutePathBuilder().path(book.getId()).build();
|
||||
// return Response.created(bookUri).build();
|
||||
// }
|
||||
|
||||
// @PUT
|
||||
// public Response updateBook(Book book) {
|
||||
// if (book == null)
|
||||
// throw new BadRequestException();
|
||||
//
|
||||
// em.merge(book);
|
||||
// return Response.ok().build();
|
||||
// }
|
||||
|
||||
/**
|
||||
* curl -X DELETE http://localhost:8080/chapter15-service-1.0/rs/book/1 -v
|
||||
*/
|
||||
// @DELETE
|
||||
// @Path("{id}")
|
||||
// public Response deleteBook(@PathParam("id") String id) {
|
||||
// Book book = em.find(Book.class, id);
|
||||
//
|
||||
// if (book == null)
|
||||
// throw new NotFoundException();
|
||||
//
|
||||
// em.remove(book);
|
||||
//
|
||||
// return Response.noContent().build();
|
||||
// }
|
||||
|
||||
/**
|
||||
* JSON : curl -X GET -H "Accept: application/json" http://localhost:8080/chapter15-service-1.0/rs/book -v
|
||||
* XML : curl -X GET -H "Accept: application/xml" http://localhost:8080/chapter15-service-1.0/rs/book -v
|
||||
*/
|
||||
// @GET
|
||||
// public Response getAllBooks() {
|
||||
// TypedQuery<Book> query = em.createNamedQuery(Book.FIND_ALL, Book.class);
|
||||
// Books books = new Books(query.getResultList());
|
||||
// return Response.ok(books).build();
|
||||
// }
|
@@ -8,8 +8,8 @@
|
||||
<jta-data-source>java:/ejb/postgres/wildfly</jta-data-source>
|
||||
<properties>
|
||||
<!--<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>-->
|
||||
<!--<property name="javax.persistence.schema-generation.database.action" value="none"/>-->
|
||||
<property name="javax.persistence.schema-generation.database.action" value="create"/>
|
||||
<property name="javax.persistence.schema-generation.database.action" value="none"/>
|
||||
<!--<property name="javax.persistence.schema-generation.database.action" value="create"/>-->
|
||||
<property name="eclipselink.logging.level" value="INFO"/>
|
||||
<property name="hibernate.default_schema" value="jpacrepo"/>
|
||||
</properties>
|
||||
|
40
src/test/java/ClientTest.java
Normal file
40
src/test/java/ClientTest.java
Normal file
@@ -0,0 +1,40 @@
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import model.PkgData;
|
||||
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
|
||||
import org.jboss.resteasy.plugins.providers.jackson.ResteasyJacksonProvider;
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
import javax.ws.rs.client.Invocation;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
/**
|
||||
* Created by walter on 29/03/15.
|
||||
*/
|
||||
public class ClientTest
|
||||
{
|
||||
@Test
|
||||
public void test() throws Exception
|
||||
{
|
||||
ResteasyProviderFactory instance = ResteasyProviderFactory.getInstance();
|
||||
RegisterBuiltin.register(instance);
|
||||
instance.registerProvider(ResteasyJacksonProvider.class);
|
||||
Client client = ClientBuilder.newClient();
|
||||
UriBuilder builder = UriBuilder.fromUri("http://odroid-u3:8080/").path("jpacrepo/rest/pkg/search");
|
||||
// builder.queryParam("name", "linux");
|
||||
// builder.queryParam("version", "324");
|
||||
builder.queryParam("md5sum", "19787793429AF74D4D2D09890247E2EC");
|
||||
WebTarget target = client.target(builder.build());
|
||||
Invocation invocation = target.request().accept("application/xml").buildGet();
|
||||
Response response = invocation.invoke();
|
||||
if (response.getStatusInfo() == Response.Status.OK)
|
||||
{
|
||||
PkgData pkg = response.readEntity(PkgData.class);
|
||||
System.out.println(new XStream().toXML(pkg));
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,17 +1,15 @@
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import model.PkgData;
|
||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.filefilter.DirectoryFileFilter;
|
||||
import org.apache.commons.io.filefilter.RegexFileFilter;
|
||||
import org.junit.Test;
|
||||
import pacbase.Parser;
|
||||
import service.PacmanService;
|
||||
|
||||
import javax.naming.*;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -19,14 +17,14 @@ import java.util.*;
|
||||
*/
|
||||
public class ParseTest
|
||||
{
|
||||
@Test
|
||||
// @Test
|
||||
public void test() throws Exception
|
||||
{
|
||||
|
||||
Collection<File> ls = FileUtils.listFiles(new File("/var/cache/pacman/pkg"), new RegexFileFilter(".*\\.pkg\\.tar\\.xz"), DirectoryFileFilter.DIRECTORY);
|
||||
int i=0;
|
||||
int i = 0;
|
||||
List<PkgData> lista = new ArrayList<>();
|
||||
for(File file : ls)
|
||||
for (File file : ls)
|
||||
{
|
||||
PkgData data = Parser.parseFile(file);
|
||||
lista.add(data);
|
||||
@@ -35,4 +33,41 @@ public class ParseTest
|
||||
}
|
||||
System.out.print(lista);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeStatelessBean() throws NamingException, IOException
|
||||
{
|
||||
// Let's lookup the remote stateless calculator
|
||||
|
||||
Properties prop = new Properties();
|
||||
InputStream in = getClass().getClassLoader().getResourceAsStream("jboss-ejb-client.properties");
|
||||
prop.load(in);
|
||||
prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
|
||||
|
||||
prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
|
||||
prop.put(Context.PROVIDER_URL, "http-remoting://odroid-u3:8080");
|
||||
// prop.put(Context.PROVIDER_URL, "remote://odroid-u3:4447");
|
||||
prop.put(Context.SECURITY_PRINCIPAL, "jpacrepo");
|
||||
prop.put(Context.SECURITY_CREDENTIALS, "password01.");
|
||||
prop.put("jboss.naming.client.ejb.context", true);
|
||||
Context context = new InitialContext(prop);
|
||||
Context ctx = new InitialContext(prop);
|
||||
traverseJndiNode("/", context);
|
||||
// final PacmanService stateService = (PacmanService) ctx.lookup("/jpacrepo-1.0/remote/PacmanServiceEJB!service.PacmanService");
|
||||
final PacmanService stateService = (PacmanService) ctx.lookup("/jpacrepo-1.0/PacmanServiceEJB!service.PacmanService");
|
||||
stateService.syncDB();
|
||||
}
|
||||
|
||||
private static void traverseJndiNode(String nodeName, Context context) {
|
||||
try {
|
||||
NamingEnumeration<NameClassPair> list = context.list(nodeName);
|
||||
while (list.hasMore()){
|
||||
String childName = nodeName + "" + list.next().getName();
|
||||
System.out.println(childName);
|
||||
traverseJndiNode(childName, context);
|
||||
}
|
||||
} catch (NamingException ex) {
|
||||
// We reached a leaf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
src/test/resources/jboss-ejb-client.properties
Normal file
21
src/test/resources/jboss-ejb-client.properties
Normal file
@@ -0,0 +1,21 @@
|
||||
#remote.connections=default
|
||||
#remote.connection.default.host=odroid-u3
|
||||
#remote.connection.default.port=8080
|
||||
#remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
|
||||
#remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false
|
||||
#remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=${host.auth:JBOSS-LOCAL-USER}
|
||||
#
|
||||
#remote.connection.default.username=jpacrepo
|
||||
#remote.connection.default.password=password01.
|
||||
#
|
||||
#remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
|
||||
#remote.connections=default
|
||||
#remote.connection.default.host=odroid-u3
|
||||
#remote.connection.default.port=4447
|
||||
#remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
|
||||
#jboss.naming.client.ejb.context=true
|
||||
#
|
||||
#java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
|
||||
#java.naming.factory.initial=java.naming.spi.InitialContextFactory
|
||||
#java.naming.factory.url.pkgs=org.jboss.ejb.client.naming
|
||||
#java.naming.provider.url=remote://odroid-u3:4447
|
11
src/test/resources/remote.properties
Normal file
11
src/test/resources/remote.properties
Normal file
@@ -0,0 +1,11 @@
|
||||
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
|
||||
remote.connections=default
|
||||
remote.connection.default.host=odroid-u3
|
||||
remote.connection.default.port=4447
|
||||
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
|
||||
jboss.naming.client.ejb.context=true
|
||||
|
||||
java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
|
||||
#java.naming.factory.initial=java.naming.spi.InitialContextFactory
|
||||
java.naming.factory.url.pkgs=org.jboss.ejb.client.naming
|
||||
java.naming.provider.url=remote://odroid-u3:4447
|
Reference in New Issue
Block a user