From b136b001871989c89f5f580bba830f1fa65ddfd5 Mon Sep 17 00:00:00 2001 From: insanity Date: Thu, 25 May 2017 17:58:36 +0900 Subject: [PATCH] dbproxy --- .gitignore | 85 ++++++++++ pom.xml | 114 ++++++++++++- src/main/java/com/loafle/App.java | 7 - .../com/loafle/overflow/proxy/db/DBProxy.java | 152 ++++++++++++++++++ src/main/resources/META-INF/persistence.xml | 17 ++ src/test/java/com/loafle/AppTest.java | 11 -- src/test/java/com/loafle/TestClient.java | 85 ++++++++++ 7 files changed, 450 insertions(+), 21 deletions(-) create mode 100644 .gitignore delete mode 100644 src/main/java/com/loafle/App.java create mode 100644 src/main/java/com/loafle/overflow/proxy/db/DBProxy.java create mode 100644 src/main/resources/META-INF/persistence.xml delete mode 100644 src/test/java/com/loafle/AppTest.java create mode 100644 src/test/java/com/loafle/TestClient.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dae8e41 --- /dev/null +++ b/.gitignore @@ -0,0 +1,85 @@ +# Created by .ignore support plugin (hsz.mobi) +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle: +.idea/**/gradle.xml +.idea/**/libraries + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### Maven template +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties + +# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) +!/.mvn/wrapper/maven-wrapper.jar +### Java template +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +.idea/ +*.iml + diff --git a/pom.xml b/pom.xml index b60bc1e..59e7a89 100644 --- a/pom.xml +++ b/pom.xml @@ -5,9 +5,9 @@ 4.0.0 - com.loafle - maven_parent_jar - 1.0.0-RELEASE + com.loafle + maven_parent_jar + 1.0.0-RELEASE com.loafle @@ -16,6 +16,114 @@ 1.0.0-SNAPSHOT com.loafle.overflow_proxy_db + + 1.2.0 + 4.3.10.Final + + + + io.grpc + grpc-netty + ${grpc.version} + + + io.grpc + grpc-protobuf + ${grpc.version} + + + io.grpc + grpc-stub + ${grpc.version} + + + org.mockito + mockito-core + 1.9.5 + test + + + + + org.hibernate + hibernate-entitymanager + 5.2.10.Final + + + + + org.postgresql + postgresql + 9.4-1200-jdbc41 + + + + + + + + + + + + org.codehaus.jackson + jackson-mapper-asl + 1.9.13 + + + + com.loafle + overflow_jpa_member_dao + 1.0.0-SNAPSHOT + + + + + + + + + src/main/resources + true + + + + + src/test/resources + true + + + + + + kr.motd.maven + os-maven-plugin + 1.4.1.Final + + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.5.0 + + com.google.protobuf:protoc:3.2.0:exe:${os.detected.classifier} + grpc-java + io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + + + + + compile + compile-custom + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/loafle/App.java b/src/main/java/com/loafle/App.java deleted file mode 100644 index 61cc3e6..0000000 --- a/src/main/java/com/loafle/App.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.loafle; - -public class App { - public static void main(String[] args) { - System.out.println("Hello World!"); - } -} \ No newline at end of file diff --git a/src/main/java/com/loafle/overflow/proxy/db/DBProxy.java b/src/main/java/com/loafle/overflow/proxy/db/DBProxy.java new file mode 100644 index 0000000..d7b464f --- /dev/null +++ b/src/main/java/com/loafle/overflow/proxy/db/DBProxy.java @@ -0,0 +1,152 @@ +package com.loafle.overflow.proxy.db; + + +import com.loafle.overflow.db.api.DBGrpc; +import com.loafle.overflow.db.api.DBInput; +import com.loafle.overflow.db.api.DBOutput; +import com.loafle.overflow.commons.dao.JPABaseDAO; +import com.loafle.overflow.member.dao.JPAMemberDAO; +import io.grpc.ServerBuilder; +import org.codehaus.jackson.map.ObjectMapper; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * Created by insanity on 17. 5. 23. + */ + +public class DBProxy { + + private static final Logger logger = Logger.getLogger(DBProxy.class.getName()); + private io.grpc.Server server; + + private static Map daoMap = null; + + public DBProxy() { + daoMap = new ConcurrentHashMap(); + JPAMemberDAO memberDao = new JPAMemberDAO(); + daoMap.put("member", memberDao); + } + + public void start(int port) throws IOException { + server = ServerBuilder.forPort(port) + .addService(new ServiceImpl()) + .build() + .start(); + logger.info("Server started, listening on " + port); + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + // Use stderr here since the logger may have been reset by its JVM shutdown hook. + System.err.println("*** shutting down gRPC server since JVM is shutting down"); + DBProxy.this.stop(); + System.err.println("*** server shut down"); + } + }); + } + + public void stop() { + if (server != null) { + server.shutdown(); + } + } + + static class ServiceImpl extends DBGrpc.DBImplBase { + @Override + public void exec(DBInput request, + io.grpc.stub.StreamObserver responseObserver) { + String targetDAO = request.getTargetDao(); + + JPABaseDAO dao = daoMap.get(targetDAO); + + if(dao != null) { + try { + + String jsonResult = doQuery(request, dao); + + DBOutput reply = DBOutput.newBuilder() + .setResult(jsonResult) + .build(); + responseObserver.onNext(reply); + responseObserver.onCompleted(); + }catch(Exception e) { + e.printStackTrace(); + responseObserver.onError(e); + } + + }else { + responseObserver.onError(new Exception("Not assigned DAO :" + targetDAO)); + } + } + + private String doQuery(DBInput request, JPABaseDAO dao) throws Exception { + + String methodName = request.getMethod(); + Map params = request.getParamsMap(); + + ObjectMapper mapper = new ObjectMapper(); + + List paramTypes = new ArrayList(); + List valueList = new ArrayList(); + for( String className : params.keySet() ){ + //className - model name(with package) , value - model JsonString + Class cls = Class.forName(className); + Object obj = mapper.readValue((String)params.get(className), cls); + valueList.add(obj); + paramTypes.add(cls); + } + + Object retObj = null; + Method method = null; + + try { + //Check if it belongs to the JPABaseDAO. + method = dao.getClass().getSuperclass().getMethod(methodName, Object.class); + if(method != null) { + retObj = method.invoke(dao, valueList.toArray(new Object[valueList.size()])); + } + }catch(NoSuchMethodException e) { + if(params.size() > 0) { + method = dao.getClass().getMethod(methodName, paramTypes.toArray(new Class[paramTypes.size()])); + retObj = method.invoke(dao, valueList.toArray(new Object[valueList.size()])); + }else { + method = dao.getClass().getMethod(methodName); + retObj = method.invoke(dao); + } + }catch(InvocationTargetException e) { + e.printStackTrace(); + } + + return mapper.writeValueAsString(retObj); + } + } + + + private void blockUntilShutdown() throws InterruptedException { + if (server != null) { + server.awaitTermination(); + } + } + + public static void main(String[] args) throws IOException, InterruptedException { + + if(args.length <= 0) { + System.out.println("Port args"); + System.out.println("first parameter is Port Number"); + return; + } + + int port = Integer.valueOf(args[0]); + + final DBProxy server = new DBProxy(); + server.start(port); + server.blockUntilShutdown(); + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000..2646cf5 --- /dev/null +++ b/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/com/loafle/AppTest.java b/src/test/java/com/loafle/AppTest.java deleted file mode 100644 index cbadf31..0000000 --- a/src/test/java/com/loafle/AppTest.java +++ /dev/null @@ -1,11 +0,0 @@ - -package com.loafle; -import static org.junit.Assert.*; -import org.junit.Test; - -public class AppTest { - @Test - public void testSum() { - fail("Not yet implemented"); - } -} \ No newline at end of file diff --git a/src/test/java/com/loafle/TestClient.java b/src/test/java/com/loafle/TestClient.java new file mode 100644 index 0000000..4339d17 --- /dev/null +++ b/src/test/java/com/loafle/TestClient.java @@ -0,0 +1,85 @@ +package com.loafle; + + +import com.loafle.overflow.db.api.DBGrpc; +import com.loafle.overflow.db.api.DBInput; +import com.loafle.overflow.db.api.DBOutput; +import com.loafle.overflow.member.model.Member; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import io.grpc.StatusRuntimeException; +import org.codehaus.jackson.map.ObjectMapper; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class TestClient { + + private static final Logger logger = Logger.getLogger(TestClient.class.getName()); + + private final ManagedChannel channel; + private final DBGrpc.DBBlockingStub dbStub; + + public TestClient() { + channel = ManagedChannelBuilder.forAddress("127.0.0.1", 50006).usePlaintext(true).build(); + dbStub = DBGrpc.newBlockingStub(channel); + } + + + public void shutdown() throws InterruptedException { + channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + + + public void execute() { + + try { + Member m = new Member(); + m.setName("insanity2222"); + m.setCompany("loafle"); + m.setDigest("bbbbbbbbb"); + m.setPwSalt("salktttt"); + m.setEmail("insanity@loafle.com"); + m.setRegistDate(111110); + + ObjectMapper mapper = new ObjectMapper(); + + DBInput request = DBInput.newBuilder() + .setTargetDao("member") + .setMethod("create") + .putParams("com.loafle.overflow.member.model.Member", mapper.writeValueAsString(m)) + //.putParams("com.loafle.overflow.member.Member2", mapper.writeValueAsString(m2)) + .build(); + DBOutput response; + try { + response = dbStub.exec(request); + } catch (StatusRuntimeException e) { + logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); + return; + } + logger.log(Level.INFO, response.getResult()); + }catch(Exception e) { + e.printStackTrace(); + } + + } + + @Test + public void testRPCServer() { + TestClient client = new TestClient(); + try { + client.execute(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + client.shutdown(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} \ No newline at end of file