Skip to content

Commit 8035eeb

Browse files
Merge pull request #16793 from parthiv39731/BAEL-8055
Bael 8055
2 parents a1e41ee + d00b595 commit 8035eeb

File tree

4 files changed

+192
-5
lines changed

4 files changed

+192
-5
lines changed

grpc/pom.xml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@
2525
<scope>runtime</scope>
2626
<version>${io.grpc.version}</version>
2727
</dependency>
28-
<dependency>
29-
<groupId>io.grpc</groupId>
30-
<artifactId>grpc-protobuf</artifactId>
31-
<version>${io.grpc.version}</version>
32-
</dependency>
3328
<dependency>
3429
<groupId>io.grpc</groupId>
3530
<artifactId>grpc-stub</artifactId>
@@ -80,6 +75,14 @@
8075
</execution>
8176
</executions>
8277
</plugin>
78+
<plugin>
79+
<groupId>org.apache.maven.plugins</groupId>
80+
<artifactId>maven-compiler-plugin</artifactId>
81+
<configuration>
82+
<source>9</source>
83+
<target>9</target>
84+
</configuration>
85+
</plugin>
8386
</plugins>
8487
</build>
8588

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.baeldung.grpc.repeated;
2+
3+
import java.util.List;
4+
import java.util.Random;
5+
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
9+
import io.grpc.stub.StreamObserver;
10+
11+
public class OrderService extends OrderServiceGrpc.OrderServiceImplBase {
12+
private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
13+
14+
@Override
15+
public void createOrder(UnpackedOrder unpackedOrder, StreamObserver<UnpackedOrder> responseObserver) {
16+
List<Integer> productIds = unpackedOrder.getProductIdsList();
17+
if(validateProducts(productIds)) {
18+
int orderID = insertOrder(unpackedOrder);
19+
logger.info("Order {} created successfully", orderID);
20+
UnpackedOrder createdUnpackedOrder = UnpackedOrder.newBuilder(unpackedOrder)
21+
.setOrderId(orderID)
22+
.build();
23+
responseObserver.onNext(createdUnpackedOrder);
24+
responseObserver.onCompleted();
25+
}
26+
}
27+
28+
private int insertOrder(UnpackedOrder unpackedOrder) {
29+
return new Random().nextInt(100);
30+
}
31+
32+
private boolean validateProducts(List<Integer> productIds) {
33+
return true;
34+
}
35+
}

grpc/src/main/proto/repeated.proto

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
syntax = "proto3";
2+
option java_multiple_files = true;
3+
option java_package = "com.baeldung.grpc.repeated";
4+
package repeated;
5+
6+
message PackedOrder {
7+
int32 orderId = 1;
8+
repeated int32 productIds = 2 [packed = true];
9+
}
10+
11+
message UnpackedOrder {
12+
int32 orderId = 1;
13+
repeated int32 productIds = 2 [packed = false];
14+
}
15+
16+
service OrderService {
17+
rpc createOrder(UnpackedOrder) returns (UnpackedOrder){}
18+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package com.baeldung.grpc.repeated;
2+
3+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
4+
import static org.junit.jupiter.api.Assertions.assertTrue;
5+
6+
import java.io.File;
7+
import java.io.FileOutputStream;
8+
import java.io.IOException;
9+
import java.util.Arrays;
10+
import java.util.Random;
11+
12+
import org.junit.Rule;
13+
import org.junit.jupiter.api.AfterAll;
14+
import org.junit.jupiter.api.BeforeEach;
15+
import org.junit.jupiter.api.Test;
16+
import org.junit.platform.commons.util.ClassLoaderUtils;
17+
import org.slf4j.Logger;
18+
import org.slf4j.LoggerFactory;
19+
20+
import com.google.protobuf.GeneratedMessageV3;
21+
22+
import io.grpc.inprocess.InProcessChannelBuilder;
23+
import io.grpc.inprocess.InProcessServerBuilder;
24+
import io.grpc.testing.GrpcCleanupRule;
25+
26+
public class ProtobufPackedFieldUnitTest {
27+
private static final Logger logger = LoggerFactory.getLogger(ProtobufPackedFieldUnitTest.class);
28+
29+
@Rule
30+
public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule();
31+
32+
OrderServiceGrpc.OrderServiceBlockingStub orderClientStub = null;
33+
34+
static int[] PRODUCT_IDS = null;
35+
static final String FOLDER_TO_WRITE_OBJECTS = getFolderToWriteObject();
36+
37+
@AfterAll
38+
static void clean() {
39+
File packedFile = new File(FOLDER_TO_WRITE_OBJECTS + "packed_order.bin");
40+
File unpackedFile = new File(FOLDER_TO_WRITE_OBJECTS + "unpacked_order.bin");
41+
if (packedFile.delete() && unpackedFile.delete()) {
42+
logger.info("files {} and {} deleted successfully", "packed_order.bin", "unpacked_order.bin");
43+
}
44+
}
45+
46+
@BeforeEach
47+
void setup() throws IOException {
48+
String serverName = InProcessServerBuilder.generateName();
49+
grpcCleanup.register(
50+
InProcessServerBuilder.forName(serverName)
51+
.directExecutor()
52+
.addService(new OrderService())
53+
.build()
54+
.start()
55+
);
56+
orderClientStub = OrderServiceGrpc.newBlockingStub(
57+
grpcCleanup.register(
58+
InProcessChannelBuilder.forName(serverName)
59+
.directExecutor()
60+
.build()
61+
)
62+
);
63+
PRODUCT_IDS = fetchProductIds();
64+
}
65+
66+
@Test
67+
void whenUnpackedRepeatedProductIds_thenCreateUnpackedOrderAndInvokeRPC() {
68+
UnpackedOrder.Builder unpackedOrderBuilder = UnpackedOrder.newBuilder();
69+
unpackedOrderBuilder.setOrderId(1);
70+
Arrays.stream(fetchProductIds()).forEach(unpackedOrderBuilder::addProductIds);
71+
UnpackedOrder unpackedOrderRequest = unpackedOrderBuilder.build();
72+
73+
UnpackedOrder unpackedOrderResponse = orderClientStub.createOrder(unpackedOrderRequest);
74+
75+
assertInstanceOf(Integer.class, unpackedOrderResponse.getOrderId());
76+
}
77+
78+
@Test
79+
void whenSerializeUnpackedOrderAndPackedOrderObject_thenSizeofPackedOrderObjectIsLess() throws IOException {
80+
UnpackedOrder.Builder unpackedOrderBuilder = UnpackedOrder.newBuilder();
81+
unpackedOrderBuilder.setOrderId(1);
82+
Arrays.stream(fetchProductIds()).forEach(unpackedOrderBuilder::addProductIds);
83+
UnpackedOrder unpackedOrder = unpackedOrderBuilder.build();
84+
String unpackedOrderObjFileName = FOLDER_TO_WRITE_OBJECTS + "unpacked_order.bin";
85+
86+
serializeObject(unpackedOrderObjFileName, unpackedOrder);
87+
88+
PackedOrder.Builder packedOrderBuilder = PackedOrder.newBuilder();
89+
packedOrderBuilder.setOrderId(1);
90+
Arrays.stream(fetchProductIds()).forEach(packedOrderBuilder::addProductIds);
91+
PackedOrder packedOrder = packedOrderBuilder.build();
92+
String packedOrderObjFileName = FOLDER_TO_WRITE_OBJECTS + "packed_order.bin";
93+
94+
serializeObject(packedOrderObjFileName, packedOrder);
95+
96+
long sizeOfUnpackedOrderObjectFile = getFileSize(unpackedOrderObjFileName);
97+
long sizeOfPackedOrderObjectFile = getFileSize(packedOrderObjFileName);
98+
long sizeReductionPercentage = (sizeOfUnpackedOrderObjectFile - sizeOfPackedOrderObjectFile) * 100/sizeOfUnpackedOrderObjectFile;
99+
logger.info("Packed field saved {}% over unpacked field", sizeReductionPercentage);
100+
assertTrue(sizeOfUnpackedOrderObjectFile > sizeOfPackedOrderObjectFile);
101+
}
102+
103+
static String getFolderToWriteObject() {
104+
final String PROTO_FILE = "repeated.proto";
105+
String FILE_PATH = ClassLoaderUtils.getDefaultClassLoader().getResource(PROTO_FILE).getPath();
106+
return FILE_PATH.substring(0, FILE_PATH.indexOf(PROTO_FILE));
107+
}
108+
109+
private long getFileSize(String fileName) {
110+
return new File(fileName).length();
111+
}
112+
113+
private void serializeObject(String file, GeneratedMessageV3 object) throws IOException {
114+
try(FileOutputStream fileOutputStream = new FileOutputStream(file)) {
115+
object.writeTo(fileOutputStream);
116+
}
117+
}
118+
119+
private int[] fetchProductIds() {
120+
if (null != PRODUCT_IDS) {
121+
return PRODUCT_IDS;
122+
}
123+
final int ARRAY_SIZE = 20;
124+
Random random = new Random();
125+
int[] prodIds = new int[ARRAY_SIZE];
126+
for (int i = 0; i < ARRAY_SIZE; i++) {
127+
prodIds[i] = random.nextInt(900) + 100;
128+
}
129+
return prodIds;
130+
}
131+
}

0 commit comments

Comments
 (0)