diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/client/AccountingManagerController.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/client/AccountingManagerController.java index 9a0dff7..4a98c28 100644 --- a/src/main/java/org/gcube/portlets/admin/accountingmanager/client/AccountingManagerController.java +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/client/AccountingManagerController.java @@ -12,6 +12,9 @@ import org.gcube.portlets.admin.accountingmanager.client.event.SessionExpiredEve import org.gcube.portlets.admin.accountingmanager.client.event.StateChangeEvent; import org.gcube.portlets.admin.accountingmanager.client.event.UIStateEvent; import org.gcube.portlets.admin.accountingmanager.client.monitor.AccountingMonitor; +import org.gcube.portlets.admin.accountingmanager.client.monitor.MonitorRequest; +import org.gcube.portlets.admin.accountingmanager.client.monitor.MonitorRequestEvent; +import org.gcube.portlets.admin.accountingmanager.client.monitor.MonitorRequestEvent.MonitorRequestEventHandler; import org.gcube.portlets.admin.accountingmanager.client.rpc.AccountingManagerServiceAsync; import org.gcube.portlets.admin.accountingmanager.client.state.AccountingClientState; import org.gcube.portlets.admin.accountingmanager.client.state.AccountingClientStateData; @@ -400,7 +403,7 @@ public class AccountingManagerController { public void onSuccess(SeriesResponse seriesResponse) { Log.debug("SeriesResponse: " + seriesResponse); if (seriesResponse == null) { - //TODO + // TODO callDefaultSeriesRequestNoCache(); } else { AccountingClientStateData accountingStateData = accountingState @@ -439,8 +442,7 @@ public class AccountingManagerController { }); } - - + private void callDefaultSeriesRequestNoCache() { AccountingManagerServiceAsync.INSTANCE.getSeries(accountingType, @@ -450,21 +452,20 @@ public class AccountingManagerController { @Override public void onSuccess(String operationId) { Log.debug("Service OperationId: " + operationId); - if (operationId == null||operationId.isEmpty()) { + if (operationId == null || operationId.isEmpty()) { accountingMonitor.hide(); - Log.error("Invalid Operation Id: " +operationId); - UtilsGXT3.alert("Error", - "Invalid Operation Id: " +operationId); + Log.error("Invalid Operation Id: " + operationId); + UtilsGXT3.alert("Error", "Invalid Operation Id: " + + operationId); StateChangeEvent stateChangeEvent = new StateChangeEvent( StateChangeType.Restore, accountingState .getState(accountingType)); eventBus.fireEvent(stateChangeEvent); } else { - operationMonitor(operationId,true); + defaultOperationMonitor(operationId); } } - @Override public void onFailure(Throwable caught) { accountingMonitor.hide(); @@ -487,23 +488,88 @@ public class AccountingManagerController { }); } - - private void operationMonitor(String operationId, boolean defaultOperation) { - AccountingClientStateData accountingStateData = accountingState - .getState(accountingType); - ///accountingStateData - // .setSeriesResponse(seriesResponse); - accountingState.setState(accountingType, - accountingStateData); - StateChangeEvent stateChangeEvent = new StateChangeEvent( - StateChangeType.Restore, - accountingStateData); - eventBus.fireEvent(stateChangeEvent); - accountingMonitor.hide(); - - - } + private void defaultOperationMonitor(final String operationId) { + final MonitorRequest monitorRequest = new MonitorRequest(); + MonitorRequestEventHandler handler = new MonitorRequestEventHandler() { + + @Override + public void onMonitor(MonitorRequestEvent event) { + switch (event.getMonitorRequestType()) { + case Period: + AccountingManagerServiceAsync.INSTANCE.operationMonitor( + operationId, new AsyncCallback() { + + @Override + public void onSuccess( + SeriesResponse seriesResponse) { + Log.debug("SeriesResponse: " + + seriesResponse); + if (seriesResponse != null) { + monitorRequest.stop(); + AccountingClientStateData accountingStateData = accountingState + .getState(accountingType); + accountingStateData + .setSeriesResponse(seriesResponse); + accountingState.setState( + accountingType, + accountingStateData); + StateChangeEvent stateChangeEvent = new StateChangeEvent( + StateChangeType.Restore, + accountingStateData); + eventBus.fireEvent(stateChangeEvent); + accountingMonitor.hide(); + } else { + monitorRequest.repeat(); + } + } + + @Override + public void onFailure(Throwable caught) { + monitorRequest.stop(); + accountingMonitor.hide(); + if (caught instanceof SessionExpiredException) { + eventBus.fireEvent(new SessionExpiredEvent( + SessionExpiredType.EXPIREDONSERVER)); + } else { + Log.error("Error:" + + caught.getLocalizedMessage()); + caught.printStackTrace(); + UtilsGXT3.alert("Error", + caught.getLocalizedMessage()); + StateChangeEvent stateChangeEvent = new StateChangeEvent( + StateChangeType.Restore, + accountingState + .getState(accountingType)); + eventBus.fireEvent(stateChangeEvent); + + } + + } + }); + + break; + case TimeOut: + default: + monitorRequest.stop(); + accountingMonitor.hide(); + Log.error("Error: TimeOut!"); + UtilsGXT3.alert("Error Time Out", "Error Time Out"); + StateChangeEvent stateChangeEvent = new StateChangeEvent( + StateChangeType.Restore, + accountingState.getState(accountingType)); + eventBus.fireEvent(stateChangeEvent); + break; + + } + + } + }; + + monitorRequest.addHandler(handler); + monitorRequest.start(); + + } private void doFiltersChangeCommand(FiltersChangeEvent event) { if (event == null || event.getFiltersChangeType() == null) { @@ -541,7 +607,8 @@ public class AccountingManagerController { public void onSuccess(SeriesResponse seriesResponse) { Log.debug("SeriesResponse: " + seriesResponse); if (seriesResponse == null) { - //TODO + // TODO + callSeriesRequestNoCache(); } else { AccountingClientStateData accountingStateData = accountingState .getState(accountingType); @@ -574,6 +641,115 @@ public class AccountingManagerController { } + private void callSeriesRequestNoCache() { + + AccountingManagerServiceAsync.INSTANCE.getSeries(accountingType, + accountingState.getState(accountingType).getSeriesRequest(), + new AsyncCallback() { + + @Override + public void onSuccess(String operationId) { + Log.debug("Service OperationId: " + operationId); + if (operationId == null || operationId.isEmpty()) { + accountingMonitor.hide(); + Log.error("Invalid Operation Id: " + operationId); + UtilsGXT3.alert("Error", "Invalid Operation Id: " + + operationId); + } else { + operationMonitor(operationId); + } + } + + @Override + public void onFailure(Throwable caught) { + accountingMonitor.hide(); + if (caught instanceof SessionExpiredException) { + eventBus.fireEvent(new SessionExpiredEvent( + SessionExpiredType.EXPIREDONSERVER)); + } else { + Log.error("Error:" + caught.getLocalizedMessage()); + UtilsGXT3.alert("Error", + caught.getLocalizedMessage()); + caught.printStackTrace(); + } + + } + }); + + } + + private void operationMonitor(final String operationId) { + final MonitorRequest monitorRequest = new MonitorRequest(); + MonitorRequestEventHandler handler = new MonitorRequestEventHandler() { + + @Override + public void onMonitor(MonitorRequestEvent event) { + switch (event.getMonitorRequestType()) { + case Period: + AccountingManagerServiceAsync.INSTANCE.operationMonitor( + operationId, new AsyncCallback() { + + @Override + public void onSuccess( + SeriesResponse seriesResponse) { + Log.debug("SeriesResponse: " + + seriesResponse); + if (seriesResponse != null) { + monitorRequest.stop(); + AccountingClientStateData accountingStateData = accountingState + .getState(accountingType); + accountingStateData + .setSeriesResponse(seriesResponse); + accountingState.setState( + accountingType, + accountingStateData); + StateChangeEvent stateChangeEvent = new StateChangeEvent( + StateChangeType.Update, + accountingStateData); + eventBus.fireEvent(stateChangeEvent); + accountingMonitor.hide(); + } else { + monitorRequest.repeat(); + } + } + + @Override + public void onFailure(Throwable caught) { + monitorRequest.stop(); + accountingMonitor.hide(); + if (caught instanceof SessionExpiredException) { + eventBus.fireEvent(new SessionExpiredEvent( + SessionExpiredType.EXPIREDONSERVER)); + } else { + Log.error("Error:" + + caught.getLocalizedMessage()); + UtilsGXT3.alert("Error", + caught.getLocalizedMessage()); + caught.printStackTrace(); + } + + } + }); + + break; + case TimeOut: + default: + monitorRequest.stop(); + accountingMonitor.hide(); + Log.error("Error: TimeOut!"); + UtilsGXT3.alert("Error Time Out", "Error Time Out"); + break; + + } + + } + }; + + monitorRequest.addHandler(handler); + monitorRequest.start(); + + } + // TODO save on workspace @SuppressWarnings("unused") private void doSaveDataOnWorkspace(ExportRequestEvent event) { diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/client/maindata/charts/storage/StorageChartBasicPanel.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/client/maindata/charts/storage/StorageChartBasicPanel.java index 217fd1e..d53edb8 100644 --- a/src/main/java/org/gcube/portlets/admin/accountingmanager/client/maindata/charts/storage/StorageChartBasicPanel.java +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/client/maindata/charts/storage/StorageChartBasicPanel.java @@ -25,8 +25,6 @@ import com.github.highcharts4gwt.model.factory.jso.JsoHighchartsOptionFactory; import com.github.highcharts4gwt.model.highcharts.option.api.ChartOptions; import com.github.highcharts4gwt.model.highcharts.option.api.SeriesArea; import com.github.highcharts4gwt.model.highcharts.option.api.SeriesColumn; -import com.github.highcharts4gwt.model.highcharts.option.api.seriescolumn.ClickEvent; -import com.github.highcharts4gwt.model.highcharts.option.api.seriescolumn.ClickHandler; import com.github.highcharts4gwt.model.highcharts.option.api.seriescolumn.Data; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/client/monitor/MonitorRequest.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/client/monitor/MonitorRequest.java new file mode 100644 index 0000000..579f0bb --- /dev/null +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/client/monitor/MonitorRequest.java @@ -0,0 +1,81 @@ +package org.gcube.portlets.admin.accountingmanager.client.monitor; + +import org.gcube.portlets.admin.accountingmanager.client.monitor.MonitorRequestEvent.MonitorRequestEventHandler; +import org.gcube.portlets.admin.accountingmanager.shared.Constants; + +import com.google.gwt.user.client.Timer; + +/** + * + * @author Giancarlo Panichi email: g.panichi@isti.cnr.it + * + */ +public class MonitorRequest { + + private Timer monitor = null; + private Timer timeOut = null; + private MonitorRequestEventHandler handler; + + public MonitorRequest() { + + timeOut = new Timer() { + public void run() { + timeOutMonitor(); + } + + }; + + monitor = new Timer() { + public void run() { + executeCommand(); + } + }; + + } + + private void stopMonitor() { + if (monitor.isRunning()) { + monitor.cancel(); + } + if (timeOut.isRunning()) { + timeOut.cancel(); + } + + } + + private void timeOutMonitor() { + stopMonitor(); + MonitorRequestEvent event = new MonitorRequestEvent( + MonitorRequestType.TimeOut); + handler.onMonitor(event); + + } + + private void executeCommand() { + MonitorRequestEvent event = new MonitorRequestEvent( + MonitorRequestType.Period); + handler.onMonitor(event); + + } + + public void addHandler(MonitorRequestEventHandler handler) { + this.handler = handler; + } + + public void start() { + // Execute the timer to expire 2 seconds in the future + monitor.schedule(Constants.CLIENT_MONITOR_PERIODMILLIS); + timeOut.schedule(Constants.CLIENT_MONITOR_TIME_OUT_PERIODMILLIS); + + } + + public void repeat() { + monitor.schedule(Constants.CLIENT_MONITOR_PERIODMILLIS); + } + + public void stop() { + stopMonitor(); + } + +} diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/client/monitor/MonitorRequestEvent.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/client/monitor/MonitorRequestEvent.java new file mode 100644 index 0000000..b2b6edf --- /dev/null +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/client/monitor/MonitorRequestEvent.java @@ -0,0 +1,62 @@ +package org.gcube.portlets.admin.accountingmanager.client.monitor; + +import com.google.gwt.event.shared.EventHandler; +import com.google.gwt.event.shared.GwtEvent; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.event.shared.HasHandlers; + +/** + * Accounting Period Request Event + * + * @author "Giancarlo Panichi" g.panichi@isti.cnr.it + * + */ +public class MonitorRequestEvent extends + GwtEvent { + + public static Type TYPE = new Type(); + private MonitorRequestType monitorRequestType; + + public interface MonitorRequestEventHandler extends EventHandler { + void onMonitor(MonitorRequestEvent event); + } + + public interface HasMonitorRequestEventHandler extends HasHandlers { + public HandlerRegistration addMonitorRequestEventHandler( + MonitorRequestEventHandler handler); + } + + public MonitorRequestEvent(MonitorRequestType monitorRequestType) { + this.monitorRequestType = monitorRequestType; + } + + @Override + protected void dispatch(MonitorRequestEventHandler handler) { + handler.onMonitor(this); + } + + @Override + public Type getAssociatedType() { + return TYPE; + } + + public static Type getType() { + return TYPE; + } + + public static void fire(HasHandlers source, MonitorRequestEvent event) { + source.fireEvent(event); + } + + public MonitorRequestType getMonitorRequestType() { + return monitorRequestType; + } + + @Override + public String toString() { + return "MonitorRequestEvent [monitorRequestType=" + monitorRequestType + + "]"; + } + +} diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/client/monitor/MonitorRequestType.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/client/monitor/MonitorRequestType.java new file mode 100644 index 0000000..c6624aa --- /dev/null +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/client/monitor/MonitorRequestType.java @@ -0,0 +1,11 @@ +package org.gcube.portlets.admin.accountingmanager.client.monitor; + +/** + * + * @author Giancarlo Panichi email: g.panichi@isti.cnr.it + * + */ +public enum MonitorRequestType { + TimeOut, Period; +} diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingClientCallable.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingClientCallable.java new file mode 100644 index 0000000..8369c14 --- /dev/null +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingClientCallable.java @@ -0,0 +1,128 @@ +package org.gcube.portlets.admin.accountingmanager.server; + +import java.util.HashMap; +import java.util.concurrent.Callable; + +import javax.servlet.AsyncContext; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; + +import org.gcube.portlets.admin.accountingmanager.server.amservice.AccountingCaller; +import org.gcube.portlets.admin.accountingmanager.server.amservice.AccountingCallerInterface; +import org.gcube.portlets.admin.accountingmanager.server.amservice.AccountingCallerTester; +import org.gcube.portlets.admin.accountingmanager.server.amservice.cache.AccountingCache; +import org.gcube.portlets.admin.accountingmanager.server.state.AccountingStateData; +import org.gcube.portlets.admin.accountingmanager.server.util.TaskRequest; +import org.gcube.portlets.admin.accountingmanager.server.util.TaskStatus; +import org.gcube.portlets.admin.accountingmanager.server.util.TaskWrapper; +import org.gcube.portlets.admin.accountingmanager.shared.Constants; +import org.gcube.portlets.admin.accountingmanager.shared.data.response.SeriesResponse; +import org.gcube.portlets.admin.accountingmanager.shared.exception.ServiceException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AccountingClientCallable implements Callable { + + private static Logger logger = LoggerFactory + .getLogger(AccountingClientCallable.class); + + private TaskRequest taskRequest; + private AccountingCache accountingCache; + + public AccountingClientCallable(TaskRequest taskRequest, AccountingCache accountingCache) { + super(); + this.taskRequest = taskRequest; + this.accountingCache = accountingCache; + } + + @Override + public TaskStatus call() throws Exception { + try { + + AsyncContext asyncContext = taskRequest.getAsyncContext(); + ServletRequest servletRequest = asyncContext.getRequest(); + HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; + + AccountingCallerInterface accountingCaller; + if (Constants.DEBUG_MODE) { + accountingCaller = new AccountingCallerTester(); + } else { + accountingCaller = new AccountingCaller(); + } + + SeriesResponse seriesResponse = null; + + try { + seriesResponse = accountingCaller.getSeries( + taskRequest.getAccountingType(), + taskRequest.getSeriesRequest()); + + } catch (ServiceException e) { + + TaskWrapper taskWrapper = new TaskWrapper( + taskRequest.getOperationId(), TaskStatus.ERROR, + e.getLocalizedMessage()); + + HashMap taskWrapperMap = SessionUtil + .getTaskWrapperMap(httpRequest, + taskRequest.getServiceCredentials()); + if (taskWrapperMap == null) { + taskWrapperMap = new HashMap<>(); + SessionUtil + .setTaskWrapperMap(httpRequest, + taskRequest.getServiceCredentials(), + taskWrapperMap); + + } + + taskWrapperMap.put(taskWrapper.getOperationId(), taskWrapper); + + asyncContext.complete(); + return TaskStatus.ERROR; + } + + String key = new String(taskRequest.getServiceCredentials() + .getScope() + + "_" + + taskRequest.getAccountingType().name() + + "_" + taskRequest.getSeriesRequest().toString()); + + + accountingCache.put(key, seriesResponse); + + AccountingStateData accountingStateData = new AccountingStateData( + taskRequest.getAccountingType(), + taskRequest.getSeriesRequest(), seriesResponse); + SessionUtil.setAccountingStateData(httpRequest, + taskRequest.getServiceCredentials(), + taskRequest.getAccountingType(), accountingStateData); + + TaskWrapper taskWrapper = new TaskWrapper( + taskRequest.getOperationId(), TaskStatus.COMPLETED, + seriesResponse); + + HashMap taskWrapperMap = SessionUtil + .getTaskWrapperMap(httpRequest, + taskRequest.getServiceCredentials()); + + if (taskWrapperMap == null) { + taskWrapperMap = new HashMap<>(); + SessionUtil.setTaskWrapperMap(httpRequest, + taskRequest.getServiceCredentials(), taskWrapperMap); + + } + + taskWrapperMap.put(taskWrapper.getOperationId(), taskWrapper); + + asyncContext.complete(); + return TaskStatus.COMPLETED; + + } catch (Throwable e) { + logger.error( + "AccountingClientDaemon Execute(): " + + e.getLocalizedMessage(), e); + return TaskStatus.ERROR; + } + + } +} diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingClientDaemon.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingClientDaemon.java index 627fc48..4aa531f 100644 --- a/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingClientDaemon.java +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingClientDaemon.java @@ -1,27 +1,20 @@ package org.gcube.portlets.admin.accountingmanager.server; -import java.util.HashMap; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; -import javax.servlet.AsyncContext; -import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import org.gcube.portlets.admin.accountingmanager.server.amservice.AccountingCaller; -import org.gcube.portlets.admin.accountingmanager.server.amservice.AccountingCallerInterface; -import org.gcube.portlets.admin.accountingmanager.server.amservice.AccountingCallerTester; import org.gcube.portlets.admin.accountingmanager.server.amservice.cache.AccountingCache; -import org.gcube.portlets.admin.accountingmanager.server.state.AccountingStateData; import org.gcube.portlets.admin.accountingmanager.server.util.TaskRequest; -import org.gcube.portlets.admin.accountingmanager.server.util.TaskWrapper; +import org.gcube.portlets.admin.accountingmanager.server.util.TaskStatus; import org.gcube.portlets.admin.accountingmanager.shared.Constants; -import org.gcube.portlets.admin.accountingmanager.shared.data.response.SeriesResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,9 +30,11 @@ public class AccountingClientDaemon implements Runnable { private ServletContextEvent sce; private volatile boolean running = true; + private volatile AccountingCache accountingCache; - public AccountingClientDaemon(ServletContextEvent sce) { + public AccountingClientDaemon(ServletContextEvent sce, AccountingCache accountingCache) { this.sce = sce; + this.accountingCache=accountingCache; } public void terminate() { @@ -54,85 +49,31 @@ public class AccountingClientDaemon implements Runnable { // pool size matching Web services capacity ExecutorService executorService = Executors.newFixedThreadPool(20); - - try { - executorService.awaitTermination(30, TimeUnit.MINUTES); - } catch (InterruptedException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - + while (running) { if (!jobQueue.isEmpty()) { final TaskRequest taskRequest = jobQueue.poll(); - - executorService.execute(new Runnable() { - public void run() { - try { - AsyncContext asyncContext = taskRequest - .getAsyncContext(); - ServletRequest servletRequest = asyncContext - .getRequest(); - HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; + AccountingClientCallable accountingClientCallable = new AccountingClientCallable( + taskRequest,accountingCache); + Future futureResult = executorService + .submit(accountingClientCallable); + TaskStatus result = null; + try { + result = futureResult.get(Constants.SERVICE_CLIENT_TIMEOUT_DEFAULT_MINUTES, + TimeUnit.MINUTES); + logger.info("AccountingClientTask: " + result); - AccountingCallerInterface accountingCaller; - if (Constants.DEBUG_MODE) { - accountingCaller = new AccountingCallerTester(); - } else { - accountingCaller = new AccountingCaller(); - } + } catch (InterruptedException | ExecutionException e) { + logger.error( + "AccountingClientTask: " + e.getLocalizedMessage(), + e); + } catch (TimeoutException e) { + logger.error("AccountingClientTask No response after " + + Constants.SERVICE_CLIENT_TIMEOUT_DEFAULT_MINUTES + " minutes!"); + futureResult.cancel(true); + } - SeriesResponse seriesResponse = accountingCaller - .getSeries(taskRequest.getAccountingType(), - taskRequest.getSeriesRequest()); - - String key = new String(taskRequest - .getServiceCredentials().getScope() - + "_" - + taskRequest.getAccountingType().name() - + "_" - + taskRequest.getSeriesRequest().toString()); - - ServletContext sc = httpRequest.getServletContext(); - AccountingCache accountingCache = (AccountingCache) sc - .getAttribute(SessionConstants.ACCOUNTING_CACHE); - - accountingCache.put(key, seriesResponse); - - AccountingStateData accountingStateData = new AccountingStateData( - taskRequest.getAccountingType(), - taskRequest.getSeriesRequest(), - seriesResponse); - SessionUtil.setAccountingStateData(httpRequest, - taskRequest.getServiceCredentials(), - taskRequest.getAccountingType(), - accountingStateData); - - - TaskWrapper taskWrapper = new TaskWrapper( - taskRequest.getOperationId(), seriesResponse); - - HashMap taskWrapperMap = SessionUtil - .getTaskWrapperMap(httpRequest, - taskRequest.getServiceCredentials()); - - if (taskWrapperMap == null) { - taskWrapperMap = new HashMap<>(); - SessionUtil.setTaskWrapperMap(httpRequest, - taskRequest.getServiceCredentials(), taskWrapperMap); - - } - - taskWrapperMap.put(taskWrapper.getOperationId(), taskWrapper); - - asyncContext.complete(); - } catch (Throwable e) { - logger.error("AccountingClientDaemon Execute(): " - + e.getLocalizedMessage(), e); - } - } - }); } } } diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingClientListener.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingClientListener.java index 4d8fd01..151188a 100644 --- a/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingClientListener.java +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingClientListener.java @@ -24,11 +24,12 @@ public class AccountingClientListener implements ServletContextListener { private AccountingClientDaemon accountingClientDaemon = null; private Thread thread = null; + private volatile AccountingCache accountingCache; @Override public void contextInitialized(ServletContextEvent sce) { logger.info("Initializing AccountingCache"); - AccountingCache accountingCache=null; + accountingCache=null; try { accountingCache = new AccountingCache(); } catch (ServiceException e) { @@ -41,7 +42,7 @@ public class AccountingClientListener implements ServletContextListener { logger.info("AccountingCache value saved in context."); - accountingClientDaemon = new AccountingClientDaemon(sce); + accountingClientDaemon = new AccountingClientDaemon(sce,accountingCache); thread = new Thread(accountingClientDaemon); logger.info("Starting AccountingClientDaemon: " + thread); thread.start(); @@ -59,8 +60,20 @@ public class AccountingClientListener implements ServletContextListener { } logger.info("AccountingClientDaemon successfully stopped."); } + logger.info("Clear AccountingCache"); + try { + accountingCache.finalize(); + logger.info("AccountingCache finelized"); + } catch (Throwable e) { + logger.error( + "Error in finalize AccountingCache: " + + e.getLocalizedMessage(), e); + } + ServletContext sc = sce.getServletContext(); sc.removeAttribute(SessionConstants.ACCOUNTING_CACHE); + + logger.info("AccountingCache value deleted from context."); } diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingManagerServiceImpl.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingManagerServiceImpl.java index a242833..d4a1c91 100644 --- a/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingManagerServiceImpl.java +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/AccountingManagerServiceImpl.java @@ -56,7 +56,7 @@ public class AccountingManagerServiceImpl extends RemoteServiceServlet private static Logger logger = LoggerFactory .getLogger(AccountingManagerServiceImpl.class); - private static AccountingCache accountingCache; + /** * {@inheritDoc} @@ -69,29 +69,12 @@ public class AccountingManagerServiceImpl extends RemoteServiceServlet logger.info("Initializing AccountingManager"); - ServletContext sc = getServletContext(); - accountingCache = (AccountingCache) sc - .getAttribute(SessionConstants.ACCOUNTING_CACHE); - /* - * try { accountingCache = new AccountingCache(); } catch - * (ServiceException e) { logger.error( - * "Error initializing AccountingCache: " + e.getLocalizedMessage(), e); - * } - */ - } @Override public void destroy() { super.destroy(); - logger.info("Clear AccountingCache"); - try { - accountingCache.finalize(); - } catch (Throwable e) { - logger.error( - "Error initializing AccountingCache: " - + e.getLocalizedMessage(), e); - } + } /** @@ -157,7 +140,12 @@ public class AccountingManagerServiceImpl extends RemoteServiceServlet String key = new String(serviceCredentials.getScope() + "_" + accountingType.name() + "_" + seriesRequest.toString()); logger.info("Search Accounting data in Cache with key: " + key); - + + ServletContext sc = getServletContext(); + AccountingCache accountingCache = (AccountingCache) sc + .getAttribute(SessionConstants.ACCOUNTING_CACHE); + logger.debug("Accounting Cache retrieved in Servlet: "+accountingCache); + SeriesResponse seriesResponse = accountingCache.get(key); if (seriesResponse == null) { @@ -240,8 +228,22 @@ public class AccountingManagerServiceImpl extends RemoteServiceServlet } else { if (taskWrapperMap.containsKey(operationId)) { TaskWrapper taskWrapper = taskWrapperMap.get(operationId); - return taskWrapper.getSeriesResponse(); - + if(taskWrapper.getTaskStatus()!=null){ + switch(taskWrapper.getTaskStatus()){ + case RUNNING: + case STARTED: + case COMPLETED: + return taskWrapper.getSeriesResponse(); + case ERROR: + String errorMsg="OperationMonitor, Error in Task: "+taskWrapper.getErrorMessage(); + logger.error(errorMsg); + throw new ServiceException(errorMsg); + default: + return taskWrapper.getSeriesResponse(); + } + } else { + return null; + } } else { return null; } @@ -254,6 +256,7 @@ public class AccountingManagerServiceImpl extends RemoteServiceServlet logger.error("Operation Monitor(): " + e.getLocalizedMessage(), e); throw new ServiceException(e.getLocalizedMessage()); } + } /** diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/server/util/TaskStatus.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/util/TaskStatus.java new file mode 100644 index 0000000..d913430 --- /dev/null +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/util/TaskStatus.java @@ -0,0 +1,14 @@ +package org.gcube.portlets.admin.accountingmanager.server.util; + +/** + * + * @author Giancarlo Panichi email: g.panichi@isti.cnr.it + * + */ +public enum TaskStatus { + STARTED, + RUNNING, + COMPLETED, + ERROR; +} diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/server/util/TaskWrapper.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/util/TaskWrapper.java index af263e2..60941ce 100644 --- a/src/main/java/org/gcube/portlets/admin/accountingmanager/server/util/TaskWrapper.java +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/util/TaskWrapper.java @@ -14,14 +14,28 @@ public class TaskWrapper implements Serializable { private static final long serialVersionUID = -4010108343968344171L; private String operationId; + private TaskStatus taskStatus; + private String errorMessage; private SeriesResponse seriesResponse; - public TaskWrapper(String operationId, SeriesResponse seriesResponse) { + public TaskWrapper(String operationId, TaskStatus taskStatus, + SeriesResponse seriesResponse) { super(); this.operationId = operationId; + this.taskStatus = taskStatus; + this.errorMessage = null; this.seriesResponse = seriesResponse; } + public TaskWrapper(String operationId, TaskStatus taskStatus, + String errorMessage) { + super(); + this.operationId = operationId; + this.taskStatus = taskStatus; + this.errorMessage = errorMessage; + this.seriesResponse = null; + } + public String getOperationId() { return operationId; } @@ -30,6 +44,14 @@ public class TaskWrapper implements Serializable { this.operationId = operationId; } + public TaskStatus getTaskStatus() { + return taskStatus; + } + + public void setTaskStatus(TaskStatus taskStatus) { + this.taskStatus = taskStatus; + } + public SeriesResponse getSeriesResponse() { return seriesResponse; } @@ -38,10 +60,19 @@ public class TaskWrapper implements Serializable { this.seriesResponse = seriesResponse; } + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + @Override public String toString() { - return "TaskWrapper [operationId=" + operationId + ", seriesResponse=" - + seriesResponse + "]"; + return "TaskWrapper [operationId=" + operationId + ", taskStatus=" + + taskStatus + ", errorMessage=" + errorMessage + + ", seriesResponse=" + seriesResponse + "]"; } } diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/server/util/TaskWrapperManager.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/util/TaskWrapperManager.java new file mode 100644 index 0000000..0d4b99c --- /dev/null +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/server/util/TaskWrapperManager.java @@ -0,0 +1,5 @@ +package org.gcube.portlets.admin.accountingmanager.server.util; + +public class TaskWrapperManager { + +} diff --git a/src/main/java/org/gcube/portlets/admin/accountingmanager/shared/Constants.java b/src/main/java/org/gcube/portlets/admin/accountingmanager/shared/Constants.java index 13b0fa8..00c2fbb 100644 --- a/src/main/java/org/gcube/portlets/admin/accountingmanager/shared/Constants.java +++ b/src/main/java/org/gcube/portlets/admin/accountingmanager/shared/Constants.java @@ -40,5 +40,10 @@ public class Constants { public static final String ACCOUNTING_NAME = "AccountingManager"; public static final String ACCOUNTING_CATEGORY = "AccountingProfile"; + //TimeOut + public static final long SERVICE_CLIENT_TIMEOUT_DEFAULT_MINUTES = 30; + public static final int CLIENT_MONITOR_PERIODMILLIS = 2000; + public static final int CLIENT_MONITOR_TIME_OUT_PERIODMILLIS = 1800000; + } diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index ff49662..3b73ded 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -4,6 +4,10 @@ http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> + + org.gcube.portlets.admin.accountingmanager.server.AccountingClientListener + + @@ -15,8 +19,9 @@ AccountingManagerService org.gcube.portlets.admin.accountingmanager.server.AccountingManagerServiceImpl + true - + ExportServlet @@ -42,7 +47,7 @@ ExportServlet /accountingman/ExportServlet - +