package net.badata.protobuf.example.client; import com.google.protobuf.Any; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import net.badata.protobuf.converter.Converter; import net.badata.protobuf.example.client.domain.Reader; import net.badata.protobuf.example.client.domain.ReadingBook; import net.badata.protobuf.example.proto.Book; import net.badata.protobuf.example.proto.Books; import net.badata.protobuf.example.proto.Failure; import net.badata.protobuf.example.proto.LibraryServiceGrpc; import net.badata.protobuf.example.proto.Request; import net.badata.protobuf.example.proto.Response; import net.badata.protobuf.example.proto.User; import java.util.List; import java.util.concurrent.TimeUnit; /** * @author jsjem * @author Roman Gushel */ public class ProtobufClient { private static Reader currentUser; private final ManagedChannel channel; private final LibraryServiceGrpc.LibraryServiceBlockingStub blockingStub; private String userToken; public ProtobufClient(String host, int port) { channel = ManagedChannelBuilder.forAddress(host, port) .usePlaintext(true) .build(); blockingStub = LibraryServiceGrpc.newBlockingStub(channel); } public void shutdown() { try { channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } } public static boolean isCurrentUser(final String name) { return currentUser.getName().equals(name); } public boolean signIn(final Reader user) { User userCredentials = Converter.create().toProtobuf(User.class, user); userToken = blockingStub.signIn(userCredentials).getToken(); if(userToken != null && !userToken.isEmpty()) { currentUser = user; return true; } return false; } public void logOut() { userToken = null; } public ReadingBook getBook(final ReadingBook book) throws ClientException { Converter converter = Converter.create(); Book bookInfo = converter.toProtobuf(Book.class, book); Response response = blockingStub.getBook(createRequest(bookInfo)); return converter.toDomain(ReadingBook.class, extractResponseData(response, Book.class)); } private Request createRequest(final Message message) { Request.Builder builder = Request.newBuilder().setUserToken(userToken); if (message != null) { builder.setData(Any.pack(message)); } return builder.build(); } private <T extends Message> T extractResponseData(final Response response, final Class<T> clazz) throws ClientException { Any data = response.getData(); try { if (data.is(Failure.class)) { throw new ClientException(data.unpack(Failure.class).getCause()); } return data.unpack(clazz); } catch (InvalidProtocolBufferException e) { throw new ClientException(e.getMessage()); } } public List<ReadingBook> addBook(final ReadingBook book) throws ClientException { Converter converter = Converter.create(); Book bookInfo = converter.toProtobuf(Book.class, book); Response response = blockingStub.addBook(createRequest(bookInfo)); return converter.toDomain(ReadingBook.class, extractResponseData(response, Books.class).getBookList()); } public List<ReadingBook> showAllBooks() throws ClientException { Response response = blockingStub.showLibrary(createRequest(null)); return Converter.create().toDomain(ReadingBook.class, extractResponseData(response, Books.class).getBookList()); } }