Before You Begin
Purpose
This tutorial shows you how to develop a standalone web service with Jersey and Grizzly, and how to integrate the caching feature of Oracle Application Container Cloud Service using the REST API.
Time to Complete
30 minutes approximately
Background
The new caching capability of Oracle Application Container Cloud Service allows applications to accelerate access to data, share data among applications, and off-load state management.
The caching feature of Oracle Application Container Cloud Service can be accessed from your application through the REST API. The REST API defines the following endpoints:
Method | URL | Description |
---|---|---|
GET | /ccs/{cacheName}/{key} | Retrieves the value associated with the specified key |
PUT | /ccs/{cacheName}/{key} | Stores the value and associates it with the specified key |
POST | /ccs/{cacheName}/{key} | Issues one of the following: putIfAbsent, replace, or removeValue |
DELETE | /ccs/{cacheName}/{key} | Deletes a key/value pair from a cache |
GET | /ccs/{cacheName} | Returns the server-side metrics for the specified cache. |
DELETE | /ccs/{cacheName} | Clears the specified cache. |
The caching REST API uses JSON as data the exchange format.
Scenario
In this tutorial, you create a self-contained application using Jersey and Grizzly. The application implements the CRUD (Create, Read, Update, and Delete) operations on an employee object. Each operation implements the caching feature of Oracle Application Container Cloud Service. You use Maven to resolve the application dependencies and create the archive to deploy the application on Oracle Application Container Cloud Service. You test the REST service by using an HTML client developed with Angular and Bootstrap. This tutorial doesn't cover how to implement the client. The client project is provided in the "What do You Need?" section.
What Do You Need?
- An Oracle Cloud account with Oracle Application Cloud Container Service
- Java Development Kit 8 (JDK 8)
- Maven 3.0+
- Employee client HTML
Creating a Caching Service
- In a web browser, go to https://cloud.oracle.com/home and click Sign In.
- From the Cloud Account menu, select Traditional Cloud Account, select your data center, and click My Services.
- Enter your identity domain and click Go.
- Enter your cloud account credentials and click Sign In.
- In the Oracle Cloud My Services dashboard, click Action
, click Services, and select Application Container.
- Click Menu and select Application Cache.
- Click Create Instance.
- In the Service Name field enter
MyCachingService
, keep the default values, and then click Next:View ImageDescription of this image - In the Confirmation page, click Create.
Creating the Web Service
-
Open a command-line window (or a terminal in Linux).
-
Go to the directory where the new project will reside.
-
Create the Jersey application:
mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-grizzly2 -DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false -DgroupId=com.example.caching -DartifactId=jersey-service-caching -Dpackage=com.example.caching -DarchetypeVersion=2.25
-
Open the
pom.xml
file located in the root directory (jersey-service-caching
) in a text editor. -
Update the Maven Compiler Plugin to use the JDK 1.8.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin> -
Add the
jersey-media-json-jackson
dependency inside the<dependencies>
tags, and then save and close the file.<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency> -
In the
com.example.accs.caching
package, create theEmployee
class.The
Employee
class is a Plain Old Java Object (POJO) that contains the employee properties and their getters and setters methods to access to the properties.View Employee class/* Copyright © 2018 Oracle and/or its affiliates. All rights reserved. */
package com.example.caching;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Employee {
private long id;
private String firstName;
private String lastName;
private String birthDate;
private String title;
private String dept;
private String email;
private String phone;
private static int countId = 0;
public Employee() {
}
public Employee(String firstName, String lastName, String birthDate,
String title, String dept, String email, String phone) {
countId++;
this.id = countId;
this.firstName = firstName;
this.lastName = lastName;
this.birthDate = birthDate;
this.title = title;
this.dept = dept;
this.email = email;
this.phone = phone;
}
public Employee(long id, String firstName, String lastName, String birthDate,
String title, String dept, String email, String phone) {
this(firstName, lastName, birthDate, title, dept, email, phone);
this.id = id;
}
@JsonProperty
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@JsonProperty
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@JsonProperty
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@JsonProperty
public String getBirthDate() {
return birthDate;
}
public void setBirthDate(String birthDate) {
this.birthDate = birthDate;
}
@JsonProperty
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@JsonProperty
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
@JsonProperty
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@JsonProperty
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
} -
Create the
EmployeeList
class.The
EmployeeList
class is a helper class designed to store the employee records in memory and preload a few records.View EmployeeList class/* Copyright © 2017 Oracle and/or its affiliates. All rights reserved. */
package com.example.caching;
import java.util.concurrent.CopyOnWriteArrayList;
public class EmployeeList {
private static final CopyOnWriteArrayList<Employee> employeeList = new CopyOnWriteArrayList<>();
private EmployeeList(){
}
static{
employeeList.add(new Employee("John","Smith","12-12-1980","Manager","Sales","john.smith@example.com","923-814-0502"));
employeeList.add(new Employee("Laura","Adams","02-11-1979","Manager","IT","laura.adams@example.com","293-596-3547"));
employeeList.add(new Employee("Peter","Williams","22-10-1966","Coordinator","HR","peter.williams@example.com","923-814-0502"));
employeeList.add(new Employee("Joana","Sanders","11-11-1976","Manager","Marketing","joana.sanders@example.com","730-715-4446"));
employeeList.add(new Employee("John","Drake","18-08-1988","Coordinator","Finance","john.drake@example.com","769-569-1789"));
employeeList.add(new Employee("Samuel","Williams","22-03-1985","Coordinator","Finance","samuel.williams@example.com","429-071-2018"));
}
public static CopyOnWriteArrayList <Employee> getInstance(){
return employeeList;
}
} Create the
EmployeeDAO
class.The
EmployeeDAO
class isn't a real DAO, it simulates the persistence layer in the application. It contains the basic methods found in a DAO. However, instead of using a database, it stores data in memory to keep the example simple.View EmployeeDAO class/* Copyright © 2017 Oracle and/or its affiliates. All rights reserved. */
package com.example.caching;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import javax.ws.rs.core.Response;
public class EmployeeDAO {
private final CopyOnWriteArrayList<Employee> employeeList = EmployeeList.getInstance();
private final static Logger LOGGER = Logger.getLogger(EmployeeDAO.class.getName());
public Employee[] getAll() {
LOGGER.log(Level.INFO, "EmployeeDao getAll method");
return employeeList.toArray(new Employee[0]);
}
public Employee findById(long id) {
LOGGER.log(Level.INFO, "EmployeeDao getById method");
Optional<Employee> match
= employeeList.stream()
.filter(e -> e.getId() == id)
.findFirst();
if (match.isPresent()) {
return match.get();
} else {
return null;
}
}
public List<Employee> findByLastName(String lastName) {
LOGGER.log(Level.INFO, "EmployeeDao findByLastName method");
List<Employee> employees
= employeeList.stream()
.filter(e -> e.getLastName().equals(lastName))
.collect(Collectors.toList());
return employees;
}
public List<Employee> findByDepartment(String department) {
LOGGER.log(Level.INFO, "EmployeeDao findByLastName method");
List<Employee> employees
= employeeList.stream()
.filter(e -> e.getDept().equals(department))
.collect(Collectors.toList());
return employees;
}
public List<Employee> findByTitle(String title) {
LOGGER.log(Level.INFO, "EmployeeDao findByTitle method");
List<Employee> employees = employeeList.stream()
.filter(e -> e.getTitle().equals(title)).collect(Collectors.toList());
return employees;
}
public Response insert(Employee employee) {
LOGGER.log(Level.INFO, "EmployeeDao insert method");
employeeList.add(employee);
return Response.status(201).build();
}
public boolean update(long id, Employee employee) {
LOGGER.log(Level.INFO, "EmployeeDao update method");
int matchIdx = 0;
Optional<Employee> match = employeeList.stream()
.filter(e -> e.getId() == id)
.findFirst();
if (match.isPresent()) {
matchIdx = employeeList.indexOf(match.get());
employeeList.set(matchIdx, employee);
return true;
} else {
return false;
}
}
public boolean delete(long id) {
LOGGER.log(Level.INFO, "EmployeeDao delete method " + id);
Predicate<Employee> employee = e -> e.getId() == id;
if (!employeeList.removeIf(employee)) {
LOGGER.log(Level.INFO,"Employee removed");
return false;
} else {
return true;
}
}
}Create the
EmployeeResource
class.The
EmployeeResource
class defines the endpoint/employees
and responds to theGET, POST, DELETE,
andPUT
HTTP methods.View EmployeeResource class/* Copyright © 2017 Oracle and/or its affiliates. All rights reserved. */
package com.example.caching;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
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.MediaType;
import javax.ws.rs.core.Response;
@Path("/employees")
public class EmployeeResource {
private final static Logger LOGGER = Logger.getLogger(EmployeeResource.class.getName());
private final EmployeeDAO employeeDao = new EmployeeDAO();
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getAllEmployees() {
LOGGER.log(Level.INFO, "GET Method");
return Response.ok(employeeDao.getAll()) //200
.build();
}
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getEmployee(@PathParam("id") long id) {
LOGGER.log(Level.INFO, "GET Method by ID");
Employee employee = employeeDao.findById(id);
return Response.ok(employee) //200
.build();
}
@GET
@Path("{searchCriteria}/{searchValue}")
public Response searchEmployees(@PathParam("searchCriteria") String searchCriteria, @PathParam("searchValue") String searchValue) throws Exception {
List<Employee> employees = null;
if (searchCriteria.equals("title")) {
employees = employeeDao.findByTitle(searchValue);
} else if (searchCriteria.equals("lastname")) {
employees = employeeDao.findByLastName(searchValue);
} else if (searchCriteria.equals("department")) {
employees = employeeDao.findByDepartment(searchValue);
} else {
throw new Exception("Filter criteria not valid");
}
return Response.ok() //200
.entity(employees.toArray(new Employee[0]))
.build();
}
@POST
@Produces(MediaType.APPLICATION_JSON)
public Response addEmployee(Employee employee) {
LOGGER.log(Level.INFO, "POST Method");
employeeDao.insert(employee);
return Response.status(201)
.build();
}
@PUT
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response updateEmployee(@PathParam("id") long id, Employee employee) {
LOGGER.log(Level.INFO, "PUT Method {0}", id);
boolean response = employeeDao.update(id, employee);
if (response) {
return Response.status(Response.Status.OK)
.build();
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
}
@DELETE
@Path("{id}")
public void deleteEmployee(@PathParam("id") long id) {
LOGGER.log(Level.INFO, "DELETE Method {0}", id);
boolean response = employeeDao.delete(id);
if (!response) {
throw new NotFoundException("Error Employee " + id + " not found");
}
}
}Create the
CrossOriginEmployeeFilter
class.Browsers and applications usually prevent calling REST services from different sources. Thus, if you run the client on Server A and the REST services on Server B, then you must provide a list of known clients in Server B by using the Access-Control headers. Clients check these headers to allow invocation of a service. This is used to prevent cross-site scripting attacks (XSS). To allow external clients to make calls to our application, we create a filter to add the headers to the response.
View CrossOriginEmployeeFilter class/* Copyright © 2017 Oracle and/or its affiliates. All rights reserved. */
package com.example.caching;
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 CrossOriginEmployeeFilter implements ContainerResponseFilter{
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");
responseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
}
}Open the
Main
class, and in thestartServer
method, register theCrossOriginEmployeeFilter
class filter.public static HttpServer startServer() {
final ResourceConfig rc = new ResourceConfig().packages("com.example.caching ");
rc.register(CrossOriginEmployeeFilter.class); //Registering the new filter
return GrizzlyHttpServerFactory.createHttpServer(URI.create(new Main().BASE_URI), rc);
}
Implementing the Caching Feature in Your Application
Create the
CacheClient
class.The
CacheClient
class contains thedelete, get, put,
andreplace.
Each method implements the HTTP request to the caching API.When you add a cache cluster to your application on Oracle Application Container Cloud Service, the
CACHING_INTERNAL_CACHE_URL
environment variable is generated. This environment variable contains the host name of the cache. In your code you must read this environment variable to generate the URL of the caching API. By default, the port is 8080. The complete path of the Caching REST API is:http://CACHING_INTERNAL_CACHE_URL:8080/ccs
View CacheClient class/* Copyright © 2017 Oracle and/or its affiliates. All rights reserved. */
package com.example.caching;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
public class CacheClient {
private final static Logger LOGGER = Logger.getLogger(CacheClient.class.getName());
// Environment variable that holds CCS service name
private static final String CCS_ENV_NAME = "CACHING_INTERNAL_CACHE_URL";
private static final String CACHE_HOST = System.getenv(CCS_ENV_NAME);
// REST port is 8080
private static final String REST_PORT = "8080";
// Cache name to use for the test
/*
For our example application, we will name our cache 'testcache'.
Note that a single caching service can support multiple, individual named caches.
*/
private static final String CACHE_NAME = "testcache";
private static final String CACHE_URL = "http://" + CACHE_HOST + ":" + REST_PORT + "/ccs";
private static final WebTarget target = ClientBuilder.newClient().target(CACHE_URL);
;
public Employee get(long id) {
LOGGER.log(Level.INFO,"CacheClient get method");
Employee employee = null;
try {
Response getResponse = target
.path(CACHE_NAME + "/" + id)
.request(MediaType.APPLICATION_OCTET_STREAM)
.get();
LOGGER.log(Level.INFO, "Status GET method {0}", getResponse.getStatus());
if (getResponse.getStatus() != 404) { // 404 = Key not found error.
String response = getResponse.readEntity(String.class);
LOGGER.log(Level.INFO,"Response " + response);
ObjectMapper mapper = new ObjectMapper();
employee = mapper.readValue(response, Employee.class);
}
} catch (Exception e) {
e.printStackTrace();
}
return employee;
}
public boolean put(long id, Employee employee) {
LOGGER.log(Level.INFO,"CacheClient put method");
boolean result = false;
try {
Response putResponse = target
.path(CACHE_NAME + "/" + id)
.request(MediaType.APPLICATION_JSON_TYPE)
.put(Entity.json(employee));
LOGGER.log(Level.INFO,"Status PUT method " + putResponse.getStatus());
if (putResponse.getStatus() == 204) { //Successful!
result = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public boolean replace(long id, Employee employee) {
System.out.println("CacheClient replace method");
boolean result = false;
try {
Response replaceResponse = target
.path(CACHE_NAME + "/" + id)
.request()
.header("X-Method", "replace")
.post(Entity.json(employee));
LOGGER.log(Level.INFO,"Status REPLACE method " + replaceResponse.getStatus());
if (replaceResponse.getStatus() == 204) { //Successful!
result = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public void delete(long id) {
LOGGER.log(Level.INFO,"CacheClient delete method");
try {
Response deleteResponse = target
.path(CACHE_NAME + "/" + id)
.request()
.delete();
LOGGER.log(Level.INFO,"Status DELETE method " + deleteResponse.getStatus());
} catch (Exception e) {
e.printStackTrace();
}
}
}Open the
EmployeeResource
class in a text editor.Add the
cache
member variable of theCacheClient
class.View the codeprivate final CacheClient cache = new CacheClient();
Edit the
getEmployee, addEmployee, updateEmployee,
anddeleteEmployee
methods to use the cache.View the code@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getEmployee(@PathParam("id") long id) {
LOGGER.log(Level.INFO, "GET Method by ID");
Employee employee = cache.get(id);
if (employee == null) {
employee = employeeDao.findById(id);
}
return Response.ok(employee) //200
.build();
}
@POST
@Produces(MediaType.APPLICATION_JSON)
public Response addEmployee(Employee employee) {
LOGGER.log(Level.INFO, "POST Method");
employeeDao.insert(employee);
cache.put(employee.getId(), employee);
return Response.status(201)
.build();
}
@PUT
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response updateEmployee(@PathParam("id") long id, Employee employee) {
LOGGER.log(Level.INFO, "PUT Method {0}", id);
boolean response = employeeDao.update(id, employee);
if (response) {
cache.replace(id, employee);
return Response.status(Response.Status.OK)
.build();
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
}
@DELETE
@Path("{id}")
public void deleteEmployee(@PathParam("id") long id) {
LOGGER.log(Level.INFO, "DELETE Method {0}", id);
boolean response = employeeDao.delete(id);
if (!response) {
throw new NotFoundException("Error Employee " + id + " not found");
} else {
cache.delete(id);
Response.status(Response.Status.OK)
.build();
}
}
Preparing the Application for Cloud Deployment
For your service application to run properly on Oracle Application Container Cloud Service, it must comply with the following requirements:
- The application must be bundled in a .zip file.
- The .zip file must contain all the project dependencies or a fat JAR, and the
manifest.json
file that specifies what command Oracle Application Container Cloud Service should run and the Java version. - Your application must listen to requests on a port provided by the
PORT
environment variable. Oracle Application Container Cloud uses this port to redirect requests made to your application. - The embedded server must run on
0.0.0.0.
The0.0.0.0,
specification ensures that the server will bind to all IPs, allowing the server to be accessed from external devices through the machine's IP or host name.
-
Create the
manifest.json
file in the root directory and add the following content:{ "runtime": { "majorVersion": "8" }, "command": "java -jar jersey-service-caching-1.0-SNAPSHOT.jar", "isClustered":"true" }
Note: To use the caching feature on Oracle Application Container Cloud Service isClustered=true is required.
-
Create the
assembly
directory in thesrc
folder. -
Create the
distribution.xml
file in theassembly
folder and add the following content:View code<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>dist</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>manifest.json</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>jersey-service-caching-1.0-SNAPSHOT.jar</include>
</includes>
<excludes>
<exclude>*.zip</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
-
Open the
pom.xml
file in a text editor and add following code inside the<plugins>
tags.The Maven Shade Plugin generates the fat JAR:
jersey-service-caching-1.0-SNAPSHOT.jar,
which contains the project classes and its dependencies. The Maven Shade Plugin creates the zip file:jersey-service-caching-1.0-SNAPSHOT.zip
to deploy the application on Oracle Application Container Cloud Service.View code<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.caching.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/assembly/distribution.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin> -
Open the
Main
class and add thejava.util.Optional
import.import java.util.Optional;
Open the
Main
class and update theBASE_URI
variable to use thePORT
environment variable and the0.0.0.0
host name.private static final Optional<String> port = Optional.ofNullable(System.getenv("PORT"));
public static final String BASE_URI = "http://0.0.0.0:"+port.orElse("8080")+"/myapp/";-
In the command-line window, build your application using the Maven command:
mvn clean package
Look at the
target
directory and you'll find thejersey-service-caching-1.0-SNAPSHOT.zip
file. You'll use this file to deploy your application to Oracle Application Container Cloud Service.
The distribution.xml
script creates a zip
file that includes
the fat JAR (jersey-service-caching-1.0-SNAPSHOT.jar)
and the manifest.json
file.
Deploying the Application to Oracle Application Cloud Service
-
Go back to the Oracle Application Container Cloud Service console.
-
In the Applications list view, click Create Application, and select Java SE.
-
In the Application section, enter a name for your application, and then click Choose File next to Application.
-
In the File Upload dialog box, select the
jersey-service-caching-1.0-SNAPSHOT.zip
file, and click Open. -
In the Application section, click More Options.
-
In More Options section, select the following values, leave the other fields with their default values, and then click Create:
- Metering Frecuency: Monthly
- Application Cache: MyCachingService
View ImageDescription of this image Wait until the application is deployed, and then click the URL.
View ImageDescription of this image Add
/myapp/employees
to the end of the URL.View ImageDescription of this image Write down the URL, you'll use it in the next section.
Testing the Application
Extract the content of the
employee-client.zip
file in your local system.Open the
EmployeeController.js
file in a text editor.Replace the value of the
urlService
variable with the URL of your application.$scope.urlService = "http://javaexamplecache-apaasuser-mydomain.apaas.oraclecloud.com/employees";
Open the
index.html
file in a web browser, and then click Add New..View ImageDescription of this image Enter the First Name, Last Name, Email, Phone, Birthdate, Title, and Department values.
View ImageDescription of this image Click Save.
View ImageDescription of this image Test the delete, update and search options.
Getting the Logs
Open the Oracle Application Container Cloud Service console.
Select your application.
View ImageDescription of this image Click Administration, and then click Logs
View ImageDescription of this image Click Get Log.
View ImageDescription of this image -
Select the Instance from which you want get the logs.
View ImageDescription of this image Wait a minute, and then click Refresh.
-
Click the log file you want to download.
View ImageDescription of this image In the Save As dialog box, select a location for the zip file, and click Save.
Extract the content of the zip file and open the
server.out
file in a text editor.Examine the logs to see when the employee object was gotten from the DAO and when it was obtained from the cache.
Want to Learn More?
- Oracle Application Container Cloud Service in the Oracle Help Center
- Using Caches in Oracle Application Container Cloud Service in the Oracle Help Center
- REST API for Caching Applications in the Oracle Help Center