Package client

Source Code of client.RESTClient

/**
* Copyright (C) 2010 Talend Inc. - www.talend.com
*/
package client;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.interceptor.transform.TransformInInterceptor;
import org.apache.cxf.interceptor.transform.TransformOutInterceptor;
import org.apache.cxf.jaxrs.client.ClientConfiguration;
import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.ext.xml.XMLSource;
import org.apache.cxf.jaxrs.provider.JAXBElementProvider;

/**
* Demonstrates how the forward and backward compatibility between
* the old and new SOAP and REST clients is achieved with the help
* of the CXF STAX Transform Feature
*/

public class RESTClient {

    private static final String PORT_PROPERTY = "http.port";
    private static final int DEFAULT_PORT_VALUE = 8080;

    private static final String HTTP_PORT;
    static {
        Properties props = new Properties();
        try {
            props.load(RESTClient.class.getResourceAsStream("/client.properties"));
        } catch (Exception ex) {
            throw new RuntimeException("client.properties resource is not available");
        }
        HTTP_PORT = props.getProperty(PORT_PROPERTY);
    }

    int port;

    public RESTClient() {
        port = getPort();
    }

       
    /**
     * Old REST client uses old REST service
     */
    public void useOldRESTService() throws Exception {
        List<Object> providers = createJAXRSProviders();

        com.example.customerservice.CustomerService customerService = JAXRSClientFactory
            .createFromModel("http://localhost:" + port + "/examples/direct/rest",
                             com.example.customerservice.CustomerService.class,
                             "classpath:/model/CustomerService-jaxrs.xml",
                             providers,
                             null);

        System.out.println("Using old RESTful CustomerService with old client");

        customer.v1.Customer customer = createOldCustomer("Smith Old REST");
        customerService.updateCustomer(customer);

        customer = customerService.getCustomerByName("Smith Old REST");
        printOldCustomerDetails(customer);
    }

    /**
     * New REST client uses new REST service
     */
    public void useNewRESTService(String address) throws Exception {
        List<Object> providers = createJAXRSProviders();

        org.customer.service.CustomerService customerService = JAXRSClientFactory
            .createFromModel(address,
                             org.customer.service.CustomerService.class,
                             "classpath:/model/CustomerService-jaxrs.xml",
                             providers,
                             null);

        System.out.println("Using new RESTful CustomerService with new client");

        customer.v2.Customer customer = createNewCustomer("Smith New REST");
        customerService.updateCustomer(customer);

        customer = customerService.getCustomerByName("Smith New REST");
        printNewCustomerDetails(customer);
    }

    /**
     * New REST client uses old REST service
     */
    public void useOldRESTServiceWithNewClient() throws Exception {
        List<Object> providers = createJAXRSProviders();

        org.customer.service.CustomerService customerService = JAXRSClientFactory
            .createFromModel("http://localhost:" + port + "/examples/direct/rest",
                             org.customer.service.CustomerService.class,
                             "classpath:/model/CustomerService-jaxrs.xml",
                             providers,
                             null);
       
        // The outgoing new Customer data needs to be transformed for
        // the old service to understand it and the response from the old service
        // needs to be transformed for this new client to understand it.
        ClientConfiguration config = WebClient.getConfig(customerService);
        addTransformInterceptors(config.getInInterceptors(),
                                 config.getOutInterceptors(),
                                 true);
       
       
        System.out.println("Using old RESTful CustomerService with new client");

        customer.v2.Customer customer = createNewCustomer("Smith New to Old REST");
        customerService.updateCustomer(customer);
        customer = customerService.getCustomerByName("Smith New to Old REST");
        printNewCustomerDetails(customer);
    }
   
    /**
     * New REST client uses old REST service
     */
    public void useOldRESTServiceWithNewClientAndXPath() throws Exception {
        List<Object> providers = createJAXRSProviders();

        String address = "http://localhost:" + port + "/examples/direct/rest/customerservice";
        WebClient client = WebClient.create(address, providers);
       
        // The outgoing new Customer data needs to be transformed for
        // the old service to understand it and the response from the old service
        // needs to be transformed for this new client to understand it.
        ClientConfiguration config = WebClient.getConfig(client);
        addTransformInterceptors(config.getInInterceptors(),
                                 config.getOutInterceptors(),
                                 true);
       
       
        System.out.println("Consuming old RESTful CustomerService with new client and XPath");

        customer.v2.Customer customer = createNewCustomer("Smith New to Old REST, XPath");
        client.path("customer");
        client.put(customer);
       
        XMLSource source =
            client.query("name", "Smith New to Old REST, XPath").get(XMLSource.class);
        customer.v2.Customer xmlCustomer =
            source.getNode("/ns:customer",
                           Collections.singletonMap("ns", "http://customer/v2"),
                           customer.v2.Customer.class);
        printNewCustomerDetails(xmlCustomer);
    }
   
    /**
     * Old REST client uses new REST service
     */
    public void useNewRESTServiceWithOldClient() throws Exception {
        List<Object> providers = createJAXRSProviders();

        com.example.customerservice.CustomerService customerService = JAXRSClientFactory
            .createFromModel("http://localhost:" + port + "/examples/direct/new-rest",
                             com.example.customerservice.CustomerService.class,
                             "classpath:/model/CustomerService-jaxrs.xml",
                             providers,
                             null);
       
        // The outgoing old Customer data needs to be transformed for
        // the new service to understand it and the response from the new service
        // needs to be transformed for this old client to understand it.
        ClientConfiguration config = WebClient.getConfig(customerService);
        addTransformInterceptors(config.getInInterceptors(),
                                 config.getOutInterceptors(),
                                 false);
       
       
        System.out.println("Using new RESTful CustomerService with old Client");

        customer.v1.Customer customer = createOldCustomer("Smith Old to New REST");
        customerService.updateCustomer(customer);

        customer = customerService.getCustomerByName("Smith Old to New REST");
        printOldCustomerDetails(customer);
    }
   
    /**
     * Old REST client uses new REST service with the
     * redirection to the new endpoint and transformation
     * on the server side
     */
    public void useNewRESTServiceWithOldClientAndRedirection() throws Exception {
        List<Object> providers = createJAXRSProviders();

        com.example.customerservice.CustomerService customerService = JAXRSClientFactory
            .createFromModel("http://localhost:" + port + "/examples/old/rest-endpoint",
                             com.example.customerservice.CustomerService.class,
                             "classpath:/model/CustomerService-jaxrs.xml",
                             providers,
                             null);

       
        System.out.println("Using new RESTful CustomerService with old client and the redirection");

        customer.v1.Customer customer = createOldCustomer("Smith Old to New REST With Redirection");
        customerService.updateCustomer(customer);

        customer = customerService.getCustomerByName("Smith Old to New REST With Redirection");
        printOldCustomerDetails(customer);
    }
   
    /**
     * Prepares transformation interceptors for a client.
     *
     * @param clientConfig the client configuration
     * @param newClient indicates if it is a new/updated client
     */
    private void addTransformInterceptors(List<Interceptor<?>> inInterceptors,
                                          List<Interceptor<?>> outInterceptors,
                                          boolean newClient) {
       
        // The old service expects the Customer data be qualified with
        // the 'http://customer/v1' namespace.
       
        // The new service expects the Customer data be qualified with
        // the 'http://customer/v2' namespace.
       
        // If it is an old client talking to the new service then:
        // - the out transformation interceptor is configured for
        //   'http://customer/v1' qualified data be transformed into
        //   'http://customer/v2' qualified data.
        // - the in transformation interceptor is configured for
        //   'http://customer/v2' qualified response data be transformed into
        //   'http://customer/v1' qualified data.
      
        // If it is a new client talking to the old service then:
        // - the out transformation interceptor is configured for
        //   'http://customer/v2' qualified data be transformed into
        //   'http://customer/v1' qualified data.
        // - the in transformation interceptor is configured for
        //   'http://customer/v1' qualified response data be transformed into
        //   'http://customer/v2' qualified data.
        // - new Customer type also introduces a briefDescription property
        //   which needs to be dropped for the old service validation to succeed
       
       
        // this configuration can be provided externally
       
        Map<String, String> newToOldTransformMap =
            Collections.singletonMap("{http://customer/v2}*", "{http://customer/v1}*");
        Map<String, String> oldToNewTransformMap =
            Collections.singletonMap("{http://customer/v1}*", "{http://customer/v2}*");
       
        TransformOutInterceptor outTransform =  new TransformOutInterceptor();
        outTransform.setOutTransformElements(newClient ? newToOldTransformMap
                                              : oldToNewTransformMap);
       
        if (newClient) {
            outTransform.setOutDropElements(
                Collections.singletonList("{http://customer/v2}briefDescription"));   
        }
       
        TransformInInterceptor inTransform =  new TransformInInterceptor();
        inTransform.setInTransformElements(newClient ? oldToNewTransformMap
                                            : newToOldTransformMap);

        inInterceptors.add(inTransform);
        outInterceptors.add(outTransform);
       
       
    }
   
    /**
     * Creates a custom JAX-RS JAXBElementProvider which can handle
     * generated JAXB clasess with no XmlRootElement annotation
     * @return providers
     */
    private List<Object> createJAXRSProviders() {
        JAXBElementProvider provider = new JAXBElementProvider();
        provider.setUnmarshallAsJaxbElement(true);
        provider.setMarshallAsJaxbElement(true);
        List<Object> providers = new ArrayList<Object>();
        providers.add(provider);
        return providers;
    }
   
    /**
     * namespace: {http://customer}v1
     */
    private customer.v1.Customer createOldCustomer(String name) {
        customer.v1.Customer cust = new customer.v1.Customer();
        cust.setName(name);
        cust.getAddress().add("Pine Street 200");
        Date bDate = new GregorianCalendar(2009, 01, 01).getTime();
        cust.setBirthDate(bDate);
        cust.setNumOrders(1);
        cust.setRevenue(10000);
        cust.setShares(new BigDecimal(1.5));
        cust.setType(customer.v1.CustomerType.BUSINESS);
        return cust;
    }
   
    /**
     * namespace: {http://customer}v2
     * new simple element: briefDescription
     */
    private customer.v2.Customer createNewCustomer(String name) {
        customer.v2.Customer cust = new customer.v2.Customer();
        cust.setName(name);
        cust.getAddress().add("Pine Street 200");
        Date bDate = new GregorianCalendar(2009, 01, 01).getTime();
        cust.setBirthDate(bDate);
        cust.setNumOrders(1);
        cust.setRevenue(10000);
        cust.setShares(new BigDecimal(1.5));
        cust.setType(customer.v2.CustomerType.BUSINESS);
        cust.setBriefDescription("Business Customer");
        return cust;
    }
   
    private void printOldCustomerDetails(customer.v1.Customer customer) {
        System.out.print("Name : " + customer.getName());
        System.out.print(", orders : " + customer.getNumOrders());
        System.out.print(", shares : " + customer.getShares());
        System.out.println();
    }
   
    private void printNewCustomerDetails(customer.v2.Customer customer) {
        System.out.print("Name : " + customer.getName());
        System.out.print(", orders : " + customer.getNumOrders());
        System.out.print(", shares : " + customer.getShares());
        System.out.println();
    }
   
    private static int getPort() {
        try {
            return Integer.valueOf(HTTP_PORT);
        } catch (NumberFormatException ex) {
            // ignore
        }
        return DEFAULT_PORT_VALUE;
    }

    public static void main(String args[]) throws Exception {
        RESTClient client = new RESTClient();
       
        // Scenario 1:
        // - Old clients have become aware that the new endpoints have been deployed.
        // They continue talking to the old endpoints which have not been stopped yet
        // otherwise they are configured such that they can talk to new endpoints
       
        // - New clients talk to the new endpoints but in some cases where new endpoints
        // have not been introduced yet, they are configured such that they can talk to
        // the old endpoints
       
        System.out.println("Scenario 1: Old and new clients are configured"
                           + " to invoke on the new and old endpoints respectively");
       
        // JAX-RS: Scenario 1
        System.out.println("JAX-RS:");
        System.out.println();
       
        // Old Client uses Old Service
        client.useOldRESTService();
        System.out.println();
        // New Client uses Old Service
        client.useOldRESTServiceWithNewClient();
        System.out.println();
       
        // New Client uses Old Service, XPath is used to consume the response
        client.useOldRESTServiceWithNewClientAndXPath();
        System.out.println();
       
        // New Client uses New Service
        client.useNewRESTService("http://localhost:" + RESTClient.getPort()
                                         + "/examples/direct/new-rest");
        System.out.println();
        // Old Client uses New Service
        client.useNewRESTServiceWithOldClient();
        System.out.println();
       
        // Scenario 2:
        // Old clients are unaware of the fact that the old endpoint has been removed
        // and the new endpoint has been introduced.
        // Old Client thinks Old Service is still being used but
        // on the server the request will be redirected to the New Service endpoint
       
        // Similarly, the new clients can be redirected to the old endpoints on the server
        // if no new endpoints have been introduced yet in a given destination
       
        System.out.println("Scenario 2: Old clients invoke on the new endpoints"
                           + " without being aware of it");
       
        // JAX-RS: Scenario 2
        System.out.println("JAX-RS:");
        System.out.println();
       
        // Old Client uses New Service without being aware of it
        client.useNewRESTServiceWithOldClientAndRedirection();
        System.out.println();
        // New Client uses New Service, the same new endpoint handles
        // new and redirected old client requests
        client.useNewRESTService("http://localhost:" + RESTClient.getPort()
                                         + "/examples/new/rest-endpoint");
       
        System.exit(0);
    }
}
TOP

Related Classes of client.RESTClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.