This topic describes how to develop RESTful applications in High-Speed Service Framework (HSF) and implement service registration and discovery. Enterprise Distributed Application Service (EDAS) supports native Spring Cloud applications. Therefore, we recommend that new users do not use HSF to develop RESTful applications.

Background information

For more information about how to develop applications in the native Spring Cloud framework, see Implement service registration and discovery.

Service registration and discovery

This topic provides a simple example on how to develop RESTful applications and implement service registration and discovery locally.

Download the demo source code: sc-vip-serversc-vip-client.

  1. Create a service provider.
    The service provider provides a simple echo service and registers itself with the service registry.
    1. Create a RESTful application project named sc-vip-server.
    2. Add required dependencies to the pom.xml file.
          <parent>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-parent</artifactId>
              <version>1.5.8.RELEASE</version>
              <relativePath/>
          </parent>
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-vipclient</artifactId>
                  <version>1.3</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-pandora</artifactId>
                  <version>1.3</version>
              </dependency>
          </dependencies>
      
          <dependencyManagement>
              <dependencies>
                  <dependency>
                      <groupId>org.springframework.cloud</groupId>
                      <artifactId>spring-cloud-dependencies</artifactId>
                      <version>Dalston.SR4</version>
                      <type>pom</type>
                      <scope>import</scope>
                  </dependency>
              </dependencies>
          </dependencyManagement>

      If you do not want to set the parent of the project to spring-boot-starter-parent, you can add dependencyManagement and set scope=import to manage dependencies.

      <dependencyManagement>
                  <dependencies>
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-dependencies</artifactId>
                          <version>1.5.8.RELEASE</version>
                          <type>pom</type>
                          <scope>import</scope>
                      </dependency>
                  </dependencies>
      </dependencyManagement>
    3. Create a service provider application, in which the @EnableDiscoveryClient annotation enables service registration and discovery for the application.
      @SpringBootApplication
          @EnableDiscoveryClient
          public class ServerApplication {
      
              public static void main(String[] args) {
                  PandoraBootstrap.run(args);
                  SpringApplication.run(ServerApplication.class, args);
                  PandoraBootstrap.markStartupAndWait();
              }
          }
    4. Create EchoController to provide simple echo services.
      @RestController
          public class EchoController {
              @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
              public String echo(@PathVariable String string) {
                  return string;
              }
          }
    5. Configure the application name and the listener port number in the application.properties file in the resources directory.
      spring.application.name=service-provider
      server.port=18081
  2. Create a service consumer.
    In this example, a service consumer is created to call the service provider by using RestTemplate, AsyncRestTemplate, and FeignClient.
    1. Create a RESTful application project named sc-vip-client.
    2. Add required dependencies to the pom.xml file.
      <parent>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-parent</artifactId>
              <version>1.5.8.RELEASE</version>
              <relativePath/>
          </parent>
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-vipclient</artifactId>
                  <version>1.3</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-pandora</artifactId>
                  <version>1.3</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-feign</artifactId>
              </dependency>
          </dependencies>
      
          <dependencyManagement>
              <dependencies>
                  <dependency>
                      <groupId>org.springframework.cloud</groupId>
                      <artifactId>spring-cloud-dependencies</artifactId>
                      <version>Dalston.SR4</version>
                      <type>pom</type>
                      <scope>import</scope>
                  </dependency>
              </dependencies>
          </dependencyManagement>

      FeignClient is used in this example for demonstration. Compared with sc-vip-server (service provider), the pom.xml file contains the spring-cloud-starter-feign dependency.

    3. In addition to enabling service registration and discovery as in sc-vip-server, add the following two annotations to enable RestTemplate, AsyncRestTemplate, and FeignClient:
      • Add the @LoadBalanced annotation to combine RestTemplate, AsyncRestTemplate, and the service registry.
      • Use the @EnableFeignClients annotation to activate FeignClient.
        @SpringBootApplication
            @EnableDiscoveryClient
            @EnableFeignClients
            public class ConsumerApplication {
        
                @LoadBalanced
                @Bean
                public RestTemplate restTemplate() {
                    return new RestTemplate();
                }
        
                @LoadBalanced
                @Bean
                public AsyncRestTemplate asyncRestTemplate(){
                    return new AsyncRestTemplate();
                }
        
                public static void main(String[] args) {
                    PandoraBootstrap.run(args);
                    SpringApplication.run(ConsumerApplication.class, args);
                    PandoraBootstrap.markStartupAndWait();
                }
        
            }
    4. Configure the service name and the HTTP request of the HTTP method before you use FeignClient of EchoService. In the sc-vip-server project, set the service name to service-provider.
      @FeignClient(name = "service-provider")
          public interface EchoService {
              @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
              String echo(@PathVariable("str") String str);
          }
    5. Create a Controller for call test.
      @RestController
      public class Controller {
         @Autowired
         private RestTemplate restTemplate;
         @Autowired
         private AsyncRestTemplate asyncRestTemplate;
         @Autowired
         private  EchoService echoService;
         @RequestMapping(value = "/echo-rest/{str}", method = RequestMethod.GET)
         public String rest(@PathVariable String str) {
             return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
         }
         @RequestMapping(value = "/echo-async-rest/{str}", method = RequestMethod.GET)
         public String asyncRest(@PathVariable String str) throws Exception{
             ListenableFuture<ResponseEntity<String>> future = asyncRestTemplate.
                     getForEntity("http://service-provider/echo/"+str, String.class);
             return future.get().getBody();
         }
         @RequestMapping(value = "/echo-feign/{str}", method = RequestMethod.GET)
         public String feign(@PathVariable String str) {
             return echoService.echo(str);
         }
      }
      Take note of the following information when you write the code:
      • /echo-rest/ calls the service from the service provider by using RestTemplate.
      • /echo-async-rest/ calls the service from the service provider by using AsyncRestTemplate.
      • /echo-feign/ calls the service from the service provider by using FeignClient.
    6. Configure the application name and the listener port number.
      spring.application.name=service-consumer
      server.port=18082
  3. Perform local code development and debugging.
    1. Start the light-weight configuration center.
      The light-weight configuration center must be started for local code development and debugging, which includes a light-weight EDAS service registry for service providers. For more information about the light-weight configuration center, see Start the light-weight configuration registry.
    2. Start the application.
      • Start the application in an integrated development environment (IDE)

        To start the application in IDE, set the -Dvipserver.server.port=8080 startup parameter in VM options and start the application by calling the main method. This parameter is added only when the application is locally deployed and the light-weight configuration center is used. When the application is deployed to EDAS, remove this parameter. Otherwise, the application cannot be normally released or subscribed to.

        The light-weight configuration center and the application are deployed on different instances and need to be bound in the hosts file. For more information, see Start the light-weight configuration registry.

      • Start the application by using FatJar
        1. Add a FatJar packaging plug-in.

          To package the pandora-boot project into a FatJar package by using Maven, add the following plug-in to pom.xml. To prevent conflicts with other packaging plug-ins, do not add configurations of other FatJar plug-ins to the plugin field in build.

          <build>
              <plugin>
                  <groupId>com.taobao.pandora</groupId>
                      <artifactId>pandora-boot-maven-plugin</artifactId>
                      <version>2.1.9.1</version>
                      <executions>
                         <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                         </execution>
                       </executions>
              </plugin>
          </build>
        2. After you add the plug-in, run the mvn clean package command in the home directory of the project to create a FatJar package in the target directory.
        3. Start the application by running the following Java command:
          java -Dvipserver.server.port=8080 -Dpandora.location=/Users/{$username}/.m2/repository/com/taobao/pandora/taobao-hsf.sar/dev-SNAPSHOT/taobao-hsf.sar-dev-SNAPSHOT.jar  -jar sc-vip-server-0.0.1-SNAPSHOT.jar
          Note The path specified by -Dpandora.location must be a full path placed before sc-vip-server-0.0.1-SNAPSHOT.jar.
      Start the service consumer and call the service provider. The calls are all successful.Develop RESTful applications in HSF and deploy them to EDAS
  4. Troubleshoot frequently asked questions (FAQ).
    • What can I do if I cannot enable service discovery for AsyncRestTemplate?

      AsyncRestTemplate provides service registration and discovery only in Spring Cloud Dalston and later versions. For more information, see pull request.

    • What can I do when FatJar packaging plug-ins conflict with other plug-ins?

      To prevent conflicts with other packaging plug-ins, do not add configurations of other FatJar plug-ins to the plugin field in build.

    • Can taobao-hsf.sar be included during packaging?

      Yes. It can be included. However, we recommend that you do not include it.

      You can modify pandora-boot-maven-plugin and set excludeSar to false to automatically add taobao-hsf.sar to the package file.
      <plugin>
          <groupId>com.taobao.pandora</groupId>
          <artifactId>pandora-boot-maven-plugin</artifactId>
          <version>2.1.9.1</version>
          <configuration>
          <excludeSar>false</excludeSar>
          </configuration>
             <executions>
                 <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                  </execution>
          </executions>
      </plugin>
      This way, the package can be started even if the Pandora address is not configured.
      java -jar  -Dvipserver.server.port=8080 sc-vip-server-0.0.1-SNAPSHOT.jar

      Restore the configuration to exclude the taobao-hsf.sar package before an application is deployed in EDAS.

End-to-end tracing

You can modify your RESTful application locally and connect it to EagleEye of EDAS to enable end-to-end tracing.

To reduce development costs and improve development efficiency, EDAS provides EagleEye for end-to-end tracing. After EagleEye tracking is configured in code, you can use the end-to-end tracing feature of EDAS, without considering log collection, analytics, and storage.

Download the demo source code service1 and service2.

Access EagleEye

  1. Configure the local repository path of EDAS in Maven.
    Pandora Boot Starter-related packages are published in the local repository of EDAS. Therefore, you must configure the local repository path in the settings.xml configuration file of Maven (V3.x or later). For more information, see Configure the local repository path and light-weight configuration registry of EDAS.
  2. Modify the code.
    You can connect RESTful applications to EDAS EagleEye by performing the following steps:
    1. Add the following public settings to the pom.xml file:
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-eagleeye</artifactId>
                  <version>1.3</version>
              </dependency>
      
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-pandora</artifactId>
                  <version>1.3</version>
              </dependency>
    2. Modify the code in the main function.
      The following code shows the original content of the main function:
      public static void main(String[] args) {
          SpringApplication.run(ServerApplication.class, args);
      }
      The following code shows the main function after modification:
      public static void main(String[] args) {
          PandoraBootstrap.run(args);
          SpringApplication.run(ServerApplication.class, args);
          PandoraBootstrap.markStartupAndWait();
      }
    3. Add a FatJar packaging plug-in.
      To package the pandora-boot project into a FatJar package by using Maven, add the following plug-in to pom.xml.

      To prevent conflicts with other packaging plug-ins, do not add configurations of other FatJar plug-ins to the plugin field in build.

      <build>
          <plugins>
          <plugin>
              <groupId>com.taobao.pandora</groupId>
              <artifactId>pandora-boot-maven-plugin</artifactId>
              <version>2.1.9.1</version>
              <executions>
              <execution>
                  <phase>package</phase>
                  <goals>
                  <goal>repackage</goal>
                  </goals>
                  </execution>
              </executions>
          </plugin>
          </plugins>
      </build>

      After you complete the preceding steps, you can use the end-to-end tracing feature of EDAS without setting up collection and analytics systems.

End-to-end tracing examples

To demonstrate how to perform end-to-end tracing, two application demos including service1 and service2 are used in this example.

service2 calls service1, which results in three types of responses.

  • /rest/ok for normal callsEnd-to-end tracing example rest_ok
  • /rest/delay for calls with a large delayEnd-to-end tracing example rest_delay
  • /rest/error for calls with errorsEnd-to-end tracing example rest_error
  1. Deploy an application.
    The collection and analytics features of EagleEye are set up in EDAS. To demonstrate the trace query feature, deploy the service1 and service2 applications in EDAS. For more information, see the following topics:
  2. View the trace information.
    To view the trace information after the application is deployed, you must know the call methods for calling service1 in each of the three demonstration scenarios. You can run the curl http://{$ip:$port}/rest/ok command. You can also use tools such as Postman, or call the methods in your browser. To observe the response, we recommend that you call the methods in script or other modes multiple times. Then, perform the following steps to view the trace information:
    • Log on to the EDAS console and access the application that you deployed.
    • In the left-side navigation pane, choose Application Monitoring > Interface call.
    • View the trace information on the Interface Call page.
  3. Demonstrate on other clients.
    EagleEye implements auto tracking for RestTemplate, AsyncRestTemplate, and FeignClient in /echo-rest/{str}, /echo-async-rest/{str}, and /echo-feign/{str} of service1. You can view the trace information in the same way after you call them.
  4. Troubleshoot FAQ.
    • Auto tracking

      EagleEye of EDAS supports auto tracking for requests of RestTemplate, AsyncRestTemplate, and FeignClient. Auto tracking of more components will be soon added.

    • AsyncRestTemplate

      AsyncRestTemplate must modify the auto tracking configuration during class instantiation. Therefore, injection of the eagleEyeAsyncRestTemplate object, which supports service discovery by default, is required to enable end-to-end tracing.

      @Autowired
      private AsyncRestTemplate eagleEyeAsyncRestTemplate;
    • FatJar packaging plug-in

      To package the pandora-boot project into a FatJar package by using Maven, add pandora-boot-maven-plugin to pom.xml. To prevent conflicts with other packaging plug-ins, do not add configurations of other FatJar plug-ins to the plugin field in build.