Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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,17 @@
subprojects {
group = "sample"
project.version = '1.0'

ext {
scalarDbVersion = '3.13.0'
grpcVersion = '1.65.0'
protobufVersion = '3.24.4'
picoCliVersion = '4.7.5'
log4jVersion = '2.22.1'
annotationVersion = '1.3.2'
}

repositories {
mavenCentral()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
plugins {
id 'java'
id 'application'
}

dependencies {
implementation project(':rpc')
implementation "info.picocli:picocli:${picoCliVersion}"
implementation "com.google.protobuf:protobuf-java-util:${protobufVersion}"
}

application {
mainClassName = 'sample.client.Client'
}

archivesBaseName = "sample-order-service"

sourceCompatibility = 1.8
targetCompatibility = 1.8
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package sample.client;

import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import sample.client.command.GetCustomerInfoCommand;
import sample.client.command.GetOrderCommand;
import sample.client.command.GetOrdersCommand;
import sample.client.command.PlaceOrderCommand;
import sample.client.command.RepaymentCommand;

@Command(
name = "bin/client",
description = "Sample application for Microservice Transaction",
subcommands = {
PlaceOrderCommand.class,
GetOrderCommand.class,
GetOrdersCommand.class,
GetCustomerInfoCommand.class,
RepaymentCommand.class
})
public class Client implements Runnable {

@Option(
names = {"-h", "--help"},
usageHelp = true,
description = "Displays this help message and quits.",
defaultValue = "true")
private Boolean showHelp;

@Override
public void run() {
if (showHelp) {
CommandLine.usage(this, System.out);
}
}

public static void main(String[] args) {
new CommandLine(new Client()).execute(args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package sample.client.command;

import io.grpc.ManagedChannel;
import java.util.concurrent.Callable;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;
import sample.rpc.CustomerServiceGrpc;
import sample.rpc.GetCustomerInfoRequest;
import sample.rpc.GetCustomerInfoResponse;

@Command(name = "GetCustomerInfo", description = "Get customer information")
public class GetCustomerInfoCommand implements Callable<Integer> {

@Parameters(index = "0", paramLabel = "CUSTOMER_ID", description = "customer ID")
private int customerId;

@Override
public Integer call() {
ManagedChannel channel = Utils.getCustomerServiceChannel();
try {
CustomerServiceGrpc.CustomerServiceBlockingStub stub =
CustomerServiceGrpc.newBlockingStub(channel);
GetCustomerInfoResponse response =
stub.getCustomerInfo(
GetCustomerInfoRequest.newBuilder().setCustomerId(customerId).build());
Utils.printJsonString(response);
return 0;
} catch (Exception e) {
e.printStackTrace();
return 1;
} finally {
Utils.shutdownChannel(channel);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package sample.client.command;

import io.grpc.ManagedChannel;
import java.util.concurrent.Callable;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;
import sample.rpc.GetOrderRequest;
import sample.rpc.GetOrderResponse;
import sample.rpc.OrderServiceGrpc;

@Command(name = "GetOrder", description = "Get order information by order ID")
public class GetOrderCommand implements Callable<Integer> {

@Parameters(index = "0", paramLabel = "ORDER_ID", description = "order ID")
private String orderId;

@Override
public Integer call() {
ManagedChannel channel = Utils.getOrderServiceChannel();
try {
OrderServiceGrpc.OrderServiceBlockingStub stub = OrderServiceGrpc.newBlockingStub(channel);
GetOrderResponse response =
stub.getOrder(GetOrderRequest.newBuilder().setOrderId(orderId).build());
Utils.printJsonString(response);
return 0;
} catch (Exception e) {
e.printStackTrace();
return 1;
} finally {
Utils.shutdownChannel(channel);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package sample.client.command;

import io.grpc.ManagedChannel;
import java.util.concurrent.Callable;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;
import sample.rpc.GetOrdersRequest;
import sample.rpc.GetOrdersResponse;
import sample.rpc.OrderServiceGrpc;

@Command(name = "GetOrders", description = "Get order information by customer ID")
public class GetOrdersCommand implements Callable<Integer> {

@Parameters(index = "0", paramLabel = "CUSTOMER_ID", description = "customer ID")
private int customerId;

@Override
public Integer call() {
ManagedChannel channel = Utils.getOrderServiceChannel();
try {
OrderServiceGrpc.OrderServiceBlockingStub stub = OrderServiceGrpc.newBlockingStub(channel);
GetOrdersResponse response =
stub.getOrders(GetOrdersRequest.newBuilder().setCustomerId(customerId).build());
Utils.printJsonString(response);
return 0;
} catch (Exception e) {
e.printStackTrace();
return 1;
} finally {
Utils.shutdownChannel(channel);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package sample.client.command;

import io.grpc.ManagedChannel;
import java.util.concurrent.Callable;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;
import sample.rpc.ItemOrder;
import sample.rpc.OrderServiceGrpc;
import sample.rpc.PlaceOrderRequest;
import sample.rpc.PlaceOrderResponse;

@Command(name = "PlaceOrder", description = "Place an order")
public class PlaceOrderCommand implements Callable<Integer> {

@Parameters(index = "0", paramLabel = "CUSTOMER_ID", description = "customer ID")
private int customerId;

@Parameters(
index = "1",
paramLabel = "ORDERS",
description = "orders. The format is \"<Item ID>:<Count>,<Item ID>:<Count>,...\"")
private String orders;

@Override
public Integer call() {
ManagedChannel channel = Utils.getOrderServiceChannel();
try {
OrderServiceGrpc.OrderServiceBlockingStub stub = OrderServiceGrpc.newBlockingStub(channel);

PlaceOrderRequest.Builder builder = PlaceOrderRequest.newBuilder().setCustomerId(customerId);
for (String order : orders.split(",", -1)) {
String[] s = order.split(":", -1);
int itemId = Integer.parseInt(s[0]);
int count = Integer.parseInt(s[1]);
builder.addItemOrder(ItemOrder.newBuilder().setItemId(itemId).setCount(count).build());
}

PlaceOrderResponse response = stub.placeOrder(builder.build());

Utils.printJsonString(response);
return 0;
} catch (Exception e) {
e.printStackTrace();
return 1;
} finally {
Utils.shutdownChannel(channel);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package sample.client.command;

import io.grpc.ManagedChannel;
import java.util.concurrent.Callable;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;
import sample.rpc.CustomerServiceGrpc;
import sample.rpc.RepaymentRequest;
import sample.rpc.RepaymentResponse;

@Command(name = "Repayment", description = "Repayment")
public class RepaymentCommand implements Callable<Integer> {

@Parameters(index = "0", paramLabel = "CUSTOMER_ID", description = "customer ID")
private int customerId;

@Parameters(index = "1", paramLabel = "AMOUNT", description = "repayment amount")
private int amount;

@Override
public Integer call() {
ManagedChannel channel = Utils.getCustomerServiceChannel();
try {
CustomerServiceGrpc.CustomerServiceBlockingStub stub =
CustomerServiceGrpc.newBlockingStub(channel);
RepaymentResponse response =
stub.repayment(
RepaymentRequest.newBuilder().setCustomerId(customerId).setAmount(amount).build());
Utils.printJsonString(response);
return 0;
} catch (Exception e) {
e.printStackTrace();
return 1;
} finally {
Utils.shutdownChannel(channel);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package sample.client.command;

import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageOrBuilder;
import com.google.protobuf.util.JsonFormat;
import io.grpc.ManagedChannel;
import io.grpc.netty.NettyChannelBuilder;
import java.util.concurrent.TimeUnit;

public final class Utils {

private Utils() {}

public static ManagedChannel getCustomerServiceChannel() {
return NettyChannelBuilder.forAddress("localhost", 10010).usePlaintext().build();
}

public static ManagedChannel getOrderServiceChannel() {
return NettyChannelBuilder.forAddress("localhost", 10020).usePlaintext().build();
}

public static void shutdownChannel(ManagedChannel channel) {
try {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.err.println("failed to shut down the channel");
}
}

public static void printJsonString(MessageOrBuilder messageOrBuilder)
throws InvalidProtocolBufferException {
System.out.println(JsonFormat.printer().print(messageOrBuilder));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM eclipse-temurin:8-jre-jammy

WORKDIR /

ADD customer-service.tar .

WORKDIR /customer-service

COPY customer-service.properties database.properties

ENTRYPOINT ["./bin/customer-service", "--config", "database.properties"]

EXPOSE 10010
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
plugins {
id 'java'
id 'java-library-distribution'
id 'application'
id 'com.palantir.docker' version '0.25.0'
}

dependencies {
implementation project(':rpc')
implementation "com.scalar-labs:scalardb-sql-jdbc:${scalarDbVersion}"
implementation "com.scalar-labs:scalardb-cluster-java-client-sdk:${scalarDbVersion}"
implementation "info.picocli:picocli:${picoCliVersion}"
implementation "org.apache.logging.log4j:log4j-api:${log4jVersion}"
implementation "org.apache.logging.log4j:log4j-core:${log4jVersion}"
implementation "org.apache.logging.log4j:log4j-slf4j2-impl:${log4jVersion}"
}

application {
mainClassName = 'sample.customer.CustomerServiceServer'
}

docker {
name "sample-customer-service:${project.version}"
files tasks.distTar.outputs, 'customer-service.properties'
}

distTar {
archiveFileName = "${project.name}.tar"
duplicatesStrategy DuplicatesStrategy.EXCLUDE
}

distZip {
duplicatesStrategy DuplicatesStrategy.EXCLUDE
}

installDist {
duplicatesStrategy DuplicatesStrategy.EXCLUDE
}

archivesBaseName = "sample-customer-service"

sourceCompatibility = 1.8
targetCompatibility = 1.8
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
scalar.db.sql.connection_mode=cluster
scalar.db.sql.cluster_mode.contact_points=indirect:scalardb-cluster-node

# Enable ScalarDB Auth
scalar.db.cluster.auth.enabled=true
scalar.db.sql.cluster_mode.username=customer-service
scalar.db.sql.cluster_mode.password=customer-service
Loading