blob: 1189e9a5e1fb6150483cb63839dd981c101f2949 [file] [log] [blame]
// 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.cloudstack.ha;
import com.cloud.api.response.SimulatorHAStateResponse;
import com.cloud.host.Host;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.utils.fsm.StateListener;
import com.cloud.utils.fsm.StateMachine2;
import org.apache.cloudstack.ha.provider.HACheckerException;
import org.apache.cloudstack.ha.provider.HAFenceException;
import org.apache.cloudstack.ha.provider.HAProvider;
import org.apache.cloudstack.ha.provider.HARecoveryException;
import org.apache.cloudstack.ha.provider.host.HAAbstractHostProvider;
import org.joda.time.DateTime;
import javax.inject.Inject;
import java.security.InvalidParameterException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class SimulatorHAProvider extends HAAbstractHostProvider implements HAProvider<Host>, StateListener<HAConfig.HAState, HAConfig.Event, HAConfig> {
@Inject
private HAManager haManager;
private final Map<Long, SimulatorHAState> hostHAStateMap = new ConcurrentHashMap<>();
public SimulatorHAProvider() {
HAConfig.HAState.getStateMachine().registerListener(this);
}
public void setHAStateForHost(final Long hostId, final SimulatorHAState state) {
hostHAStateMap.put(hostId, state);
haManager.purgeHACounter(hostId, HAResource.ResourceType.Host);
}
public List<SimulatorHAStateResponse> listHAStateTransitions(final Long hostId) {
final SimulatorHAState haState = hostHAStateMap.get(hostId);
if (haState == null) {
return Collections.emptyList();
}
return haState.listRecentStateTransitions();
}
@Override
public HAResource.ResourceType resourceType() {
return HAResource.ResourceType.Host;
}
@Override
public HAResource.ResourceSubType resourceSubType() {
return HAResource.ResourceSubType.Simulator;
}
@Override
public boolean isEligible(final Host host) {
if (host == null) {
return false;
}
final SimulatorHAState haState = hostHAStateMap.get(host.getId());
return !isInMaintenanceMode(host) && !isDisabled(host) && haState != null
&& Hypervisor.HypervisorType.Simulator.equals(host.getHypervisorType());
}
@Override
public boolean isHealthy(final Host host) throws HACheckerException {
final SimulatorHAState haState = hostHAStateMap.get(host.getId());
return haState != null && haState.isHealthy();
}
@Override
public boolean hasActivity(final Host host, final DateTime afterThis) throws HACheckerException {
final SimulatorHAState haState = hostHAStateMap.get(host.getId());
return haState != null && haState.hasActivity();
}
@Override
public boolean recover(final Host host) throws HARecoveryException {
final SimulatorHAState haState = hostHAStateMap.get(host.getId());
return haState != null && haState.canRecover();
}
@Override
public boolean fence(final Host host) throws HAFenceException {
final SimulatorHAState haState = hostHAStateMap.get(host.getId());
return haState != null && haState.canFenced();
}
@Override
public Object getConfigValue(final HAProvider.HAProviderConfig name, final Host host) {
switch (name) {
case HealthCheckTimeout:
return 5L;
case ActivityCheckTimeout:
return 5L;
case RecoveryTimeout:
return 5L;
case FenceTimeout:
return 5L;
case MaxActivityCheckInterval:
return 1L;
case MaxActivityChecks:
return 3L;
case ActivityCheckFailureRatio:
final SimulatorHAState haState = hostHAStateMap.get(host.getId());
return (haState != null && haState.hasActivity()) ? 1.0 : 0.0;
case MaxDegradedWaitTimeout:
return 1L;
case MaxRecoveryAttempts:
return 2L;
case RecoveryWaitTimeout:
return 1L;
default:
throw new InvalidParameterException("Unknown HAProviderConfig " + name.toString());
}
}
private boolean addStateTransition(final HAConfig vo, final boolean status,
final HAConfig.HAState oldState, final HAConfig.HAState newState, final HAConfig.Event event) {
if (vo.getResourceType() != HAResource.ResourceType.Host) {
return false;
}
final SimulatorHAState haState = hostHAStateMap.get(vo.getResourceId());
if (haState == null || !status) {
return false;
}
final HAResourceCounter counter = haManager.getHACounter(vo.getResourceId(), vo.getResourceType());
return haState.addStateTransition(newState, oldState, event, counter);
}
@Override
public boolean preStateTransitionEvent(final HAConfig.HAState oldState, final HAConfig.Event event,
final HAConfig.HAState newState, final HAConfig vo, final boolean status, final Object opaque) {
return addStateTransition(vo, status, oldState, newState, event);
}
@Override
public boolean postStateTransitionEvent(final StateMachine2.Transition<HAConfig.HAState, HAConfig.Event> transition,
final HAConfig vo, final boolean status, final Object opaque) {
return addStateTransition(vo, status, transition.getCurrentState(), transition.getToState(), transition.getEvent());
}
}