Java tutorial
// Copyright 2015 The Project Buendia Authors // // Licensed 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 distrib- // uted 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 // specific language governing permissions and limitations under the License. package org.projectbuendia.client.diagnostics; import com.google.common.collect.ImmutableSet; import org.projectbuendia.client.events.diagnostics.TroubleshootingActionsChangedEvent; import org.projectbuendia.client.utils.Logger; import java.util.HashSet; import java.util.Set; import de.greenrobot.event.EventBus; /** * Aggregates reported {@link HealthIssue}s and fires events containing the appropriate * troubleshooting steps. */ public class Troubleshooter { private static final Logger LOG = Logger.create(); private final Object mIssuesLock = new Object(); private final Object mTroubleshootingLock = new Object(); private final EventBus mEventBus; private Set<HealthIssue> mActiveIssues; private TroubleshootingActionsChangedEvent mLastTroubleshootingActionsChangedEvent; public Troubleshooter(EventBus eventBus) { mEventBus = eventBus; mActiveIssues = new HashSet<>(); } /** Returns a set of all currently-active health issues. */ public ImmutableSet<HealthIssue> getActiveIssues() { return ImmutableSet.copyOf(mActiveIssues); } /** * Returns true iff the given issue is current active. * @param issue {@link HealthIssue} to check for */ public boolean hasIssue(HealthIssue issue) { return mActiveIssues.contains(issue); } /** Returns true iff no active issues exist. */ public boolean isHealthy() { return mActiveIssues.isEmpty(); } /** * Returns true if no ongoing issues preventing access to the Buendia server exist. Note that * connectivity is still not guaranteed, just not ruled out. */ public boolean isServerHealthy() { return getNetworkConnectivityTroubleshootingActions().isEmpty() && getConfigurationTroubleshootingActions().isEmpty(); } /** Called when a new health issue is discovered. */ public <T extends HealthIssue> void onDiscovered(T healthIssue) { synchronized (mIssuesLock) { mActiveIssues.add(healthIssue); } // TODO: Consider scheduling this for ~100 milliseconds in the future so as to // prevent multiple troubleshooting events from firing for issues resulting from the same // root cause. postTroubleshootingEvents(); } /** Called when a health issue is resolved. */ public void onResolved(HealthIssue healthIssue) { synchronized (mIssuesLock) { if (!mActiveIssues.remove(healthIssue)) { LOG.w("Attempted to remove health issue '%1$s' that the troubleshooter was not " + "previously aware of.", healthIssue.toString()); } } // TODO: Consider scheduling this for ~100 milliseconds in the future so as to // prevent multiple troubleshooting events from firing for issues resulting from the same // root cause. postTroubleshootingEvents(); } private void postTroubleshootingEvents() { synchronized (mTroubleshootingLock) { ImmutableSet.Builder<TroubleshootingAction> actionsBuilder = ImmutableSet.builder(); actionsBuilder.addAll(getNetworkConnectivityTroubleshootingActions()); actionsBuilder.addAll(getConfigurationTroubleshootingActions()); actionsBuilder.addAll(getUpdateServerTroubleshootingActions()); ImmutableSet<TroubleshootingAction> actions = actionsBuilder.build(); if (mLastTroubleshootingActionsChangedEvent != null) { // If nothing's changed since the last time we checked, don't post a new event. if (mLastTroubleshootingActionsChangedEvent.actions.equals(actions)) { return; } mEventBus.removeStickyEvent(mLastTroubleshootingActionsChangedEvent); } mLastTroubleshootingActionsChangedEvent = new TroubleshootingActionsChangedEvent(actions); mEventBus.postSticky(mLastTroubleshootingActionsChangedEvent); } } private Set<TroubleshootingAction> getNetworkConnectivityTroubleshootingActions() { Set<TroubleshootingAction> actions = new HashSet<>(); if (mActiveIssues.contains(HealthIssue.WIFI_DISABLED)) { actions.add(TroubleshootingAction.ENABLE_WIFI); } else if (mActiveIssues.contains(HealthIssue.WIFI_NOT_CONNECTED)) { actions.add(TroubleshootingAction.CONNECT_WIFI); } else if (mActiveIssues.contains(HealthIssue.SERVER_HOST_UNREACHABLE)) { actions.add(TroubleshootingAction.CHECK_SERVER_REACHABILITY); } else if (mActiveIssues.contains(HealthIssue.SERVER_INTERNAL_ISSUE)) { actions.add(TroubleshootingAction.CHECK_SERVER_SETUP); } else if (mActiveIssues.contains(HealthIssue.SERVER_NOT_RESPONDING)) { actions.add(TroubleshootingAction.CHECK_SERVER_STATUS); } return actions; } private Set<TroubleshootingAction> getConfigurationTroubleshootingActions() { Set<TroubleshootingAction> actions = new HashSet<>(); if (mActiveIssues.contains(HealthIssue.SERVER_CONFIGURATION_INVALID)) { actions.add(TroubleshootingAction.CHECK_SERVER_CONFIGURATION); } else if (mActiveIssues.contains(HealthIssue.SERVER_AUTHENTICATION_ISSUE)) { actions.add(TroubleshootingAction.CHECK_SERVER_AUTH); } return actions; } private Set<TroubleshootingAction> getUpdateServerTroubleshootingActions() { Set<TroubleshootingAction> actions = new HashSet<>(); if (mActiveIssues.contains(HealthIssue.UPDATE_SERVER_HOST_UNREACHABLE)) { actions.add(TroubleshootingAction.CHECK_UPDATE_SERVER_REACHABILITY); } else if (mActiveIssues.contains(HealthIssue.UPDATE_SERVER_INDEX_NOT_FOUND)) { actions.add(TroubleshootingAction.CHECK_UPDATE_SERVER_CONFIGURATION); } return actions; } }