Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the Thrift tutorial #4865

Merged
merged 76 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
d17cfe9
Add thrift tutorial
geun-son Mar 20, 2023
2c86fdf
Rewrite Thrift tutorial introduction
haneepark Apr 20, 2023
5765946
Update toc for Thrift tutorial
haneepark May 1, 2023
9902dde
Rewrite implement CREATE for Thrift tutorial
haneepark May 3, 2023
60f94a5
Rewrite implement READ for Thrift tutorial
haneepark May 3, 2023
a744e63
Rewrite implement UPDATE for Thrift tutorial
haneepark May 3, 2023
00f31af
Rewrite implement DELETE for Thrift tutorial
haneepark May 3, 2023
358f2d6
Add define service method step in Thrift tutorial
haneepark May 4, 2023
41e9c09
Add DocService in implement DELETE step
haneepark May 4, 2023
f4a1085
Change expressions in Thrift tutorial
haneepark May 4, 2023
d6ef691
Update what you need for Thrift tutorial
haneepark May 4, 2023
eb4355a
Write intros and outros for each steps in Thrift tutorial
haneepark May 8, 2023
da0956e
Update expressions and sentences in Thrift tutorial
haneepark May 8, 2023
1d68d46
Merge branch 'main' of github.com:line/armeria into thrift-tutorial
jrhee17 May 9, 2023
531034d
Update introduction for Thrift tutorial
haneepark May 11, 2023
f95c091
Update site/src/pages/tutorials/thrift/blog/implement-delete.mdx
haneepark May 11, 2023
efc9544
Add BlogClient for testing Thrift tutorial
jrhee17 May 9, 2023
b46fd02
Add more test cases for Thrift tutorial
haneepark May 15, 2023
33d928f
Use BlogServiceTest instead of using separate client module
haneepark May 15, 2023
c10796c
Remove class declarations in code snippets if possible
haneepark May 15, 2023
dece866
Fix a typo
haneepark May 15, 2023
b1f1720
Update expressions in Thrift Tutorial
haneepark May 16, 2023
64b88e3
Merge branch 'main' into thrift-tutorial
jrhee17 May 16, 2023
2998d74
Fix lint errors
haneepark May 16, 2023
43e3966
Update site/src/pages/tutorials/thrift/blog/index.mdx
haneepark May 17, 2023
86f10f2
Update site/src/pages/tutorials/thrift/blog/index.mdx
haneepark May 17, 2023
4d4de6c
Update site/src/pages/tutorials/thrift/blog/index.mdx
haneepark May 17, 2023
e3c5780
Update site/src/pages/tutorials/thrift/blog/index.mdx
haneepark May 17, 2023
b33c852
Update site/src/pages/tutorials/thrift/blog/create-service.mdx
haneepark May 17, 2023
7ca77d6
Update site/src/pages/tutorials/thrift/blog/run-server-and-client.mdx
haneepark May 17, 2023
ec618e5
Update site/src/pages/tutorials/thrift/blog/run-server-and-client.mdx
haneepark May 17, 2023
9ec29e8
Update site/src/pages/tutorials/thrift/blog/define-service-methods.mdx
haneepark May 17, 2023
38dcfed
Reflect feedbacks
haneepark May 17, 2023
284afa4
Update site/src/pages/tutorials/thrift/blog/implement-read.mdx
haneepark May 17, 2023
8330bd6
Update site/src/pages/tutorials/thrift/blog/implement-delete.mdx
haneepark May 17, 2023
0137c43
Update site/src/pages/tutorials/thrift/blog/implement-read.mdx
haneepark May 17, 2023
bab7696
Change indents to 2 spaces and remove javadocs for Thrift tutorial codes
haneepark May 17, 2023
ae779aa
Update build.gradle example
haneepark May 17, 2023
8d059b1
Move 'add an exception handler' part to 'Implement UPDATE'
haneepark May 17, 2023
763d61b
Split the '4. Test creating a blog post' step into two steps
haneepark May 17, 2023
ec87186
Update site/src/pages/tutorials/thrift/blog/index.mdx
haneepark May 23, 2023
d877530
Update site/src/pages/tutorials/thrift/blog/define-service-methods.mdx
haneepark May 23, 2023
5888dc4
Update site/src/pages/tutorials/thrift/blog/define-service-methods.mdx
haneepark May 23, 2023
0e5cfa0
Update site/src/pages/tutorials/thrift/blog/implement-create.mdx
haneepark May 23, 2023
f05c115
Update site/src/pages/tutorials/thrift/blog/implement-update.mdx
haneepark May 23, 2023
5f4ffac
Update site/src/pages/tutorials/thrift/blog/implement-delete.mdx
haneepark May 23, 2023
a2513cd
Update site/src/pages/tutorials/thrift/blog/implement-read.mdx
haneepark May 23, 2023
cc3016f
Update site/src/pages/tutorials/thrift/blog/implement-delete.mdx
haneepark May 23, 2023
170a044
Update site/src/pages/tutorials/thrift/blog/implement-create.mdx
haneepark May 23, 2023
dc37fa9
Update an expression
haneepark May 23, 2023
10bf2a1
Remove redundant words
haneepark May 23, 2023
0e9794e
Add printing out the response in test code
haneepark Jun 2, 2023
48c076d
Adjust indents so that the comments are not hidden
haneepark Jun 2, 2023
2bb84d0
Merge branch 'main' into thrift-tutorial
jrhee17 Jun 2, 2023
6872350
Update site/src/pages/tutorials/thrift/blog/create-service.mdx
haneepark Jun 2, 2023
f4e76a7
Add monospaces for filenames in What you need
haneepark Jun 2, 2023
f0b390b
Adjust indent for readability
haneepark Jun 2, 2023
1b80822
Adjust indent for readability
haneepark Jun 2, 2023
4132574
Add spaces for aligning
haneepark Jun 2, 2023
7fba1a7
Update site/src/pages/tutorials/thrift/blog/index.mdx
haneepark Jun 2, 2023
15e8c83
Update site/src/pages/tutorials/thrift/blog/implement-update.mdx
haneepark Jun 2, 2023
8e1ec88
Introduce testing in the earlier step and remove main() method for cl…
haneepark Jun 2, 2023
c342cea
Update site/src/pages/tutorials/thrift/blog/index.mdx
haneepark Jun 7, 2023
4e50577
Mention directory path explicitly
haneepark Jun 7, 2023
d584c0f
Update site/src/pages/tutorials/thrift/blog/run-server.mdx
haneepark Jun 7, 2023
3da77f9
Update site/src/pages/tutorials/thrift/blog/run-server.mdx
haneepark Jun 7, 2023
8511376
Remove the main method in BlogClient
haneepark Jun 7, 2023
21d357e
Update site/src/pages/tutorials/thrift/blog/implement-delete.mdx
haneepark Jun 7, 2023
a03a006
Update site/src/pages/tutorials/thrift/blog/implement-delete.mdx
haneepark Jun 7, 2023
fe780c0
Update site/src/pages/tutorials/thrift/blog/implement-update.mdx
haneepark Jun 7, 2023
98ca732
Update site/src/pages/tutorials/thrift/blog/implement-read.mdx
haneepark Jun 7, 2023
7b60018
Update site/src/pages/tutorials/thrift/blog/implement-read.mdx
haneepark Jun 7, 2023
dea93a3
Update site/src/pages/tutorials/thrift/blog/implement-create.mdx
haneepark Jun 7, 2023
c4358d1
Remove or disable the hello() test method
haneepark Jun 7, 2023
f3c13b7
Make the implementing READ step simpler and clearer
haneepark Jun 7, 2023
1173e70
Use cpp as syntax highlighter since there is no highlighter for thrift
ikhoon Jun 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package example.armeria.server.blog.thrift;

import java.net.URI;
import java.util.List;

import org.apache.thrift.TException;

import com.linecorp.armeria.client.logging.LoggingClient;
import com.linecorp.armeria.client.thrift.ThriftClients;

import example.armeria.blog.thrift.BlogPost;
import example.armeria.blog.thrift.BlogService;
import example.armeria.blog.thrift.CreateBlogPostRequest;
import example.armeria.blog.thrift.DeleteBlogPostRequest;
import example.armeria.blog.thrift.GetBlogPostRequest;
import example.armeria.blog.thrift.ListBlogPostsRequest;
import example.armeria.blog.thrift.UpdateBlogPostRequest;

public final class BlogClient {

private final BlogService.Iface blogService;

BlogClient(URI uri, String path) {
blogService = ThriftClients.builder(uri)
.path(path)
.decorator(LoggingClient.newDecorator())
.build(BlogService.Iface.class);
}

BlogPost createBlogPost(String title, String content) throws TException {
final CreateBlogPostRequest request =
new CreateBlogPostRequest().setTitle(title)
.setContent(content);
return blogService.createBlogPost(request);
}

BlogPost getBlogPost(int id) throws TException {
final GetBlogPostRequest request =
new GetBlogPostRequest().setId(id);
return blogService.getBlogPost(request);
}

List<BlogPost> listBlogPosts(boolean descending) throws TException {
return blogService.listBlogPosts(new ListBlogPostsRequest().setDescending(descending))
.getBlogs();
}

BlogPost updateBlogPost(int id, String newTitle, String newContent) throws TException {
final UpdateBlogPostRequest request = new UpdateBlogPostRequest().setId(id)
.setTitle(newTitle)
.setContent(newContent);
return blogService.updateBlogPost(request);
}

void deleteBlogPost(int id) throws TException {
final DeleteBlogPostRequest request = new DeleteBlogPostRequest().setId(id);
blogService.deleteBlogPost(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public void updateBlogPost(UpdateBlogPostRequest request, AsyncMethodCallback<Bl
final BlogPost oldBlogPost = blogPosts.get(request.getId());
if (oldBlogPost == null) {
resultHandler.onError(
new BlogNotFoundException("The blog post does not exist. ID: " + request.getId()));
new IllegalArgumentException("The blog post does not exist. ID: " + request.getId()));
} else {
final BlogPost newBlogPost = oldBlogPost.deepCopy()
.setTitle(request.getTitle())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,18 @@
import java.util.List;

import org.apache.thrift.TException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.linecorp.armeria.client.logging.LoggingRpcClient;
import com.linecorp.armeria.client.thrift.ThriftClients;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.thrift.THttpService;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;

import example.armeria.blog.thrift.BlogNotFoundException;
import example.armeria.blog.thrift.BlogPost;
import example.armeria.blog.thrift.BlogService;
import example.armeria.blog.thrift.CreateBlogPostRequest;
import example.armeria.blog.thrift.DeleteBlogPostRequest;
import example.armeria.blog.thrift.GetBlogPostRequest;
import example.armeria.blog.thrift.ListBlogPostsRequest;
import example.armeria.blog.thrift.ListBlogPostsResponse;
import example.armeria.blog.thrift.UpdateBlogPostRequest;

@TestMethodOrder(OrderAnnotation.class)
class BlogServiceTest {
Expand All @@ -43,42 +33,34 @@ protected void configure(ServerBuilder sb) throws Exception {
}
};

static BlogService.Iface client;

@BeforeAll
static void beforeAll() {
client = ThriftClients.builder(server.httpUri())
.path("/thrift")
.rpcDecorator(LoggingRpcClient.newDecorator())
.build(BlogService.Iface.class);
}

@Test
@Order(1)
void createBlogPost() throws TException {
final CreateBlogPostRequest request = new CreateBlogPostRequest()
.setTitle("My first blog")
.setContent("Hello Armeria!");
final BlogPost response = client.createBlogPost(request);
final BlogClient client = new BlogClient(server.httpUri(), "/thrift");
final BlogPost response = client.createBlogPost("My first blog", "Hello Armeria!");
assertThat(response.getId()).isGreaterThanOrEqualTo(0);
assertThat(response.getTitle()).isEqualTo(request.getTitle());
assertThat(response.getContent()).isEqualTo(request.getContent());
assertThat(response.getTitle()).isEqualTo("My first blog");
assertThat(response.getContent()).isEqualTo("Hello Armeria!");
System.out.println(response);
}

@Test
@Order(2)
void getBlogPost() throws TException {
final BlogPost blogPost = client.getBlogPost(new GetBlogPostRequest().setId(0));
final BlogClient client = new BlogClient(server.httpUri(), "/thrift");
final BlogPost blogPost = client.getBlogPost(0);

assertThat(blogPost.getTitle()).isEqualTo("My first blog");
assertThat(blogPost.getContent()).isEqualTo("Hello Armeria!");
System.out.println(blogPost);
}

@Test
@Order(3)
void getInvalidBlogPost() {
final BlogClient client = new BlogClient(server.httpUri(), "/thrift");
final Throwable exception = catchThrowable(() -> {
client.getBlogPost(new GetBlogPostRequest().setId(Integer.MAX_VALUE));
client.getBlogPost(Integer.MAX_VALUE);
});
assertThat(exception).isInstanceOf(BlogNotFoundException.class)
.extracting("reason")
Expand All @@ -89,15 +71,10 @@ void getInvalidBlogPost() {
@Test
@Order(4)
void listBlogPosts() throws TException {
final CreateBlogPostRequest newBlogPost = new CreateBlogPostRequest()
.setTitle("My second blog")
.setContent("Armeria is awesome!");
client.createBlogPost(newBlogPost);
final ListBlogPostsResponse
response = client.listBlogPosts(new ListBlogPostsRequest()
.setDescending(false));

final List<BlogPost> blogs = response.getBlogs();
final BlogClient client = new BlogClient(server.httpUri(), "/thrift");
client.createBlogPost("My second blog", "Armeria is awesome!");

final List<BlogPost> blogs = client.listBlogPosts(false);
assertThat(blogs).hasSize(2);
final BlogPost firstBlog = blogs.get(0);
assertThat(firstBlog.getTitle()).isEqualTo("My first blog");
Expand All @@ -106,26 +83,54 @@ void listBlogPosts() throws TException {
final BlogPost secondBlog = blogs.get(1);
assertThat(secondBlog.getTitle()).isEqualTo("My second blog");
assertThat(secondBlog.getContent()).isEqualTo("Armeria is awesome!");
System.out.println(blogs);
}

@Test
@Order(5)
void updateBlogPosts() throws TException {
final UpdateBlogPostRequest request = new UpdateBlogPostRequest()
.setId(0)
.setTitle("My first blog")
.setContent("Hello awesome Armeria!");
final BlogPost updated = client.updateBlogPost(request);
final BlogClient client = new BlogClient(server.httpUri(), "/thrift");
final BlogPost updated = client.updateBlogPost(0, "My first blog", "Hello awesome Armeria!");
assertThat(updated.getId()).isZero();
assertThat(updated.getTitle()).isEqualTo("My first blog");
assertThat(updated.getContent()).isEqualTo("Hello awesome Armeria!");
System.out.println(updated);
}

@Test
@Order(6)
void badRequestExceptionHandlerWhenTryingDeleteMissingBlogPost() {
void updateInvalidBlogPost() {
final BlogClient client = new BlogClient(server.httpUri(), "/thrift");
final Throwable exception = catchThrowable(() -> {
final BlogPost updated = client.updateBlogPost(Integer.MAX_VALUE, "My first blog",
"Hello awesome Armeria!");
});
assertThat(exception).isInstanceOf(BlogNotFoundException.class)
.extracting("reason")
.asString()
.isEqualTo("The blog post does not exist. ID: " + Integer.MAX_VALUE);
}

@Test
@Order(7)
void deleteBlogPost() throws TException {
final BlogClient client = new BlogClient(server.httpUri(), "/thrift");
client.deleteBlogPost(1);
final Throwable exception = catchThrowable(() -> {
client.getBlogPost(1);
});
assertThat(exception).isInstanceOf(BlogNotFoundException.class)
.extracting("reason")
.asString()
.isEqualTo("The blog post does not exist. ID: 1");
}

@Test
@Order(8)
void deleteInvalidBlogPost() {
final BlogClient client = new BlogClient(server.httpUri(), "/thrift");
final Throwable exception = catchThrowable(() -> {
client.deleteBlogPost(new DeleteBlogPostRequest().setId(100));
client.deleteBlogPost(100);
});
assertThat(exception).isInstanceOf(BlogNotFoundException.class)
.extracting("reason")
Expand Down
2 changes: 2 additions & 0 deletions site/src/components/code-block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import prismTheme from 'react-syntax-highlighter/dist/esm/styles/prism/cb';
// Prism syntaxes
/* eslint-disable import/no-extraneous-dependencies */
import bash from 'react-syntax-highlighter/dist/esm/languages/prism/bash';
import cpp from 'react-syntax-highlighter/dist/esm/languages/prism/cpp';
import graphql from 'react-syntax-highlighter/dist/esm/languages/prism/graphql';
import groovy from 'react-syntax-highlighter/dist/esm/languages/prism/groovy';
import http from 'react-syntax-highlighter/dist/esm/languages/prism/http';
Expand Down Expand Up @@ -40,6 +41,7 @@ none.aliases = [] as string[];

const supportedLanguages = {
bash,
cpp,
graphql,
groovy,
http,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
86 changes: 86 additions & 0 deletions site/src/pages/tutorials/thrift/blog/create-service.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
menuTitle: "Create a service"
order: 1
category: thrift
type: step
targetLang: java
---

# Creating a service

As the first step of the tutorial, we'll create a simple service with a dummy method in Thrift and implement the service in Java.

<TutorialSteps current={1} />

## What you need

No preparation is required for this step. Do check that you've prepared the [prerequisites](/tutorials/thrift/blog/#prerequisites).

## 1. Create a thrift file

Create a thrift file, `blog.thrift` in the `{project_root}/src/main/thrift` folder as follows.
In the thrift file, let's define the `BlogService` service with the `hello()` method.

```cpp filename=blog.thrift
namespace java example.armeria.blog.thrift

service BlogService {
string hello()
}
```

<Tip>

See [Sample service structure](/tutorials/thrift/blog#sample-service-structure) for the overall folder structure.

</Tip>

## 2. Compile the thrift file

Compile the `blog.thrift` file to generate Java code.
You can refer to the full [build.gradle](https://github.com/line/armeria-examples/tree/main/tutorials/thrift/build.gradle) file for generating code with [Gradle Thrift Plugin](https://github.com/jruyi/thrift-gradle-plugin).

```bash
./gradlew compileThrift
```

You'll see the generated Java code in the `{project_root}/build/generated-sources/thrift/gen-java/example/armeria/blog/thrift/` folder.

## 3. Implement the service

Now, let's implement the service in Java.

1. Create a file, `BlogServiceImpl.java`.
2. Declare the `BlogServiceImpl` class implementing the `BlogService` service we defined earlier in Thrift.
haneepark marked this conversation as resolved.
Show resolved Hide resolved
```java filename=BlogServiceImpl.java
package example.armeria.server.blog.thrift;

import example.armeria.blog.thrift.BlogService;

public class BlogServiceImpl implements BlogService.AsyncIface {}
```
3. In the `BlogServiceImpl` class, override the `hello()` method, a dummy method for temporary use to test the connection between server and client.
haneepark marked this conversation as resolved.
Show resolved Hide resolved
```java filename=BlogServiceImpl.java
import org.apache.thrift.async.AsyncMethodCallback;
...
@Override
public void hello(AsyncMethodCallback<String> resultHandler) {
resultHandler.onComplete("Hello, Armeria!");
}
```

<Tip>

Although here we implement the asynchronous interface `BlogService.AsyncIface`, note that implementing the synchronous interface `BlogService.Iface` isn't very different.
See [Running a Thrift service](/docs/server-thrift) for more information.

</Tip>

## What's next

In this step, we've created a simple service with a dummy method.

Next, at [Step 2. Run a server](/tutorials/thrift/blog/run-server), we'll create and run a server with the service we've created.
Also, we'll run a client to make a call to the service.

<TutorialSteps current={1} />
Loading