/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.shardingsphere.proxy.frontend.state.impl;

import io.netty.channel.ChannelHandlerContext;
import org.apache.shardingsphere.db.protocol.packet.DatabasePacket;
import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
import org.apache.shardingsphere.proxy.backend.exception.CircuitBreakException;
import org.apache.shardingsphere.proxy.frontend.spi.DatabaseProtocolFrontendEngine;
import org.apache.shardingsphere.proxy.frontend.state.ProxyState;

import java.util.Optional;

/**
 * Circuit break proxy state.
 */
public final class CircuitBreakProxyState implements ProxyState {
    
    @Override
    public void execute(final ChannelHandlerContext context, final Object message, final DatabaseProtocolFrontendEngine databaseProtocolFrontendEngine, final BackendConnection backendConnection) {
        context.writeAndFlush(databaseProtocolFrontendEngine.getCommandExecuteEngine().getErrorPacket(new CircuitBreakException()));
        Optional<DatabasePacket<?>> databasePacket = databaseProtocolFrontendEngine.getCommandExecuteEngine().getOtherPacket();
        databasePacket.ifPresent(context::writeAndFlush);
    }
}

@@ -858,16 +858,61 @@
 .impl;%0A%0A
+import com.google.common.eventbus.Subscribe;%0A
 import i
@@ -1018,16 +1018,181 @@
 Packet;%0A
+import org.apache.shardingsphere.governance.core.event.GovernanceEventBus;%0Aimport org.apache.shardingsphere.governance.core.registry.event.CircuitStateChangedEvent;%0A
 import o
@@ -1508,16 +1508,159 @@
 xyState;
+%0Aimport org.apache.shardingsphere.proxy.frontend.state.ProxyStateMachine;%0Aimport org.apache.shardingsphere.proxy.frontend.state.ProxyStateType;
 %0A%0Aimport
@@ -1790,16 +1790,122 @@
  %7B%0A    %0A
+    public CircuitBreakProxyState() %7B%0A        GovernanceEventBus.getInstance().register(this);%0A    %7D%0A    %0A
     @Ove
@@ -2432,10 +2432,471 @@
 ;%0A    %7D%0A
+    %0A    /**%0A     * Renew circuit breaker state.%0A     *%0A     * @param event circuit state changed event%0A     */%0A    @Subscribe%0A    public synchronized void renew(final CircuitStateChangedEvent event) %7B%0A        if (event.isCircuitBreak()) %7B%0A            ProxyStateMachine.switchState(ProxyStateType.CIRCUIT_BREAK);%0A        %7D else %7B%0A            // TODO check previous state, maybe lock%0A            ProxyStateMachine.switchState(ProxyStateType.OK);%0A        %7D%0A    %7D%0A
 %7D%0A

Integrate circuit break state switch with proxy