Building Microservices with Spring Boot and Apache Thrift. Part 2. Swifty services
http://bsideup.blogspot.com/2015/04/spring-boot-thrift-part2.html
Few words about Swift. Swift - Java annotation-based generator for Apache Thrift. It's priceless when you develop your APIs in Java and want to expose them to the other world using Apache Thrift.
Protocol
Lets recreate our previous example ( https://github.com/bsideup/spring-boot-thrift ) with it. Start with simple build.gradle file:
| apply plugin: 'java' | |
| apply plugin: 'spring-boot' | |
| buildscript { | |
| repositories { | |
| jcenter() | |
| } | |
| dependencies { | |
| classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.1.RELEASE") | |
| } | |
| } | |
| repositories { | |
| jcenter() | |
| } | |
| sourceCompatibility = 1.8 | |
| targetCompatibility = 1.8 | |
| dependencies { | |
| compile "org.projectlombok:lombok:1.16.2" | |
| compile("org.springframework.boot:spring-boot-starter-web") | |
| compile 'com.facebook.swift:swift-annotations:0.14.1' | |
| compile 'com.facebook.swift:swift-service:0.14.1' | |
| compile 'com.facebook.swift:swift-codec:0.14.1' | |
| compile 'com.facebook.nifty:nifty-core:0.14.1' | |
| compile 'org.apache.thrift:libthrift:0.9.1' | |
| testCompile "org.springframework.boot:spring-boot-starter-test" | |
| } |
Nothing special, Spring Boot with few Facebook Swift libraries.
Next we need to add Swift protocol classes:
| package com.example.calculator.protocol; | |
| import com.facebook.swift.service.ThriftMethod; | |
| import com.facebook.swift.service.ThriftService; | |
| import com.google.common.util.concurrent.ListenableFuture; | |
| @ThriftService | |
| public interface TCalculatorService { | |
| @ThriftMethod | |
| int calculate(int num1, int num2, TOperation op) throws TDivisionByZeroException; | |
| } |
Exception is simple Swift struct which extend Exception (See Ma no TException)
| package com.example.calculator.protocol; | |
| import com.facebook.swift.codec.ThriftStruct; | |
| @ThriftStruct | |
| public final class TDivisionByZeroException extends Exception { | |
| } |
Enums are handled with Swift, so we don't need to annotate them (but we can)
| package com.example.calculator.protocol; | |
| public enum TOperation { | |
| ADD, | |
| SUBTRACT, | |
| MULTIPLY, | |
| DIVIDE | |
| } |
Next - application main class for Spring Boot:
| package com.example.calculator; | |
| import com.example.calculator.protocol.TCalculatorService; | |
| import com.facebook.nifty.processor.NiftyProcessorAdapters; | |
| import com.facebook.swift.codec.ThriftCodecManager; | |
| import com.facebook.swift.service.ThriftEventHandler; | |
| import com.facebook.swift.service.ThriftServiceProcessor; | |
| import org.apache.thrift.protocol.*; | |
| import org.apache.thrift.server.TServlet; | |
| import org.springframework.boot.SpringApplication; | |
| import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | |
| import org.springframework.context.annotation.*; | |
| import javax.servlet.Servlet; | |
| import java.util.Arrays; | |
| @Configuration | |
| @EnableAutoConfiguration | |
| @ComponentScan | |
| public class CalculatorApplication { | |
| public static void main(String[] args) { | |
| SpringApplication.run(CalculatorApplication.class, args); | |
| } | |
| @Bean | |
| TProtocolFactory tProtocolFactory() { | |
| return new TBinaryProtocol.Factory(); | |
| } | |
| @Bean | |
| ThriftCodecManager thriftCodecManager() { | |
| return new ThriftCodecManager(); | |
| } | |
| @Bean | |
| Servlet thrift(ThriftCodecManager thriftCodecManager, TProtocolFactory protocolFactory, TCalculatorService exampleService) { | |
| ThriftServiceProcessor processor = new ThriftServiceProcessor(thriftCodecManager, Arrays.<ThriftEventHandler>asList(), exampleService); | |
| return new TServlet( | |
| NiftyProcessorAdapters.processorToTProcessor(processor), | |
| protocolFactory, | |
| protocolFactory | |
| ); | |
| } | |
| } |
Test
Now we're ready to write some tests:
| package com.example.calculator; | |
| import com.example.calculator.protocol.TCalculatorService; | |
| import com.example.calculator.protocol.TDivisionByZeroException; | |
| import com.example.calculator.protocol.TOperation; | |
| import com.facebook.nifty.client.HttpClientConnector; | |
| import com.facebook.swift.codec.ThriftCodecManager; | |
| import com.facebook.swift.service.ThriftClientManager; | |
| import org.apache.thrift.protocol.TProtocolFactory; | |
| import org.junit.Before; | |
| import org.junit.Test; | |
| import org.junit.runner.RunWith; | |
| import org.springframework.beans.factory.annotation.Autowired; | |
| import org.springframework.beans.factory.annotation.Value; | |
| import org.springframework.boot.test.IntegrationTest; | |
| import org.springframework.boot.test.SpringApplicationConfiguration; | |
| import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | |
| import org.springframework.test.context.web.WebAppConfiguration; | |
| import java.net.URI; | |
| import static org.junit.Assert.*; | |
| @RunWith(SpringJUnit4ClassRunner.class) | |
| @SpringApplicationConfiguration(classes = CalculatorApplication.class) | |
| @WebAppConfiguration | |
| @IntegrationTest("server.port:0") | |
| public class CalculatorApplicationTest { | |
| @Autowired | |
| TProtocolFactory protocolFactory; | |
| @Autowired | |
| ThriftCodecManager thriftCodecManager; | |
| @Value("${local.server.port}") | |
| protected int port; | |
| protected TCalculatorService client; | |
| @Before | |
| public void setUp() throws Exception { | |
| HttpClientConnector connector = new HttpClientConnector(URI.create("http://localhost:" + port + "/thrift/")); | |
| ThriftClientManager clientManager = new ThriftClientManager(thriftCodecManager); | |
| client = clientManager.createClient(connector, TCalculatorService.class).get(); | |
| } | |
| @Test | |
| public void testAdd() throws Exception { | |
| assertEquals(5, client.calculate(2, 3, TOperation.ADD)); | |
| } | |
| @Test | |
| public void testSubtract() throws Exception { | |
| assertEquals(3, client.calculate(5, 2, TOperation.SUBTRACT)); | |
| } | |
| @Test | |
| public void testMultiply() throws Exception { | |
| assertEquals(10, client.calculate(5, 2, TOperation.MULTIPLY)); | |
| } | |
| @Test | |
| public void testDivide() throws Exception { | |
| assertEquals(2, client.calculate(10, 5, TOperation.DIVIDE)); | |
| } | |
| @Test(expected = TDivisionByZeroException.class) | |
| public void testDivisionByZero() throws Exception { | |
| client.calculate(10, 0, TOperation.DIVIDE); | |
| } | |
| } |
As you can see, only difference here (compared to Thrift version) is setUp method.
Diff with Thrift version
Implementation
We still have no Swift service implementation. Implementation of handler looks almost the same asprevious:
| package com.example.calculator.handler; | |
| import com.example.calculator.protocol.TCalculatorService; | |
| import com.example.calculator.protocol.TDivisionByZeroException; | |
| import com.example.calculator.protocol.TOperation; | |
| import org.springframework.stereotype.Component; | |
| import com.example.calculator.service.CalculatorService; | |
| import org.springframework.beans.factory.annotation.Autowired; | |
| @Component | |
| public class CalculatorServiceHandler implements TCalculatorService { | |
| @Autowired | |
| CalculatorService calculatorService; | |
| @Override | |
| public int calculate(int num1, int num2, TOperation op) throws TDivisionByZeroException { | |
| switch(op) { | |
| case ADD: | |
| return calculatorService.add(num1, num2); | |
| case SUBTRACT: | |
| return calculatorService.subtract(num1, num2); | |
| case MULTIPLY: | |
| return calculatorService.multiply(num1, num2); | |
| case DIVIDE: | |
| try { | |
| return calculatorService.divide(num1, num2); | |
| } catch(IllegalArgumentException e) { | |
| throw new TDivisionByZeroException(); | |
| } | |
| default: | |
| throw new IllegalArgumentException("Unknown operation " + op); | |
| } | |
| } | |
| } |
Now if you will run tests you should see all tests green.

Thrift integration
But hey, how about other non-Java consumers of service? Don't worry, Swift comes with a tool for generating *.thrift files from annotated Java classes:https://github.com/facebook/swift/tree/master/swift2thrift-generator-cli
Example output for our service will be:
| namespace java.swift com.example.calculator.protocol | |
| namespace java com.example.calculator.protocol | |
| namespace py com.example.calculator.protocol | |
| namespace as3 com.example.calculator.protocol | |
| enum TOperation { | |
| ADD, SUBTRACT, MULTIPLY, DIVIDE | |
| } | |
| exception TDivisionByZeroException { | |
| } | |
| service TCalculatorService { | |
| i32 calculate(1: i32 arg0, 2: i32 arg1, 3: TOperation arg2) throws (1: TDivisionByZeroException ex1); | |
| } |
Conclusion
Full source files for this example can be found at GitHub: https://github.com/bsideup/spring-boot-swift
Next time I will show you how to write Async Thrift services using Swift with minimal changes. Stay tuned!
Building Microservices with Spring Boot and Apache Thrift. Part 2. Swifty services的更多相关文章
- Building Microservices with Spring Boot and Apache Thrift. Part 1 with servlet
https://dzone.com/articles/building-microservices-spring In the modern world of microservices it's i ...
- Quick Guide to Microservices with Spring Boot 2.0, Eureka and Spring Cloud
https://piotrminkowski.wordpress.com/2018/04/26/quick-guide-to-microservices-with-spring-boot-2-0-eu ...
- Building microservices with Spring Cloud and Netflix OSS, part 2
In Part 1 we used core components in Spring Cloud and Netflix OSS, i.e. Eureka, Ribbon and Zuul, to ...
- Spring Boot 整合 Apache Dubbo
Apache Dubbo是一款高性能.轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现. 注意,是 Apache Dubb ...
- Spring Boot 整合 Apache Ignite
关于Ignite的介绍,这边推荐三个链接进行学习了解. https://ignite.apache.org/,首选还是官网,不过是英文版,如果阅读比较吃力可以选择下方两个链接. https://www ...
- Microservices with Spring Boot
找到一套比较不错的Spring Boot/Cloud入门教程,推荐一下. https://dzone.com/users/1041459/ranga_pec.html
- Spring boot with Apache Hive
5.29.1. Maven <dependency> <groupId>org.springframework.boot</groupId> <artif ...
- spring boot 集成 Apache CXF 调用 .NET 服务端 WebService
1. pom.xml加入 cxf 的依赖 <dependency> <groupId>org.apache.cxf</groupId> <artifactId ...
- Spring Boot Reference Guide
Spring Boot Reference Guide Authors Phillip Webb, Dave Syer, Josh Long, Stéphane Nicoll, Rob Winch, ...
随机推荐
- MySQL5.5 安装配置方法教程
MySQL下载地址:http://dev.mysql.com/downloads/installer/ 1.首先进入的是安装引导界面 2.然后进入的是类型选择界面,这里有3个类型:Typical(典型 ...
- MRP设置自动执行
1.在计划向导中,找到调度运算,如下配置, 2.配置成功后自动生成执行计划
- Alertmanager 安装(k8s报警)
一.下载Alertmanager https://prometheus.io/download/ wget https://github.com/prometheus/alertmanager/rel ...
- Centso7 简单优化(阿里云服务器)
##.下载常用包 # yum -y install wget net-tools screen lsof tcpdump nc mtr openssl-devel vim bash-completio ...
- 多线程的实现方式01 Thread
/* * 多线程 有三种实现方式 * 其一 Thread * * 写一个类 * * 1.让他继承 Thread * 2.重写thread中的run方法 * 3.创建子类对象就是在 创建线程! * 3. ...
- Codeforces 888G(分治+trie)
按位贪心,以当前考虑位是0还是1将数分成两部分,则MST中这两部分之间只会存在一条边,因为一旦有两条或以上的边,考虑两条边在原图中所成的环,显然这两条边有一条是环上的权值最大边,不会出现在MST中.则 ...
- PHP——敏感词过滤
前言 如果可以用第三方的话,那么你是幸运的,因为现在这种敏感词过滤,敏感图片,敏感语音过滤的第三方服务还是挺多的 敏感词过滤 核心代码 利用PHP内置的三个函数 array_combine() | a ...
- Docker最全教程
摘自雪雁大佬的博客,地址:https://www.cnblogs.com/codelove/default.html 目录: Docker最全教程——从理论到实战(一) Docker最全教程——从理论 ...
- P1308 统计单词数
P1308 题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定一个单词,请 ...
- Number Sequence POJ - 1019 递推 数学
题意 1 12 123 1234 12345 ....这样的序列 问第n位数字是几 是数字! 1-9! 思路:递推关系 主要是位数的计算 用a[i]=a[i-1]+(int)log10((do ...