/* This file is part of ZAX. ZAX is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ZAX is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with ZAX. If not, see <http://www.gnu.org/licenses/>. */ package com.inovex.zabbixmobile.data; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.os.AsyncTask; import android.os.Binder; import android.os.IBinder; import android.util.Log; import android.view.LayoutInflater; import com.inovex.zabbixmobile.activities.BaseSeverityFilterActivity; import com.inovex.zabbixmobile.activities.ChecksActivity; import com.inovex.zabbixmobile.activities.fragments.ChecksHostsFragment; import com.inovex.zabbixmobile.activities.fragments.EventsDetailsFragment; import com.inovex.zabbixmobile.activities.fragments.EventsListPage; import com.inovex.zabbixmobile.activities.fragments.ProblemsDetailsFragment; import com.inovex.zabbixmobile.activities.fragments.ProblemsListPage; import com.inovex.zabbixmobile.activities.fragments.ScreensListFragment; import com.inovex.zabbixmobile.adapters.BaseServiceAdapter; import com.inovex.zabbixmobile.adapters.BaseServicePagerAdapter; import com.inovex.zabbixmobile.adapters.BaseSeverityListPagerAdapter; import com.inovex.zabbixmobile.adapters.BaseSeverityPagerAdapter; import com.inovex.zabbixmobile.adapters.ChecksApplicationsPagerAdapter; import com.inovex.zabbixmobile.adapters.ChecksItemsListAdapter; import com.inovex.zabbixmobile.adapters.EventsDetailsPagerAdapter; import com.inovex.zabbixmobile.adapters.EventsListAdapter; import com.inovex.zabbixmobile.adapters.EventsListPagerAdapter; import com.inovex.zabbixmobile.adapters.HostGroupsSpinnerAdapter; import com.inovex.zabbixmobile.adapters.HostsListAdapter; import com.inovex.zabbixmobile.adapters.ProblemsDetailsPagerAdapter; import com.inovex.zabbixmobile.adapters.ProblemsListAdapter; import com.inovex.zabbixmobile.adapters.ProblemsListPagerAdapter; import com.inovex.zabbixmobile.adapters.ScreensListAdapter; import com.inovex.zabbixmobile.adapters.ServersListManagementAdapter; import com.inovex.zabbixmobile.adapters.ServersListSelectionAdapter; import com.inovex.zabbixmobile.exceptions.FatalException; import com.inovex.zabbixmobile.exceptions.ZabbixLoginRequiredException; import com.inovex.zabbixmobile.listeners.OnAcknowledgeEventListener; import com.inovex.zabbixmobile.listeners.OnApplicationsLoadedListener; import com.inovex.zabbixmobile.listeners.OnGraphDataLoadedListener; import com.inovex.zabbixmobile.listeners.OnGraphsLoadedListener; import com.inovex.zabbixmobile.listeners.OnHostsLoadedListener; import com.inovex.zabbixmobile.listeners.OnItemsLoadedListener; import com.inovex.zabbixmobile.listeners.OnScreensLoadedListener; import com.inovex.zabbixmobile.listeners.OnSeverityListAdapterLoadedListener; import com.inovex.zabbixmobile.model.Application; import com.inovex.zabbixmobile.model.Event; import com.inovex.zabbixmobile.model.Graph; import com.inovex.zabbixmobile.model.GraphItem; import com.inovex.zabbixmobile.model.HistoryDetail; import com.inovex.zabbixmobile.model.Host; import com.inovex.zabbixmobile.model.HostGroup; import com.inovex.zabbixmobile.model.Item; import com.inovex.zabbixmobile.model.Screen; import com.inovex.zabbixmobile.model.Trigger; import com.inovex.zabbixmobile.model.TriggerSeverity; import com.inovex.zabbixmobile.model.ZabbixServer; import com.inovex.zabbixmobile.model.ZaxPreferences; import com.j256.ormlite.android.apptools.OpenHelperManager; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * Bound service maintaining the connection with the Zabbix API as well as the * local SQLite database. It provides an interface to the data no matter where * it is stored, * * This class also contains all adapters used for the various views throughout * the app. These are initialized when the service is created. * */ public class ZabbixDataService extends Service { public interface OnLoginProgressListener { public void onLoginStarted(); public void onLoginFinished(boolean success, boolean showToast); } private static final String TAG = ZabbixDataService.class.getSimpleName(); public static final String EXTRA_IS_TESTING = "is_testing"; boolean mIsTesting = false; // Binder given to clients private final IBinder mBinder = new ZabbixDataBinder(); private DatabaseHelper mDatabaseHelper; private HostGroupsSpinnerAdapter mHostGroupsSpinnerAdapter; /** * Adapters maintained by {@link ZabbixDataService}. */ // Servers private ServersListSelectionAdapter mServersListSelectionAdapter; private ServersListManagementAdapter mServersListManagementAdapter; // Events private EventsListPagerAdapter mEventsListPagerAdapter; private HashMap<TriggerSeverity, EventsListAdapter> mEventsListAdapters; private HashMap<TriggerSeverity, EventsDetailsPagerAdapter> mEventsDetailsPagerAdapters; // Problems private ProblemsListPagerAdapter mProblemsListPagerAdapter; private ProblemsListAdapter mProblemsMainListAdapter; private HashMap<TriggerSeverity, ProblemsListAdapter> mProblemsListAdapters; private HashMap<TriggerSeverity, ProblemsDetailsPagerAdapter> mProblemsDetailsPagerAdapters; // Checks private HostsListAdapter mHostsListAdapter; private ChecksApplicationsPagerAdapter mChecksApplicationsPagerAdapter; private HashMap<String, ChecksItemsListAdapter> mChecksItemsListAdapters; // Screens private ScreensListAdapter mScreensListAdapter; // API-Tasks private Set<RemoteAPITask> mCurrentLoadHistoryDetailsTasks; private RemoteAPITask mCurrentLoadEventsTask; private RemoteAPITask mCurrentLoadProblemsTask; private RemoteAPITask mCurrentLoadApplicationsTask; private RemoteAPITask mCurrentLoadItemsTask; private RemoteAPITask mCurrentLoadGraphsTask; private Context mActivityContext; private LayoutInflater mInflater; private ZabbixRemoteAPI mRemoteAPI; private Map<Long,ZabbixRemoteAPI> zabbixAPIs = new HashMap<>(); private int mBindings = 0; private long mCurrentZabbixServerId; private ZaxPreferences mPreferences; /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ public class ZabbixDataBinder extends Binder { public ZabbixDataService getService() { // Return this service instance so clients can call public methods return ZabbixDataService.this; } } public boolean isLoggedIn() { return mRemoteAPI.isLoggedIn(); } /** * Clears all data in the database and in the adapters. */ public void clearAllData(){ this.clearAllData(true); } public void clearAllData(boolean logout) { Log.d(TAG, "clearing all data"); mDatabaseHelper.clearAllData(); mPreferences.refresh(getApplicationContext()); mCurrentZabbixServerId = mPreferences.getServerSelection(); Log.d(TAG, "mCurrentZabbixServerId="+mCurrentZabbixServerId); // clear adapters ArrayList<BaseServiceAdapter<?>> listAdapters = new ArrayList<BaseServiceAdapter<?>>(); listAdapters.add(mHostGroupsSpinnerAdapter); listAdapters.addAll(mEventsListAdapters.values()); listAdapters.addAll(mProblemsListAdapters.values()); listAdapters.add(mProblemsMainListAdapter); listAdapters.add(mHostsListAdapter); listAdapters.addAll(mChecksItemsListAdapters.values()); listAdapters.add(mScreensListAdapter); for (BaseServiceAdapter<?> adapter : listAdapters) { adapter.clear(); adapter.notifyDataSetChanged(); } ArrayList<BaseServicePagerAdapter<?>> pagerAdapters = new ArrayList<BaseServicePagerAdapter<?>>(); pagerAdapters.addAll(mEventsDetailsPagerAdapters.values()); pagerAdapters.addAll(mProblemsDetailsPagerAdapters.values()); pagerAdapters.add(mChecksApplicationsPagerAdapter); for (BaseServicePagerAdapter<?> adapter : pagerAdapters) { adapter.clear(); adapter.notifyDataSetChanged(); } if(logout){ mRemoteAPI.logout(); zabbixAPIs.remove(mRemoteAPI); mRemoteAPI = new ZabbixRemoteAPI(this.getApplicationContext(), mDatabaseHelper, mCurrentZabbixServerId, null); zabbixAPIs.put(mRemoteAPI.getZabbixSeverId(),mRemoteAPI); } } public ZabbixServer getServerById(long id){ return mDatabaseHelper.getZabbixServerById(id); } /** * Returns the Zabbix server list adapter for the server management * activity. * * @return list adapter */ public BaseServiceAdapter<ZabbixServer> getServersListManagementAdapter() { return mServersListManagementAdapter; } /** * Returns the Zabbix server selection list adapter for the drawer fragment. * * @return list adapter */ public BaseServiceAdapter<ZabbixServer> getServersSelectionAdapter() { return mServersListSelectionAdapter; } /** * Returns the event list pager adapter. * * @return list pager adapter */ public BaseSeverityListPagerAdapter<Event> getEventsListPagerAdapter() { return mEventsListPagerAdapter; } /** * Returns an event list adapter. * * See {@link EventsListPage}. * * @param severity * severity of the adapter * @return list adapter */ public BaseServiceAdapter<Event> getEventsListAdapter( TriggerSeverity severity) { return mEventsListAdapters.get(severity); } /** * Returns an event details adapter to be used by the view pager. * * See {@link EventsDetailsFragment}. * * @param severity * severity of the adapter * @return details pager adapter */ public BaseSeverityPagerAdapter<Event> getEventsDetailsPagerAdapter( TriggerSeverity severity) { return mEventsDetailsPagerAdapters.get(severity); } /** * Returns the adapter for the host group spinner. * * See {@link BaseSeverityFilterActivity}, {@link ChecksActivity}. * * @return spinner adapter */ public HostGroupsSpinnerAdapter getHostGroupSpinnerAdapter() { return mHostGroupsSpinnerAdapter; } /** * Returns the problems list pager adapter. * * @return list pager adapter */ public BaseSeverityListPagerAdapter<Trigger> getProblemsListPagerAdapter() { return mProblemsListPagerAdapter; } /** * Returns the problems list adapter for the main view. This adapter * contains all active problems regardless of severity and hostgroup. * * @return list adapter */ public BaseServiceAdapter<Trigger> getProblemsMainListAdapter() { return mProblemsMainListAdapter; } /** * Returns a problems list adapter. * * See {@link ProblemsListPage}. * * @param severity * severity of the adapter * @return list adapter */ public BaseServiceAdapter<Trigger> getProblemsListAdapter( TriggerSeverity severity) { return mProblemsListAdapters.get(severity); } /** * Returns a problems details adapter to be used by the view pager. * * See {@link ProblemsDetailsFragment}. * * @param severity * severity of the adapter * @return details pager adapter */ public BaseSeverityPagerAdapter<Trigger> getProblemsDetailsPagerAdapter( TriggerSeverity severity) { return mProblemsDetailsPagerAdapters.get(severity); } /** * Returns a host list adapter. * * See {@link ChecksHostsFragment}. * * @return host list adapter */ public HostsListAdapter getHostsListAdapter() { return mHostsListAdapter; } /** * Returns the screens list adapter. * * See {@link ScreensListFragment}. * * @return screens list adapter */ public ScreensListAdapter getScreensListAdapter() { return mScreensListAdapter; } /** * Returns the application adapter. * * @return */ public ChecksApplicationsPagerAdapter getChecksApplicationsPagerAdapter() { return mChecksApplicationsPagerAdapter; } /** * Returns the application items list adapter. * * @return */ public ChecksItemsListAdapter getChecksItemsListAdapter(long applicationID) { return mChecksItemsListAdapters.get(mDatabaseHelper.getApplicationById(applicationID).toString()); } /** * Retrieves the host with the given ID from the database. * * @param hostId * @return */ public Host getHostById(long hostId) { return mDatabaseHelper.getHostById(hostId); } /** * Retrieves the item with the given ID from the database. No remote api * call * * @param itemId * @return */ public Item getItemById(long itemId) { return mDatabaseHelper.getItemById(itemId); } /** * Retrieves the event with the given ID from the database. * * @param eventId * @return */ public Event getEventById(long eventId) { return mDatabaseHelper.getEventById(eventId); } /** * Retrieves the trigger with the given ID from the database. * * @param triggerId * @return */ public Trigger getTriggerById(long triggerId) { return mDatabaseHelper.getTriggerById(triggerId); } @Override public IBinder onBind(Intent intent) { mBindings++; Log.d(TAG, "onBind: " + mBindings); Log.d(TAG, "Binder " + this.toString() + ": intent " + intent.toString() + " bound."); if (intent.getBooleanExtra(EXTRA_IS_TESTING, false)) { mIsTesting = true; } if (!mIsTesting) { onBind(null, null); } return mBinder; } public void onBind(DatabaseHelper databasehelperMock, ZabbixRemoteAPI remoteAPIMock) { if (mDatabaseHelper == null) { // set up SQLite connection using OrmLite if (databasehelperMock != null) { mDatabaseHelper = databasehelperMock; } else { mDatabaseHelper = OpenHelperManager.getHelper(this, DatabaseHelper.class); // recreate database // mDatabaseHelper.onUpgrade( // mDatabaseHelper.getWritableDatabase(), 0, 1); } Log.d(TAG, "onCreate"); } if (mRemoteAPI == null) { if (remoteAPIMock != null) { mRemoteAPI = remoteAPIMock; } else { // in case there was a preferences migration mPreferences.refresh(getApplicationContext()); mCurrentZabbixServerId = mPreferences.getServerSelection(); mRemoteAPI = new ZabbixRemoteAPI(this.getApplicationContext(), mDatabaseHelper, mCurrentZabbixServerId, null); zabbixAPIs.put(mRemoteAPI.getZabbixSeverId(),mRemoteAPI); } } } /** * Performs the Zabbix login using the server address and credentials from * the preferences. Login is only performed if the user Additionally, this * method loads the host groups and fills the corresponding adapter because * host groups are used at so many spots in the program, so they should be * available all the time. * * @param listener * listener to be informed about start and end of the login * process * */ public void performZabbixLogin(final OnLoginProgressListener listener) { final boolean loginNecessary = !mRemoteAPI.isLoggedIn(); if (loginNecessary && listener != null) listener.onLoginStarted(); // authenticate RemoteAPITask loginTask = new RemoteAPITask(mRemoteAPI,this) { private boolean success = false; private List<HostGroup> hostGroups; private final BaseServiceAdapter<HostGroup> groupsAdapter = mHostGroupsSpinnerAdapter; @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { if (loginNecessary) mRemoteAPI.authenticate(); success = true; hostGroups = new ArrayList<HostGroup>(); try { mRemoteAPI.importHostsAndGroups(); // even if the api call is not successful, we can still use // the cached events } finally { hostGroups = mDatabaseHelper.getHostGroups(mCurrentZabbixServerId); } } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); if (groupsAdapter != null && hostGroups != null) { // adapter.clear(); groupsAdapter.addAll(hostGroups); groupsAdapter.notifyDataSetChanged(); } if (listener != null) listener.onLoginFinished(success, loginNecessary); } }; loginTask.execute(); } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate"); mPreferences = ZaxPreferences.getInstance(getApplicationContext()); mCurrentZabbixServerId = mPreferences.getServerSelection(); // set up adapters mServersListSelectionAdapter = new ServersListSelectionAdapter(this); mServersListManagementAdapter = new ServersListManagementAdapter(this); mEventsListPagerAdapter = new EventsListPagerAdapter(this); mEventsListAdapters = new HashMap<TriggerSeverity, EventsListAdapter>( TriggerSeverity.values().length); mEventsDetailsPagerAdapters = new HashMap<TriggerSeverity, EventsDetailsPagerAdapter>( TriggerSeverity.values().length); for (TriggerSeverity s : TriggerSeverity.values()) { mEventsListAdapters.put(s, new EventsListAdapter(this)); mEventsDetailsPagerAdapters .put(s, new EventsDetailsPagerAdapter(s)); } mProblemsListPagerAdapter = new ProblemsListPagerAdapter(this); mProblemsListAdapters = new HashMap<TriggerSeverity, ProblemsListAdapter>( TriggerSeverity.values().length); mProblemsMainListAdapter = new ProblemsListAdapter(this); mProblemsDetailsPagerAdapters = new HashMap<TriggerSeverity, ProblemsDetailsPagerAdapter>( TriggerSeverity.values().length); for (TriggerSeverity s : TriggerSeverity.values()) { mProblemsListAdapters.put(s, new ProblemsListAdapter(this)); mProblemsDetailsPagerAdapters.put(s, new ProblemsDetailsPagerAdapter(s)); } mHostGroupsSpinnerAdapter = new HostGroupsSpinnerAdapter(this); mHostsListAdapter = new HostsListAdapter(this); mChecksApplicationsPagerAdapter = new ChecksApplicationsPagerAdapter(); mChecksItemsListAdapters = new HashMap<String,ChecksItemsListAdapter>(); mScreensListAdapter = new ScreensListAdapter(this); mCurrentLoadHistoryDetailsTasks = new HashSet<RemoteAPITask>(); } /** * Loads all events with a given severity and host group from the database * asynchronously. After loading the events, the corresponding adapters are * updated. If necessary, an import from the Zabbix API is triggered. * * @param hostGroupId * host group id by which the events will be filtered * @param hostGroupChanged * whether the host group has changed. If this is true, the * adapters will be cleared before being filled with entries * matching the selected host group. * @param callback * listener to be called when the adapters have been updated */ public void loadEventsByHostGroup(final long hostGroupId, final boolean hostGroupChanged, final OnSeverityListAdapterLoadedListener callback) { cancelTask(mCurrentLoadEventsTask); mCurrentLoadEventsTask = new RemoteAPITask(mRemoteAPI,this) { private Map<TriggerSeverity, List<Event>> events; @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { events = new HashMap<TriggerSeverity, List<Event>>(); try { mRemoteAPI.importEvents(this); } finally { // even if the api call is not successful, we can still use // the cached events for (TriggerSeverity severity : TriggerSeverity.values()) { events.put(severity, mDatabaseHelper .getEventsBySeverityAndHostGroupId(severity, hostGroupId)); } } } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); for (TriggerSeverity severity : TriggerSeverity.values()) { BaseServiceAdapter<Event> listAdapter = mEventsListAdapters .get(severity); BaseSeverityPagerAdapter<Event> detailsAdapter = mEventsDetailsPagerAdapters .get(severity); if (listAdapter != null) { if (hostGroupChanged) listAdapter.clear(); listAdapter.addAll(events.get(severity)); listAdapter.notifyDataSetChanged(); } if (detailsAdapter != null) { if (hostGroupChanged) detailsAdapter.clear(); detailsAdapter.addAll(events.get(severity)); detailsAdapter.notifyDataSetChanged(); } if (callback != null) callback.onSeverityListAdapterLoaded(severity, hostGroupChanged); } } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); if (callback != null) callback.onSeverityListAdapterProgressUpdate(values[0]); } }; mCurrentLoadEventsTask.execute(); } /** * Loads all triggers with a given severity and host group from the database * asynchronously. After loading the events, the corresponding adapters are * updated. If necessary, an import from the Zabbix API is triggered. * * @param hostGroupId * host group id by which the events will be filtered * @param hostGroupChanged * whether the host group has changed. If this is true, the * adapters will be cleared before being filled with entries * matching the selected host group. * @param callback * listener to be called when the adapters have been updated */ public void loadProblemsByHostGroup(final long hostGroupId, final boolean hostGroupChanged, final OnSeverityListAdapterLoadedListener callback) { cancelTask(mCurrentLoadProblemsTask); mCurrentLoadProblemsTask = new RemoteAPITask(mRemoteAPI,this) { private Map<TriggerSeverity, List<Trigger>> triggers; @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { triggers = new HashMap<TriggerSeverity, List<Trigger>>(); try { mRemoteAPI.importActiveTriggers(this); // even if the api call is not successful, we can still use // the cached events } finally { for (TriggerSeverity severity : TriggerSeverity.values()) { triggers.put(severity, mDatabaseHelper .getProblemsBySeverityAndHostGroupId(severity, hostGroupId)); } } } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); for (TriggerSeverity severity : TriggerSeverity.values()) { BaseServiceAdapter<Trigger> adapter = mProblemsListAdapters .get(severity); BaseServiceAdapter<Trigger> mainAdapter = mProblemsMainListAdapter; BaseSeverityPagerAdapter<Trigger> detailsAdapter = mProblemsDetailsPagerAdapters .get(severity); if (mainAdapter != null && severity == TriggerSeverity.ALL && hostGroupId == HostGroup.GROUP_ID_ALL) { mainAdapter.addAll(triggers.get(severity)); mainAdapter.notifyDataSetChanged(); } if (adapter != null) { if (hostGroupChanged) adapter.clear(); adapter.addAll(triggers.get(severity)); adapter.notifyDataSetChanged(); } if (detailsAdapter != null) { if (hostGroupChanged) detailsAdapter.clear(); detailsAdapter.addAll(triggers.get(severity)); detailsAdapter.notifyDataSetChanged(); } if (callback != null) callback.onSeverityListAdapterLoaded(severity, hostGroupChanged); } } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); if (callback != null) callback.onSeverityListAdapterProgressUpdate(values[0]); } }; mCurrentLoadProblemsTask.execute(); } /** * Loads all hosts with a given host group from the database asynchronously. * After loading the hosts, the host list adapter is updated. If necessary, * an import from the Zabbix API is triggered. * * Additionally, this method initializes * {@link ChecksApplicationsPagerAdapter}s (one for each host) if necessary. * * @param hostGroupId * host group id by which the events will be filtered * @param hostGroupChanged * whether the host group has changed. If this is true, the * adapter will be cleared before being filled with entries * matching the selected host group. * @param callback * listener to be called when the adapter has been updated */ public void loadHostsByHostGroup(final long hostGroupId, final boolean hostGroupChanged, final OnHostsLoadedListener callback) { new RemoteAPITask(mRemoteAPI,this) { private List<Host> hosts; private final BaseServiceAdapter<Host> hostsAdapter = mHostsListAdapter; @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { hosts = new ArrayList<Host>(); try { mRemoteAPI.importHostsAndGroups(); // even if the api call is not successful, we can still use // the cached events } finally { hosts = mDatabaseHelper.getHostsByHostGroup(hostGroupId); } } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); if (hostsAdapter != null) { if (hostGroupChanged) hostsAdapter.clear(); hostsAdapter.addAll(hosts); hostsAdapter.notifyDataSetChanged(); } if (callback != null) callback.onHostsLoaded(); Log.d(TAG, "Hosts imported."); } }.execute(); } /** * Loads all hosts and host groups from the database asynchronously. After * loading, the host groups spinner adapter is updated. If necessary, an * import from the Zabbix API is triggered. * */ public void loadHostsAndHostGroups() { new RemoteAPITask(mRemoteAPI,this) { private List<HostGroup> hostGroups; private final BaseServiceAdapter<HostGroup> hostGroupsAdapter = mHostGroupsSpinnerAdapter; @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { hostGroups = new ArrayList<HostGroup>(); try { mRemoteAPI.importHostsAndGroups(); // even if the api call is not successful, we can still use // the cached events } finally { hostGroups = mDatabaseHelper.getHostGroups(mCurrentZabbixServerId); } } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); if (hostGroupsAdapter != null) { hostGroupsAdapter.clear(); hostGroupsAdapter.addAll(hostGroups); hostGroupsAdapter.notifyDataSetChanged(); } Log.d(TAG, "Hosts and host groups imported."); } }.execute(); } /** * Loads all applications with a given host group from the database * asynchronously. After loading the applications, the corresponding * adapters are updated. If necessary, an import from the Zabbix API is * triggered. * * Attention: This call needs to take care of loading all items inside the * applications as well. Otherwise they will not be available when * {@link ZabbixDataService#loadItemsByApplicationId(long, OnItemsLoadedListener)} * is called. * * @param hostId * host id * @param callback * Callback needed to trigger a redraw the view pager indicator * @param resetSelection * flag indicating if the application selection shall be reset * when the data is loaded */ public void loadApplicationsByHostId(final long hostId, final OnApplicationsLoadedListener callback, final boolean resetSelection) { cancelTask(mCurrentLoadApplicationsTask); mCurrentLoadApplicationsTask = new RemoteAPITask(mRemoteAPI,this) { List<Application> applications; @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { try { // We only import applications with corresponding hosts // (this way templates are ignored) mRemoteAPI.importApplicationsByHostId(hostId, this); mRemoteAPI.importItemsByHostId(hostId, this); } finally { applications = mDatabaseHelper .getApplicationsByHostId(hostId); } } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); // fill adapter if (mChecksApplicationsPagerAdapter != null) { mChecksApplicationsPagerAdapter.clear(); mChecksApplicationsPagerAdapter.addAll(applications); mChecksApplicationsPagerAdapter.notifyDataSetChanged(); if (callback != null) callback.onApplicationsLoaded(resetSelection); } } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); if(values[0] % 10 == 0){ Log.d(TAG, "progress: " + values[0]); } if (callback != null) callback.onApplicationsProgressUpdate(values[0]); } }; mCurrentLoadApplicationsTask.execute(); } /** * Loads all items in a given application from the database asynchronously. * After loading the items, the corresponding adapters are updated. An * import from Zabbix is not necessary, because the items have already been * loaded together with the applications. * */ public void loadItemsByApplicationId(final long applicationId, final OnItemsLoadedListener callback) { // cancelTask(mCurrentLoadItemsTask); mCurrentLoadItemsTask = new RemoteAPITask(mRemoteAPI,this) { List<Item> items; Application application; // @Override // protected void onPreExecute() { // super.onPreExecute(); // clear adapters first to avoid display of old items // if (mChecksItemsListAdapters != null) { // mChecksItemsListAdapters.clear(); // mChecksItemsListAdapters.notifyDataSetChanged(); // } // } @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { items = mDatabaseHelper.getItemsByApplicationId(applicationId); application = mDatabaseHelper.getApplicationById(applicationId); } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); // fill adapters if(application != null){ ChecksItemsListAdapter checksItemsListAdapter = mChecksItemsListAdapters.get(application); if (checksItemsListAdapter == null){ checksItemsListAdapter = new ChecksItemsListAdapter(ZabbixDataService.this); } checksItemsListAdapter.clear(); checksItemsListAdapter.addAll(items); checksItemsListAdapter.notifyDataSetChanged(); mChecksItemsListAdapters.put(application.toString(), checksItemsListAdapter); if (callback != null) { callback.onItemsLoaded(); } } } }; mCurrentLoadItemsTask.execute(); } public void loadZabbixServers() { List<ZabbixServer> serverSet = mDatabaseHelper.getZabbixServers(); mServersListSelectionAdapter.clear(); mServersListSelectionAdapter.addAll(serverSet); mServersListManagementAdapter.clear(); mServersListManagementAdapter.addAll(serverSet); } /** * Loads all history details for a given item. If necessary, an import from * the Zabbix API is triggered. * * @param item */ public void loadHistoryDetailsByItem(final Item item, boolean cancelPreviousTasks, final OnGraphDataLoadedListener callback) { Log.d(TAG, "Loading history for item " + item.toString()); if (cancelPreviousTasks) { cancelLoadHistoryDetailsTasks(); } RemoteAPITask currentTask = new RemoteAPITask(mRemoteAPI,this) { List<HistoryDetail> historyDetails; @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { try { mRemoteAPI.importHistoryDetails(item.getId(), this); } finally { historyDetails = mDatabaseHelper .getHistoryDetailsByItemId(item.getId()); } } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); item.setHistoryDetails(historyDetails); if (callback != null) callback.onGraphDataLoaded(); } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); if (callback != null) callback.onGraphDataProgressUpdate(values[0]); } }; mCurrentLoadHistoryDetailsTasks.add(currentTask); currentTask.execute(); } /** * Loads all screens. If necessary, an import from the Zabbix API is * triggered. * */ public void loadScreens(final OnScreensLoadedListener callback) { new RemoteAPITask(mRemoteAPI,this) { List<Screen> screens; @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { try { mRemoteAPI.importScreens(); } finally { screens = mDatabaseHelper.getScreens(mCurrentZabbixServerId); } } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); if (mScreensListAdapter != null) { mScreensListAdapter.clear(); mScreensListAdapter.addAll(screens); mScreensListAdapter.notifyDataSetChanged(); } if (callback != null) callback.onScreensLoaded(); } }.execute(); } /** * Loads graphs belonging to a screen. If necessary, an import from the * Zabbix API is triggered. * * @param screen * @param callback */ public void loadGraphsByScreen(final Screen screen, final OnGraphsLoadedListener callback) { cancelTask(mCurrentLoadGraphsTask); mCurrentLoadGraphsTask = new RemoteAPITask(mRemoteAPI,this) { @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { mRemoteAPI.importGraphsByScreen(screen); screen.setGraphs(mDatabaseHelper.getGraphsByScreen(screen)); int numGraphs = screen.getGraphs().size(); int j = 0; for (Graph g : screen.getGraphs()) { int numItems = g.getGraphItems().size(); int k = 0; for (GraphItem gi : g.getGraphItems()) { Item item = gi.getItem(); mRemoteAPI.importHistoryDetails(item.getId(), null); item.setHistoryDetails(mDatabaseHelper .getHistoryDetailsByItemId(item.getId())); k++; if (numItems > 0 && numGraphs > 0) updateProgress((100 * j + ((100 * k) / numItems)) / numGraphs); } j++; // updateProgress((100 * j) / numGraphs); } } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); if (callback != null) callback.onGraphsProgressUpdate(values[0]); } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); if (callback != null) callback.onGraphsLoaded(); } }; mCurrentLoadGraphsTask.execute(); } /** * Loads a graph's data from the database and triggers an import from Zabbix * if necessary (i.e. the graph is not cached). * * All graph items in the given graph are filled with the corresponding * history details from the local database / the Zabbix server. * * @param graph * the graph to be filled with data * @param callback */ public void loadGraph(final Graph graph, final OnGraphsLoadedListener callback) { new RemoteAPITask(mRemoteAPI,this) { @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { for (GraphItem gi : graph.getGraphItems()) { Item item = gi.getItem(); mRemoteAPI.importHistoryDetails(item.getId(), this); item.setHistoryDetails(mDatabaseHelper .getHistoryDetailsByItemId(item.getId())); } } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); if (callback != null) callback.onGraphsLoaded(); } }.execute(); } private void cancelTask(RemoteAPITask task) { if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) { if (task.cancel(true)) Log.d(TAG, "Cancelled task: " + task); else Log.d(TAG, "Task was already done: " + task); } } /** * Cancels all tasks currently loading events. */ public void cancelLoadEventsTask() { cancelTask(mCurrentLoadEventsTask); } /** * Cancels all tasks currently loading problems. */ public void cancelLoadProblemsTask() { cancelTask(mCurrentLoadProblemsTask); } /** * Cancels all tasks currently loading problems. */ public void cancelLoadHistoryDetailsTasks() { for (RemoteAPITask task : mCurrentLoadHistoryDetailsTasks) cancelTask(task); mCurrentLoadHistoryDetailsTasks.clear(); } /** * Cancels the task currently loading applications. */ public void cancelLoadApplicationsTask() { cancelTask(mCurrentLoadApplicationsTask); } /** * Cancels the task currently loading items. */ public void cancelLoadItemsTask() { cancelTask(mCurrentLoadItemsTask); } /** * Cancels the task currently loading graphs. */ public void cancelLoadGraphsTask() { cancelTask(mCurrentLoadGraphsTask); } /** * Acknowledges an event. * * @param event * the event * @param comment * an optional comment * @param callback * callback to be notified when the acknowledgement was * successful */ public void acknowledgeEvent(final Event event, final String comment, final OnAcknowledgeEventListener callback) { new RemoteAPITask(mRemoteAPI,this) { private boolean mSuccess = false; @Override protected void executeTask() throws ZabbixLoginRequiredException, FatalException { if (event == null) return; mRemoteAPI.acknowledgeEvent(event.getId(), comment); mSuccess = mDatabaseHelper.acknowledgeEvent(event); } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); if (mSuccess && callback != null) callback.onEventAcknowledged(); } }.execute(); } /** * Sets the activity context, which is needed to inflate layout elements. * This also initializes the layout inflater * {@link ZabbixDataService#mInflater}. * * @param context * the context */ public void setActivityContext(Context context) { this.mActivityContext = context; this.mInflater = (LayoutInflater) mActivityContext .getSystemService(LAYOUT_INFLATER_SERVICE); } public LayoutInflater getInflater() { return mInflater; } @Override public void onDestroy() { Log.d(TAG, "onDestroy()"); super.onDestroy(); } @Override public void onConfigurationChanged(Configuration newConfig) { Log.d(TAG, "onConfigChanged"); super.onConfigurationChanged(newConfig); } @Override public boolean onUnbind(Intent intent) { mBindings--; Log.d(TAG, "onUnbind: " + mBindings); return super.onUnbind(intent); } public Graph getGraphById(long graphId) { return mDatabaseHelper.getGraphById(graphId); } public void performZabbixLogout() { mRemoteAPI.logout(); } public void initConnection() { mRemoteAPI.initConnection(); } public ZabbixServer createNewZabbixServer(String name) { ZabbixServer srv = new ZabbixServer(); srv.setName(name); mDatabaseHelper.insertZabbixServer(srv); loadZabbixServers(); return srv; } public void updateZabbixServer(ZabbixServer zabbixServer) { mDatabaseHelper.updateZabbixServer(zabbixServer); } public void removeZabbixServer(ZabbixServer item) { mDatabaseHelper.deleteZabbixServer(item); loadZabbixServers(); mServersListManagementAdapter.notifyDataSetChanged(); } public void setZabbixServer(long zabbixServerID){ if(mRemoteAPI.getZabbixSeverId() != zabbixServerID){ if(zabbixAPIs.containsKey(zabbixServerID)){ mRemoteAPI = zabbixAPIs.get(zabbixServerID); Log.d(TAG,"switching to existing API-instance"); } else { ZabbixRemoteAPI newZabbixServer = new ZabbixRemoteAPI(this.getApplicationContext(), mDatabaseHelper, mCurrentZabbixServerId, null); zabbixAPIs.put(zabbixServerID,newZabbixServer); mRemoteAPI = newZabbixServer; this.clearAllData(false); Log.d(TAG,"creating new API-instance and switching to it"); } } } }