package org.ovirt.engine.core.bll; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import org.ovirt.engine.core.common.interfaces.IBackendCallBackServer; import org.ovirt.engine.core.common.queries.IRegisterQueryUpdatedData; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.LogCompat; import org.ovirt.engine.core.compat.LogFactoryCompat; import org.ovirt.engine.core.compat.RefObject; /** * Class, responcible to communication with frontends. Contain all search * requests, recieved from single frontend */ public class CallBackData { private static LogCompat log = LogFactoryCompat.getLog(CallBackData.class); private static final String QUERY_TYPE_UNKNOWN = "Unknown"; private String privateSessionId; private IBackendCallBackServer _callback; private final java.util.HashMap<Guid, QueryData> _queries = new java.util.HashMap<Guid, QueryData>(); private AtomicBoolean duringRefresh = new AtomicBoolean(); public AtomicInteger RefreshCyclesWithoutPolling = new AtomicInteger(); public CallBackData(IBackendCallBackServer callBack, String sessionId) { _callback = callBack; privateSessionId = sessionId; } public void RegisterQuery(Guid QueryId, QueryData queryData) { synchronized (_queries) { _queries.put(QueryId, queryData); } } public void UnregisterQuery(Guid queryID) { synchronized (_queries) { if (_queries.containsKey(queryID)) { if (log.isDebugEnabled()) { String queryType = QUERY_TYPE_UNKNOWN; if (_queries.get(queryID) != null) queryType = _queries.get(queryID).getQueryType().toString(); log.debugFormat("Frontend {0} will unregister from query. Query Id: {1}, query type: {2}", getSessionId(), queryID, queryType); } _queries.remove(queryID); this.getCallback().ClearQuery(queryID); } else { log.errorFormat("Frontend {0} tried to unregister from query which was not registered. Query Id: {1}", getSessionId(), queryID); } } } public void RefreshQueries() { synchronized (_queries) { for (QueryData queryData : _queries.values()) { // Faults (if registered) will have null QueryData, so skip them if (queryData == null) continue; refreshQuery(queryData); } } } private void refreshQuery(QueryData queryData) { java.util.ArrayList<QueryData> toRemove = new java.util.ArrayList<QueryData>(); RefObject<IRegisterQueryUpdatedData> updatedData = new RefObject<IRegisterQueryUpdatedData>(); RefObject<Boolean> changed = new RefObject<Boolean>(); if (!queryData.RefreshQuery(updatedData, changed)) { toRemove.add(queryData); } queryData.setInitialized(true); if (changed.argvalue) { getCallback().QueryDataChanged(queryData.getQueryId(), updatedData.argvalue); if (log.isDebugEnabled()) { log.debugFormat("Session {0}: Query {1} Results Updated.", getSessionId(), queryData.getQueryId()); } } for (QueryData dataToRemove : toRemove) { QueryData data = _queries.remove(dataToRemove.getQueryId()); if (data != null) { this.getCallback().ClearQuery(dataToRemove.getQueryId()); log.errorFormat( "Frontend unregistered forcibly from query due illegal query. Query Id: {0}, Query Type: {1}", dataToRemove.getQueryId(), dataToRemove.getQueryType()); } } } public String getSessionId() { return privateSessionId; } public int getQueriesCount() { return _queries.size(); } public IBackendCallBackServer getCallback() { return _callback; } public Guid[] getQueryIDs() { synchronized (_queries) { List<Guid> list = new ArrayList<Guid>(); for (Guid key : _queries.keySet()) { QueryData data = _queries.get(key); if (data == null || data.isInitialized()) { list.add(key); } } Guid[] keys = new Guid[list.size()]; list.toArray(keys); return keys; } } public void resetDuringRefresh() { duringRefresh.set(false); } public boolean compareAndSetDuringRefresh() { return duringRefresh.compareAndSet(false, true); } }