Commit 4294bb39 authored by terrymanu's avatar terrymanu
Browse files

set datasource prop for json and spring boot starter

parent 02fcf6c3
Loading
Loading
Loading
Loading
+67 −0
Original line number Diff line number Diff line
package io.shardingjdbc.core.util;

import com.google.common.collect.Sets;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import javax.sql.DataSource;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Data source utility class.
 *
 * @author zhangliang
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class DataSourceUtil {
    
    private static final String SET_METHOD_PREFIX = "set";
    
    private static Collection<Class<?>> generalClassType;
    
    static {
        generalClassType = Sets.<Class<?>>newHashSet(boolean.class, Boolean.class, int.class, Integer.class, long.class, Long.class, String.class);
    }
    
    /**
     * Get data source.
     * 
     * @param dataSourceClassName Data source class name
     * @param dataSourceProperties Data source properties
     * @return data source instance
     * @throws ReflectiveOperationException reflective operation exception
     */
    public static DataSource getDataSource(final String dataSourceClassName, final Map<String, Object> dataSourceProperties) throws ReflectiveOperationException {
        DataSource result = (DataSource) Class.forName(dataSourceClassName).newInstance();
        for (Entry<String, Object> entry : dataSourceProperties.entrySet()) {
            callSetterMethod(result, getSetterMethodName(entry.getKey()), null == entry.getValue() ? null : entry.getValue().toString());
        }
        return result;
    }
    
    private static String getSetterMethodName(final String propertyName) {
        return SET_METHOD_PREFIX + String.valueOf(propertyName.charAt(0)).toUpperCase() + propertyName.substring(1, propertyName.length());
    }
    
    private static void callSetterMethod(final DataSource dataSource, final String methodName, final String setterValue) {
        for (Class<?> each : generalClassType) {
            try {
                Method method = dataSource.getClass().getDeclaredMethod(methodName, each);
                if (boolean.class == each || Boolean.class == each) {
                    method.invoke(dataSource, Boolean.valueOf(setterValue));
                } else if (int.class == each || Integer.class == each) {
                    method.invoke(dataSource, Integer.parseInt(setterValue));
                } else if (long.class == each || Long.class == each) {
                    method.invoke(dataSource, Long.parseLong(setterValue));
                } else {
                    method.invoke(dataSource, setterValue);
                }
                return;
            } catch (final ReflectiveOperationException ex) {
            }
        }
    }
}
+7 −32
Original line number Diff line number Diff line
@@ -17,13 +17,14 @@

package io.shardingjdbc.orchestration.json;

import io.shardingjdbc.core.jdbc.core.datasource.NamedDataSource;
import com.google.common.collect.Sets;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import io.shardingjdbc.core.exception.ShardingJdbcException;
import io.shardingjdbc.core.jdbc.core.datasource.NamedDataSource;
import io.shardingjdbc.core.util.DataSourceUtil;

import javax.sql.DataSource;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collection;
@@ -44,11 +45,12 @@ public final class DataSourceGsonTypeAdapter extends TypeAdapter<NamedDataSource
        generalClassType = Sets.<Class<?>>newHashSet(boolean.class, Boolean.class, int.class, Integer.class, long.class, Long.class, String.class);
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public NamedDataSource read(final JsonReader in) throws IOException {
        String name = "";
        String clazz = "";
        Map<String, String> properties = new TreeMap<>();
        Map<String, Object> properties = new TreeMap<>();
        in.beginObject();
        while (in.hasNext()) {
            String jsonName = in.nextName();
@@ -61,15 +63,11 @@ public final class DataSourceGsonTypeAdapter extends TypeAdapter<NamedDataSource
            }
        }
        in.endObject();
        DataSource dataSource = null;
        try {
            dataSource = (DataSource) Class.forName(clazz).newInstance();
            for (Entry<String, String> entry : properties.entrySet()) {
                callSetterMethod(dataSource, getSetterMethodName(entry.getKey()), entry.getValue());
            }
            return new NamedDataSource(name, DataSourceUtil.getDataSource(clazz, properties));
        } catch (final ReflectiveOperationException ex) {
            throw new ShardingJdbcException(ex);
        }
        return new NamedDataSource(name, dataSource);
    }
    
    @Override
@@ -132,27 +130,4 @@ public final class DataSourceGsonTypeAdapter extends TypeAdapter<NamedDataSource
        }
        return result;
    }
    
    private String getSetterMethodName(final String propertyName) {
        return "set" + String.valueOf(propertyName.charAt(0)).toUpperCase() + propertyName.substring(1, propertyName.length());
    }
    
    private void callSetterMethod(final DataSource dataSource, final String methodName, final String setterValue) {
        for (Class<?> each : generalClassType) {
            try {
                Method method = dataSource.getClass().getDeclaredMethod(methodName, each);
                if (boolean.class == each || Boolean.class == each) {
                    method.invoke(dataSource, Boolean.valueOf(setterValue));
                } else if (int.class == each || Integer.class == each) {
                    method.invoke(dataSource, Integer.parseInt(setterValue));
                } else if (long.class == each || Long.class == each) {
                    method.invoke(dataSource, Long.parseLong(setterValue));
                } else {
                    method.invoke(dataSource, setterValue);
                }
                return;
            } catch (final ReflectiveOperationException ex) {
            }
        }
    }
}
+5 −6
Original line number Diff line number Diff line
package io.shardingjdbc.spring.boot.util;

import com.google.common.base.Preconditions;
import io.shardingjdbc.core.exception.ShardingJdbcException;
import io.shardingjdbc.core.util.DataSourceUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.core.env.Environment;

@@ -31,12 +32,10 @@ public final class EnvironmentAwareUtil {
            try {
                Map<String, Object> dataSourceProps = propertyResolver.getSubProperties(each + ".");
                Preconditions.checkState(!dataSourceProps.isEmpty(), "Wrong datasource properties!");
                DataSource dataSource = DataSourceBuilder.create().driverClassName(dataSourceProps.get("driver-class-name").toString())
                        .username(dataSourceProps.get("username").toString()).password(dataSourceProps.get("password").toString())
                        .url(dataSourceProps.get("url").toString()).type((Class<? extends DataSource>) Class.forName(dataSourceProps.get("type").toString())).build();
                DataSource dataSource = DataSourceUtil.getDataSource(dataSourceProps.get("type").toString(), dataSourceProps);
                dataSourceMap.put(each, dataSource);
            } catch (final ClassNotFoundException ex) {
                throw new RuntimeException("Can't find datasource type!", ex);
            } catch (final ReflectiveOperationException ex) {
                throw new ShardingJdbcException("Can't find datasource type!", ex);
            }
        }
    }
+6 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ package io.shardingjdbc.spring.boot.type;

import io.shardingjdbc.core.jdbc.core.datasource.MasterSlaveDataSource;
import io.shardingjdbc.spring.boot.SpringBootMain;
import org.apache.commons.dbcp.BasicDataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -11,6 +12,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.sql.DataSource;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

@RunWith(SpringJUnit4ClassRunner.class)
@@ -24,5 +27,8 @@ public class SpringBootMasterSlaveTest {
    @Test
    public void testWithMasterSlaveDataSource() {
        assertTrue(dataSource instanceof MasterSlaveDataSource);
        for (DataSource each : ((MasterSlaveDataSource) dataSource).getAllDataSources().values()) {
            assertThat(((BasicDataSource) each).getMaxActive(), is(16));
        }
    }
}
+12 −1
Original line number Diff line number Diff line
package io.shardingjdbc.spring.boot.type;

import io.shardingjdbc.core.jdbc.core.ShardingContext;
import io.shardingjdbc.core.jdbc.core.datasource.ShardingDataSource;
import io.shardingjdbc.spring.boot.SpringBootMain;
import org.apache.commons.dbcp.BasicDataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -10,7 +12,10 @@ import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.sql.DataSource;
import java.lang.reflect.Field;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

@RunWith(SpringJUnit4ClassRunner.class)
@@ -22,7 +27,13 @@ public class SpringBootShardingTest {
    private DataSource dataSource;
    
    @Test
    public void testWithShardingDataSource() {
    public void testWithShardingDataSource() throws NoSuchFieldException, IllegalAccessException {
        assertTrue(dataSource instanceof ShardingDataSource);
        Field field = ShardingDataSource.class.getDeclaredField("shardingContext");
        field.setAccessible(true);
        ShardingContext shardingContext = (ShardingContext) field.get(dataSource);
        for (DataSource each : shardingContext.getShardingRule().getDataSourceMap().values()) {
            assertThat(((BasicDataSource) each).getMaxActive(), is(16));
        }
    }
}
Loading