Search in sources :

Example 1 with DatasourceConfig

use of io.mycat.config.DatasourceConfig in project Mycat2 by MyCATApache.

the class JdbcConnectionManager method getConnection.

public DefaultConnection getConnection(String name, Boolean autocommit, int transactionIsolation) {
    name = resolveDataSource(name);
    final JdbcDataSource key = dataSourceMap.get(name);
    Objects.requireNonNull(key, "unknown target:" + name);
    DefaultConnection defaultConnection;
    Connection connection = null;
    switch(key.getDbType()) {
        default:
            {
                try {
                    DatasourceConfig config = key.getConfig();
                    connection = key.getDataSource().getConnection();
                    defaultConnection = new DefaultConnection(connection, key, autocommit, transactionIsolation, this);
                    LOGGER.debug("get connection:{} {}", name, defaultConnection);
                    if (config.isInitSqlsGetConnection()) {
                        if (config.getInitSqls() != null && !config.getInitSqls().isEmpty()) {
                            try (Statement statement = connection.createStatement()) {
                                for (String initSql : config.getInitSqls()) {
                                    statement.execute(initSql);
                                }
                            }
                        }
                    }
                    key.counter.getAndIncrement();
                    return defaultConnection;
                } catch (SQLException e) {
                    if (connection != null) {
                        JdbcUtils.close(connection);
                    }
                    LOGGER.debug("", e);
                    throw new MycatException(e);
                }
            }
        case "mongodb":
            {
                try {
                    Properties properties = new Properties();
                    String username = key.getUsername();
                    String password = key.getPassword();
                    if (username != null) {
                        properties.setProperty("username", username);
                    }
                    if (password != null) {
                        properties.setProperty("password", password);
                    }
                    Connection connect = new MongoDriver().connect(key.getUrl(), properties);
                    return new DefaultConnection(connect, key, autocommit, transactionIsolation, this);
                } catch (SQLException ex) {
                    throw new MycatException(ex);
                }
            }
    }
}
Also used : DatasourceConfig(io.mycat.config.DatasourceConfig) MycatException(io.mycat.MycatException) SQLException(java.sql.SQLException) Statement(java.sql.Statement) Connection(java.sql.Connection) MongoDriver(io.mycat.datasource.jdbc.mongodb.MongoDriver)

Example 2 with DatasourceConfig

use of io.mycat.config.DatasourceConfig in project Mycat2 by MyCATApache.

the class TreeItemCellFactory method call.

@Override
public TreeCell<ObjectItem> call(TreeView<ObjectItem> tree) {
    TreeCell<ObjectItem> cell = new SchemaObjectCell();
    cell.setOnMouseClicked(event -> {
        Optional<Command> commandOptional = Command.parsePath(getPath(cell.getTreeItem()));
        if (event != null) {
            if (event.getButton() == MouseButton.SECONDARY) {
                ContextMenu contextMenu = new ContextMenu();
                TreeItem<ObjectItem> treeItem = cell.getTreeItem();
                if (treeItem == null) {
                    return;
                }
                if (!treeItem.isLeaf() && treeItem.getParent() == tree.getRoot()) {
                    ObjectItem value = treeItem.getValue();
                    switch(value.getText()) {
                        case "schemas":
                            {
                                MenuItem item1 = new MenuItem("新建逻辑库");
                                item1.setId("addSchema");
                                item1.setOnAction(new EventHandler<ActionEvent>() {

                                    @Override
                                    public void handle(ActionEvent event1) {
                                        try {
                                            controller.edit(new LogicSchemaConfig());
                                        } catch (Exception e) {
                                            popAlter(e);
                                        }
                                    }
                                });
                                contextMenu.getItems().add(item1);
                                break;
                            }
                        case "datasources":
                            {
                                MenuItem item1 = new MenuItem("新建数据源");
                                item1.setId("addDatasource");
                                item1.setOnAction(new EventHandler<ActionEvent>() {

                                    @Override
                                    public void handle(ActionEvent event1) {
                                        try {
                                            controller.edit(new DatasourceConfig());
                                        } catch (Exception e) {
                                            popAlter(e);
                                        }
                                    }
                                });
                                contextMenu.getItems().add(item1);
                                break;
                            }
                        case "clusters":
                            {
                                MenuItem item1 = new MenuItem("新建集群");
                                item1.setId("addCluster");
                                item1.setOnAction(new EventHandler<ActionEvent>() {

                                    @Override
                                    public void handle(ActionEvent event1) {
                                        try {
                                            controller.edit(new ClusterConfig());
                                        } catch (Exception e) {
                                            popAlter(e);
                                        }
                                    }
                                });
                                contextMenu.getItems().add(item1);
                                break;
                            }
                    }
                } else {
                    if (commandOptional.isPresent()) {
                        Command command = commandOptional.get();
                        String schema = command.getSchema();
                        switch(command.getType()) {
                            case SCHEMA:
                                {
                                    MenuItem item1 = new MenuItem("删除逻辑库配置");
                                    item1.setId("deleteSchema");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                boolean doAction = display("删除逻辑库配置", "确认删除逻辑库配置");
                                                if (doAction) {
                                                    controller.getInfoProvider().deleteLogicalSchema(command.getSchema());
                                                    controller.flashRoot();
                                                }
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case SHARDING_TABLES:
                                {
                                    MenuItem item1 = new MenuItem("新建分片表");
                                    item1.setId("addShardingTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                controller.addShardingTable(schema);
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case GLOBAL_TABLES:
                                {
                                    MenuItem item1 = new MenuItem("新建全局表");
                                    item1.setId("addGlobalTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                controller.addGlobalTableConfig(schema);
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case SINGLE_TABLES:
                                {
                                    MenuItem item1 = new MenuItem("新建单表");
                                    item1.setId("addSingleTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                controller.addNormalTableConfig(schema);
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case SHARDING_TABLE:
                                {
                                    MenuItem item1 = new MenuItem("删除分片表配置");
                                    item1.setId("deleteShardingTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                boolean doAction = display("删除分片表", "确认删除分片表配置");
                                                if (doAction) {
                                                    controller.getInfoProvider().deleteTable(schema, command.getTable());
                                                    controller.flashSchemas();
                                                }
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case GLOBAL_TABLE:
                                {
                                    MenuItem item1 = new MenuItem("删除全局表配置");
                                    item1.setId("deleteGlobalTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                boolean doAction = display("删除全局表配置", "确认删除全局表配置");
                                                if (doAction) {
                                                    controller.getInfoProvider().deleteTable(command.getSchema(), command.getTable());
                                                    controller.flashSchemas();
                                                }
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case SINGLE_TABLE:
                                {
                                    MenuItem item1 = new MenuItem("删除单表配置");
                                    item1.setId("deleteSingleTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                boolean doAction = display("删除单表配置", "确认删除单表配置");
                                                if (doAction) {
                                                    controller.getInfoProvider().deleteTable(command.getSchema(), command.getTable());
                                                    controller.flashSchemas();
                                                }
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case CLUSTER:
                                {
                                    MenuItem item1 = new MenuItem("删除");
                                    item1.setId("deleteCluster");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                boolean doAction = display("删除集群", "确认删除集群");
                                                if (doAction) {
                                                    controller.getInfoProvider().deleteCluster(command.getCluster());
                                                    controller.flashClusterAndDataSource();
                                                }
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case DATASOURCE:
                                {
                                    MenuItem item1 = new MenuItem("删除");
                                    item1.setId("deleteDatasource");
                                    item1.setOnAction(event1 -> {
                                        try {
                                            boolean doAction = display("删除数据源", "确认删除数据源");
                                            if (doAction) {
                                                controller.getInfoProvider().deleteDatasource(command.getDatasource());
                                                controller.flashClusterAndDataSource();
                                            }
                                        } catch (Exception e) {
                                            popAlter(e);
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                        }
                    }
                }
                if (contextMenu != null) {
                    cell.setContextMenu(contextMenu);
                }
            }
        }
        if (!cell.isEmpty()) {
            controller.clearObjectInfo();
            if (!commandOptional.isPresent()) {
                return;
            }
            Command command = commandOptional.get();
            switch(command.getType()) {
                case SCHEMA:
                    Optional<LogicSchemaConfig> logicSchemaConfigOptional = controller.getInfoProvider().getSchemaConfigByName(command.getSchema());
                    logicSchemaConfigOptional.ifPresent(r -> controller.edit(r));
                    break;
                case SHARDING_TABLE:
                case GLOBAL_TABLE:
                case SINGLE_TABLE:
                    {
                        if (command.getSchema() == null || command.getTable() == null) {
                            return;
                        }
                        LogicTableType logicTableType;
                        String schemaName = command.getSchema();
                        String tableName = command.getTable();
                        switch(command.getType()) {
                            case GLOBAL_TABLE:
                                logicTableType = LogicTableType.GLOBAL;
                                break;
                            case SINGLE_TABLE:
                                logicTableType = LogicTableType.NORMAL;
                                break;
                            case SHARDING_TABLE:
                                logicTableType = LogicTableType.SHARDING;
                                break;
                            default:
                                throw new IllegalArgumentException();
                        }
                        Optional<Object> config = controller.getInfoProvider().getTableConfigByName(command.getSchema(), command.getTable());
                        config.ifPresent(c -> controller.edit(logicTableType, schemaName, tableName, c));
                        break;
                    }
                case CLUSTER:
                    Optional<ClusterConfig> clusterConfigOptional = controller.getInfoProvider().getClusterConfigByPath(command.getCluster());
                    clusterConfigOptional.ifPresent(c -> controller.edit(c));
                    break;
                case DATASOURCE:
                    Optional<DatasourceConfig> datasourceConfigOptional = controller.getInfoProvider().getDatasourceConfigByPath(command.getDatasource());
                    datasourceConfigOptional.ifPresent(c -> controller.edit(c));
                    break;
            }
            System.out.println("");
        }
    });
    return cell;
}
Also used : ClusterConfig(io.mycat.config.ClusterConfig) EventHandler(javafx.event.EventHandler) Pos(javafx.geometry.Pos) Scene(javafx.scene.Scene) HBox(javafx.scene.layout.HBox) MouseButton(javafx.scene.input.MouseButton) Modality(javafx.stage.Modality) javafx.scene.control(javafx.scene.control) MainPaneVO.popAlter(io.mycat.ui.MainPaneVO.popAlter) Node(javafx.scene.Node) UIMain.getPath(io.mycat.ui.UIMain.getPath) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) VBox(javafx.scene.layout.VBox) ActionEvent(javafx.event.ActionEvent) Stage(javafx.stage.Stage) LogicTableType(io.mycat.LogicTableType) LogicSchemaConfig(io.mycat.config.LogicSchemaConfig) Optional(java.util.Optional) DatasourceConfig(io.mycat.config.DatasourceConfig) Callback(javafx.util.Callback) Optional(java.util.Optional) ActionEvent(javafx.event.ActionEvent) EventHandler(javafx.event.EventHandler) LogicTableType(io.mycat.LogicTableType) DatasourceConfig(io.mycat.config.DatasourceConfig) LogicSchemaConfig(io.mycat.config.LogicSchemaConfig) ClusterConfig(io.mycat.config.ClusterConfig)

Example 3 with DatasourceConfig

use of io.mycat.config.DatasourceConfig in project Mycat2 by MyCATApache.

the class BaseTest method testCreateDatasource.

@org.junit.Test
public void testCreateDatasource() {
    FxRobot robot = this;
    Set<Scene> sceneSet = SceneUtil.sceneSet;
    testTcpConnectionLogin();
    lookupNode("#objectTree").ifPresent(new Consumer<Node>() {

        @Override
        public void accept(Node node) {
            lookupNode("#datasources").ifPresent(c -> {
                SchemaObjectCell schemaObjectCell = (SchemaObjectCell) c;
                schemaObjectCell.getTreeItem().setExpanded(true);
                robot.interrupt();
            });
            robot.interrupt();
            rightClickOn(lookupNode("#datasources").get());
            robot.moveTo("#addDatasource", Motion.DEFAULT);
            robot.clickOn("#addDatasource");
            robot.interrupt();
            String url = "jdbc:mysql://localhost:3306/db1?useServerPrepStmts=false&useCursorFetch=true&serverTimezone=Asia/Shanghai&allowMultiQueries=false&useBatchMultiSend=false&characterEncoding=utf8";
            DatasourceConfig datasourceConfig = new DatasourceConfig();
            datasourceConfig.setDbType("mysql");
            datasourceConfig.setName("ds3");
            datasourceConfig.setUser("root");
            datasourceConfig.setPassword("123456");
            datasourceConfig.setUrl(url);
            String config = Json.encode(datasourceConfig);
            lookupTextNode("#objectText").ifPresent(c -> {
                c.setText(config);
                robot.interrupt();
            });
            Controller.INSTANCE.textToNax.handle(null);
            robot.interrupt();
            lookupNode("#saveDatasource").ifPresent(c -> {
                clickOn(c);
                robot.interrupt();
            });
            Node node1 = lookupNode("#datasources").get();
            lookupNode("#datasources").ifPresent(c -> {
                SchemaObjectCell schemaObjectCell = (SchemaObjectCell) c;
                schemaObjectCell.getTreeItem().setExpanded(true);
                robot.interrupt();
            });
            Optional<Node> ds3Node = lookupNode(ObjectItem.ofDatasource("ds3").getId());
            Assert.assertTrue(ds3Node.isPresent());
            ds3Node.ifPresent(n -> {
                rightClickOn(ds3Node.get());
                robot.moveTo("#deleteDatasource", Motion.DEFAULT);
                robot.clickOn("#deleteDatasource");
            });
            robot.interrupt();
            lookupNode("enter").ifPresent(c -> {
                clickOn(c);
                robot.interrupt();
            });
            Optional<Node> deletedDs3Node = lookupNode(ObjectItem.ofDatasource("ds3").getId());
            deletedDs3Node.ifPresent(new Consumer<Node>() {

                @Override
                public void accept(Node node) {
                    SchemaObjectCell schemaObjectCell = (SchemaObjectCell) node;
                    System.out.println();
                    Assert.assertNull(schemaObjectCell.getTreeItem());
                }
            });
        }
    });
    System.out.println(sceneSet);
}
Also used : Scene(javafx.scene.Scene) Json(io.vertx.core.json.Json) Arrays(java.util.Arrays) TextInputControl(javafx.scene.control.TextInputControl) Connection(java.sql.Connection) TextArea(javafx.scene.control.TextArea) BeforeClass(org.junit.BeforeClass) ApplicationTest(org.testfx.framework.junit.ApplicationTest) SneakyThrows(lombok.SneakyThrows) CreateSchemaHint(io.mycat.hint.CreateSchemaHint) Function(java.util.function.Function) CreateDataSourceHint(io.mycat.hint.CreateDataSourceHint) Maps(org.apache.groovy.util.Maps) TabPane(javafx.scene.control.TabPane) ShardingFunction(io.mycat.config.ShardingFunction) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) CreateClusterHint(io.mycat.hint.CreateClusterHint) FxRobot(org.testfx.api.FxRobot) DatasourceConfig(io.mycat.config.DatasourceConfig) JsonUtil(io.mycat.util.JsonUtil) TableView(javafx.scene.control.TableView) Path(java.nio.file.Path) SceneUtil.lookupTextNode(io.mycat.ui.SceneUtil.lookupTextNode) PartitionByRangeMod(io.mycat.router.mycat1xfunction.PartitionByRangeMod) Files(java.nio.file.Files) CSVWriter(au.com.bytecode.opencsv.CSVWriter) Node(javafx.scene.Node) StringWriter(java.io.StringWriter) Motion(org.testfx.robot.Motion) StandardOpenOption(java.nio.file.StandardOpenOption) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) StandardCharsets(java.nio.charset.StandardCharsets) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Stage(javafx.stage.Stage) SceneUtil.lookupNode(io.mycat.ui.SceneUtil.lookupNode) DruidDataSource(com.alibaba.druid.pool.DruidDataSource) GlobalBackEndTableInfoConfig(io.mycat.config.GlobalBackEndTableInfoConfig) JdbcUtils(com.alibaba.druid.util.JdbcUtils) Optional(java.util.Optional) Assert(org.junit.Assert) GlobalTableConfig(io.mycat.config.GlobalTableConfig) DatasourceConfig(io.mycat.config.DatasourceConfig) Optional(java.util.Optional) Consumer(java.util.function.Consumer) SceneUtil.lookupTextNode(io.mycat.ui.SceneUtil.lookupTextNode) Node(javafx.scene.Node) SceneUtil.lookupNode(io.mycat.ui.SceneUtil.lookupNode) FxRobot(org.testfx.api.FxRobot) Scene(javafx.scene.Scene)

Example 4 with DatasourceConfig

use of io.mycat.config.DatasourceConfig in project Mycat2 by MyCATApache.

the class MGRTest method testSlaveBroken.

@Test
public void testSlaveBroken() {
    ClusterConfig clusterConfig = CreateClusterHint.createConfig("c0", Arrays.asList("dsw1", "dsw2"), Arrays.asList("dsr1"));
    TimerConfig timerConfig = new TimerConfig();
    timerConfig.setTimeUnit(TimeUnit.SECONDS.name());
    timerConfig.setPeriod(1);
    timerConfig.setInitialDelay(0);
    clusterConfig.setTimer(timerConfig);
    clusterConfig.setClusterType(ReplicaType.MGR.name());
    HashMap<String, DatasourceConfig> map = new HashMap<>();
    map.put("dsw1", CreateDataSourceHint.createConfig("dsw1", DB1));
    map.put("dsw2", CreateDataSourceHint.createConfig("dsw2", DB2));
    map.put("dsr1", CreateDataSourceHint.createConfig("dsr1", DB2));
    LinkedList<Runnable> runnables = new LinkedList<>();
    ReplicaSelectorManager manager = ReplicaSelectorRuntime.create(Arrays.asList(clusterConfig), map, new LoadBalanceManager(), name -> 0, (command, initialDelay, period, unit) -> {
        runnables.add(command);
        return () -> {
        };
    });
    manager.start();
    MetaClusterCurrent.register(Maps.of(ConfigReporter.class, new ConfigReporter() {

        @Override
        public void reportReplica(Map<String, List<String>> state) {
            List<String> c0 = state.get("c0");
            Assert.assertEquals("[dsw2]", c0.toString());
        }
    }));
    manager.putHeartFlow("c0", "dsw1", checkMGR(true));
    manager.putHeartFlow("c0", "dsw2", checkMGR(false));
    manager.putHeartFlow("c0", "dsr1", makeBroken());
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    // 测试已经切换
    Set<String> balanceTargets = new HashSet<>();
    test(() -> {
        balanceTargets.add(manager.getDatasourceNameByReplicaName("c0", false, null));
        return false;
    });
    Assert.assertFalse(balanceTargets.contains("dsr1"));
    Set<String> masterTargets = new HashSet<>();
    test(() -> {
        masterTargets.add(manager.getDatasourceNameByReplicaName("c0", true, null));
        return false;
    });
    Assert.assertEquals(1, masterTargets.size());
    Assert.assertTrue(masterTargets.contains("dsw1"));
    manager.putHeartFlow("c0", "dsr1", checkMGR(false));
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    PhysicsInstance dsr1 = manager.getPhysicsInstanceByName("dsr1");
    Assert.assertTrue(dsr1.asSelectRead());
    Assert.assertTrue(dsr1.isAlive());
}
Also used : TimerConfig(io.mycat.config.TimerConfig) LoadBalanceManager(io.mycat.plug.loadBalance.LoadBalanceManager) DatasourceConfig(io.mycat.config.DatasourceConfig) ConfigReporter(io.mycat.ConfigReporter) ClusterConfig(io.mycat.config.ClusterConfig) Test(org.junit.Test)

Example 5 with DatasourceConfig

use of io.mycat.config.DatasourceConfig in project Mycat2 by MyCATApache.

the class MGRTest method testMasterBroken.

@Test
public void testMasterBroken() {
    ClusterConfig clusterConfig = CreateClusterHint.createConfig("c0", Arrays.asList("dsw1", "dsw2"), Arrays.asList("dsr1"));
    TimerConfig timerConfig = new TimerConfig();
    timerConfig.setTimeUnit(TimeUnit.SECONDS.name());
    timerConfig.setPeriod(1);
    timerConfig.setInitialDelay(0);
    clusterConfig.setTimer(timerConfig);
    clusterConfig.setClusterType(ReplicaType.MGR.name());
    HashMap<String, DatasourceConfig> map = new HashMap<>();
    map.put("dsw1", CreateDataSourceHint.createConfig("dsw1", DB1));
    map.put("dsw2", CreateDataSourceHint.createConfig("dsw2", DB2));
    map.put("dsr1", CreateDataSourceHint.createConfig("dsr1", DB2));
    LinkedList<Runnable> runnables = new LinkedList<>();
    ReplicaSelectorManager manager = ReplicaSelectorRuntime.create(Arrays.asList(clusterConfig), map, new LoadBalanceManager(), name -> 0, (command, initialDelay, period, unit) -> {
        runnables.add(command);
        return () -> {
        };
    });
    manager.start();
    manager.putHeartFlow("c0", "dsw1", makeBroken());
    manager.putHeartFlow("c0", "dsw2", checkMGR(false, 0));
    manager.putHeartFlow("c0", "dsr1", checkMGR(false, 0));
    // 模拟第一主节点无法连接
    MetaClusterCurrent.register(Maps.of(ConfigReporter.class, new ConfigReporter() {

        @Override
        public void reportReplica(Map<String, List<String>> state) {
            List<String> c0 = state.get("c0");
            Assert.assertEquals("[dsw2]", c0.toString());
        }
    }));
    // 三次错误后触发主从切换
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    {
        checkALlRight(manager);
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    {
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    {
        PhysicsInstance dsw1 = manager.getPhysicsInstanceByName("dsw1");
        Assert.assertFalse(dsw1.asSelectRead());
        Assert.assertFalse(dsw1.isAlive());
        PhysicsInstance dsw2 = manager.getPhysicsInstanceByName("dsw2");
        Assert.assertTrue(dsw2.asSelectRead());
        Assert.assertTrue(dsw2.isAlive());
        PhysicsInstance dsr1 = manager.getPhysicsInstanceByName("dsr1");
        Assert.assertTrue(dsr1.asSelectRead());
        Assert.assertTrue(dsr1.isAlive());
    }
    // 触发切换
    manager.putHeartFlow("c0", "dsw2", checkMGR(true, 0));
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    // 测试已经切换
    Set<String> balanceTargets = new HashSet<>();
    test(() -> {
        balanceTargets.add(manager.getDatasourceNameByReplicaName("c0", false, null));
        return false;
    });
    Assert.assertTrue(balanceTargets.size() <= 2);
    Assert.assertFalse(balanceTargets.contains("dsw1"));
    Set<String> masterTargets = new HashSet<>();
    test(() -> {
        masterTargets.add(manager.getDatasourceNameByReplicaName("c0", true, null));
        return false;
    });
    Assert.assertEquals(1, masterTargets.size());
    Assert.assertTrue(masterTargets.contains("dsw2"));
    manager.putHeartFlow("c0", "dsw2", checkMGR(true, 0));
    manager.putHeartFlow("c0", "dsw1", checkMGR(false, 0));
    manager.putHeartFlow("c0", "dsr1", checkMGR(false, 0));
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    checkALlRight(manager);
    // 切换后又发生短暂的连接损坏,因为新建心跳对象导致切换周期重置,这里不测试最小切换周期
    manager.putHeartFlow("c0", "dsw2", makeBroken());
    manager.putHeartFlow("c0", "dsw1", checkMGR(false, 0));
    manager.putHeartFlow("c0", "dsr1", checkMGR(false, 0));
    MetaClusterCurrent.register(Maps.of(ConfigReporter.class, new ConfigReporter() {

        @Override
        public void reportReplica(Map<String, List<String>> state) {
            List<String> c0 = state.get("c0");
            Assert.assertEquals("[dsw1]", c0.toString());
        }
    }));
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    {
        PhysicsInstance dsw1 = manager.getPhysicsInstanceByName("dsw2");
        Assert.assertFalse(dsw1.asSelectRead());
        Assert.assertFalse(dsw1.isAlive());
        PhysicsInstance dsw2 = manager.getPhysicsInstanceByName("dsw1");
        Assert.assertTrue(dsw2.asSelectRead());
        Assert.assertTrue(dsw2.isAlive());
        PhysicsInstance dsr1 = manager.getPhysicsInstanceByName("dsr1");
        Assert.assertTrue(dsr1.asSelectRead());
        Assert.assertTrue(dsr1.isAlive());
    }
    // 测试最小切换周期
    Consumer<HeartBeatStrategy> consumer = new Consumer<HeartBeatStrategy>() {

        int count = 0;

        @Override
        public void accept(HeartBeatStrategy heartBeatStrategy) {
            if (ThreadLocalRandom.current().nextBoolean()) {
                makeBroken().accept(heartBeatStrategy);
            } else {
                checkMasterSlave().accept(heartBeatStrategy);
            }
            count++;
        }
    };
    manager.putHeartFlow("c0", "dsw2", consumer);
    manager.putHeartFlow("c0", "dsw1", consumer);
    manager.putHeartFlow("c0", "dsr1", consumer);
    AtomicInteger switchCounter = new AtomicInteger();
    MetaClusterCurrent.register(Maps.of(ConfigReporter.class, new ConfigReporter() {

        @Override
        public void reportReplica(Map<String, List<String>> state) {
            switchCounter.getAndIncrement();
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
            }
        }
    }));
    for (int i = 0; i < 1000; i++) {
        for (Runnable runnable : runnables) {
            runnable.run();
        }
    }
    Assert.assertTrue(switchCounter.get() < 100);
}
Also used : TimerConfig(io.mycat.config.TimerConfig) LoadBalanceManager(io.mycat.plug.loadBalance.LoadBalanceManager) CreateDataSourceHint(io.mycat.hint.CreateDataSourceHint) CreateClusterHint(io.mycat.hint.CreateClusterHint) MGRHeartBeatStrategy(io.mycat.replica.heartbeat.strategy.MGRHeartBeatStrategy) HeartBeatStrategy(io.mycat.replica.heartbeat.HeartBeatStrategy) DatasourceConfig(io.mycat.config.DatasourceConfig) Consumer(java.util.function.Consumer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConfigReporter(io.mycat.ConfigReporter) ClusterConfig(io.mycat.config.ClusterConfig) Test(org.junit.Test)

Aggregations

DatasourceConfig (io.mycat.config.DatasourceConfig)44 ClusterConfig (io.mycat.config.ClusterConfig)26 LoadBalanceManager (io.mycat.plug.loadBalance.LoadBalanceManager)24 TimerConfig (io.mycat.config.TimerConfig)22 Test (org.junit.Test)22 ConfigReporter (io.mycat.ConfigReporter)16 Consumer (java.util.function.Consumer)8 JdbcConnectionManager (io.mycat.datasource.jdbc.datasource.JdbcConnectionManager)7 CreateClusterHint (io.mycat.hint.CreateClusterHint)6 CreateDataSourceHint (io.mycat.hint.CreateDataSourceHint)6 Connection (java.sql.Connection)6 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)6 SneakyThrows (lombok.SneakyThrows)6 HeartBeatStrategy (io.mycat.replica.heartbeat.HeartBeatStrategy)5 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)5 ConnectionUrlParser (com.mysql.cj.conf.ConnectionUrlParser)3 HostInfo (com.mysql.cj.conf.HostInfo)3 MycatException (io.mycat.MycatException)3 SchemaHandler (io.mycat.calcite.table.SchemaHandler)3 DruidDatasourceProvider (io.mycat.datasource.jdbc.DruidDatasourceProvider)3