// 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 android.app.Application; import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.HttpHostConnectException; import org.apache.http.impl.client.DefaultHttpClient; import org.projectbuendia.client.AppSettings; import org.projectbuendia.client.utils.Logger; import java.io.IOException; import java.net.UnknownHostException; /** A {@link HealthCheck} that checks whether the package server is up and running. */ public class PackageServerHealthCheck extends HealthCheck { private static final Logger LOG = Logger.create(); /** Check for issues with this frequency. */ private static final int CHECK_PERIOD_MS = 20000; private static final String HEALTH_CHECK_ENDPOINT = "/dists/stable/Release"; private final Object mLock = new Object(); private HandlerThread mHandlerThread; private Handler mHandler; private AppSettings mSettings; private final Runnable mHealthCheckRunnable = new Runnable() { @Override public void run() { performCheck(); synchronized (mLock) { if (mHandler != null) { mHandler.postDelayed(this, CHECK_PERIOD_MS); } } } private void performCheck() { Uri uri = Uri.parse(mSettings.getPackageServerUrl(HEALTH_CHECK_ENDPOINT)); HttpClient httpClient = new DefaultHttpClient(); HttpGet getRequest = new HttpGet(uri.toString()); if (getRequest.getURI().getHost() == null) { LOG.w("Configured package server URL is invalid: %s", uri); reportIssue(HealthIssue.SERVER_CONFIGURATION_INVALID); return; } try { HttpResponse response = httpClient.execute(getRequest); switch (response.getStatusLine().getStatusCode()) { case HttpStatus.SC_OK: LOG.d("Package server check completed, OK."); resolveAllIssues(); return; case HttpStatus.SC_NOT_FOUND: LOG.d("Package server check completed, 404."); // The package server is reachable if we get a 404. resolveIssue(HealthIssue.PACKAGE_SERVER_HOST_UNREACHABLE); reportIssue(HealthIssue.PACKAGE_SERVER_INDEX_NOT_FOUND); return; default: LOG.w("Package server check failed for URI %1$s.", uri); } } catch (UnknownHostException | IllegalArgumentException e) { LOG.w("Package server unreachable: %s", uri); reportIssue(HealthIssue.PACKAGE_SERVER_HOST_UNREACHABLE); } catch (HttpHostConnectException e) { LOG.w("Package server connection refused: %s", e.getHost()); } catch (IOException e) { LOG.w(e, "Package server check failed: %s", uri); } } }; PackageServerHealthCheck(Application application, AppSettings settings) { super(application); mSettings = settings; } @Override protected void startImpl() { synchronized (mLock) { if (mHandlerThread == null) { mHandlerThread = new HandlerThread("Buendia Package Server Health Check"); mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mHandler.post(mHealthCheckRunnable); } } } @Override protected void stopImpl() { synchronized (mLock) { if (mHandlerThread != null) { mHandlerThread.quit(); mHandlerThread = null; mHandler = null; } } } }