Commit f739d617 authored by Administrator's avatar Administrator

Adds the REST layer implementation partially tested

The REST layer has been added but with incomplete tests. Students will
have to complete the tests.

This commit includes an important refactorization regarding tests. Test
classes and datasets have been moved from the "service" project to a new
"tests" project. This way, any project can include this "tests" project
as a dependency in order to have access to these common testing
resources.
parent 7fe00cf8
......@@ -5,3 +5,6 @@
#Maven
target
#General
bak
......@@ -42,22 +42,26 @@ Eclipse should then import 2 projects (`xcs-sample` and `domain`)
## Sample 1: Testing entities
Using JUnit and Hamcrest, we will see how to test JPA entities or any other
basic Java class.
Java class. This libraries are the base for every test done in the application.
## Sample 2: Testing with test doubles
Coming soon....
## Sample 2: Testing EJBs
Using Arquillian and Arquillian Persistence, the EJBs are tested. We wouldn't do
unit testing in this layer, as we don't want to mock the `EntityManager`.
## Sample 3: Testing EJBs
Coming soon...
In this layer we will use some workarounds to set the desired role and principal
in the tests.
## Sample 4: Testing JAX-RS
Coming soon...
## Sample 3: Testing with test doubles
Using EasyMock, we will mock the EJBs to test the REST classes isolated from the
underlying layer.
## Sample 5: Testing AngularJS
Coming soon...
## Sample 4: Testing JAX-RS
Using Arquillian REST Client, we will test the REST API accessing it as real
HTTP clients.
## Sample 6: Testing JSF
Coming soon...
## Sample 5: Testing JSF
Using Arquillian Drone, Arquillian Graphene and Selenium, we will test the JSF
web interface accessing it as real Web clients.
## Sample 7: Additional Testing Tools
## Sample 6: Additional Testing Tools
Coming soon...
......@@ -4,6 +4,7 @@ import java.io.Serializable;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.xml.bind.annotation.XmlRootElement;
/**
* An administrator of the application.
......@@ -12,6 +13,7 @@ import javax.persistence.Entity;
*/
@Entity
@DiscriminatorValue("ADMIN")
@XmlRootElement(name = "admin", namespace = "http://entities.domain.xcs.esei.uvigo.es")
public class Administrator extends User implements Serializable {
private static final long serialVersionUID = 1L;
......
......@@ -11,7 +11,9 @@ import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.xml.bind.annotation.XmlRootElement;
/**
* A pet owner.
......@@ -20,6 +22,7 @@ import javax.persistence.OneToMany;
*/
@Entity
@DiscriminatorValue("OWNER")
@XmlRootElement(name = "owner", namespace = "http://entities.domain.xcs.esei.uvigo.es")
public class Owner extends User implements Serializable {
private static final long serialVersionUID = 1L;
......@@ -27,7 +30,8 @@ public class Owner extends User implements Serializable {
mappedBy = "owner",
targetEntity = Pet.class,
cascade = CascadeType.ALL,
orphanRemoval = true
orphanRemoval = true,
fetch = FetchType.EAGER
)
private Collection<Pet> pets;
......
......@@ -17,6 +17,10 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
* A pet.
......@@ -24,6 +28,8 @@ import javax.persistence.TemporalType;
* @author Miguel Reboiro-Jato
*/
@Entity(name = "Pet")
@XmlRootElement(name = "pet", namespace = "http://entities.domain.xcs.esei.uvigo.es")
@XmlAccessorType(XmlAccessType.FIELD)
public class Pet implements Serializable {
private static final long serialVersionUID = 1L;
......@@ -43,7 +49,8 @@ public class Pet implements Serializable {
private Date birth;
@ManyToOne
@JoinColumn(name = "owner", referencedColumnName = "login")
@JoinColumn(name = "owner", referencedColumnName = "login", nullable = false)
@XmlTransient
private Owner owner;
// Required for JPA.
......
......@@ -10,7 +10,9 @@
<modules>
<module>domain</module>
<module>tests</module>
<module>service</module>
<module>rest</module>
</modules>
<properties>
......@@ -24,6 +26,8 @@
<!-- BOM versions -->
<javaee.api.version>7.0</javaee.api.version>
<arquillian.version>1.1.9.Final</arquillian.version>
<arquillian.rest.version>1.0.0.Alpha3</arquillian.rest.version>
<arquillian.selenium.version>2.47.1</arquillian.selenium.version>
<!-- Dependencies versions -->
<wildfly.version>8.2.1.Final</wildfly.version>
......@@ -36,8 +40,8 @@
<mysql.connector.java.version>5.1.21</mysql.connector.java.version>
<slf4j.version>1.5.10</slf4j.version>
<easymock.version>3.4</easymock.version>
<arquillian.glassfish.embedded.version>1.0.0.CR4</arquillian.glassfish.embedded.version>
<glassfish.embedded.all.version>4.1</glassfish.embedded.all.version>
<resteasy.version>3.0.13.Final</resteasy.version>
<graphene.webdrive.version>2.1.0.Alpha2</graphene.webdrive.version>
<!-- Plugins versions -->
<wildfly.maven.plugin.version>1.1.0.Alpha1</wildfly.maven.plugin.version>
......@@ -61,6 +65,13 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.selenium</groupId>
<artifactId>selenium-bom</artifactId>
<version>${arquillian.selenium.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Modules -->
<dependency>
......@@ -73,6 +84,17 @@
<artifactId>service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>rest</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>tests</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<!-- General -->
<dependency>
......@@ -102,6 +124,23 @@
<artifactId>arquillian-persistence-dbunit</artifactId>
<version>${arquillian.persistence.dbunit.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-rest-client-impl-3x</artifactId>
<version>${arquillian.rest.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>${resteasy.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.graphene</groupId>
<artifactId>graphene-webdriver</artifactId>
<version>${graphene.webdrive.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
......@@ -132,17 +171,6 @@
<artifactId>wildfly-arquillian-container-embedded</artifactId>
<version>${wildfly.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-glassfish-embedded-3.1</artifactId>
<version>${arquillian.glassfish.embedded.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>${glassfish.embedded.all.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
......
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>es.uvigo.esei.xcs</groupId>
<artifactId>sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>rest</artifactId>
<packaging>war</packaging>
<name>REST</name>
<description>XCS Sample - REST</description>
<dependencies>
<!-- General -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>es.uvigo.esei.xcs</groupId>
<artifactId>service</artifactId>
</dependency>
<!-- Testing -->
<dependency>
<groupId>es.uvigo.esei.xcs</groupId>
<artifactId>tests</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>java-hamcrest</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-persistence-dbunit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-rest-client-impl-3x</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package es.uvigo.esei.xcs.rest;
import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
@Provider
public class CORSFilter implements ContainerResponseFilter {
@Override
public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext cres)
throws IOException {
cres.getHeaders().add("Access-Control-Allow-Origin", "*");
cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
cres.getHeaders().add("Access-Control-Max-Age", "1209600");
}
}
\ No newline at end of file
package es.uvigo.esei.xcs.rest;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
public class IllegalArgumentExceptionMapper
implements ExceptionMapper<IllegalArgumentException> {
@Override
public Response toResponse(IllegalArgumentException e) {
return Response.status(Response.Status.BAD_REQUEST)
.entity(e.getMessage())
.type(MediaType.TEXT_PLAIN)
.build();
}
}
package es.uvigo.esei.xcs.rest;
import java.net.URI;
import javax.ejb.EJB;
import javax.persistence.EntityExistsException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
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 es.uvigo.esei.xcs.domain.entities.Owner;
import es.uvigo.esei.xcs.domain.entities.Pet;
import es.uvigo.esei.xcs.service.OwnerService;
/**
* Resource that represents the owners in the application.
*
* @author Miguel Reboiro Jato
*/
@Path("owner")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class OwnerResource {
@EJB
private OwnerService service;
@Context
private UriInfo uriInfo;
/**
* Returns the owner identified by the login.
*
* @param login the login of an owner.
* @return an {@code OK} response containing the {@link Owner} with the
* provided login.
* @throws IllegalArgumentException if {@code login} is {@code null} or
* if it does not correspond with any owner.
*/
@Path("{login}")
@GET
public Response get(@PathParam("login") String login) {
if (login == null)
throw new IllegalArgumentException("login can't be null");
final Owner owner = this.service.get(login);
if (owner == null)
throw new IllegalArgumentException("Owner not found: " + login);
else
return Response.ok(owner).build();
}
/**
* Returns the list of owners stored in the application.
*
* @return an {@code OK} response containing the list of owners stored in
* the application.
*/
@GET
public Response list() {
return Response.ok(this.service.list()).build();
}
/**
* Creates a new owner. This owner may include a list of pets, that will be
* also created.
*
* @param owner a new owner to be stored.
* @return a {@code CREATED} response with the URI of the new owner in the
* {@code Location} header.
* @throws IllegalArgumentException if owner is {@code null} or if an owner
* with the same login already exists.
*/
@POST
public Response create(Owner owner) {
// Pets are serialized without owner.
assignOwnerToPets(owner);
try {
final Owner newOwner = this.service.create(owner);
final URI ownerUri = uriInfo.getAbsolutePathBuilder()
.path(newOwner.getLogin())
.build();
return Response.created(ownerUri).build();
} catch (EntityExistsException eee) {
throw new IllegalArgumentException("The owner already exists");
}
}
/**
* Updates an owner. This owner may include a list of pets, that will be
* also created or updated. If the owner does not exists it will be created.
*
* @param owner an owner to be updated.
* @return an empty {@code OK} response.
* @throws IllegalArgumentException if owner is {@code null}.
*/
@PUT
public Response update(Owner owner) {
// Pets are serialized without owner.
assignOwnerToPets(owner);
this.service.update(owner);
return Response.ok().build();
}
/**
* Deletes an owner.
*
* @param login the login of the owner to be deleted.
* @throws IllegalArgumentException if {@code login} is {@code null} or if
* it does not identifies a valid owner.
*/
@Path("{login}")
@DELETE
public Response delete(@PathParam("login") String login) {
if (login == null)
throw new IllegalArgumentException("login can't be null");
this.service.remove(login);
return Response.ok().build();
}
private static void assignOwnerToPets(Owner owner) {
if (owner == null)
throw new IllegalArgumentException("owner can't be null");
for (Pet pet : owner.getPets()) {
if (pet.getOwner() != owner)
pet.setOwner(owner);
}
}
}
package es.uvigo.esei.xcs.rest;
import java.net.URI;
import javax.ejb.EJB;
import javax.ejb.EJBAccessException;
import javax.persistence.EntityExistsException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
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 es.uvigo.esei.xcs.domain.entities.Pet;
import es.uvigo.esei.xcs.service.PetService;
/**
* Resource that represents the pets in the application.
*
* @author Miguel Reboiro Jato
*/
@Path("pet")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class PetResource {
@EJB
private PetService service;
@Context
private UriInfo uriInfo;
/**
* Returns the owner identified by the login.
*
* @param id the identified of a pet.
* @return an {@code OK} response containing the {@link Pet} with the
* provided identifier.
* @throws SecurityException if the current owner does not owns the pet.
*/
@Path("{id}")
@GET
public Response get(@PathParam("id") int id) throws SecurityException {
try {
final Pet pet = this.service.get(id);
if (pet == null)
throw new IllegalArgumentException("Pet not found: " + id);
else
return Response.ok(pet).build();
} catch (EJBAccessException eae) {
throw new SecurityException(eae);
}
}
/**
* Returns the complete list of pets of the current owner.
*
* @return an {@code OK} response containing the complete list of pets of
* the current owner.
*/
@GET
public Response list() {
return Response.ok(this.service.list()).build();
}
/**
* Creates a new pet owned by the current user.
*
* @param pet a new owner to be stored.
* @return a {@code CREATED} response with the URI of the new pet in the
* {@code Location} header.
* @throws IllegalArgumentException if pet is {@code null} or if a pet with
* the same identifier already exists.
* @throws SecurityException if the pet already has an owner and it is not
* the current user. If the pet has no owner, this exception will be never
* thrown.
*/
@POST
public Response create(Pet pet) throws SecurityException {
if (pet == null)
throw new IllegalArgumentException("pet can't be null");
try {
final Pet newPet = this.service.create(pet);
final URI petUri = uriInfo.getAbsolutePathBuilder()
.path(Integer.toString(newPet.getId()))
.build();
return Response.created(petUri).build();
} catch (EntityExistsException eee) {
throw new IllegalArgumentException("The pet already exists");
} catch (EJBAccessException eae) {
throw new SecurityException(eae);
}
}
/**
* Updates the information of a pet. If the pet is not stored, it will be
* created.
*
* @param pet a pet to be updated.
* @return an empty {@code OK} response.
* @throws IllegalArgumentException if pet is {@code null} of it has no
* owner.
* @throws SecurityException if the pet's owner is not the current user.
*/
@PUT
public Response update(Pet pet) throws SecurityException {
if (pet == null)
throw new IllegalArgumentException("pet can't be null");
try {
this.service.update(pet);
return Response.ok().build();
} catch (EJBAccessException eae) {
throw new SecurityException(eae);
}
}
/**
* Deletes a pet.
*
* @param id the identifier of the pet to be deleted.
* @throws IllegalArgumentException if there is no pet with the provided
* identifier.
* @throws SecurityException if the pet's owner is not the current user.
*/
@Path("{id}")
@DELETE
public Response delete(@PathParam("id") int id) throws SecurityException {
try {
this.service.remove(id);
return Response.ok().build();
} catch (EJBAccessException eae) {
throw new SecurityException(eae);
}
}
}
package es.uvigo.esei.xcs.rest;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
public class SecurityExceptionMapper implements ExceptionMapper<SecurityException> {
@Override
public Response toResponse(SecurityException e) {
return Response.status(Response.Status.FORBIDDEN)
.entity(e.getMessage())
.type(MediaType.TEXT_PLAIN)
.build();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="runtime">
<jta-data-source>java:jboss/datasources/xcs</jta-data-source>
<class>es.uvigo.esei.xcs.domain.entities.Owner</class>
<class>es.uvigo.esei.xcs.domain.entities.Pet</class>
<class>es.uvigo.esei.xcs.domain.entities.Administrator</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="false"/>
</properties>
</persistence-unit>
</persistence>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>xcs-sample-security-domain</security-domain>
</jboss-web>
\ No newline at end of file
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Pet Store REST</display-name>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<!--Defining security constraint for type of roles available -->
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/api/owner/*</url-pattern>
<http-method-omission>OPTIONS</http-method-omission>
</web-resource-collection>
<auth-constraint>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>owner</web-resource-name>
<url-pattern>/api/pet/*</url-pattern>
<http-method-omission>OPTIONS</http-method-omission>
</web-resource-collection>
<auth-constraint>
<role-name>OWNER</role-name>
</auth-constraint>
</security-constraint>
<!--Defining security constraint for type of roles available -->
<!--Denining security role -->
<security-role>
<role-name>ADMIN</role-name>
</security-role>
<security-role>
<role-name>OWNER</role-name>
</security-role>
<!--Denining security role -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>default</realm-name>
</login-config>
</web-app>
\ No newline at end of file
package es.uvigo.esei.xcs.rest;
import java.util.List;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import es.uvigo.esei.xcs.domain.entities.Owner;
public final class GenericTypes {
private GenericTypes() {}
public static class ListOwnerType extends GenericType<List<Owner>> {
public static ListOwnerType INSTANCE = new ListOwnerType();
public static List<Owner> readEntity(Response response) {
return response.readEntity(INSTANCE);
}
}
}
package es.uvigo.esei.xcs.rest;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.containsOwnersInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.equalsToOwner;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.EXISTENT_LOGIN;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.NON_EXISTENT_LOGIN;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.OWNER_WITHOUT_PETS_LOGIN;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.OWNER_WITH_PETS_LOGIN;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newOwnerWithFreshPets;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newOwnerWithPersistentPets;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newOwnerWithoutPets;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.owner;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.owners;
import static javax.ws.rs.client.Entity.json;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.List;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.extension.rest.client.ArquillianResteasyResource;
import org.jboss.arquillian.extension.rest.client.Header;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.persistence.Cleanup;
import org.jboss.arquillian.persistence.CleanupUsingScript;
import org.jboss.arquillian.persistence.ShouldMatchDataSet;
import org.jboss.arquillian.persistence.TestExecutionPhase;
import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.junit.runner.RunWith;
import es.uvigo.esei.xcs.domain.entities.Owner;
import es.uvigo.esei.xcs.domain.entities.OwnersDataset;
import es.uvigo.esei.xcs.rest.GenericTypes.ListOwnerType;
import es.uvigo.esei.xcs.service.OwnerService;
@RunWith(Arquillian.class)
public class OwnerResourceRestTest {
private final static String BASE_PATH = "api/owner/";
private static final String BASIC_AUTHORIZATION = "Basic am9zZTpqb3NlcGFzcw=";
@Deployment
public static Archive<?> createDeployment() {
final WebArchive archive = ShrinkWrap.create(WebArchive.class, "test.war")
.addClass(OwnerResource.class)
.addClasses(CORSFilter.class, IllegalArgumentExceptionMapper.class, SecurityExceptionMapper.class)
.addPackage(OwnerService.class.getPackage())
.addPackage(Owner.class.getPackage())
.addAsResource("test-persistence.xml", "META-INF/persistence.xml")
.addAsWebInfResource("jboss-web.xml")
.addAsWebInfResource("web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
return archive;
}
@Test @InSequence(1)
@UsingDataSet("owners.xml")
@Cleanup(phase = TestExecutionPhase.NONE)
public void beforeGet() {}
@Test @InSequence(2)
@RunAsClient
@Header(name = "Authorization", value = BASIC_AUTHORIZATION)
public void testGet(
@ArquillianResteasyResource(BASE_PATH + EXISTENT_LOGIN) ResteasyWebTarget webTarget
) throws Exception {
final Response response = webTarget.request().get();
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.OK)));
final Owner owner = response.readEntity(Owner.class);
final Owner expected = owner("pepe");
assertThat(owner, is(equalsToOwner(expected)));
}
@Test @InSequence(3)
@ShouldMatchDataSet("owners.xml")
@CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" })
public void afterGet() {}
@Test @InSequence(4)
@UsingDataSet("owners.xml")
@Cleanup(phase = TestExecutionPhase.NONE)
public void beforeGetNonExistent() {}
@Test @InSequence(5)
@RunAsClient
@Header(name = "Authorization", value = BASIC_AUTHORIZATION)
public void testGetNonExistent(
@ArquillianResteasyResource(BASE_PATH + NON_EXISTENT_LOGIN) ResteasyWebTarget webTarget
) throws Exception {
final Response response = webTarget.request().get();
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.BAD_REQUEST)));
}
@Test @InSequence(6)
@ShouldMatchDataSet("owners.xml")
@CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" })
public void afterGetNonExistent() {}
@Test @InSequence(10)
@UsingDataSet("owners.xml")
@Cleanup(phase = TestExecutionPhase.NONE)
public void beforeList() {}
@Test @InSequence(11)
@RunAsClient
@Header(name = "Authorization", value = BASIC_AUTHORIZATION)
public void testList(
@ArquillianResteasyResource(BASE_PATH) ResteasyWebTarget webTarget
) throws Exception {
final Response response = webTarget.request().get();
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.OK)));
final List<Owner> list = ListOwnerType.readEntity(response);
assertThat(list, containsOwnersInAnyOrder(owners()));
}
@Test @InSequence(12)
@ShouldMatchDataSet("owners.xml")
@CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" })
public void afterList() {}
@Test @InSequence(20)
@UsingDataSet("owners.xml")
@Cleanup(phase = TestExecutionPhase.NONE)
public void beforeCreate() {}
@Test @InSequence(21)
@RunAsClient
@Header(name = "Authorization", value = BASIC_AUTHORIZATION)
public void testCreate(
@ArquillianResteasyResource(BASE_PATH) ResteasyWebTarget webTarget
) throws Exception {
testCreateOwner(webTarget, newOwnerWithoutPets());
}
@Test @InSequence(22)
@ShouldMatchDataSet({"owners.xml", "owners-create-without-pets.xml"})
@CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" })
public void afterCreate() {}
@Test @InSequence(23)
@UsingDataSet("owners.xml")
@Cleanup(phase = TestExecutionPhase.NONE)
public void beforeCreateWithPets() {}
@Test @InSequence(24)
@RunAsClient
@Header(name = "Authorization", value = BASIC_AUTHORIZATION)
public void testCreateWithPets(
@ArquillianResteasyResource(BASE_PATH) ResteasyWebTarget webTarget
) throws Exception {
testCreateOwner(webTarget, newOwnerWithFreshPets(), newOwnerWithPersistentPets());
}
@Test @InSequence(25)
@ShouldMatchDataSet({"owners.xml", "owners-create-with-pets.xml"})
@CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" })
public void afterCreateWithPets() {}
private void testCreateOwner(WebTarget webTarget, Owner newOwner) {
testCreateOwner(webTarget, newOwner, newOwner);
}
private void testCreateOwner(WebTarget webTarget, Owner newOwner, Owner persistentOwner) {
final Response response = webTarget.request().post(json(newOwner));
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.CREATED)));
final String location = response.getHeaderString("Location");
final Response responseGet = authorizedJsonRequestGet(location);
final Owner owner = responseGet.readEntity(Owner.class);
assertThat(owner, is(equalsToOwner(persistentOwner)));
}
@Test @InSequence(30)
@UsingDataSet("owners.xml")
@Cleanup(phase = TestExecutionPhase.NONE)
public void beforeUpdatePassword() {}
@Test @InSequence(31)
@RunAsClient
@Header(name = "Authorization", value = BASIC_AUTHORIZATION)
public void testUpdatePassword(
@ArquillianResteasyResource(BASE_PATH) ResteasyWebTarget webTarget
) throws Exception {
final Owner owner = OwnersDataset.anyOwner();
owner.changePassword("newpassword");
final Response response = webTarget.request().put(json(owner));
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.OK)));
}
@Test @InSequence(32)
@ShouldMatchDataSet("owners-update-password.xml")
@CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" })
public void afterUpdatePassword() {}
@Test @InSequence(40)
@UsingDataSet("owners.xml")
@Cleanup(phase = TestExecutionPhase.NONE)
public void beforeDeleteWithoutPets() {}
@Test @InSequence(41)
@RunAsClient
@Header(name = "Authorization", value = BASIC_AUTHORIZATION)
public void testDeleteWithoutPets(
@ArquillianResteasyResource(BASE_PATH + OWNER_WITHOUT_PETS_LOGIN) ResteasyWebTarget webTarget
) throws Exception {
final Response response = webTarget.request().delete();
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.OK)));
}
@Test @InSequence(42)
@ShouldMatchDataSet("owners-remove-without-pets.xml")
@CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" })
public void afterDeleteWithoutPets() {}
@Test @InSequence(43)
@UsingDataSet("owners.xml")
@Cleanup(phase = TestExecutionPhase.NONE)
public void beforeDeleteWithPets() {}
@Test @InSequence(44)
@RunAsClient
@Header(name = "Authorization", value = BASIC_AUTHORIZATION)
public void testDeleteWithPets(
@ArquillianResteasyResource(BASE_PATH + OWNER_WITH_PETS_LOGIN) ResteasyWebTarget webTarget
) throws Exception {
final Response response = webTarget.request().delete();
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.OK)));
}
@Test @InSequence(45)
@ShouldMatchDataSet("owners-remove-with-pets.xml")
@CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" })
public void afterDeleteWithPets() {}
@Test @InSequence(46)
@UsingDataSet("owners.xml")
@Cleanup(phase = TestExecutionPhase.NONE)
public void beforeDeleteNoLogin() {}
@Test @InSequence(47)
@RunAsClient
@Header(name = "Authorization", value = BASIC_AUTHORIZATION)
public void testDeleteNoLogin(
@ArquillianResteasyResource(BASE_PATH) ResteasyWebTarget webTarget
) throws Exception {
final Response response = webTarget.request().delete();
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.METHOD_NOT_ALLOWED)));
}
@Test @InSequence(48)
@ShouldMatchDataSet("owners.xml")
@CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" })
public void afterDeleteNoLogin() {}
private static Response authorizedJsonRequestGet(String uri) {
return ClientBuilder.newClient().target(uri)
.request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", BASIC_AUTHORIZATION)
.get();
}
}
package es.uvigo.esei.xcs.rest;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.containsOwnersInAnyOrder;
import static es.uvigo.esei.xcs.domain.entities.IsEqualsToOwner.equalsToOwner;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.anyLogin;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.anyOwner;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newOwnerWithFreshPets;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newOwnerWithPersistentPets;
import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.owners;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.collection.IsEmptyCollection.empty;
import static org.junit.Assert.assertThat;
import java.net.URI;
import java.util.List;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import org.easymock.EasyMockRunner;
import org.easymock.EasyMockSupport;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import es.uvigo.esei.xcs.domain.entities.Owner;
import es.uvigo.esei.xcs.domain.entities.OwnersDataset;
import es.uvigo.esei.xcs.service.OwnerService;
@RunWith(EasyMockRunner.class)
public class OwnerResourceUnitTest extends EasyMockSupport {
@TestSubject
private OwnerResource resource = new OwnerResource();
@Mock
private OwnerService facade;
@Mock
private UriInfo uriInfo;
@Mock
private UriBuilder uriBuilder;
@After
public void tearDown() throws Exception {
verifyAll();
}
@Test
public void testGet() {
final Owner owner = OwnersDataset.anyOwner();
expect(facade.get(owner.getLogin()))
.andReturn(owner);
replayAll();
final Response response = resource.get(owner.getLogin());
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.OK)));
assertThat(response.getEntity(), is(instanceOf(Owner.class)));
assertThat((Owner) response.getEntity(), is(equalsToOwner(owner)));
}
@Test(expected = IllegalArgumentException.class)
public void testGetNull() {
replayAll();
resource.get(null);
}
@Test(expected = IllegalArgumentException.class)
public void testGetMissing() {
final String login = anyLogin();
expect(facade.get(login))
.andReturn(null);
replayAll();
resource.get(login);
}
@Test
@SuppressWarnings("unchecked")
public void testList() {
final Owner[] owners = owners();
expect(facade.list())
.andReturn(asList(owners));
replayAll();
final Response response = resource.list();
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.OK)));
assertThat(response.getEntity(), is(instanceOf(List.class)));
assertThat((List<Owner>) response.getEntity(), containsOwnersInAnyOrder(owners));
}
@Test
@SuppressWarnings("unchecked")
public void testListEmpty() {
expect(facade.list())
.andReturn(emptyList());
replayAll();
final Response response = resource.list();
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.OK)));
assertThat(response.getEntity(), is(instanceOf(List.class)));
assertThat((List<Owner>) response.getEntity(), is(empty()));
}
@Test
public void testCreate() throws Exception {
final Owner newOwner = newOwnerWithFreshPets();
final Owner createdOwner = newOwnerWithPersistentPets();
final URI mockUri = new URI("http://host/api/owner/" + newOwner.getLogin());
expect(facade.create(newOwner))
.andReturn(createdOwner);
expect(uriInfo.getAbsolutePathBuilder())
.andReturn(uriBuilder);
expect(uriBuilder.path(newOwner.getLogin()))
.andReturn(uriBuilder);
expect(uriBuilder.build())
.andReturn(mockUri);
replayAll();
final Response response = resource.create(newOwner);
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.CREATED)));
assertThat(response.getHeaderString("Location"), is(equalTo(mockUri.toString())));
}
@Test(expected = IllegalArgumentException.class)
public void testCreateNull() {
replayAll();
resource.create(null);
}
@Test
public void testUpdate() {
final Owner owner = anyOwner();
facade.update(owner);
expectLastCall().andReturn(owner);
replayAll();
final Response response = resource.update(owner);
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.OK)));
}
@Test(expected = IllegalArgumentException.class)
public void testUpdateNull() {
replayAll();
resource.update(null);
}
@Test
public void testDelete() {
final String login = OwnersDataset.anyLogin();
facade.remove(login);
replayAll();
final Response response = resource.delete(login);
assertThat(response.getStatusInfo(), is(equalTo(Response.Status.OK)));
}
@Test(expected = IllegalArgumentException.class)
public void testDeleteNull() {
replayAll();
resource.delete(null);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
<alternatives>
<class>es.uvigo.esei.xcs.service.util.security.TestPrincipal</class>
</alternatives>
</beans>
ALTER TABLE Pet ALTER COLUMN id RESTART WITH 1;
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>xcs-sample-security-domain</security-domain>
</jboss-web>
\ No newline at end of file
<?xml version="1.0" ?>
<server xmlns="urn:jboss:domain:2.2">
<extensions>
<extension module="org.jboss.as.clustering.infinispan"/>
<extension module="org.jboss.as.connector"/>
<extension module="org.jboss.as.deployment-scanner"/>
<extension module="org.jboss.as.ee"/>
<extension module="org.jboss.as.ejb3"/>
<extension module="org.jboss.as.jaxrs"/>
<extension module="org.jboss.as.jdr"/>
<extension module="org.jboss.as.jmx"/>
<extension module="org.jboss.as.jpa"/>
<extension module="org.jboss.as.jsf"/>
<extension module="org.jboss.as.logging"/>
<extension module="org.jboss.as.mail"/>
<extension module="org.jboss.as.naming"/>
<extension module="org.jboss.as.pojo"/>
<extension module="org.jboss.as.remoting"/>
<extension module="org.jboss.as.sar"/>
<extension module="org.jboss.as.security"/>
<extension module="org.jboss.as.transactions"/>
<extension module="org.jboss.as.webservices"/>
<extension module="org.jboss.as.weld"/>
<extension module="org.wildfly.extension.batch"/>
<extension module="org.wildfly.extension.io"/>
<extension module="org.wildfly.extension.undertow"/>
</extensions>
<management>
<security-realms>
<security-realm name="ManagementRealm">
<authentication>
<local default-user="$local" skip-group-loading="true"/>
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization map-groups-to-roles="false">
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
<security-realm name="ApplicationRealm">
<authentication>
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
<!-- Custom realm -->
<security-realm name="RemotingRealm">
<authentication>
<jaas name="AppRealmLoopThrough" />
</authentication>
</security-realm>
</security-realms>
<audit-log>
<formatters>
<json-formatter name="json-formatter"/>
</formatters>
<handlers>
<file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
</handlers>
<logger log-boot="true" log-read-only="false" enabled="false">
<handlers>
<handler name="file"/>
</handlers>
</logger>
</audit-log>
<management-interfaces>
<http-interface security-realm="ManagementRealm" http-upgrade-enabled="true">
<socket-binding http="management-http"/>
</http-interface>
</management-interfaces>
<access-control provider="simple">
<role-mapping>
<role name="SuperUser">
<include>
<user name="$local"/>
</include>
</role>
</role-mapping>
</access-control>
</management>
<profile>
<subsystem xmlns="urn:jboss:domain:logging:2.0">
<console-handler name="CONSOLE">
<level name="INFO"/>
<formatter>
<named-formatter name="COLOR-PATTERN"/>
</formatter>
</console-handler>
<periodic-rotating-file-handler name="FILE" autoflush="true">
<formatter>
<named-formatter name="PATTERN"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="server.log"/>
<suffix value=".yyyy-MM-dd"/>
<append value="true"/>
</periodic-rotating-file-handler>
<logger category="com.arjuna">
<level name="WARN"/>
</logger>
<logger category="org.apache.tomcat.util.modeler">
<level name="WARN"/>
</logger>
<logger category="org.jboss.as.config">
<level name="DEBUG"/>
</logger>
<logger category="sun.rmi">
<level name="WARN"/>
</logger>
<logger category="jacorb">
<level name="WARN"/>
</logger>
<logger category="jacorb.config">
<level name="ERROR"/>
</logger>
<root-logger>
<level name="INFO"/>
<handlers>
<handler name="CONSOLE"/>
<handler name="FILE"/>
</handlers>
</root-logger>
<formatter name="PATTERN">
<pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
<formatter name="COLOR-PATTERN">
<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
</subsystem>
<subsystem xmlns="urn:jboss:domain:batch:1.0">
<job-repository>
<in-memory/>
</job-repository>
<thread-pool>
<max-threads count="10"/>
<keepalive-time time="30" unit="seconds"/>
</thread-pool>
</subsystem>
<subsystem xmlns="urn:jboss:domain:datasources:2.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
<drivers>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
<subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
<deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:ee:2.0">
<spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
<concurrent>
<context-services>
<context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
</context-services>
<managed-thread-factories>
<managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
</managed-thread-factories>
<managed-executor-services>
<managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" core-threads="5" max-threads="25" keepalive-time="5000"/>
</managed-executor-services>
<managed-scheduled-executor-services>
<managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" core-threads="2" keepalive-time="3000"/>
</managed-scheduled-executor-services>
</concurrent>
<default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" jms-connection-factory="java:jboss/DefaultJMSConnectionFactory" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:ejb3:2.0">
<session-bean>
<stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
<singleton default-access-timeout="5000"/>
</session-bean>
<pools>
<bean-instance-pools>
<strict-max-pool name="slsb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
<strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
</bean-instance-pools>
</pools>
<caches>
<cache name="simple"/>
<cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
</caches>
<passivation-stores>
<passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
</passivation-stores>
<async thread-pool-name="default"/>
<timer-service thread-pool-name="default" default-data-store="default-file-store">
<data-stores>
<file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
</data-stores>
</timer-service>
<remote connector-ref="http-remoting-connector" thread-pool-name="default"/>
<thread-pools>
<thread-pool name="default">
<max-threads count="10"/>
<keepalive-time time="100" unit="milliseconds"/>
</thread-pool>
</thread-pools>
<default-security-domain value="other"/>
<default-missing-method-permissions-deny-access value="true"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:io:1.1">
<worker name="default"/>
<buffer-pool name="default"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:infinispan:2.0">
<cache-container name="web" default-cache="passivation" module="org.wildfly.clustering.web.infinispan">
<local-cache name="passivation" batching="true">
<file-store passivation="true" purge="false"/>
</local-cache>
<local-cache name="persistent" batching="true">
<file-store passivation="false" purge="false"/>
</local-cache>
</cache-container>
<cache-container name="ejb" default-cache="passivation" module="org.wildfly.clustering.ejb.infinispan" aliases="sfsb">
<local-cache name="passivation" batching="true">
<file-store passivation="true" purge="false"/>
</local-cache>
<local-cache name="persistent" batching="true">
<file-store passivation="false" purge="false"/>
</local-cache>
</cache-container>
<cache-container name="hibernate" default-cache="local-query" module="org.hibernate">
<local-cache name="entity">
<transaction mode="NON_XA"/>
<eviction strategy="LRU" max-entries="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="local-query">
<transaction mode="NONE"/>
<eviction strategy="LRU" max-entries="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="timestamps">
<transaction mode="NONE"/>
<eviction strategy="NONE"/>
</local-cache>
</cache-container>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>
<subsystem xmlns="urn:jboss:domain:jca:2.0">
<archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
<bean-validation enabled="true"/>
<default-workmanager>
<short-running-threads>
<core-threads count="50"/>
<queue-length count="50"/>
<max-threads count="50"/>
<keepalive-time time="10" unit="seconds"/>
</short-running-threads>
<long-running-threads>
<core-threads count="50"/>
<queue-length count="50"/>
<max-threads count="50"/>
<keepalive-time time="10" unit="seconds"/>
</long-running-threads>
</default-workmanager>
<cached-connection-manager/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jdr:1.0"/>
<subsystem xmlns="urn:jboss:domain:jmx:1.3">
<expose-resolved-model/>
<expose-expression-model/>
<remoting-connector/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jpa:1.1">
<jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jsf:1.0"/>
<subsystem xmlns="urn:jboss:domain:mail:2.0">
<mail-session name="default" jndi-name="java:jboss/mail/Default">
<smtp-server outbound-socket-binding-ref="mail-smtp"/>
</mail-session>
</subsystem>
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<remote-naming/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:pojo:1.0"/>
<subsystem xmlns="urn:jboss:domain:remoting:2.0">
<endpoint worker="default"/>
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="RemotingRealm"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:resource-adapters:2.0"/>
<subsystem xmlns="urn:jboss:domain:sar:1.0"/>
<subsystem xmlns="urn:jboss:domain:security:1.2">
<security-domains>
<security-domain name="other" cache-type="default">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="RealmDirect" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
</authentication>
</security-domain>
<security-domain name="jboss-web-policy" cache-type="default">
<authorization>
<policy-module code="Delegating" flag="required"/>
</authorization>
</security-domain>
<security-domain name="jboss-ejb-policy" cache-type="default">
<authorization>
<policy-module code="Delegating" flag="required"/>
</authorization>
</security-domain>
<!-- Custom domain -->
<security-domain name="AppRealmLoopThrough" cache-type="default">
<authentication>
<login-module code="Client" flag="required">
<module-option name="multi-threaded" value="true" />
</login-module>
</authentication>
</security-domain>
<security-domain name="xcs-sample-security-domain">
<authentication>
<login-module code="Database" flag="required">
<module-option name="dsJndiName" value="java:jboss/datasources/ExampleDS" />
<module-option name="principalsQuery"
value="SELECT password FROM User WHERE login=?" />
<module-option name="rolesQuery"
value="SELECT role, 'Roles' FROM User WHERE login=?" />
<module-option name="hashAlgorithm" value="MD5"/>
<module-option name="hashEncoding" value="hex"/>
<module-option name="ignorePasswordCase" value="true"/>
</login-module>
</authentication>
</security-domain>
</security-domains>
</subsystem>
<subsystem xmlns="urn:jboss:domain:transactions:2.0">
<core-environment>
<process-id>
<uuid/>
</process-id>
</core-environment>
<recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:undertow:1.2">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
</host>
</server>
<servlet-container name="default">
<jsp-config/>
<websockets/>
</servlet-container>
<handlers>
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers>
<filters>
<response-header name="server-header" header-name="Server" header-value="WildFly/8"/>
<response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
</filters>
</subsystem>
<subsystem xmlns="urn:jboss:domain:webservices:1.2">
<wsdl-host>${jboss.bind.address:127.0.0.1}</wsdl-host>
<endpoint-config name="Standard-Endpoint-Config"/>
<endpoint-config name="Recording-Endpoint-Config">
<pre-handler-chain name="recording-handlers" protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM">
<handler name="RecordingHandler" class="org.jboss.ws.common.invocation.RecordingServerHandler"/>
</pre-handler-chain>
</endpoint-config>
<client-config name="Standard-Client-Config"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:weld:2.0"/>
</profile>
<interfaces>
<interface name="management">
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
</interface>
<interface name="public">
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
</interface>
<interface name="unsecure">
<inet-address value="${jboss.bind.address.unsecure:127.0.0.1}"/>
</interface>
</interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="0">
<socket-binding name="management-http" interface="management" port="9990"/>
<socket-binding name="management-https" interface="management" port="9993"/>
<socket-binding name="ajp" port="8009"/>
<socket-binding name="http" port="8080"/>
<socket-binding name="https" port="8443"/>
<socket-binding name="txn-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/>
<outbound-socket-binding name="mail-smtp">
<remote-destination host="localhost" port="25"/>
</outbound-socket-binding>
</socket-binding-group>
</server>
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="test">
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
<alternatives>
<class>es.uvigo.esei.xcs.service.util.security.TestPrincipal</class>
</alternatives>
</beans>
ALTER TABLE Pet AUTO_INCREMENT = 1;
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>xcs-sample-security-domain</security-domain>
</jboss-web>
\ No newline at end of file
<datasources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.ironjacamar.org/doc/schema"
xsi:schemaLocation="http://www.ironjacamar.org/doc/schema http://www.ironjacamar.org/doc/schema/datasources_1_1.xsd">
<datasource jndi-name="java:jboss/datasources/xcs" pool-name="MySQLPool">
<connection-url>jdbc:mysql://localhost:3306/xcs</connection-url>
<driver>mysql-connector-java-${mysql.version}.jar</driver>
<pool>
<max-pool-size>30</max-pool-size>
</pool>
<security>
<user-name>xcs</user-name>
<password>xcs</password>
</security>
</datasource>
</datasources>
\ No newline at end of file
<?xml version="1.0" ?>
<server xmlns="urn:jboss:domain:2.2">
<extensions>
<extension module="org.jboss.as.clustering.infinispan"/>
<extension module="org.jboss.as.connector"/>
<extension module="org.jboss.as.deployment-scanner"/>
<extension module="org.jboss.as.ee"/>
<extension module="org.jboss.as.ejb3"/>
<extension module="org.jboss.as.jaxrs"/>
<extension module="org.jboss.as.jdr"/>
<extension module="org.jboss.as.jmx"/>
<extension module="org.jboss.as.jpa"/>
<extension module="org.jboss.as.jsf"/>
<extension module="org.jboss.as.logging"/>
<extension module="org.jboss.as.mail"/>
<extension module="org.jboss.as.naming"/>
<extension module="org.jboss.as.pojo"/>
<extension module="org.jboss.as.remoting"/>
<extension module="org.jboss.as.sar"/>
<extension module="org.jboss.as.security"/>
<extension module="org.jboss.as.transactions"/>
<extension module="org.jboss.as.webservices"/>
<extension module="org.jboss.as.weld"/>
<extension module="org.wildfly.extension.batch"/>
<extension module="org.wildfly.extension.io"/>
<extension module="org.wildfly.extension.undertow"/>
</extensions>
<management>
<security-realms>
<security-realm name="ManagementRealm">
<authentication>
<local default-user="$local" skip-group-loading="true"/>
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization map-groups-to-roles="false">
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
<security-realm name="ApplicationRealm">
<authentication>
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
<!-- Custom realm -->
<security-realm name="RemotingRealm">
<authentication>
<jaas name="AppRealmLoopThrough" />
</authentication>
</security-realm>
</security-realms>
<audit-log>
<formatters>
<json-formatter name="json-formatter"/>
</formatters>
<handlers>
<file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
</handlers>
<logger log-boot="true" log-read-only="false" enabled="false">
<handlers>
<handler name="file"/>
</handlers>
</logger>
</audit-log>
<management-interfaces>
<http-interface security-realm="ManagementRealm" http-upgrade-enabled="true">
<socket-binding http="management-http"/>
</http-interface>
</management-interfaces>
<access-control provider="simple">
<role-mapping>
<role name="SuperUser">
<include>
<user name="$local"/>
</include>
</role>
</role-mapping>
</access-control>
</management>
<profile>
<subsystem xmlns="urn:jboss:domain:logging:2.0">
<console-handler name="CONSOLE">
<level name="INFO"/>
<formatter>
<named-formatter name="COLOR-PATTERN"/>
</formatter>
</console-handler>
<periodic-rotating-file-handler name="FILE" autoflush="true">
<formatter>
<named-formatter name="PATTERN"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="server.log"/>
<suffix value=".yyyy-MM-dd"/>
<append value="true"/>
</periodic-rotating-file-handler>
<logger category="com.arjuna">
<level name="WARN"/>
</logger>
<logger category="org.apache.tomcat.util.modeler">
<level name="WARN"/>
</logger>
<logger category="org.jboss.as.config">
<level name="DEBUG"/>
</logger>
<logger category="sun.rmi">
<level name="WARN"/>
</logger>
<logger category="jacorb">
<level name="WARN"/>
</logger>
<logger category="jacorb.config">
<level name="ERROR"/>
</logger>
<root-logger>
<level name="INFO"/>
<handlers>
<handler name="CONSOLE"/>
<handler name="FILE"/>
</handlers>
</root-logger>
<formatter name="PATTERN">
<pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
<formatter name="COLOR-PATTERN">
<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
</subsystem>
<subsystem xmlns="urn:jboss:domain:batch:1.0">
<job-repository>
<in-memory/>
</job-repository>
<thread-pool>
<max-threads count="10"/>
<keepalive-time time="30" unit="seconds"/>
</thread-pool>
</subsystem>
<subsystem xmlns="urn:jboss:domain:datasources:2.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
<drivers>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
<subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
<deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:ee:2.0">
<spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
<concurrent>
<context-services>
<context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
</context-services>
<managed-thread-factories>
<managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
</managed-thread-factories>
<managed-executor-services>
<managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" core-threads="5" max-threads="25" keepalive-time="5000"/>
</managed-executor-services>
<managed-scheduled-executor-services>
<managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" core-threads="2" keepalive-time="3000"/>
</managed-scheduled-executor-services>
</concurrent>
<default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" jms-connection-factory="java:jboss/DefaultJMSConnectionFactory" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:ejb3:2.0">
<session-bean>
<stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
<singleton default-access-timeout="5000"/>
</session-bean>
<pools>
<bean-instance-pools>
<strict-max-pool name="slsb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
<strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
</bean-instance-pools>
</pools>
<caches>
<cache name="simple"/>
<cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
</caches>
<passivation-stores>
<passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
</passivation-stores>
<async thread-pool-name="default"/>
<timer-service thread-pool-name="default" default-data-store="default-file-store">
<data-stores>
<file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
</data-stores>
</timer-service>
<remote connector-ref="http-remoting-connector" thread-pool-name="default"/>
<thread-pools>
<thread-pool name="default">
<max-threads count="10"/>
<keepalive-time time="100" unit="milliseconds"/>
</thread-pool>
</thread-pools>
<default-security-domain value="other"/>
<default-missing-method-permissions-deny-access value="true"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:io:1.1">
<worker name="default"/>
<buffer-pool name="default"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:infinispan:2.0">
<cache-container name="web" default-cache="passivation" module="org.wildfly.clustering.web.infinispan">
<local-cache name="passivation" batching="true">
<file-store passivation="true" purge="false"/>
</local-cache>
<local-cache name="persistent" batching="true">
<file-store passivation="false" purge="false"/>
</local-cache>
</cache-container>
<cache-container name="ejb" default-cache="passivation" module="org.wildfly.clustering.ejb.infinispan" aliases="sfsb">
<local-cache name="passivation" batching="true">
<file-store passivation="true" purge="false"/>
</local-cache>
<local-cache name="persistent" batching="true">
<file-store passivation="false" purge="false"/>
</local-cache>
</cache-container>
<cache-container name="hibernate" default-cache="local-query" module="org.hibernate">
<local-cache name="entity">
<transaction mode="NON_XA"/>
<eviction strategy="LRU" max-entries="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="local-query">
<transaction mode="NONE"/>
<eviction strategy="LRU" max-entries="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="timestamps">
<transaction mode="NONE"/>
<eviction strategy="NONE"/>
</local-cache>
</cache-container>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>
<subsystem xmlns="urn:jboss:domain:jca:2.0">
<archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
<bean-validation enabled="true"/>
<default-workmanager>
<short-running-threads>
<core-threads count="50"/>
<queue-length count="50"/>
<max-threads count="50"/>
<keepalive-time time="10" unit="seconds"/>
</short-running-threads>
<long-running-threads>
<core-threads count="50"/>
<queue-length count="50"/>
<max-threads count="50"/>
<keepalive-time time="10" unit="seconds"/>
</long-running-threads>
</default-workmanager>
<cached-connection-manager/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jdr:1.0"/>
<subsystem xmlns="urn:jboss:domain:jmx:1.3">
<expose-resolved-model/>
<expose-expression-model/>
<remoting-connector/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jpa:1.1">
<jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jsf:1.0"/>
<subsystem xmlns="urn:jboss:domain:mail:2.0">
<mail-session name="default" jndi-name="java:jboss/mail/Default">
<smtp-server outbound-socket-binding-ref="mail-smtp"/>
</mail-session>
</subsystem>
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<remote-naming/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:pojo:1.0"/>
<subsystem xmlns="urn:jboss:domain:remoting:2.0">
<endpoint worker="default"/>
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="RemotingRealm"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:resource-adapters:2.0"/>
<subsystem xmlns="urn:jboss:domain:sar:1.0"/>
<subsystem xmlns="urn:jboss:domain:security:1.2">
<security-domains>
<security-domain name="other" cache-type="default">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="RealmDirect" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
</authentication>
</security-domain>
<security-domain name="jboss-web-policy" cache-type="default">
<authorization>
<policy-module code="Delegating" flag="required"/>
</authorization>
</security-domain>
<security-domain name="jboss-ejb-policy" cache-type="default">
<authorization>
<policy-module code="Delegating" flag="required"/>
</authorization>
</security-domain>
<!-- Custom domain -->
<security-domain name="AppRealmLoopThrough" cache-type="default">
<authentication>
<login-module code="Client" flag="required">
<module-option name="multi-threaded" value="true" />
</login-module>
</authentication>
</security-domain>
<security-domain name="xcs-sample-security-domain">
<authentication>
<login-module code="Database" flag="required">
<module-option name="dsJndiName" value="java:jboss/datasources/xcs" />
<module-option name="principalsQuery"
value="SELECT password FROM User WHERE login=?" />
<module-option name="rolesQuery"
value="SELECT role, 'Roles' FROM User WHERE login=?" />
<module-option name="hashAlgorithm" value="MD5"/>
<module-option name="hashEncoding" value="hex"/>
<module-option name="ignorePasswordCase" value="true"/>
</login-module>
</authentication>
</security-domain>
</security-domains>
</subsystem>
<subsystem xmlns="urn:jboss:domain:transactions:2.0">
<core-environment>
<process-id>
<uuid/>
</process-id>
</core-environment>
<recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:undertow:1.2">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
</host>
</server>
<servlet-container name="default">
<jsp-config/>
<websockets/>
</servlet-container>
<handlers>
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers>
<filters>
<response-header name="server-header" header-name="Server" header-value="WildFly/8"/>
<response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
</filters>
</subsystem>
<subsystem xmlns="urn:jboss:domain:webservices:1.2">
<wsdl-host>${jboss.bind.address:127.0.0.1}</wsdl-host>
<endpoint-config name="Standard-Endpoint-Config"/>
<endpoint-config name="Recording-Endpoint-Config">
<pre-handler-chain name="recording-handlers" protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM">
<handler name="RecordingHandler" class="org.jboss.ws.common.invocation.RecordingServerHandler"/>
</pre-handler-chain>
</endpoint-config>
<client-config name="Standard-Client-Config"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:weld:2.0"/>
</profile>
<interfaces>
<interface name="management">
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
</interface>
<interface name="public">
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
</interface>
<interface name="unsecure">
<inet-address value="${jboss.bind.address.unsecure:127.0.0.1}"/>
</interface>
</interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="0">
<socket-binding name="management-http" interface="management" port="9990"/>
<socket-binding name="management-https" interface="management" port="9993"/>
<socket-binding name="ajp" port="8009"/>
<socket-binding name="http" port="8080"/>
<socket-binding name="https" port="8443"/>
<socket-binding name="txn-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/>
<outbound-socket-binding name="mail-smtp">
<remote-destination host="localhost" port="25"/>
</outbound-socket-binding>
</socket-binding-group>
</server>
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="test">
<jta-data-source>java:jboss/datasources/xcs</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns="http://jboss.org/schema/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<extension qualifier="persistence">
<property name="defaultDataSeedStrategy">CLEAN_INSERT</property>
</extension>
<container qualifier="wildfly-embedded-h2" default="true">
<configuration>
<property name="jbossHome">target/wildfly-${wildfly.version}</property>
<property name="modulePath">target/wildfly-${wildfly.version}/modules</property>
</configuration>
</container>
<container qualifier="wildfly-embedded-mysql">
<configuration>
<property name="jbossHome">target/wildfly-${wildfly.version}</property>
<property name="modulePath">target/wildfly-${wildfly.version}/modules</property>
</configuration>
</container>
</arquillian>
\ No newline at end of file
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Pet Store REST</display-name>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<!--Defining security constraint for type of roles available -->
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/api/owner/*</url-pattern>
<http-method-omission>OPTIONS</http-method-omission>
</web-resource-collection>
<auth-constraint>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>owner</web-resource-name>
<url-pattern>/api/pet/*</url-pattern>
<http-method-omission>OPTIONS</http-method-omission>
</web-resource-collection>
<auth-constraint>
<role-name>OWNER</role-name>
</auth-constraint>
</security-constraint>
<!--Defining security constraint for type of roles available -->
<!--Denining security role -->
<security-role>
<role-name>ADMIN</role-name>
</security-role>
<security-role>
<role-name>OWNER</role-name>
</security-role>
<!--Denining security role -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>default</realm-name>
</login-config>
</web-app>
\ No newline at end of file
......@@ -25,6 +25,11 @@
</dependency>
<!-- Testing -->
<dependency>
<groupId>es.uvigo.esei.xcs</groupId>
<artifactId>tests</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
......
......@@ -89,7 +89,7 @@ public class PetService {
* Updates the information of a pet. If the pet is not stored, it will be
* created.
*
* @param pet the pet to be updated.
* @param pet a pet to be updated.
* @throws IllegalArgumentException if the pet has no owner.
* @throws EJBAccessException if the pet's owner is not the current user.
*/
......
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>es.uvigo.esei.xcs</groupId>
<artifactId>sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>tests</artifactId>
<packaging>jar</packaging>
<name>Tests</name>
<description>XCS Sample - Test Utility Classes</description>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>domain</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>java-hamcrest</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
......@@ -8,6 +8,11 @@ import java.util.Date;
import java.util.Set;
public class OwnersDataset {
public static final String EXISTENT_LOGIN = "pepe";
public static final String NON_EXISTENT_LOGIN = "non-existent";
public static final String OWNER_WITH_PETS_LOGIN = "juan";
public static final String OWNER_WITHOUT_PETS_LOGIN = "lorena";
public static Owner owner(String login) {
return stream(owners())
.filter(owner -> owner.getLogin().equals(login))
......@@ -32,9 +37,9 @@ public class OwnersDataset {
public static Owner[] owners() {
return new Owner[] {
new Owner("pepe", "pepepass",
new Owner(EXISTENT_LOGIN, "pepepass",
new Pet(1, "Pepecat", AnimalType.CAT, new Date(946684861000L))),
new Owner("juan", "juanpass",
new Owner(OWNER_WITH_PETS_LOGIN, "juanpass",
new Pet(2, "Max", AnimalType.CAT, new Date(946684861000L)),
new Pet(3, "Juandog", AnimalType.DOG, new Date(946684861000L))
),
......@@ -43,7 +48,7 @@ public class OwnersDataset {
new Pet(5, "Max", AnimalType.DOG, new Date(946684861000L)),
new Pet(6, "Anabird", AnimalType.BIRD, new Date(946684861000L))
),
new Owner("lorena", "lorenapass")
new Owner(OWNER_WITHOUT_PETS_LOGIN, "lorenapass")
};
}
......@@ -79,11 +84,11 @@ public class OwnersDataset {
}
public static Owner ownerWithPets() {
return owners()[1];
return owner(OWNER_WITH_PETS_LOGIN);
}
public static Owner ownerWithoutPets() {
return owners()[3];
return owner(OWNER_WITHOUT_PETS_LOGIN);
}
public static Pet anyPet() {
......@@ -98,14 +103,26 @@ public class OwnersDataset {
return new Pet("Lorenacat", AnimalType.CAT, new Date(946684861000L), owner);
}
public static String anyLogin() {
return EXISTENT_LOGIN;
}
public static String existentLogin() {
return "pepe";
return EXISTENT_LOGIN;
}
public static String nonExistentLogin() {
return NON_EXISTENT_LOGIN;
}
public static String existentPetName() {
return "Pepecat";
}
public static String nonExistentPetName() {
return "NonExistentPet";
}
public static int existentPetId() {
return 2;
}
......@@ -113,4 +130,9 @@ public class OwnersDataset {
public static int nonExistentPetId() {
return 1000000;
}
public static Owner nonExistentOwner() {
final String login = nonExistentLogin();
return new Owner(login, login + "pass");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment