Commit 229174b4 authored by mohammad.salama's avatar mohammad.salama

Creatins S/C modules with Dependencies

parent 8915eb99
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.17</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>Client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Client</name>
<properties>
<java.version>17</java.version>
<spring-boot.version>2.1.5.RELEASE</spring-boot.version>
<grpc.version>1.40.1</grpc.version>
<os.classifier>windows-x86_64</os.classifier>
<protobuf.version>3.18.0</protobuf.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring-boot.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>FileUploadUsingGRPCAndSBoot</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-client-spring-boot-autoconfigure</artifactId>
<version>2.14.0.RELEASE</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.51.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.shared</groupId>
<artifactId>proto</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.classifier}</pluginArtifact>
<protoSourceRoot>src/main/java/Proto</protoSourceRoot>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder-jammy-base:latest</builder>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.example.FileUploadUsingGRPCAndSBoot;
package com.grpc.client.fileupload.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class FileUploadUsingGrpcAndSBootApplication {
public class ClientApplication {
public static void main(String[] args)
{
SpringApplication.run(FileUploadUsingGrpcAndSBootApplication.class, args);
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
package com.grpc.client.fileupload.client.controller;
import com.grpc.client.fileupload.client.service.FileUploadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@Slf4j
@RestController
public class FileUploadController {
private final FileUploadService fileUploadService;
public FileUploadController(FileUploadService fileUploadService) {
this.fileUploadService = fileUploadService;
}
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile multipartFile) {
return this.fileUploadService.uploadFile(multipartFile);
}
}
package com.grpc.client.fileupload.client.service;
import MyFileUploadService.*;
import com.google.protobuf.ByteString;
import com.shared.proto.Constants;
import io.grpc.Metadata;
import io.grpc.stub.MetadataUtils;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.CountDownLatch;
@Slf4j
@Service
public class FileUploadService {
private final FileUploadServiceGrpc.FileUploadServiceStub client;
public FileUploadService(@GrpcClient(value = "file-upload") FileUploadServiceGrpc.FileUploadServiceStub client) {
this.client = client;
}
public String uploadFile(final MultipartFile multipartFile) {
String fileName;
int fileSize;
InputStream inputStream;
fileName = multipartFile.getOriginalFilename();
try {
fileSize = multipartFile.getBytes().length;
inputStream = multipartFile.getInputStream();
} catch (IOException e) {
return "unable to extract file info";
}
StringBuilder response = new StringBuilder();
CountDownLatch countDownLatch = new CountDownLatch(1);
Metadata metadata = new Metadata();
metadata.put(Constants.fileMetadataKey,
FileMetadata.newBuilder()
.setFileNameWithType(fileName)
.setContentLength(fileSize)
.build()
.toByteArray());
StreamObserver<FileUploadRequest> fileUploadRequestStreamObserver = this.client
.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(metadata))
.uploadFile(
new StreamObserver<>()
{
@Override
public void onNext(FileUploadResponse fileUploadResponse) {
response.append(fileUploadResponse.getUploadStatus());
}
@Override
public void onError(Throwable throwable) {
response.append(UploadStatus.FAILED);
throwable.printStackTrace();
countDownLatch.countDown();
}
@Override
public void onCompleted() {
countDownLatch.countDown();
}
});
byte[] fiveKB = new byte[5120];
int length;
try {
while ((length = inputStream.read(fiveKB)) > 0) {
log.info(String.format("sending %d length of data", length));
var request = FileUploadRequest
.newBuilder()
.setFile(File.newBuilder().setContent(ByteString.copyFrom(fiveKB, 0, length)))
.build();
fileUploadRequestStreamObserver.onNext(request);
}
inputStream.close();
fileUploadRequestStreamObserver.onCompleted();
countDownLatch.await();
} catch (Exception e) {
e.printStackTrace();
response.append(UploadStatus.FAILED);
}
return response.toString();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.17</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.shared</groupId>
<artifactId>proto</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>proto</name>
<properties>
<java.version>17</java.version>
<spring-boot.version>2.1.5.RELEASE</spring-boot.version>
<grpc.version>1.40.1</grpc.version>
<os.classifier>windows-x86_64</os.classifier>
<protobuf.version>3.18.0</protobuf.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring-boot.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>FileUploadUsingGRPCAndSBoot</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-client-spring-boot-autoconfigure</artifactId>
<version>2.14.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.classifier}</pluginArtifact>
<protoSourceRoot>src/main/java/Proto</protoSourceRoot>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder-jammy-base:latest</builder>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.shared.proto;
import MyFileUploadService.FileMetadata;
import io.grpc.Context;
import io.grpc.Metadata;
public class Constants {
public static final Metadata.Key<byte[]> fileMetadataKey = Metadata.Key.of("file-meta-bin", Metadata.BINARY_BYTE_MARSHALLER);
public static final Context.Key<FileMetadata> fileMetaContext = Context.key("file-meta");
}
......@@ -2,9 +2,7 @@ syntax = "proto3";
option java_multiple_files = true;
option java_package = "MyFileUploadService";
package com.MyFileUploadService;
package com.devProblems;
message File {
bytes content = 1;
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>FileUploadUsingGRPCAndSBoot</artifactId>
<groupId>com.example</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring-boot.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>FileUploadUsingGRPCAndSBoot</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-client-spring-boot-autoconfigure</artifactId>
<version>2.14.0.RELEASE</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.51.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.shared</groupId>
<artifactId>proto</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-server-spring-boot-autoconfigure</artifactId>
<version>2.14.0.RELEASE</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
\ No newline at end of file
package com.grpc.server.fileupload.server.interceptor;
import MyFileUploadService.*;
import com.google.protobuf.InvalidProtocolBufferException;
import com.shared.proto.Constants;
import io.grpc.*;
//@GrpcGlobalServerInterceptor
public class FileUploadInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
FileMetadata fileMetadata = null;
if (metadata.containsKey(Constants.fileMetadataKey)) {
byte[] metaBytes = metadata.get(Constants.fileMetadataKey);
try {
fileMetadata = FileMetadata.parseFrom(metaBytes);
} catch (InvalidProtocolBufferException e) {
Status status = Status.INTERNAL.withDescription("unable to create file metadata");
serverCall.close(status, metadata);
}
Context context = Context.current().withValue(
Constants.fileMetaContext,
fileMetadata
);
return Contexts.interceptCall(context, serverCall, metadata, serverCallHandler);
}
return new ServerCall.Listener<>() {
};
}
}
package com.grpc.server.fileupload.server.service;
import MyFileUploadService.*;
import com.grpc.server.fileupload.server.utils.DiskFileStorage;
import com.shared.proto.Constants;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import java.io.IOException;
@Slf4j
@GrpcService
public class FileUploadService extends FileUploadServiceGrpc.FileUploadServiceImplBase {
@Override
public StreamObserver<FileUploadRequest> uploadFile(StreamObserver<FileUploadResponse> responseObserver) {
FileMetadata fileMetadata = Constants.fileMetaContext.get();
DiskFileStorage diskFileStorage = new DiskFileStorage();
return new StreamObserver<>() {
@Override
public void onNext(FileUploadRequest fileUploadRequest) {
log.info(String.format("received %d length of data", fileUploadRequest.getFile().getContent().size()));
try {
fileUploadRequest.getFile().getContent()
.writeTo(diskFileStorage.getStream());
} catch (IOException e) {
responseObserver.onError(io.grpc.Status.INTERNAL
.withDescription("cannot write data due to : " + e.getMessage())
.asRuntimeException());
}
}
@Override
public void onError(Throwable throwable) {
log.warn("{}", throwable.toString());
}
@Override
public void onCompleted() {
try {
int totalBytesReceived = diskFileStorage.getStream().size();
if (totalBytesReceived == fileMetadata.getContentLength()) {
diskFileStorage.write(fileMetadata.getFileNameWithType());
diskFileStorage.close();
} else {
responseObserver.onError(
io.grpc.Status.FAILED_PRECONDITION
.withDescription(String.format("expected %d but received %d", fileMetadata.getContentLength(), totalBytesReceived))
.asRuntimeException()
);
return;
}
} catch (IOException e) {
responseObserver.onError(io.grpc.Status.INTERNAL
.withDescription("cannot save data due to : " + e.getMessage())
.asRuntimeException());
return;
}
responseObserver.onNext(
FileUploadResponse
.newBuilder()
.setFileName(fileMetadata.getFileNameWithType())
.setUploadStatus(UploadStatus.SUCCESS)
.build()
);
responseObserver.onCompleted();
}
};
}
}
\ No newline at end of file
package com.grpc.server.fileupload.server.utils;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DiskFileStorage {
private final ByteArrayOutputStream byteArrayOutputStream;
public DiskFileStorage() {
this.byteArrayOutputStream = new ByteArrayOutputStream();
}
public ByteArrayOutputStream getStream() {
return this.byteArrayOutputStream;
}
public void write(String fileNameWithType) throws IOException {
String DEFAULT_PATH = "output/";
try (FileOutputStream fileOutputStream = new FileOutputStream(DEFAULT_PATH.concat(fileNameWithType))) {
this.byteArrayOutputStream.writeTo(fileOutputStream);
}
}
public void close() throws IOException {
this.byteArrayOutputStream.close();
}
}
......@@ -2,6 +2,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>Client</module>
<module>Proto</module>
<module>Server</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
......@@ -72,6 +78,16 @@
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>FileUploadUsingGRPCAndSBoot</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-client-spring-boot-autoconfigure</artifactId>
<version>2.14.0.RELEASE</version>
</dependency>
</dependencies>
......
package com.example.FileUploadUsingGRPCAndSBoot;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class FileUploadUsingGrpcAndSBootApplicationTests {
@Test
void contextLoads() {
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment