Ravi Srinivasan
2018-09-11 b9209f6413cb6985c0089f9677f4db9b52ca1395
Chap 6 lab code
21 files added
1187 ■■■■■ changed files
labs/hello-rest/.gitignore 5 ●●●●● patch | view | raw | blame | history
labs/hello-rest/README.md 12 ●●●●● patch | view | raw | blame | history
labs/hello-rest/pom.xml 148 ●●●●● patch | view | raw | blame | history
labs/hello-rest/src/main/java/com/redhat/training/messaging/JMSUtil.java 28 ●●●●● patch | view | raw | blame | history
labs/hello-rest/src/main/java/com/redhat/training/messaging/QueueListener.java 59 ●●●●● patch | view | raw | blame | history
labs/hello-rest/src/main/java/com/redhat/training/model/Person.java 62 ●●●●● patch | view | raw | blame | history
labs/hello-rest/src/main/java/com/redhat/training/rest/PersonService.java 154 ●●●●● patch | view | raw | blame | history
labs/hello-rest/src/main/java/com/redhat/training/servlet/PingServlet.java 60 ●●●●● patch | view | raw | blame | history
labs/hello-rest/src/main/java/com/redhat/training/ui/Hello.java 51 ●●●●● patch | view | raw | blame | history
labs/hello-rest/src/main/resources/META-INF/persistence.xml 15 ●●●●● patch | view | raw | blame | history
solutions/hello-rest/.gitignore 5 ●●●●● patch | view | raw | blame | history
solutions/hello-rest/README.md 12 ●●●●● patch | view | raw | blame | history
solutions/hello-rest/pom.xml 148 ●●●●● patch | view | raw | blame | history
solutions/hello-rest/src/main/java/com/redhat/training/messaging/JMSUtil.java 28 ●●●●● patch | view | raw | blame | history
solutions/hello-rest/src/main/java/com/redhat/training/messaging/QueueListener.java 59 ●●●●● patch | view | raw | blame | history
solutions/hello-rest/src/main/java/com/redhat/training/model/Person.java 62 ●●●●● patch | view | raw | blame | history
solutions/hello-rest/src/main/java/com/redhat/training/rest/PersonService.java 144 ●●●●● patch | view | raw | blame | history
solutions/hello-rest/src/main/java/com/redhat/training/rest/Service.java 9 ●●●●● patch | view | raw | blame | history
solutions/hello-rest/src/main/java/com/redhat/training/servlet/PingServlet.java 60 ●●●●● patch | view | raw | blame | history
solutions/hello-rest/src/main/java/com/redhat/training/ui/Hello.java 51 ●●●●● patch | view | raw | blame | history
solutions/hello-rest/src/main/resources/META-INF/persistence.xml 15 ●●●●● patch | view | raw | blame | history
labs/hello-rest/.gitignore
New file
@@ -0,0 +1,5 @@
.classpath
.project
.tern-project
.settings
target
labs/hello-rest/README.md
New file
@@ -0,0 +1,12 @@
# JB125 Java EE 7 Hello World web App
##This app is composed of the following architecture:
* Maven Project - builds a WAR
* Using JSF 2.2 for web interface, HTML5 facelets page, JSF backing beans, CDI scopes on beans, @Named
* Statelss EJB for services - uses JPA entity beans - exposes appropriate method as REST API using JAX-RS annotations
* JAX-RS Application class
* JPA entity bean to store names - uses H2 in-memory database
* Use EJB Singleton to lookup messaging connection and queue destination and inject into stateless EJB - lookup should only occur once on startup
* Servlet that returns "OK" - this is a health check - path should be [context]/health
* H2 (embedded in-memory DB) backend
labs/hello-rest/pom.xml
New file
@@ -0,0 +1,148 @@
<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>
  <artifactId>hello-rest</artifactId>
  <packaging>war</packaging>
  <name>Hello World REST app Project</name>
  <description>This is the hello-rest project</description>
  <parent>
      <groupId>com.redhat.training</groupId>
      <artifactId>parent-pom</artifactId>
      <version>1.0</version>
      <relativePath>../pom.xml</relativePath>
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
    <dependencies>
        <!-- First declare the APIs we depend on and need for compilation. All
            of them are provided by JBoss EAP -->
        <!-- Import the CDI API, we use provided scope as the API is included in
            JBoss EAP -->
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Import the Common Annotations API (JSR-250), we use provided scope
            as the API is included in JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.annotation</groupId>
            <artifactId>jboss-annotations-api_1.2_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Import the JAX-RS API, we use provided scope as the API is included
            in JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.ws.rs</groupId>
            <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Import the JPA API, we use provided scope as the API is included in
            JBoss EAP -->
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Import the EJB API, we use provided scope as the API is included in
            JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.ejb</groupId>
            <artifactId>jboss-ejb-api_3.2_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.spec.javax.jms</groupId>
            <artifactId>jboss-jms-api_2.0_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Bean Validation Implementation -->
        <!-- Provides portable constraints such as @Email -->
        <!-- Hibernate Validator is shipped in JBoss EAP -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <scope>provided</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-search-orm</artifactId>
                 <scope>provided</scope>
            </dependency>
             <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
                 <scope>provided</scope>
            </dependency>
        <!-- Import the JSF API, we use provided scope as the API is included in
            JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.faces</groupId>
            <artifactId>jboss-jsf-api_2.2_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
              <groupId>org.jboss.spec.javax.servlet</groupId>
              <artifactId>jboss-servlet-api_3.1_spec</artifactId>
            <scope>provided</scope>
          </dependency>
        <!-- Annotation processor to generate the JPA metamodel classes for
            typesafe criteria queries -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Annotation processor that raising compilation errors whenever constraint
            annotations are incorrectly used. -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator-annotation-processor</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>hello-rest</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>${version.war.plugin}</version>
                <extensions>false</extensions>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <archive>
                        <manifestEntries>
                            <Dependencies>com.google.guava,org.slf4j
                            </Dependencies>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
labs/hello-rest/src/main/java/com/redhat/training/messaging/JMSUtil.java
New file
@@ -0,0 +1,28 @@
package com.redhat.training.messaging;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.annotation.Resource;
import javax.jms.Queue;
import javax.jms.JMSContext;
import javax.inject.Inject;
@Startup
@Singleton
public class JMSUtil {
    @Resource(mappedName = "java:jboss/jms/queue/helloWorldQueue")
    private Queue helloWorldQueue;
    @Inject
    JMSContext context;
    public void sendMessage(String msg) {
        try {
            context.createProducer().send(helloWorldQueue, msg);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
labs/hello-rest/src/main/java/com/redhat/training/messaging/QueueListener.java
New file
@@ -0,0 +1,59 @@
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc. and/or its affiliates, and individual
 * contributors by the @authors tag. See the copyright.txt in the
 * distribution for a full listing of individual contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.redhat.training.messaging;
import org.jboss.logging.Logger;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/**
 * <p>
 * A simple Message Driven Bean that asynchronously receives and processes the messages that are sent to the queue.
 * </p>
 *
 * @author Serge Pagop (spagop@redhat.com)
 *
 */
@MessageDriven(name = "QueueListener", activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "queue/helloWorldQueue"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })
public class QueueListener implements MessageListener {
    private final static Logger LOGGER = Logger.getLogger(QueueListener.class.getName());
    /**
     * @see MessageListener#onMessage(Message)
     */
    public void onMessage(Message rcvMessage) {
        TextMessage msg = null;
        try {
            if (rcvMessage instanceof TextMessage) {
                msg = (TextMessage) rcvMessage;
                LOGGER.info("Received Message from helloWorldQueue ===> " + msg.getText());
            } else {
                LOGGER.warn("Message of wrong type: " + rcvMessage.getClass().getName());
            }
        } catch (JMSException e) {
            throw new RuntimeException(e);
        }
    }
}
labs/hello-rest/src/main/java/com/redhat/training/model/Person.java
New file
@@ -0,0 +1,62 @@
package com.redhat.training.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NotNull
    @Size(min=2,max=50)
    private String name;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }
}
labs/hello-rest/src/main/java/com/redhat/training/rest/PersonService.java
New file
@@ -0,0 +1,154 @@
package com.redhat.training.rest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
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.UserTransaction;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import com.redhat.training.messaging.JMSUtil;
import com.redhat.training.model.Person;
//TODO Add the stateless annotation
//TODO Add a Path for persons
//TODO Add a Consumes annotation for JSON
//TODO Add a Produces annotation for JSON
@TransactionManagement(TransactionManagementType.BEAN)
public class PersonService {
    @PersistenceContext
    private EntityManager entityManager;
    @Resource
    UserTransaction tx;
    @Inject
    JMSUtil jmsUtil;
    // Simple non-RESTy method for JSF bean invocation
    public String hello(String name) {
        try {
            try {
                // start a new transaction
                tx.begin();
                // let's grab the current date and time on the server
                LocalDateTime today = LocalDateTime.now();
                // format it nicely for on-screen display
                DateTimeFormatter format = DateTimeFormatter.ofPattern("MMM dd yyyy hh:mm:ss a");
                String fdate = today.format(format);
                // Create a new Person object and persist to database
                Person p = new Person();
                p.setName(name);
                entityManager.persist(p);
                // Send a JMS message to the 'helloWorldQueue'
                jmsUtil.sendMessage("Said Hello to " + name.toUpperCase() + " at " + fdate);
                // respond back with Hello and convert the name to UPPERCASE. Also, send the
                // current time on the server.
                return "Hello " + name.toUpperCase() + "!. " + "Time on the server is: " + fdate;
            } finally {
                // commit the transaction
                tx.commit();
            }
        } catch (Exception e) {
            throw new EJBException(e);
        }
    }
    // CRUD RESTful methods below
    // fetch result by Person id
    //TODO add GET annotation
    //TODO add path for ID
    public Person getPerson(Long id) {
        return entityManager.find(Person.class, id);
    }
    // Dump all Person objects in the Database
    //TODO add GET annotation
    public List<Person> getAllPersons() {
        TypedQuery<Person> query = entityManager.createQuery("SELECT p FROM Person p", Person.class);
        List<Person> persons = query.getResultList();
        return persons;
    }
    // delete an object by Person id
    //TODO add DELETE annotation
    //TODO add Path for ID
    public void deletePerson(Long id) {
            try {
                try {
                    tx.begin();
                    entityManager.remove(getPerson(id));
                } finally {
                    tx.commit();
                }
            } catch (Exception e) {
                throw new EJBException();
            }
    }
    // Save a Person object to Database
    //TODO add POST annotation
    public Response savePerson(Person person) {
        try {
            try {
            ResponseBuilder builder;
            if (person.getId() == null) {
                Person newPerson = new Person();
                newPerson.setName(person.getName());
                tx.begin();
                entityManager.persist(newPerson);
                builder = Response.ok();
            } else {
                Person uPerson;
                Person updatePerson = getPerson(person.getId());
                updatePerson.setName(person.getName());
                uPerson = entityManager.merge(updatePerson);
                builder = Response.ok(uPerson);
            }
            return builder.build();
            }finally {
                tx.commit();
            }
        }catch (Exception e) {
            throw new EJBException(e);
        }
    }
}
labs/hello-rest/src/main/java/com/redhat/training/servlet/PingServlet.java
New file
@@ -0,0 +1,60 @@
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc. and/or its affiliates, and individual
 * contributors by the @authors tag. See the copyright.txt in the
 * distribution for a full listing of individual contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.redhat.training.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * <p>
 * A simple servlet taking advantage of features added in 3.0.
 * </p>
 *
 * <p>
 * The servlet is registered and mapped to /HelloServlet using the {@linkplain WebServlet
 * @HttpServlet}.
 * </p>
 *
 * @author Pete Muir
 *
 */
@SuppressWarnings("serial")
@WebServlet("/health")
public class PingServlet extends HttpServlet {
    static String PAGE_HEADER = "<html><head><title>Ping Servlet</title></head><body>";
    static String PAGE_FOOTER = "</body></html>";
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        PrintWriter writer = resp.getWriter();
        writer.println(PAGE_HEADER);
        writer.println("<h1>OK.</h1>");
        writer.println("It is now " + new java.util.Date().toString() + " at the server.");
        writer.println(PAGE_FOOTER);
        writer.close();
    }
}
labs/hello-rest/src/main/java/com/redhat/training/ui/Hello.java
New file
@@ -0,0 +1,51 @@
package com.redhat.training.ui;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.inject.Inject;
import com.redhat.training.rest.PersonService;
@RequestScoped
@Named("hello")
public class Hello {
    private String name;
    @Inject
    private PersonService personService;
    public void sayHello() {
        try {
            String response = personService.hello(name);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(response));
        }catch(Exception e){
            System.out.println(e.getCause());
            if(e.getCause() != null && e.getCause() instanceof ConstraintViolationException) {
                ConstraintViolationException ex = (ConstraintViolationException) e.getCause();
                String violations = "";
                for(ConstraintViolation<?> cv: ex.getConstraintViolations()) {
                    violations += cv.getMessage() + "\n";
                    System.out.println("Violations: "+violations);
                }
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(violations));
            }
        }
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
labs/hello-rest/src/main/resources/META-INF/persistence.xml
New file
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
             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">
    <persistence-unit name="hello" transaction-type="JTA">
        <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
        <properties>
                <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
                <property name="hibernate.hbm2ddl.auto" value="create-drop" />
                <property name="hibernate.show_sql" value="true" />
                <property name="hibernate.format_sql" value="true" />
    </properties>
    </persistence-unit>
</persistence>
solutions/hello-rest/.gitignore
New file
@@ -0,0 +1,5 @@
.classpath
.project
.tern-project
.settings
target
solutions/hello-rest/README.md
New file
@@ -0,0 +1,12 @@
# JB125 Java EE 7 Hello World web App
##This app is composed of the following architecture:
* Maven Project - builds a WAR
* Using JSF 2.2 for web interface, HTML5 facelets page, JSF backing beans, CDI scopes on beans, @Named
* Statelss EJB for services - uses JPA entity beans - exposes appropriate method as REST API using JAX-RS annotations
* JAX-RS Application class
* JPA entity bean to store names - uses H2 in-memory database
* Use EJB Singleton to lookup messaging connection and queue destination and inject into stateless EJB - lookup should only occur once on startup
* Servlet that returns "OK" - this is a health check - path should be [context]/health
* H2 (embedded in-memory DB) backend
solutions/hello-rest/pom.xml
New file
@@ -0,0 +1,148 @@
<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>
  <artifactId>hello-rest-solution</artifactId>
  <packaging>war</packaging>
  <name>Hello World REST app Project -Solution</name>
  <description>This is the hello-rest solution project</description>
  <parent>
      <groupId>com.redhat.training</groupId>
      <artifactId>parent-pom</artifactId>
      <version>1.0</version>
      <relativePath>../pom.xml</relativePath>
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
    <dependencies>
        <!-- First declare the APIs we depend on and need for compilation. All
            of them are provided by JBoss EAP -->
        <!-- Import the CDI API, we use provided scope as the API is included in
            JBoss EAP -->
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Import the Common Annotations API (JSR-250), we use provided scope
            as the API is included in JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.annotation</groupId>
            <artifactId>jboss-annotations-api_1.2_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Import the JAX-RS API, we use provided scope as the API is included
            in JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.ws.rs</groupId>
            <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Import the JPA API, we use provided scope as the API is included in
            JBoss EAP -->
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Import the EJB API, we use provided scope as the API is included in
            JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.ejb</groupId>
            <artifactId>jboss-ejb-api_3.2_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.spec.javax.jms</groupId>
            <artifactId>jboss-jms-api_2.0_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Bean Validation Implementation -->
        <!-- Provides portable constraints such as @Email -->
        <!-- Hibernate Validator is shipped in JBoss EAP -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <scope>provided</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-search-orm</artifactId>
                 <scope>provided</scope>
            </dependency>
             <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
                 <scope>provided</scope>
            </dependency>
        <!-- Import the JSF API, we use provided scope as the API is included in
            JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.faces</groupId>
            <artifactId>jboss-jsf-api_2.2_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
              <groupId>org.jboss.spec.javax.servlet</groupId>
              <artifactId>jboss-servlet-api_3.1_spec</artifactId>
            <scope>provided</scope>
          </dependency>
        <!-- Annotation processor to generate the JPA metamodel classes for
            typesafe criteria queries -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Annotation processor that raising compilation errors whenever constraint
            annotations are incorrectly used. -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator-annotation-processor</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>hello-rest</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>${version.war.plugin}</version>
                <extensions>false</extensions>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <archive>
                        <manifestEntries>
                            <Dependencies>com.google.guava,org.slf4j
                            </Dependencies>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
solutions/hello-rest/src/main/java/com/redhat/training/messaging/JMSUtil.java
New file
@@ -0,0 +1,28 @@
package com.redhat.training.messaging;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.annotation.Resource;
import javax.jms.Queue;
import javax.jms.JMSContext;
import javax.inject.Inject;
@Startup
@Singleton
public class JMSUtil {
    @Resource(mappedName = "java:jboss/jms/queue/helloWorldQueue")
    private Queue helloWorldQueue;
    @Inject
    JMSContext context;
    public void sendMessage(String msg) {
        try {
            context.createProducer().send(helloWorldQueue, msg);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
solutions/hello-rest/src/main/java/com/redhat/training/messaging/QueueListener.java
New file
@@ -0,0 +1,59 @@
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc. and/or its affiliates, and individual
 * contributors by the @authors tag. See the copyright.txt in the
 * distribution for a full listing of individual contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.redhat.training.messaging;
import org.jboss.logging.Logger;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/**
 * <p>
 * A simple Message Driven Bean that asynchronously receives and processes the messages that are sent to the queue.
 * </p>
 *
 * @author Serge Pagop (spagop@redhat.com)
 *
 */
@MessageDriven(name = "QueueListener", activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "queue/helloWorldQueue"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })
public class QueueListener implements MessageListener {
    private final static Logger LOGGER = Logger.getLogger(QueueListener.class.getName());
    /**
     * @see MessageListener#onMessage(Message)
     */
    public void onMessage(Message rcvMessage) {
        TextMessage msg = null;
        try {
            if (rcvMessage instanceof TextMessage) {
                msg = (TextMessage) rcvMessage;
                LOGGER.info("Received Message from helloWorldQueue ===> " + msg.getText());
            } else {
                LOGGER.warn("Message of wrong type: " + rcvMessage.getClass().getName());
            }
        } catch (JMSException e) {
            throw new RuntimeException(e);
        }
    }
}
solutions/hello-rest/src/main/java/com/redhat/training/model/Person.java
New file
@@ -0,0 +1,62 @@
package com.redhat.training.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NotNull
    @Size(min=2,max=50)
    private String name;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }
}
solutions/hello-rest/src/main/java/com/redhat/training/rest/PersonService.java
New file
@@ -0,0 +1,144 @@
package com.redhat.training.rest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
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.UserTransaction;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import com.redhat.training.messaging.JMSUtil;
import com.redhat.training.model.Person;
@Stateless
@Path("persons")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@TransactionManagement(TransactionManagementType.BEAN)
public class PersonService {
    @PersistenceContext
    private EntityManager entityManager;
    @Resource
    UserTransaction tx;
    @Inject
    JMSUtil jmsUtil;
    // Simple non-RESTy method for JSF bean invocation
    public String hello(String name) {
        try {
            try {
                // start a new transaction
                tx.begin();
                // let's grab the current date and time on the server
                LocalDateTime today = LocalDateTime.now();
                // format it nicely for on-screen display
                DateTimeFormatter format = DateTimeFormatter.ofPattern("MMM dd yyyy hh:mm:ss a");
                String fdate = today.format(format);
                // Create a new Person object and persist to database
                Person p = new Person();
                p.setName(name);
                entityManager.persist(p);
                // Send a JMS message to the 'helloWorldQueue'
                jmsUtil.sendMessage("Said Hello to " + name.toUpperCase() + " at " + fdate);
                // respond back with Hello and convert the name to UPPERCASE. Also, send the
                // current time on the server.
                return "Hello " + name.toUpperCase() + "!. " + "Time on the server is: " + fdate;
            } finally {
                // commit the transaction
                tx.commit();
            }
        } catch (Exception e) {
            throw new EJBException(e);
        }
    }
    // CRUD RESTful methods below
    // fetch result by Person id
    @GET
    @Path("{id}")
    public Person getPerson(@PathParam("id") Long id) {
        return entityManager.find(Person.class, id);
    }
    // Dump all Person objects in the Database
    @GET
    public List<Person> getAllPersons() {
        TypedQuery<Person> query = entityManager.createQuery("SELECT p FROM Person p", Person.class);
        List<Person> persons = query.getResultList();
        return persons;
    }
    // delete an object by Person id
    @DELETE
    @Path("{id}")
    public void deletePerson(@PathParam("id") Long id) {
        try {
            try {
                tx.begin();
                entityManager.remove(getPerson(id));
            } finally {
                tx.commit();
            }
        } catch (Exception e) {
            throw new EJBException();
        }
    }
    // Save a Person object to Database
    @POST
    public Response savePerson(Person person) {
        try {
            try {
            ResponseBuilder builder;
            if (person.getId() == null) {
                Person newPerson = new Person();
                newPerson.setName(person.getName());
                tx.begin();
                entityManager.persist(newPerson);
                builder = Response.ok();
            } else {
                Person uPerson;
                Person updatePerson = getPerson(person.getId());
                updatePerson.setName(person.getName());
                uPerson = entityManager.merge(updatePerson);
                builder = Response.ok(uPerson);
            }
            return builder.build();
            }finally {
                tx.commit();
            }
        }catch (Exception e) {
            throw new EJBException(e);
        }
    }
}
solutions/hello-rest/src/main/java/com/redhat/training/rest/Service.java
New file
@@ -0,0 +1,9 @@
package com.redhat.training.rest;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/api")
public class Service extends Application {
}
solutions/hello-rest/src/main/java/com/redhat/training/servlet/PingServlet.java
New file
@@ -0,0 +1,60 @@
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc. and/or its affiliates, and individual
 * contributors by the @authors tag. See the copyright.txt in the
 * distribution for a full listing of individual contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.redhat.training.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * <p>
 * A simple servlet taking advantage of features added in 3.0.
 * </p>
 *
 * <p>
 * The servlet is registered and mapped to /HelloServlet using the {@linkplain WebServlet
 * @HttpServlet}.
 * </p>
 *
 * @author Pete Muir
 *
 */
@SuppressWarnings("serial")
@WebServlet("/health")
public class PingServlet extends HttpServlet {
    static String PAGE_HEADER = "<html><head><title>Ping Servlet</title></head><body>";
    static String PAGE_FOOTER = "</body></html>";
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        PrintWriter writer = resp.getWriter();
        writer.println(PAGE_HEADER);
        writer.println("<h1>OK.</h1>");
        writer.println("It is now " + new java.util.Date().toString() + " at the server.");
        writer.println(PAGE_FOOTER);
        writer.close();
    }
}
solutions/hello-rest/src/main/java/com/redhat/training/ui/Hello.java
New file
@@ -0,0 +1,51 @@
package com.redhat.training.ui;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.inject.Inject;
import com.redhat.training.rest.PersonService;
@RequestScoped
@Named("hello")
public class Hello {
    private String name;
    @Inject
    private PersonService personService;
    public void sayHello() {
        try {
            String response = personService.hello(name);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(response));
        }catch(Exception e){
            System.out.println(e.getCause());
            if(e.getCause() != null && e.getCause() instanceof ConstraintViolationException) {
                ConstraintViolationException ex = (ConstraintViolationException) e.getCause();
                String violations = "";
                for(ConstraintViolation<?> cv: ex.getConstraintViolations()) {
                    violations += cv.getMessage() + "\n";
                    System.out.println("Violations: "+violations);
                }
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(violations));
            }
        }
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
solutions/hello-rest/src/main/resources/META-INF/persistence.xml
New file
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
             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">
    <persistence-unit name="hello" transaction-type="JTA">
        <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
        <properties>
                <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
                <property name="hibernate.hbm2ddl.auto" value="create-drop" />
                <property name="hibernate.show_sql" value="true" />
                <property name="hibernate.format_sql" value="true" />
    </properties>
    </persistence-unit>
</persistence>