Browse Source

Use class annotation to loose coupling

pull/1/head
yichen 2 years ago
parent
commit
d0fce6d719
  1. 3
      agent/src/main/java/com/fanruan/agent/jdbc/AgentArray.java
  2. 7
      agent/src/main/java/com/fanruan/agent/jdbc/AgentBlob.java
  3. 3
      agent/src/main/java/com/fanruan/agent/jdbc/AgentClob.java
  4. 2
      agent/src/main/java/com/fanruan/agent/jdbc/AgentDataBaseMetaData.java
  5. 64
      agent/src/main/java/com/fanruan/agent/jdbc/AgentInputStream.java
  6. 4
      agent/src/main/java/com/fanruan/agent/jdbc/AgentParameterMetaData.java
  7. 71
      agent/src/main/java/com/fanruan/agent/jdbc/AgentReader.java
  8. 3
      agent/src/main/java/com/fanruan/agent/jdbc/AgentResultSetMetaData.java
  9. 3
      agent/src/main/java/com/fanruan/agent/jdbc/AgentStruct.java
  10. 2
      agent/src/main/java/com/fanruan/agent/jdbc/connection/AgentConnection.java
  11. 2
      agent/src/main/java/com/fanruan/agent/jdbc/driver/AgentDriver.java
  12. 36
      agent/src/main/java/com/fanruan/agent/jdbc/resultset/AgentResultSet.java
  13. 2
      agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentCallableStatement.java
  14. 2
      agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentPreparedStatement.java
  15. 2
      agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentStatement.java
  16. 13
      agent/src/main/java/com/fanruan/annotation/BindClass.java
  17. 28
      agent/src/main/java/com/fanruan/handler/DispatcherHelper.java
  18. 4
      agent/src/main/java/com/fanruan/handler/DispatcherImpl.java
  19. 21
      agent/src/test/java/HSQLTest.java
  20. 6
      service/src/main/java/com/fanruan/annotation/RemoteClass.java
  21. 7
      service/src/main/java/com/fanruan/proxy/interceptor/Interceptor.java
  22. 70
      service/src/main/java/com/fanruan/proxy/interceptor/InterceptorUtils.java
  23. 5
      service/src/main/java/com/fanruan/service/jdbc/ServiceBlob.java
  24. 67
      service/src/main/java/com/fanruan/service/jdbc/ServiceInputStream.java
  25. 68
      service/src/main/java/com/fanruan/service/jdbc/ServiceReader.java
  26. 19
      service/src/main/java/com/fanruan/service/jdbc/connection/ServiceConnection.java
  27. 53
      service/src/main/java/com/fanruan/service/jdbc/resultset/ServiceResultSet.java
  28. 6
      test/src/test/java/com/fanruan/ConnectionTest.java
  29. 136
      test/src/test/java/com/fanruan/ResultSetTest.java

3
agent/src/main/java/com/fanruan/agent/jdbc/AgentArray.java

@ -1,5 +1,7 @@
package com.fanruan.agent.jdbc;
import com.fanruan.annotation.BindClass;
import java.sql.Array;
import java.sql.ResultSet;
import java.sql.SQLException;
@ -9,6 +11,7 @@ import java.util.Map;
* @author Yichen Dai
* @date 2022/8/31 16:52
*/
@BindClass
public class AgentArray implements Array {
Array array;

7
agent/src/main/java/com/fanruan/agent/jdbc/AgentBlob.java

@ -1,5 +1,7 @@
package com.fanruan.agent.jdbc;
import com.fanruan.annotation.BindClass;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
@ -9,6 +11,7 @@ import java.sql.SQLException;
* @author Yichen Dai
* @date 2022/8/29 20:33
*/
@BindClass
public class AgentBlob implements Blob {
private Blob blob;
@ -28,7 +31,7 @@ public class AgentBlob implements Blob {
@Override
public InputStream getBinaryStream() throws SQLException {
return blob.getBinaryStream();
return new AgentInputStream(blob.getBinaryStream());
}
@Override
@ -68,6 +71,6 @@ public class AgentBlob implements Blob {
@Override
public InputStream getBinaryStream(long pos, long length) throws SQLException {
return blob.getBinaryStream(pos, length);
return new AgentInputStream(blob.getBinaryStream());
}
}

3
agent/src/main/java/com/fanruan/agent/jdbc/AgentClob.java

@ -1,5 +1,7 @@
package com.fanruan.agent.jdbc;
import com.fanruan.annotation.BindClass;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
@ -11,6 +13,7 @@ import java.sql.SQLException;
* @author Yichen Dai
* @date 2022/8/29 20:34
*/
@BindClass
public class AgentClob implements Clob {
private Clob clob;

2
agent/src/main/java/com/fanruan/agent/jdbc/AgentDataBaseMetaData.java

@ -1,6 +1,7 @@
package com.fanruan.agent.jdbc;
import com.fanruan.agent.jdbc.resultset.AgentResultSet;
import com.fanruan.annotation.BindClass;
import java.sql.*;
@ -8,6 +9,7 @@ import java.sql.*;
* @author Yichen Dai
* @date 2022/8/25 11:22
*/
@BindClass
public class AgentDataBaseMetaData implements DatabaseMetaData {
DatabaseMetaData metaData;

64
agent/src/main/java/com/fanruan/agent/jdbc/AgentInputStream.java

@ -0,0 +1,64 @@
package com.fanruan.agent.jdbc;
import com.fanruan.annotation.BindClass;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Yichen Dai
* @date 2022/9/8 18:15
*/
@BindClass
public class AgentInputStream extends InputStream {
private InputStream inputStream;
public AgentInputStream(InputStream inputStream){
this.inputStream = inputStream;
}
@Override
public int read() throws IOException {
return inputStream.read();
}
@Override
public int read(byte b[]) throws IOException {
return inputStream.read(b);
}
@Override
public int read(byte b[], int off, int len) throws IOException {
return inputStream.read(b, off, len);
}
@Override
public long skip(long n) throws IOException {
return inputStream.skip(n);
}
@Override
public int available() throws IOException {
return inputStream.available();
}
@Override
public void close() throws IOException {
inputStream.close();
}
@Override
public synchronized void mark(int readlimit) {
inputStream.mark(readlimit);
}
@Override
public synchronized void reset() throws IOException {
inputStream.reset();
}
@Override
public boolean markSupported() {
return inputStream.markSupported();
}
}

4
agent/src/main/java/com/fanruan/agent/jdbc/AgentParameterMetaData.java

@ -1,5 +1,7 @@
package com.fanruan.agent.jdbc;
import com.fanruan.annotation.BindClass;
import java.sql.ParameterMetaData;
import java.sql.SQLException;
@ -8,7 +10,7 @@ import java.sql.SQLException;
* @date 2022/8/25 16:41
*/
@BindClass
public class AgentParameterMetaData implements ParameterMetaData {
private ParameterMetaData metaData;

71
agent/src/main/java/com/fanruan/agent/jdbc/AgentReader.java

@ -0,0 +1,71 @@
package com.fanruan.agent.jdbc;
import com.fanruan.annotation.BindClass;
import io.socket.client.IO;
import java.io.IOException;
import java.io.Reader;
/**
* @author Yichen Dai
* @date 2022/9/8 16:55
*/
@BindClass
public class AgentReader extends Reader {
Reader reader;
public AgentReader(Reader reader){
this.reader = reader;
}
@Override
public int read(java.nio.CharBuffer target) throws IOException {
return reader.read(target);
}
@Override
public int read() throws IOException{
return reader.read();
}
@Override
public int read(char cbuf[]) throws IOException {
return reader.read(cbuf);
}
@Override
public long skip(long n) throws IOException {
return reader.skip(n);
}
@Override
public boolean ready() throws IOException{
return reader.ready();
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
return reader.read(cbuf, off, len);
}
@Override
public boolean markSupported() {
return reader.markSupported();
}
@Override
public void mark(int readAheadLimit) throws IOException {
reader.mark(readAheadLimit);
}
@Override
public void reset() throws IOException {
reader.reset();
}
@Override
public void close() throws IOException {
reader.close();
}
}

3
agent/src/main/java/com/fanruan/agent/jdbc/AgentResultSetMetaData.java

@ -1,5 +1,7 @@
package com.fanruan.agent.jdbc;
import com.fanruan.annotation.BindClass;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
@ -7,6 +9,7 @@ import java.sql.SQLException;
* @author Yichen Dai
* @date 2022/9/1 14:45
*/
@BindClass
public class AgentResultSetMetaData implements ResultSetMetaData {
private ResultSetMetaData metaData;

3
agent/src/main/java/com/fanruan/agent/jdbc/AgentStruct.java

@ -1,5 +1,7 @@
package com.fanruan.agent.jdbc;
import com.fanruan.annotation.BindClass;
import java.sql.SQLException;
import java.sql.Struct;
import java.util.Map;
@ -8,6 +10,7 @@ import java.util.Map;
* @author Yichen Dai
* @date 2022/8/31 17:04
*/
@BindClass
public class AgentStruct implements Struct {
Struct struct;

2
agent/src/main/java/com/fanruan/agent/jdbc/connection/AgentConnection.java

@ -4,6 +4,7 @@ import com.fanruan.agent.jdbc.AgentDataBaseMetaData;
import com.fanruan.agent.jdbc.statement.AgentCallableStatement;
import com.fanruan.agent.jdbc.statement.AgentPreparedStatement;
import com.fanruan.agent.jdbc.statement.AgentStatement;
import com.fanruan.annotation.BindClass;
import java.sql.*;
import java.util.Map;
@ -13,6 +14,7 @@ import java.util.concurrent.Executor;
/**
* @author Yichen Dai
*/
@BindClass
public class AgentConnection implements Connection {
final private Connection conn;

2
agent/src/main/java/com/fanruan/agent/jdbc/driver/AgentDriver.java

@ -1,6 +1,7 @@
package com.fanruan.agent.jdbc.driver;
import com.fanruan.agent.jdbc.connection.AgentConnection;
import com.fanruan.annotation.BindClass;
import java.sql.*;
import java.util.Enumeration;
@ -10,6 +11,7 @@ import java.util.logging.Logger;
/**
* @author Yichen Dai
*/
@BindClass
public class AgentDriver implements Driver {

36
agent/src/main/java/com/fanruan/agent/jdbc/resultset/AgentResultSet.java

@ -1,5 +1,8 @@
package com.fanruan.agent.jdbc.resultset;
import com.fanruan.agent.jdbc.*;
import com.fanruan.annotation.BindClass;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
@ -8,6 +11,7 @@ import java.sql.*;
import java.util.Calendar;
import java.util.Map;
@BindClass
public class AgentResultSet implements ResultSet {
final private ResultSet resultSet;
@ -98,17 +102,17 @@ public class AgentResultSet implements ResultSet {
@Override
public InputStream getAsciiStream(int columnIndex) throws SQLException {
return resultSet.getAsciiStream(columnIndex);
return new AgentInputStream(resultSet.getAsciiStream(columnIndex));
}
@Override
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
return resultSet.getUnicodeStream(columnIndex);
return new AgentInputStream(resultSet.getUnicodeStream(columnIndex));
}
@Override
public InputStream getBinaryStream(int columnIndex) throws SQLException {
return resultSet.getBinaryStream(columnIndex);
return new AgentInputStream(resultSet.getBinaryStream(columnIndex));
}
@Override
@ -178,17 +182,17 @@ public class AgentResultSet implements ResultSet {
@Override
public InputStream getAsciiStream(String columnLabel) throws SQLException {
return resultSet.getAsciiStream(columnLabel);
return new AgentInputStream(resultSet.getAsciiStream(columnLabel));
}
@Override
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
return resultSet.getUnicodeStream(columnLabel);
return new AgentInputStream(resultSet.getUnicodeStream(columnLabel));
}
@Override
public InputStream getBinaryStream(String columnLabel) throws SQLException {
return resultSet.getBinaryStream(columnLabel);
return new AgentInputStream(resultSet.getBinaryStream(columnLabel));
}
@Override
@ -228,12 +232,12 @@ public class AgentResultSet implements ResultSet {
@Override
public Reader getCharacterStream(int columnIndex) throws SQLException {
return resultSet.getCharacterStream(columnIndex);
return new AgentReader(resultSet.getCharacterStream(columnIndex));
}
@Override
public Reader getCharacterStream(String columnLabel) throws SQLException {
return resultSet.getCharacterStream(columnLabel);
return new AgentReader(resultSet.getCharacterStream(columnLabel));
}
@Override
@ -593,17 +597,17 @@ public class AgentResultSet implements ResultSet {
@Override
public Blob getBlob(int columnIndex) throws SQLException {
return resultSet.getBlob(columnIndex);
return new AgentBlob(resultSet.getBlob(columnIndex));
}
@Override
public Clob getClob(int columnIndex) throws SQLException {
return resultSet.getClob(columnIndex);
return new AgentClob(resultSet.getClob(columnIndex));
}
@Override
public Array getArray(int columnIndex) throws SQLException {
return resultSet.getArray(columnIndex);
return new AgentArray(resultSet.getArray(columnIndex));
}
@Override
@ -618,17 +622,17 @@ public class AgentResultSet implements ResultSet {
@Override
public Blob getBlob(String columnLabel) throws SQLException {
return resultSet.getBlob(columnLabel);
return new AgentBlob(resultSet.getBlob(columnLabel));
}
@Override
public Clob getClob(String columnLabel) throws SQLException {
return resultSet.getClob(columnLabel);
return new AgentClob(resultSet.getClob(columnLabel));
}
@Override
public Array getArray(String columnLabel) throws SQLException {
return resultSet.getArray(columnLabel);
return new AgentArray(resultSet.getArray(columnLabel));
}
@Override
@ -803,12 +807,12 @@ public class AgentResultSet implements ResultSet {
@Override
public Reader getNCharacterStream(int columnIndex) throws SQLException {
return resultSet.getNCharacterStream(columnIndex);
return new AgentReader(resultSet.getNCharacterStream(columnIndex));
}
@Override
public Reader getNCharacterStream(String columnLabel) throws SQLException {
return resultSet.getNCharacterStream(columnLabel);
return new AgentReader(resultSet.getNCharacterStream(columnLabel));
}
@Override

2
agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentCallableStatement.java

@ -4,6 +4,7 @@ import com.fanruan.agent.jdbc.AgentArray;
import com.fanruan.agent.jdbc.AgentBlob;
import com.fanruan.agent.jdbc.AgentClob;
import com.fanruan.agent.jdbc.AgentParameterMetaData;
import com.fanruan.annotation.BindClass;
import java.io.InputStream;
import java.io.Reader;
@ -17,6 +18,7 @@ import java.util.Map;
* @author Yichen Dai
* @date 2022/8/24 16:18
*/
@BindClass
public class AgentCallableStatement implements java.sql.CallableStatement {
final private CallableStatement cst;

2
agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentPreparedStatement.java

@ -4,6 +4,7 @@ package com.fanruan.agent.jdbc.statement;
import com.fanruan.agent.jdbc.AgentParameterMetaData;
import com.fanruan.agent.jdbc.AgentResultSetMetaData;
import com.fanruan.agent.jdbc.resultset.AgentResultSet;
import com.fanruan.annotation.BindClass;
import java.io.InputStream;
import java.io.Reader;
@ -15,6 +16,7 @@ import java.util.Calendar;
/**
* @author Yichen Dai
*/
@BindClass
public class AgentPreparedStatement implements PreparedStatement {
final PreparedStatement pst;

2
agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentStatement.java

@ -1,12 +1,14 @@
package com.fanruan.agent.jdbc.statement;
import com.fanruan.agent.jdbc.resultset.AgentResultSet;
import com.fanruan.annotation.BindClass;
import java.sql.*;
/**
* @author Yichen Dai
*/
@BindClass
public class AgentStatement implements Statement {
final private Statement st;

13
agent/src/main/java/com/fanruan/annotation/BindClass.java

@ -0,0 +1,13 @@
package com.fanruan.annotation;
import java.lang.annotation.*;
/**
* @author Yichen Dai
* @date 2022/9/9 10:19
*/
@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface BindClass {
}

28
agent/src/main/java/com/fanruan/handler/DispatcherHelper.java

@ -1,6 +1,8 @@
package com.fanruan.handler;
import com.fanruan.annotation.BindClass;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
@ -24,36 +26,14 @@ public class DispatcherHelper {
}
};
public final static String[] CACHE_LIST = new String[]{
"Driver",
"Connection",
"Statement",
"PreparedStatement",
"ResultSet",
"MetaData",
"Clob",
"Blob",
"Array",
"Struct"
};
public static boolean isInCacheList(Object obj){
if(obj == null) {
return false;
}
return isInCacheList(obj.getClass().getName());
}
public static boolean isInCacheList(String className){
if (className == null){
return false;
}
for(String s : CACHE_LIST){
if(Pattern.matches(".*" + s + ".*", className)){
Class<?> clazz = obj.getClass();
if(clazz.isAnnotationPresent(BindClass.class)){
return true;
}
}
return false;
}

4
agent/src/main/java/com/fanruan/handler/DispatcherImpl.java

@ -16,8 +16,6 @@ import java.lang.reflect.Method;
public class DispatcherImpl implements Dispatcher{
protected static final Logger logger = LogManager.getLogger();
public final static String CLOSE_NAME = "close";
public DispatcherImpl(){}
@Override
@ -32,7 +30,7 @@ public class DispatcherImpl implements Dispatcher{
RESPONSE_EMITTER_IMPL.sendError(CACHE.getSocket(dbName), rpcRequest, t);
}
if(res != null && !DispatcherHelper.isInCacheList(res.getClass().getName())){
if(res != null && !DispatcherHelper.isInCacheList(res)){
RESPONSE_EMITTER_IMPL.replyWithData(CACHE.getSocket(dbName), rpcRequest, res);
}else {
RESPONSE_EMITTER_IMPL.sendOk(CACHE.getSocket(dbName), rpcRequest);

21
agent/src/test/java/HSQLTest.java

@ -73,15 +73,18 @@ public class HSQLTest {
public void test() throws SQLException {
Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:test;sql.syntax_mys=true", "sa", "");
Statement statement = conn.createStatement();
statement.executeUpdate("CREATE TABLE city (id INTEGER, name varchar(20)); ");
statement.executeUpdate("INSERT INTO city VALUES (1, '成都'), (2, '上海'); ");
statement.execute(createStoredProcedure);
CallableStatement callableStatement = conn.prepareCall("{call get_city_name(?, ?)}");
callableStatement.setInt(1, 2);
callableStatement.registerOutParameter(2, Types.VARCHAR);
callableStatement.execute();
System.out.println(callableStatement.getString(2));
statement.execute("create table TestTable " +
" (" +
" testString varchar(20), " +
" testBoolean BOOLEAN, " +
" testByte NUMERIC(10), " +
" testShort NUMERIC(10), " +
" testInt INTEGER, " +
" testLong BIGINT, " +
" testFloat FLOAT, " +
" testDouble DOUBLE, " +
" testDecimal DECIMAL);"
);
}
/**

6
service/src/main/java/com/fanruan/annotation/RemoteClass.java

@ -1,14 +1,12 @@
package com.fanruan.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.*;
/**
* @author Yichen Dai
* @date 2022/8/19 10:50
*/
@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RemoteClass {

7
service/src/main/java/com/fanruan/proxy/interceptor/Interceptor.java

@ -8,11 +8,15 @@ import com.fanruan.cache.ClientWrapper;
import com.fanruan.cache.LockAndCondition;
import com.fanruan.pojo.message.RpcRequest;
import com.fanruan.service.jdbc.AbstractBind;
import com.fanruan.service.jdbc.ServiceInputStream;
import com.fanruan.service.jdbc.ServiceReader;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Method;
import java.util.Properties;
import java.util.concurrent.FutureTask;
@ -99,8 +103,7 @@ public class Interceptor implements MethodInterceptor {
// If the return instance is corresponding with another instance in agent, set the binding ID.
if (InterceptorUtils.isInBindList(returnObj)){
AbstractBind ab = (AbstractBind) returnObj;
ab.setID(rpcRequest.getID());
InterceptorUtils.setBindID(returnObj, rpcRequest.getID());
}
return returnObj;
}

70
service/src/main/java/com/fanruan/proxy/interceptor/InterceptorUtils.java

@ -5,8 +5,11 @@ import com.fanruan.annotation.NotImplemented;
import com.fanruan.annotation.RemoteClass;
import com.fanruan.pojo.message.RpcRequest;
import com.fanruan.service.jdbc.AbstractBind;
import com.fanruan.service.jdbc.ServiceInputStream;
import com.fanruan.service.jdbc.ServiceReader;
import com.fanruan.utils.Commons;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Pattern;
@ -15,10 +18,6 @@ import java.util.regex.Pattern;
* @author Yichen Dai
*/
public class InterceptorUtils {
private static final String[] EXCLUDED_METHOD_LIST = new String[]{
"toString",
"hashCode",
};
private static final String[] WRAPPER_CLASS_LIST = new String[]{
"Boolean",
@ -31,28 +30,6 @@ public class InterceptorUtils {
"Float"
};
private final static String[] BIND_LIST = new String[]{
"Driver",
"Connection",
"Statement",
"PreparedStatement",
"ResultSet",
"MetaData",
"Clob",
"Blob",
"Array",
"Struct"
};
public static boolean isInExcludedList(String methodName){
for(String ex : EXCLUDED_METHOD_LIST){
if(ex.equals(methodName)){
return true;
}
}
return false;
}
public static boolean isWraps(Object o){
for(String ex : WRAPPER_CLASS_LIST){
if(ex.equals(getClassName(o.getClass().getName()))){
@ -75,22 +52,42 @@ public class InterceptorUtils {
if (o == null) {
return false;
}
return isInBindList(o.getClass().getName());
}
public static boolean isInBindList(String className){
for(String pattern : BIND_LIST){
if(Pattern.matches(".*" + pattern + ".*", className)){
Class<?> clazz = o.getClass();
if(clazz.isAnnotationPresent(RemoteClass.class)){
return true;
}
}
return false;
}
public static void setBindID(Object returnObj, String ID){
if(returnObj instanceof AbstractBind){
AbstractBind ab = (AbstractBind) returnObj;
ab.setID(ID);
}else if(returnObj instanceof ServiceReader){
ServiceReader sr = (ServiceReader) returnObj;
sr.setID(ID);
}else if(returnObj instanceof ServiceInputStream){
ServiceInputStream sis = (ServiceInputStream) returnObj;
sis.setID(ID);
}
}
public static RpcRequest generateRequest(Class<?> clazz, Object o, Method method, Object[] objects){
public static String getBindID(Object o){
String idToInvoke = null;
if(o instanceof AbstractBind){
AbstractBind ab = (AbstractBind) o;
idToInvoke = ab.getID();
}else if(o instanceof Reader){
ServiceReader sr = (ServiceReader) o;
idToInvoke = sr.getID();
}else if(o instanceof ServiceInputStream){
ServiceInputStream sis = (ServiceInputStream) o;
idToInvoke = sis.getID();
}
return idToInvoke;
}
public static RpcRequest generateRequest(Class<?> clazz, Object o, Method method, Object[] objects){
RpcRequest rpcRequest = new RpcRequest();
rpcRequest
.setID(Commons.getID())
@ -109,8 +106,7 @@ public class InterceptorUtils {
// IDtoInvoke is an unique ID to identify an one-to-one binding relation.
// It comes from rpcRequest in which the instance in the agent is created.
AbstractBind ab = (AbstractBind) o;
String idToInvoke = ab.getID();
String idToInvoke = getBindID(o);
if(idToInvoke != null){
rpcRequest.setIDToInvoke(idToInvoke);

5
service/src/main/java/com/fanruan/service/jdbc/ServiceBlob.java

@ -1,6 +1,7 @@
package com.fanruan.service.jdbc;
import com.fanruan.annotation.RemoteClass;
import com.fanruan.proxy.ProxyFactory;
import com.fanruan.service.jdbc.AbstractBind;
import java.io.InputStream;
@ -28,7 +29,7 @@ public class ServiceBlob extends BasedBind implements Blob {
@Override
public InputStream getBinaryStream() throws SQLException {
return null;
return (InputStream) ProxyFactory.getProxy(ServiceInputStream.class, info);
}
@Override
@ -68,6 +69,6 @@ public class ServiceBlob extends BasedBind implements Blob {
@Override
public InputStream getBinaryStream(long pos, long length) throws SQLException {
return null;
return (InputStream) ProxyFactory.getProxy(ServiceInputStream.class, info);
}
}

67
service/src/main/java/com/fanruan/service/jdbc/ServiceInputStream.java

@ -0,0 +1,67 @@
package com.fanruan.service.jdbc;
import com.fanruan.annotation.LocalMethod;
import com.fanruan.annotation.RemoteClass;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Yichen Dai
* @date 2022/9/8 18:11
*/
@RemoteClass(remoteClassName = "com.fanruan.agent.jdbc.AgentInputStream")
public class ServiceInputStream extends InputStream {
private String ID;
@LocalMethod
public String getID(){
return this.ID;
}
@LocalMethod
public void setID(String ID){
this.ID = ID;
}
@Override
public int read() throws IOException {
return 0;
}
@Override
public void close() throws IOException {
}
@LocalMethod
@Override
public int hashCode(){
return super.hashCode();
}
@LocalMethod
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@LocalMethod
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@LocalMethod
@Override
public String toString() {
return super.toString();
}
@LocalMethod
@Override
protected void finalize() throws Throwable {
super.finalize();
}
}

68
service/src/main/java/com/fanruan/service/jdbc/ServiceReader.java

@ -0,0 +1,68 @@
package com.fanruan.service.jdbc;
import com.fanruan.annotation.LocalMethod;
import com.fanruan.annotation.RemoteClass;
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;
/**
* @author Yichen Dai
* @date 2022/9/8 16:45
*/
@RemoteClass(remoteClassName = "com.fanruan.agent.jdbc.AgentReader")
public class ServiceReader extends Reader {
private String ID;
@LocalMethod
public String getID(){
return this.ID;
}
@LocalMethod
public void setID(String ID){
this.ID = ID;
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
return 0;
}
@Override
public void close() throws IOException {
}
@LocalMethod
@Override
public int hashCode(){
return super.hashCode();
}
@LocalMethod
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@LocalMethod
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@LocalMethod
@Override
public String toString() {
return super.toString();
}
@LocalMethod
@Override
protected void finalize() throws Throwable {
super.finalize();
}
}

19
service/src/main/java/com/fanruan/service/jdbc/connection/ServiceConnection.java

@ -3,8 +3,7 @@ package com.fanruan.service.jdbc.connection;
import com.fanruan.annotation.NotImplemented;
import com.fanruan.annotation.RemoteClass;
import com.fanruan.service.jdbc.BasedBind;
import com.fanruan.service.jdbc.ServiceDatabaseMetaData;
import com.fanruan.service.jdbc.*;
import com.fanruan.service.jdbc.statement.ServiceCallableStatement;
import com.fanruan.service.jdbc.statement.ServicePreparedStatement;
import com.fanruan.service.jdbc.statement.ServiceStatement;
@ -235,12 +234,16 @@ public class ServiceConnection extends BasedBind implements Connection {
@Override
public Clob createClob() throws SQLException {
return null;
ServiceClob clob = (ServiceClob) ProxyFactory.getProxy(ServiceClob.class, info);
clob.setInfo(info);
return clob;
}
@Override
public Blob createBlob() throws SQLException {
return null;
ServiceBlob blob = (ServiceBlob) ProxyFactory.getProxy(ServiceBlob.class, info);
blob.setInfo(info);
return blob;
}
@Override
@ -280,12 +283,16 @@ public class ServiceConnection extends BasedBind implements Connection {
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
return null;
ServiceArray array = (ServiceArray) ProxyFactory.getProxy(ServiceArray.class, info);
array.setInfo(info);
return array;
}
@Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
return null;
ServiceStruct struct = (ServiceStruct) ProxyFactory.getProxy(ServiceStruct.class, info);
struct.setInfo(info);
return struct;
}
@Override

53
service/src/main/java/com/fanruan/service/jdbc/resultset/ServiceResultSet.java

@ -1,10 +1,11 @@
package com.fanruan.service.jdbc.resultset;
import com.fanruan.annotation.LocalMethod;
import com.fanruan.annotation.NotImplemented;
import com.fanruan.annotation.RemoteClass;
import com.fanruan.proxy.ProxyFactory;
import com.fanruan.service.jdbc.BasedBind;
import com.fanruan.service.jdbc.ServiceResultSetMetaData;
import com.fanruan.service.jdbc.*;
import java.io.InputStream;
import java.io.Reader;
@ -102,17 +103,17 @@ public class ServiceResultSet extends BasedBind implements ResultSet {
@Override
public InputStream getAsciiStream(int columnIndex) throws SQLException {
return null;
return (ServiceInputStream) ProxyFactory.getProxy(ServiceInputStream.class, info);
}
@Override
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
return null;
return (ServiceInputStream) ProxyFactory.getProxy(ServiceInputStream.class, info);
}
@Override
public InputStream getBinaryStream(int columnIndex) throws SQLException {
return null;
return (ServiceInputStream) ProxyFactory.getProxy(ServiceInputStream.class, info);
}
@Override
@ -182,17 +183,17 @@ public class ServiceResultSet extends BasedBind implements ResultSet {
@Override
public InputStream getAsciiStream(String columnLabel) throws SQLException {
return null;
return (ServiceInputStream) ProxyFactory.getProxy(ServiceInputStream.class, info);
}
@Override
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
return null;
return (ServiceInputStream) ProxyFactory.getProxy(ServiceInputStream.class, info);
}
@Override
public InputStream getBinaryStream(String columnLabel) throws SQLException {
return null;
return (ServiceInputStream) ProxyFactory.getProxy(ServiceInputStream.class, info);
}
@Override
@ -233,12 +234,12 @@ public class ServiceResultSet extends BasedBind implements ResultSet {
@Override
public Reader getCharacterStream(int columnIndex) throws SQLException {
return null;
return (Reader) ProxyFactory.getProxy(ServiceReader.class, info);
}
@Override
public Reader getCharacterStream(String columnLabel) throws SQLException {
return null;
return (Reader) ProxyFactory.getProxy(ServiceReader.class, info);
}
@Override
@ -598,17 +599,23 @@ public class ServiceResultSet extends BasedBind implements ResultSet {
@Override
public Blob getBlob(int columnIndex) throws SQLException {
return null;
ServiceBlob blob = (ServiceBlob) ProxyFactory.getProxy(ServiceBlob.class, info);
blob.setInfo(info);
return blob;
}
@Override
public Clob getClob(int columnIndex) throws SQLException {
return null;
ServiceClob clob = (ServiceClob) ProxyFactory.getProxy(ServiceClob.class, info);
clob.setInfo(info);
return clob;
}
@Override
public Array getArray(int columnIndex) throws SQLException {
return null;
ServiceArray array = (ServiceArray) ProxyFactory.getProxy(ServiceArray.class, info);
array.setInfo(info);
return array;
}
@Override
@ -623,17 +630,23 @@ public class ServiceResultSet extends BasedBind implements ResultSet {
@Override
public Blob getBlob(String columnLabel) throws SQLException {
return null;
ServiceBlob blob = (ServiceBlob) ProxyFactory.getProxy(ServiceBlob.class, info);
blob.setInfo(info);
return blob;
}
@Override
public Clob getClob(String columnLabel) throws SQLException {
return null;
ServiceClob clob = (ServiceClob) ProxyFactory.getProxy(ServiceClob.class, info);
clob.setInfo(info);
return clob;
}
@Override
public Array getArray(String columnLabel) throws SQLException {
return null;
ServiceArray array = (ServiceArray) ProxyFactory.getProxy(ServiceArray.class, info);
array.setInfo(info);
return array;
}
@Override
@ -808,12 +821,12 @@ public class ServiceResultSet extends BasedBind implements ResultSet {
@Override
public Reader getNCharacterStream(int columnIndex) throws SQLException {
return null;
return (Reader) ProxyFactory.getProxy(Reader.class, info);
}
@Override
public Reader getNCharacterStream(String columnLabel) throws SQLException {
return null;
return (Reader) ProxyFactory.getProxy(Reader.class, info);
}
@Override
@ -967,8 +980,10 @@ public class ServiceResultSet extends BasedBind implements ResultSet {
}
@Override
@LocalMethod
@NotImplemented
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
throw new SQLException("Not Implemented!");
}
@Override

6
test/src/test/java/com/fanruan/ConnectionTest.java

@ -311,4 +311,10 @@ public class ConnectionTest extends BaseJDBCTest{
void testGetMetaData() throws SQLException {
DatabaseMetaData metaData = connection.getMetaData();
}
@Test
void testCreate() throws SQLException{
Assertions.assertNotNull(connection.createClob());
}
}

136
test/src/test/java/com/fanruan/ResultSetTest.java

@ -4,17 +4,23 @@ import com.fanruan.cache.BeanCacheImpl;
import com.fanruan.handler.DispatcherImpl;
import com.fanruan.pojo.message.RpcRequest;
import com.fanruan.service.jdbc.AbstractBind;
import com.fanruan.service.jdbc.ServiceBlob;
import com.fanruan.service.jdbc.ServiceReader;
import com.fanruan.service.jdbc.resultset.ServiceResultSet;
import com.fanruan.service.jdbc.statement.ServiceStatement;
import org.hsqldb.jdbc.JDBCBlob;
import org.hsqldb.jdbc.JDBCClob;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.*;
/**
* @author Yichen Dai
@ -24,11 +30,17 @@ import java.sql.Statement;
public class ResultSetTest extends BaseJDBCTest{
private Connection connection = null;
ResultSet resultSet = null;
@BeforeAll
public void setUp() throws SQLException {
openSocket();
connection = getConnection();
}
@Test
public void testDate() throws SQLException{
Statement statement = connection.createStatement();
statement.execute("create table DemoTable\n" +
" (\n" +
@ -40,12 +52,8 @@ public class ResultSetTest extends BaseJDBCTest{
statement.executeUpdate("insert into DEMOTABLE(TESTTIME,TESTDATE,TESTSTAMP) " +
"values('15:50:37', '2022-09-07', '2022-09-07 15:50:37');");
}
@Test
public void testDate() throws SQLException{
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select TestTime, TestDate, TestStamp from DemoTable;");
this.resultSet = statement.executeQuery("select TestTime, TestDate, TestStamp from DemoTable;");
while(resultSet.next()){
Assertions.assertEquals("15:50:37", resultSet.getTime(1).toString());
@ -53,5 +61,115 @@ public class ResultSetTest extends BaseJDBCTest{
Assertions.assertEquals("2022-09-07 15:50:37.0", resultSet.getTimestamp(3).toString());
}
Assertions.assertFalse(resultSet.isClosed());
}
@Test
public void testGet() throws SQLException, IOException {
Statement statement = connection.createStatement();
statement.execute("create table TestTable " +
" (" +
" testString varchar(20), " +
" testBoolean BOOLEAN, " +
" testByte NUMERIC(3), " +
" testShort NUMERIC(5), " +
" testInt INTEGER, " +
" testLong BIGINT, " +
" testFloat FLOAT, " +
" testDouble DOUBLE, " +
" testDecimal DECIMAL," +
" testBlob BLOB(1024)," +
" testClob varchar(100));"
);
PreparedStatement prepareStatement = connection.prepareStatement("INSERT INTO TestTable VALUES( " +
"?, " +
"?," +
"?," +
"?," +
"?," +
"?," +
"?, " +
"?, " +
"?," +
"?," +
"?);");
prepareStatement.setString(1, "testString");
prepareStatement.setBoolean(2, true);
prepareStatement.setByte(3, Byte.MAX_VALUE);
prepareStatement.setShort(4, Short.MAX_VALUE);
prepareStatement.setInt(5, Integer.MAX_VALUE);
prepareStatement.setLong(6, Long.MAX_VALUE);
prepareStatement.setFloat(7, 0.2f);
prepareStatement.setDouble(8, 0.2D);
prepareStatement.setBigDecimal(9, new BigDecimal(1000));
byte[] chuck = {
(byte)0x0f, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00
};
Blob blob = new JDBCBlob(chuck);
prepareStatement.setBlob(10, blob);
prepareStatement.setClob(11, new JDBCClob("abcd"));
prepareStatement.executeUpdate();
ResultSet resultSet = statement.executeQuery("SELECT * FROM TestTable;");
resultSet.next();
Assertions.assertEquals("testString", resultSet.getString(1));
Assertions.assertEquals("testString", resultSet.getString("testString"));
Assertions.assertEquals(true, resultSet.getBoolean(2));
Assertions.assertEquals(true, resultSet.getBoolean("testBoolean"));
Assertions.assertEquals(Byte.MAX_VALUE, resultSet.getByte(3));
Assertions.assertEquals(Byte.MAX_VALUE, resultSet.getByte("testByte"));
Assertions.assertEquals(Short.MAX_VALUE, resultSet.getShort(4));
Assertions.assertEquals(Short.MAX_VALUE, resultSet.getShort("testShort"));
Assertions.assertEquals(Integer.MAX_VALUE, resultSet.getInt(5));
Assertions.assertEquals(Integer.MAX_VALUE, resultSet.getInt("testInt"));
Assertions.assertEquals(Long.MAX_VALUE, resultSet.getLong(6));
Assertions.assertEquals(Long.MAX_VALUE, resultSet.getLong("testLong"));
Assertions.assertEquals(0.2f, resultSet.getFloat(7));
Assertions.assertEquals(0.2f, resultSet.getFloat("testFloat"));
Assertions.assertEquals(0.2d, resultSet.getDouble(8));
Assertions.assertEquals(0.2d, resultSet.getDouble("testDouble"));
Assertions.assertEquals(1000, resultSet.getBigDecimal(9).intValue());
Assertions.assertEquals(1000, resultSet.getBigDecimal("testDecimal").intValue());
Assertions.assertEquals(chuck.length, resultSet.getBytes(10).length);
Assertions.assertEquals(chuck.length, resultSet.getBytes("testBlob").length);
Assertions.assertEquals(chuck[0], resultSet.getBinaryStream("testBlob").read());
Assertions.assertEquals(chuck[0], resultSet.getBinaryStream("testBlob").read());
Assertions.assertEquals('a', resultSet.getAsciiStream(11).read());
Assertions.assertEquals('a', resultSet.getAsciiStream("testClob").read());
Assertions.assertEquals('a', resultSet.getCharacterStream(11).read());
Assertions.assertEquals('a', resultSet.getCharacterStream("testClob").read());
Assertions.assertNull(resultSet.getCursorName());
Assertions.assertNotNull(resultSet.getMetaData());
}
@Test
public void testWrap() throws SQLException {
String SQL_INSERT = "INSERT INTO EMPLOYEE VALUES 'Tim';";
String SQL_CREATE = "CREATE TABLE EMPLOYEE (NAME varchar(100));";
Statement statement = connection.createStatement();
statement.execute(SQL_CREATE);
statement.executeUpdate(SQL_INSERT);
ResultSet resultSet = statement.executeQuery("select * from EMPLOYEE");
Assertions.assertThrows(SQLException.class, () -> resultSet.unwrap(null));
Assertions.assertFalse(resultSet.isWrapperFor(null));
}
}

Loading…
Cancel
Save