mac 4 years ago
parent
commit
750e0c40bd
15 changed files with 1218 additions and 0 deletions
  1. 19
      jboss-fuse-cxf-rest-local/.gitignore
  2. 107
      jboss-fuse-cxf-rest-local/README.md
  3. 109
      jboss-fuse-cxf-rest-local/configuration/settings.xml
  4. 363
      jboss-fuse-cxf-rest-local/pom.xml
  5. 52
      jboss-fuse-cxf-rest-local/src/main/java/io/fabric8/quickstarts/rest/Customer.java
  6. 224
      jboss-fuse-cxf-rest-local/src/main/java/io/fabric8/quickstarts/rest/CustomerService.java
  7. 113
      jboss-fuse-cxf-rest-local/src/main/java/io/fabric8/quickstarts/rest/Order.java
  8. 52
      jboss-fuse-cxf-rest-local/src/main/java/io/fabric8/quickstarts/rest/Product.java
  9. 18
      jboss-fuse-cxf-rest-local/src/main/java/io/fabric8/quickstarts/rest/package-info.java
  10. 75
      jboss-fuse-cxf-rest-local/src/main/resources/OSGI-INF/blueprint/blueprint.xml
  11. 43
      jboss-fuse-cxf-rest-local/src/main/resources/features.xml
  12. 1
      jboss-fuse-cxf-rest-local/src/test/resources/add_customer.json
  13. 3
      jboss-fuse-cxf-rest-local/src/test/resources/add_customer.xml
  14. 35
      jboss-fuse-cxf-rest-local/src/test/resources/log4j.properties
  15. 4
      jboss-fuse-cxf-rest-local/src/test/resources/update_customer.xml

19
jboss-fuse-cxf-rest-local/.gitignore

@ -0,0 +1,19 @@
target
.idea
*.iml
*.im
*.ipr
*.iws
overlays
.DS_Store
.settings
*.swp
*.log
.project
.classpath
*.fmd
.cache
dependency-reduced-pom.xml
kube-cluster/kubernetes
apps/modifiedFabric8.json
git-clones

107
jboss-fuse-cxf-rest-local/README.md

@ -0,0 +1,107 @@
# Karaf CXF REST QuickStart
This quickstart demonstrates how to create a RESTful (JAX-RS) web service using CXF and expose it through the OSGi HTTP Service.
The REST service provides a customer service that supports the following operations
- PUT /customerservice/customers/ - to create or update a customer
- GET /customerservice/customers/{id} - to view a customer with the given id
- DELETE /customerservice/customers/{id} - to delete a customer with the given id
- GET /customerservice/orders/{orderId} - to view an order with the given id
- GET /customerservice/orders/{orderId}/products/{productId} - to view a specific product on an order with the given id
When the application is deployed, you can access the REST service using a web browser.
### Building
The example can be built with
mvn clean install
### Running the example in fabric8
It is assumed that OpenShift platform is already running. If not you can find details how to [Install OpenShift at your site](https://docs.openshift.com/enterprise/3.1/install_config/install/index.html).
The example can be built and deployed using a single goal:
mvn -Pf8-deploy
When the example runs in OpenShift, you can use the OpenShift client tool to inspect the status
To list all the running pods:
oc get pods
Then find the name of the pod that runs this quickstart, and output the logs from the running pods with:
oc logs <name of pod>
You can also use the OpenShift [web console](https://docs.openshift.com/enterprise/3.1/getting_started/developers/developers_console.html#tutorial-video) to manage the
running pods, and view logs and much more.
### Access services using a web browser
You can use any browser to perform a HTTP GET. This allows you to very easily test a few of the RESTful services we defined:
Notice: As it depends on your OpenShift setup, the hostname (route) might vary. Verify with `oc get routes` which
hostname is valid for you
Use this URL to display the root of the REST service, which also allows to access the WADL of the service:
http://quickstart-cxf-rest.vagrant.f8/cxf/crm
Use this URL to display the XML representation for customer 123:
http://quickstart-cxf-rest.vagrant.f8/cxf/crm/customerservice/customers/123
You can also access the XML representation for order 223 ...
http://quickstart-cxf-rest.f8/cxf/crm/customerservice/customers/123
**Note:** if you use Safari, you will only see the text elements but not the XML tags - you can view the entire document with 'View Source'
### To run a command-line utility:
You can use a command-line utility, such as cURL or wget, to perform the HTTP requests. We have provided a few files with sample XML representations in `src/test/resources`, so we will use those for testing our services.
1. Open a command prompt and change directory to `cxf-cdi`.
2. Run the following curl commands (curl commands may not be available on all platforms):
* Create a customer
curl -X POST -T src/test/resources/add_customer.xml -H "Content-Type: text/xml" http://quickstart-cxf-rest.f8/cxf/crm/customerservice/customers
* Retrieve the customer instance with id 123
curl http://quickstart-cxf-rest.f8/cxf/crm/customerservice/customers/123
* Update the customer instance with id 123
curl -X PUT -T src/test/resources/update_customer.xml -H "Content-Type: text/xml" http://quickstart-cxf-rest.f8/cxf/crm/customerservice/customers
* Delete the customer instance with id 123
curl -X DELETE http://quickstart-cxf-rest.f8/cxf/crm/customerservice/customers/123
### Running the example using OpenShift S2I template
The example can also be built and run using the included S2I template quickstart-template.json.
The application can be run directly by first editing the template file and populating S2I build parameters, including the required parameter GIT_REPO and then executing the command:
oc new-app -f quickstart-template.json
Alternatively the template file can be used to create an OpenShift application template by executing the command:
oc create -f quickstart-template.json
### More details
You can find more details about running this [quickstart](http://fabric8.io/guide/quickstarts/running.html) on the website. This also includes instructions how to change the Docker image user and registry.

109
jboss-fuse-cxf-rest-local/configuration/settings.xml

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2005-2016 Red Hat, Inc.
Red Hat licenses this file to you 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.
-->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<profiles>
<profile>
<id>fusesource.repo</id>
<repositories>
<repository>
<id>fusesource.m2</id>
<name>FuseSource Community Release Repository</name>
<url>https://repo.fusesource.com/nexus/content/groups/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</repository>
<repository>
<id>fusesource.ea</id>
<name>FuseSource Community Early Access Release Repository</name>
<url>https://repo.fusesource.com/nexus/content/groups/ea</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</repository>
<repository>
<id>redhat.ga</id>
<name>Red Hat General Availability Repository</name>
<url>https://maven.repository.redhat.com/ga</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>fusesource.m2</id>
<name>FuseSource Community Release Repository</name>
<url>https://repo.fusesource.com/nexus/content/groups/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
<pluginRepository>
<id>fusesource.ea</id>
<name>FuseSource Community Early Access Release Repository</name>
<url>https://repo.fusesource.com/nexus/content/groups/ea</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
<pluginRepository>
<id>redhat.ga</id>
<name>Red Hat General Availability Repository</name>
<url>https://maven.repository.redhat.com/ga</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>fusesource.repo</activeProfile>
</activeProfiles>
</settings>

363
jboss-fuse-cxf-rest-local/pom.xml

@ -0,0 +1,363 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2005-2016 Red Hat, Inc.
Red Hat licenses this file to you 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.
-->
<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>
<groupId>io.fabric8.quickstarts</groupId>
<artifactId>jboss-fuse-cxf-rest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>Fabric8 :: Quickstarts :: JBoss Fuse :: CXF REST</name>
<description>REST example using CXF in Karaf container</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<version.maven-bundle-plugin>2.3.7</version.maven-bundle-plugin>
<camel.version>2.17.0.redhat-630187</camel.version>
<cxf.version>3.1.5.redhat-630187</cxf.version>
<activemq.camel.version>5.11.0.redhat-630187</activemq.camel.version>
<spring.version>3.2.16.RELEASE</spring.version>
<cxf.codegen.version>3.1.5.redhat-630187</cxf.codegen.version>
<!-- configure the versions you want to use here -->
<fuse.version>6.3.0.redhat-187</fuse.version>
<fabric8.version>2.2.156</fabric8.version>
<cxf.plugin.version>3.1.4</cxf.plugin.version>
<karaf.plugin.version>4.0.8.redhat-000017</karaf.plugin.version>
<!-- maven plugin versions -->
<fabric8.maven.plugin.version>1.2.0.redhat-630187</fabric8.maven.plugin.version>
<maven-compiler-plugin.version>3.3</maven-compiler-plugin.version>
<maven-surefire-plugin.version>2.18.1</maven-surefire-plugin.version>
<exec-maven-plugin.version>1.4.0</exec-maven-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- fabric8 bom must be before fabric8 bom -->
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>fabric8-project-bom-with-platform-deps</artifactId>
<version>${fabric8.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.jboss.fuse.bom</groupId>
<artifactId>jboss-fuse-parent</artifactId>
<version>${fuse.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- cxf -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-core</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-service-description</artifactId>
<version>${cxf.version}</version>
</dependency>
<!-- swagger -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.4</version>
<optional>true</optional>
<exclusions>
<!-- avoid this old dependency which breaks CXF -->
<exclusion>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Karaf microcontainer dependencies -->
<dependency>
<!-- scope is compile so all features (there is only one) are installed into startup.properties,
and the feature repo itself is not added in etc/org.apache.karaf.features.cfg file -->
<groupId>org.jboss.fuse</groupId>
<artifactId>fuse-karaf-framework</artifactId>
<version>${fuse.version}</version>
<type>kar</type>
<!-- no need to download kar dependencies -->
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<repositories>
<repository>
<id>redhat-ga-repository</id>
<url>https://maven.repository.redhat.com/ga</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>redhat-ea-repository</id>
<url>https://maven.repository.redhat.com/earlyaccess/all</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>redhat-ga-repository</id>
<url>https://maven.repository.redhat.com/ga</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>redhat-ea-repository</id>
<url>https://maven.repository.redhat.com/earlyaccess/all</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<defaultGoal>install</defaultGoal>
<plugins>
<!-- Compiler plugin enforces Java 1.8 compatibility and activates annotation processors -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
</plugin>
<!-- Need to setup the OSGi meta information here -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${version.maven-bundle-plugin}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Import-Package>
javax.ws.rs;version="[2,3)",
javax.ws.rs.core;version="[2,3)",
javax.ws.rs.ext;version="[2,3)",
javax.xml.bind.annotation,
org.osgi.service.blueprint,
io.swagger.jaxrs.config,
io.swagger.jaxrs.listing,
io.swagger.annotations,
org.apache.cxf.transport.http,
com.fasterxml.jackson.annotation,
com.fasterxml.jackson.core,
com.fasterxml.jackson.databind,
com.fasterxml.jackson.jaxrs.json,
*
</Import-Package>
<Export-Package>
io.fabric8.quickstarts.rest
</Export-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-java2wadl-plugin</artifactId>
<version>${cxf.plugin.version}</version>
<executions>
<execution>
<id>parsejavadoc</id>
<phase>generate-sources</phase>
<goals>
<goal>parsejavadoc</goal>
</goals>
</execution>
<execution>
<id>process-classes</id>
<phase>process-classes</phase>
<goals>
<goal>java2wadl</goal>
</goals>
<configuration>
<classResourceNames>
<classResourceName>io.fabric8.quickstarts.rest.CustomerService</classResourceName>
</classResourceNames>
<docProvider>org.apache.cxf.maven_plugin.javatowadl.ResourceMapJavaDocProvider</docProvider>
<attachWadl>false</attachWadl>
</configuration>
</execution>
</executions>
</plugin>
<!-- attach feature file to install for karaf assembly -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.outputDirectory}/features.xml</file>
<classifier>features</classifier>
<type>xml</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
<!-- plugin goals have to be executed in order -->
<!-- 1. install the bundle -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<goals>
<goal>install</goal>
</goals>
<phase>install</phase>
</execution>
</executions>
</plugin>
<!-- 2. create karaf assembly -->
<!-- karaf-maven-plugin creates custom microservice distribution -->
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
<version>${karaf.plugin.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>karaf-assembly</id>
<goals>
<goal>assembly</goal>
</goals>
<phase>install</phase>
</execution>
<execution>
<id>karaf-archive</id>
<goals>
<goal>archive</goal>
</goals>
<phase>install</phase>
</execution>
</executions>
<configuration>
<!-- we are using karaf 2.4.x -->
<karafVersion>v24</karafVersion>
<useReferenceUrls>true</useReferenceUrls>
<archiveTarGz>false</archiveTarGz>
<!-- do not include build output directory -->
<includeBuildOutputDirectory>false</includeBuildOutputDirectory>
<startupRepositories>
<repo>mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features</repo>
</startupRepositories>
<!-- no startupFeatures -->
<startupFeatures>
<feature>karaf-framework</feature>
<feature>jaas</feature>
<feature>shell</feature>
<feature>aries-blueprint</feature>
<feature>cxf-core</feature>
<feature>cxf-jaxrs</feature>
<feature>cxf-http-jetty</feature>
<!-- swagger -->
<feature>http</feature>
<feature>cxf-specs</feature>
<feature>swagger2</feature>
</startupFeatures>
<startupBundles>
<bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
</startupBundles>
</configuration>
</plugin>
<!-- 3. create docker image -->
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>fabric8-maven-plugin</artifactId>
<version>${fabric8.maven.plugin.version}</version>
</plugin>
</plugins>
</build>
</project>

52
jboss-fuse-cxf-rest-local/src/main/java/io/fabric8/quickstarts/rest/Customer.java

@ -0,0 +1,52 @@
/**
* Copyright 2005-2016 Red Hat, Inc.
*
* Red Hat licenses this file to you 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 io.fabric8.quickstarts.rest;
import javax.xml.bind.annotation.XmlRootElement;
/**
* The Customer class is just a plain old java object, with a few properties and getters and setters.
* <p/>
* By adding the @XmlRootElement annotation, we make it possible for JAXB to unmarshal this object into a XML document and
* to marshal it back from the same XML document.
* <p/>
* The XML representation of a Customer will look like this:
* <Customer>
* <id>123</id>
* <name>National Aquarium</name>
* </Customer>
*/
@XmlRootElement(name = "Customer")
public class Customer {
private long id;
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;
}
}

224
jboss-fuse-cxf-rest-local/src/main/java/io/fabric8/quickstarts/rest/CustomerService.java

@ -0,0 +1,224 @@
/**
* Copyright 2005-2016 Red Hat, Inc.
*
* Red Hat licenses this file to you 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 io.fabric8.quickstarts.rest;
import java.util.HashMap;
import java.util.Map;
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.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This Java class with be hosted in the URI path defined by the @Path annotation. @Path annotations on the methods
* of this class always refer to a path relative to the path defined at the class level.
* <p/>
* For example, with 'http://localhost:8181/cxf' as the default CXF servlet path and '/crm' as the JAX-RS server path,
* this class will be hosted in 'http://localhost:8181/cxf/crm/customerservice'. An @Path("/customers") annotation on
* one of the methods would result in 'http://localhost:8181/cxf/crm/customerservice/customers'.
*/
@Path("/customerservice/")
@Api(value = "/customerservice", description = "Operations about customerservice")
public class CustomerService {
private static final Logger LOG = LoggerFactory.getLogger(CustomerService.class);
long currentId = 123;
Map<Long, Customer> customers = new HashMap<Long, Customer>();
Map<Long, Order> orders = new HashMap<Long, Order>();
private MessageContext jaxrsContext;
public CustomerService() {
init();
}
/**
* This method is mapped to an HTTP GET of 'http://localhost:8181/cxf/crm/customerservice/customers/{id}'. The value for
* {id} will be passed to this message as a parameter, using the @PathParam annotation.
* <p/>
* The method returns a Customer object - for creating the HTTP response, this object is marshaled into XML using JAXB.
* <p/>
* For example: surfing to 'http://localhost:8181/cxf/crm/customerservice/customers/123' will show you the information of
* customer 123 in XML format.
*/
@GET
@Path("/customers/{id}/")
@Produces("application/xml")
@ApiOperation(value = "Find Customer by ID", notes = "More notes about this method", response = Customer.class)
@ApiResponses(value = {
@ApiResponse(code = 500, message = "Invalid ID supplied"),
@ApiResponse(code = 204, message = "Customer not found")
})
public Customer getCustomer(@ApiParam(value = "ID of Customer to fetch", required = true) @PathParam("id") String id) {
LOG.info("Invoking getCustomer, Customer id is: {}", id);
long idNumber = Long.parseLong(id);
Customer c = customers.get(idNumber);
return c;
}
/**
* Using HTTP PUT, we can can upload the XML representation of a customer object. This operation will be mapped
* to the method below and the XML representation will get unmarshaled into a real Customer object using JAXB.
* <p/>
* The method itself just updates the customer object in our local data map and afterwards uses the Reponse class to
* build the appropriate HTTP response: either OK if the update succeeded (translates to HTTP Status 200/OK) or not
* modified if the method failed to update a customer object (translates to HTTP Status 304/Not Modified).
* <p/>
* Note how this method is using the same @Path value as our next method - the HTTP method used will determine which
* method is being invoked.
*/
@PUT
@Path("/customers/")
@Consumes({"application/xml", "application/json" })
@ApiOperation(value = "Update an existing Customer")
@ApiResponses(value = {
@ApiResponse(code = 500, message = "Invalid ID supplied"),
@ApiResponse(code = 204, message = "Customer not found")
})
public Response updateCustomer(@ApiParam(value = "Customer object that needs to be updated", required = true) Customer customer) {
LOG.info("Invoking updateCustomer, Customer name is: {}", customer.getName());
Customer c = customers.get(customer.getId());
Response r;
if (c != null) {
customers.put(customer.getId(), customer);
r = Response.ok().build();
} else {
r = Response.notModified().build();
}
return r;
}
/**
* Using HTTP POST, we can add a new customer to the system by uploading the XML representation for the customer.
* This operation will be mapped to the method below and the XML representation will get unmarshaled into a real
* Customer object.
* <p/>
* After the method has added the customer to the local data map, it will use the Response class to build the HTTP reponse,
* sending back the inserted customer object together with a HTTP Status 200/OK. This allows us to send back the
* new id for the customer object to the client application along with any other data that might have been updated in
* the process.
* <p/>
* Note how this method is using the same @Path value as our previous method - the HTTP method used will determine which
* method is being invoked.
*/
@POST
@Path("/customers/")
@Consumes({"application/xml", "application/json" })
@ApiOperation(value = "Add a new Customer")
@ApiResponses(value = { @ApiResponse(code = 500, message = "Invalid ID supplied"), })
public Response addCustomer(@ApiParam(value = "Customer object that needs to be updated", required = true)
Customer customer) {
LOG.info("Invoking addCustomer, Customer name is: {}", customer.getName());
customer.setId(++currentId);
customers.put(customer.getId(), customer);
if (jaxrsContext.getHttpHeaders().getMediaType().getSubtype().equals("json")) {
return Response.ok().type("application/json").entity(customer).build();
} else {
return Response.ok().type("application/xml").entity(customer).build();
}
}
/**
* This method is mapped to an HTTP DELETE of 'http://localhost:8181/cxf/crm/customerservice/customers/{id}'. The value for
* {id} will be passed to this message as a parameter, using the @PathParam annotation.
* <p/>
* The method uses the Response class to create the HTTP response: either HTTP Status 200/OK if the customer object was
* successfully removed from the local data map or a HTTP Status 304/Not Modified if it failed to remove the object.
*/
@DELETE
@Path("/customers/{id}/")
@ApiOperation(value = "Delete Customer")
@ApiResponses(value = {
@ApiResponse(code = 500, message = "Invalid ID supplied"),
@ApiResponse(code = 204, message = "Customer not found")
})
public Response deleteCustomer(@ApiParam(value = "ID of Customer to delete", required = true) @PathParam("id") String id) {
LOG.info("Invoking deleteCustomer, Customer id is: {}", id);
long idNumber = Long.parseLong(id);
Customer c = customers.get(idNumber);
Response r;
if (c != null) {
r = Response.ok().build();
customers.remove(idNumber);
} else {
r = Response.notModified().build();
}
return r;
}
/**
* This method is mapped to an HTTP GET of 'http://localhost:8181/cxf/crm/customerservice/orders/{id}'. The value for
* {id} will be passed to this message as a parameter, using the @PathParam annotation.
* <p/>
* The method returns an Order object - the class for that object includes a few more JAX-RS annotations, allowing it to
* display one of these two outputs, depending on the actual URI path being used:
* - display the order information itself in XML format
* - display details about a product in the order in XML format in a path relative to the URI defined here
*/
@Path("/orders/{orderId}/")
public Order getOrder(@PathParam("orderId") String orderId) {
LOG.info("Invoking getOrder, Order id is: {}", orderId);
long idNumber = Long.parseLong(orderId);
Order c = orders.get(idNumber);
return c;
}
/**
* The init method is used by the constructor to insert a Customer and Order object into the local data map
* for testing purposes.
*/
final void init() {
Customer c = new Customer();
c.setName("John");
c.setId(123);
customers.put(c.getId(), c);
Order o = new Order();
o.setDescription("order 223");
o.setId(223);
orders.put(o.getId(), o);
}
@Context
public void setMessageContext(MessageContext messageContext) {
this.jaxrsContext = messageContext;
}
}

113
jboss-fuse-cxf-rest-local/src/main/java/io/fabric8/quickstarts/rest/Order.java

@ -0,0 +1,113 @@
/**
* Copyright 2005-2016 Red Hat, Inc.
*
* Red Hat licenses this file to you 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 io.fabric8.quickstarts.rest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Order class is not only a plain old java object, with a few properties and getters and setters, but it also defines
* a sub-resource for the Order returned by CustomerService.
* <p/>
* By adding the @XmlRootElement annotation, we make it possible for JAXB to unmarshal this object into a XML document and
* to marshal it back from the same XML document.
* <p/>
* The XML representation of an Order will look like this:
* <Order>
* <id>223</id>
* <description>Order 223</description>
* </Order>
*/
@XmlRootElement(name = "Order")
public class Order {
private static final Logger LOG = LoggerFactory.getLogger(CustomerService.class);
private long id;
private String description;
private Map<Long, Product> products = new HashMap<Long, Product>();
public Order() {
init();
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String d) {
this.description = d;
}
/**
* This method is mapped to an HTTP GET of '/', relative to the URL that point to this Order resource itself.
* <p/>
* The method returns the Order object itself - for creating the HTTP response, this object is marshaled into XML using
* JAXB.
* <p/>
* For example: if surfing to 'http://localhost:8181/cxf/crm/customerservice/orders/223' will show you the information of
* order 223 in XML format (as defined in CustomerService's getOrder() method), you can access product 323 in that order by
* accessing 'http://localhost:8181/cxf/crm/customerservice/orders/223/products/323'
*/
@GET
@Path("/")
@Produces("application/xml")
public Order getThisOrder() {
return this;
}
/**
* This method is mapped to an HTTP GET of 'products/{productId}', relative to the URL that point to this Order resource
* itself.
* The value for {productId} will be passed to this message as a parameter, using the @PathParam annotation.
* <p/>
* The method returns an Product object - for creating the HTTP response, this object is marshaled into XML using JAXB.
* <p/>
* For example: accessing 'http://localhost:8181/cxf/crm/customerservice/orders/223/products/323' will first trigger the
* CustomerService's getOrder() method to return the Order instance for order 223 and afterwards, it will use the remaining
* part of the URI ('products/323') to map to this method and return the product details for product 323 in this order.
*/
@GET
@Path("products/{productId}/")
@Produces("application/xml")
public Product getProduct(@PathParam("productId") int productId) {
LOG.info("----invoking getProduct with id: " + productId);
Product p = products.get(new Long(productId));
return p;
}
final void init() {
Product p = new Product();
p.setId(323);
p.setDescription("product 323");
products.put(p.getId(), p);
}
}

52
jboss-fuse-cxf-rest-local/src/main/java/io/fabric8/quickstarts/rest/Product.java

@ -0,0 +1,52 @@
/**
* Copyright 2005-2016 Red Hat, Inc.
*
* Red Hat licenses this file to you 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 io.fabric8.quickstarts.rest;
import javax.xml.bind.annotation.XmlRootElement;
/**
* The Product class is just a plain old java object, with a few properties and getters and setters.
* <p/>
* By adding the @XmlRootElement annotation, we make it possible for JAXB to unmarshal this object into a XML document and
* to marshal it back from the same XML document.
* <p/>
* The XML representation of a Product will look like this:
* <Product>
* <id>10010</id>
* <description>Armadillo</description>
* </Product>
*/
@XmlRootElement(name = "Product")
public class Product {
private long id;
private String description;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String d) {
this.description = d;
}
}

18
jboss-fuse-cxf-rest-local/src/main/java/io/fabric8/quickstarts/rest/package-info.java

@ -0,0 +1,18 @@
/**
* Copyright 2005-2016 Red Hat, Inc.
*
* Red Hat licenses this file to you 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.
*/
@javax.xml.bind.annotation.XmlSchema(namespace = "http://rest.fabric.quickstarts.fabric8.io/", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package io.fabric8.quickstarts.rest;

75
jboss-fuse-cxf-rest-local/src/main/resources/OSGI-INF/blueprint/blueprint.xml

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2005-2016 Red Hat, Inc.
Red Hat licenses this file to you 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.
-->
<!--
This is the OSGi Blueprint XML file defining the CXF JAX-RS beans. Because the file is in the
OSGI-INF/blueprint directory inside our JAR, it will be automatically activated as soon as the artifact is installed.
The root element for any OSGi Blueprint file is 'blueprint' - you also see the namespace definitions for both the Blueprint
and the CXF JAX-RS namespaces.
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
xmlns:cxf="http://cxf.apache.org/blueprint/core"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd">
<!-- JAXRS providers -->
<bean id="jsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
<!-- CXF Swagger2Feature -->
<bean id="swagger2Feature" class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">
<property name="basePath" value="/cxf/crm"/>
</bean>
<!--
The <jaxrs:server/> element sets up our JAX-RS services. It defines:
- the server's address, '/crm', relative to the default CXF servlet URI
with the default settings, the server will be running on 'http://localhost:8181/cxf/crm'
- a list of service beans
in this example, we refer to another bean defined in this Blueprint XML file with a <ref/> element
-->
<jaxrs:server id="customerService" address="/crm">
<jaxrs:serviceBeans>
<ref component-id="customerSvc"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref component-id="jsonProvider" />
</jaxrs:providers>
<jaxrs:features>
<ref component-id="swagger2Feature" />
</jaxrs:features>
</jaxrs:server>
<cxf:bus>
<cxf:features>
<cxf:logging />
</cxf:features>
</cxf:bus>
<!--
We are using the OSGi Blueprint XML syntax to define a bean that we referred to in our JAX-RS server setup.
This bean carries a set of JAX-RS annotations that allow its methods to be mapped to incoming requests.
-->
<bean id="customerSvc" class="io.fabric8.quickstarts.rest.CustomerService"/>
</blueprint>

43
jboss-fuse-cxf-rest-local/src/main/resources/features.xml

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
-->
<features name="swagger2" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0">
<feature name="swagger2" version="${project.version}" description="swagger2 necessary bundkles">
<!-- swagger -->
<bundle start-level="10">mvn:org.apache.servicemix.specs/org.apache.servicemix.specs.jsr339-api-2.0/2.5.0</bundle>
<bundle start-level="10">mvn:com.fasterxml.jackson.core/jackson-core/2.6.3</bundle>
<bundle start-level="10">mvn:com.fasterxml.jackson.core/jackson-databind/2.6.3</bundle>
<bundle start-level="10">mvn:com.fasterxml.jackson.core/jackson-annotations/2.6.3</bundle>
<bundle start-level="10">mvn:com.fasterxml.jackson.dataformat/jackson-dataformat-xml/2.6.3</bundle>
<bundle start-level="10">mvn:com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.6.3</bundle>
<bundle start-level="10">mvn:com.fasterxml.jackson.module/jackson-module-jaxb-annotations/2.6.3</bundle>
<bundle start-level="10">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/2.6.3</bundle>
<bundle start-level="10">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/2.6.3</bundle>
<bundle start-level="10">mvn:org.javassist/javassist/3.20.0-GA</bundle>
<bundle start-level="10">mvn:javax.validation/validation-api/1.1.0.Final</bundle>
<bundle start-level="10">mvn:org.apache.commons/commons-lang3/3.4</bundle>
<bundle start-level="10">mvn:com.google.guava/guava/18.0</bundle>
<bundle start-level="10">mvn:io.swagger/swagger-core/1.5.4</bundle>
<bundle start-level="10">mvn:io.swagger/swagger-annotations/1.5.4</bundle>
<bundle start-level="10">mvn:io.swagger/swagger-models/1.5.4</bundle>
<bundle start-level="10">mvn:io.swagger/swagger-jaxrs/1.5.4</bundle>
<bundle start-level="10">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.reflections/0.9.10_3</bundle>
</feature>
</features>

1
jboss-fuse-cxf-rest-local/src/test/resources/add_customer.json

@ -0,0 +1 @@
{ "name": "Jack" }

3
jboss-fuse-cxf-rest-local/src/test/resources/add_customer.xml

@ -0,0 +1,3 @@
<Customer xmlns="http://rest.fabric.quickstarts.fabric8.io/">
<name>Jack</name>
</Customer>

35
jboss-fuse-cxf-rest-local/src/test/resources/log4j.properties

@ -0,0 +1,35 @@
#
# Copyright 2005-2016 Red Hat, Inc.
#
# Red Hat licenses this file to you 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.
#
log4j.rootLogger=INFO, file, out
# CONSOLE appender not used by default
log4j.appender.out=org.apache.log4j.ConsoleAppender
log4j.appender.out.layout=org.apache.log4j.PatternLayout
# log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
# MDC
#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %-10.10X{camel.breadcrumbId} - %-10.10X{camelexchangeId} - %-10.10X{camel.correlationId} - %-10.10X{camel.routeId} - %m%n
# File appender
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.file=target/rest.log
log4j.appender.file.append=true
log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
# MDC
#log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %-10.10X{camel.breadcrumbId} - %-10.10X{camel.exchangeId} - %-10.10X{camel.correlationId} - %-10.10X{camel.routeId} - %m%n
log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer

4
jboss-fuse-cxf-rest-local/src/test/resources/update_customer.xml

@ -0,0 +1,4 @@
<Customer xmlns="http://rest.fabric.quickstarts.fabric8.io/">
<name>Mary</name>
<id>123</id>
</Customer>
Loading…
Cancel
Save