Async Context integration for support async call to service

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/admin/accounting-manager@142550 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Giancarlo Panichi 2017-02-14 17:04:47 +00:00
parent 6f10b2670b
commit ca2e1ac6dc
14 changed files with 615 additions and 142 deletions

View File

@ -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.StateChangeEvent;
import org.gcube.portlets.admin.accountingmanager.client.event.UIStateEvent; 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.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.rpc.AccountingManagerServiceAsync;
import org.gcube.portlets.admin.accountingmanager.client.state.AccountingClientState; import org.gcube.portlets.admin.accountingmanager.client.state.AccountingClientState;
import org.gcube.portlets.admin.accountingmanager.client.state.AccountingClientStateData; import org.gcube.portlets.admin.accountingmanager.client.state.AccountingClientStateData;
@ -400,7 +403,7 @@ public class AccountingManagerController {
public void onSuccess(SeriesResponse seriesResponse) { public void onSuccess(SeriesResponse seriesResponse) {
Log.debug("SeriesResponse: " + seriesResponse); Log.debug("SeriesResponse: " + seriesResponse);
if (seriesResponse == null) { if (seriesResponse == null) {
//TODO // TODO
callDefaultSeriesRequestNoCache(); callDefaultSeriesRequestNoCache();
} else { } else {
AccountingClientStateData accountingStateData = accountingState AccountingClientStateData accountingStateData = accountingState
@ -440,7 +443,6 @@ public class AccountingManagerController {
} }
private void callDefaultSeriesRequestNoCache() { private void callDefaultSeriesRequestNoCache() {
AccountingManagerServiceAsync.INSTANCE.getSeries(accountingType, AccountingManagerServiceAsync.INSTANCE.getSeries(accountingType,
@ -450,21 +452,20 @@ public class AccountingManagerController {
@Override @Override
public void onSuccess(String operationId) { public void onSuccess(String operationId) {
Log.debug("Service OperationId: " + operationId); Log.debug("Service OperationId: " + operationId);
if (operationId == null||operationId.isEmpty()) { if (operationId == null || operationId.isEmpty()) {
accountingMonitor.hide(); accountingMonitor.hide();
Log.error("Invalid Operation Id: " +operationId); Log.error("Invalid Operation Id: " + operationId);
UtilsGXT3.alert("Error", UtilsGXT3.alert("Error", "Invalid Operation Id: "
"Invalid Operation Id: " +operationId); + operationId);
StateChangeEvent stateChangeEvent = new StateChangeEvent( StateChangeEvent stateChangeEvent = new StateChangeEvent(
StateChangeType.Restore, accountingState StateChangeType.Restore, accountingState
.getState(accountingType)); .getState(accountingType));
eventBus.fireEvent(stateChangeEvent); eventBus.fireEvent(stateChangeEvent);
} else { } else {
operationMonitor(operationId,true); defaultOperationMonitor(operationId);
} }
} }
@Override @Override
public void onFailure(Throwable caught) { public void onFailure(Throwable caught) {
accountingMonitor.hide(); accountingMonitor.hide();
@ -488,22 +489,87 @@ public class AccountingManagerController {
} }
private void operationMonitor(String operationId, boolean defaultOperation) { 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<SeriesResponse>() {
@Override
public void onSuccess(
SeriesResponse seriesResponse) {
Log.debug("SeriesResponse: "
+ seriesResponse);
if (seriesResponse != null) {
monitorRequest.stop();
AccountingClientStateData accountingStateData = accountingState AccountingClientStateData accountingStateData = accountingState
.getState(accountingType); .getState(accountingType);
///accountingStateData accountingStateData
// .setSeriesResponse(seriesResponse); .setSeriesResponse(seriesResponse);
accountingState.setState(accountingType, accountingState.setState(
accountingType,
accountingStateData); accountingStateData);
StateChangeEvent stateChangeEvent = new StateChangeEvent( StateChangeEvent stateChangeEvent = new StateChangeEvent(
StateChangeType.Restore, StateChangeType.Restore,
accountingStateData); accountingStateData);
eventBus.fireEvent(stateChangeEvent); eventBus.fireEvent(stateChangeEvent);
accountingMonitor.hide(); 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) { private void doFiltersChangeCommand(FiltersChangeEvent event) {
if (event == null || event.getFiltersChangeType() == null) { if (event == null || event.getFiltersChangeType() == null) {
@ -541,7 +607,8 @@ public class AccountingManagerController {
public void onSuccess(SeriesResponse seriesResponse) { public void onSuccess(SeriesResponse seriesResponse) {
Log.debug("SeriesResponse: " + seriesResponse); Log.debug("SeriesResponse: " + seriesResponse);
if (seriesResponse == null) { if (seriesResponse == null) {
//TODO // TODO
callSeriesRequestNoCache();
} else { } else {
AccountingClientStateData accountingStateData = accountingState AccountingClientStateData accountingStateData = accountingState
.getState(accountingType); .getState(accountingType);
@ -574,6 +641,115 @@ public class AccountingManagerController {
} }
private void callSeriesRequestNoCache() {
AccountingManagerServiceAsync.INSTANCE.getSeries(accountingType,
accountingState.getState(accountingType).getSeriesRequest(),
new AsyncCallback<String>() {
@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<SeriesResponse>() {
@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 // TODO save on workspace
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void doSaveDataOnWorkspace(ExportRequestEvent event) { private void doSaveDataOnWorkspace(ExportRequestEvent event) {

View File

@ -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.ChartOptions;
import com.github.highcharts4gwt.model.highcharts.option.api.SeriesArea; 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;
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.github.highcharts4gwt.model.highcharts.option.api.seriescolumn.Data;
import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler; import com.google.gwt.event.logical.shared.SelectionHandler;

View File

@ -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: <a
* href="mailto:g.panichi@isti.cnr.it">g.panichi@isti.cnr.it</a>
*
*/
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();
}
}

View File

@ -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" <a
* href="mailto:g.panichi@isti.cnr.it">g.panichi@isti.cnr.it</a>
*
*/
public class MonitorRequestEvent extends
GwtEvent<MonitorRequestEvent.MonitorRequestEventHandler> {
public static Type<MonitorRequestEventHandler> TYPE = new Type<MonitorRequestEventHandler>();
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<MonitorRequestEventHandler> getAssociatedType() {
return TYPE;
}
public static Type<MonitorRequestEventHandler> 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
+ "]";
}
}

View File

@ -0,0 +1,11 @@
package org.gcube.portlets.admin.accountingmanager.client.monitor;
/**
*
* @author Giancarlo Panichi email: <a
* href="mailto:g.panichi@isti.cnr.it">g.panichi@isti.cnr.it</a>
*
*/
public enum MonitorRequestType {
TimeOut, Period;
}

View File

@ -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<TaskStatus> {
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<String, TaskWrapper> 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<String, TaskWrapper> 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;
}
}
}

View File

@ -1,27 +1,20 @@
package org.gcube.portlets.admin.accountingmanager.server; package org.gcube.portlets.admin.accountingmanager.server;
import java.util.HashMap;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; 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.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.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.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.Constants;
import org.gcube.portlets.admin.accountingmanager.shared.data.response.SeriesResponse;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -37,9 +30,11 @@ public class AccountingClientDaemon implements Runnable {
private ServletContextEvent sce; private ServletContextEvent sce;
private volatile boolean running = true; private volatile boolean running = true;
private volatile AccountingCache accountingCache;
public AccountingClientDaemon(ServletContextEvent sce) { public AccountingClientDaemon(ServletContextEvent sce, AccountingCache accountingCache) {
this.sce = sce; this.sce = sce;
this.accountingCache=accountingCache;
} }
public void terminate() { public void terminate() {
@ -55,84 +50,30 @@ public class AccountingClientDaemon implements Runnable {
ExecutorService executorService = Executors.newFixedThreadPool(20); ExecutorService executorService = Executors.newFixedThreadPool(20);
try {
executorService.awaitTermination(30, TimeUnit.MINUTES);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while (running) { while (running) {
if (!jobQueue.isEmpty()) { if (!jobQueue.isEmpty()) {
final TaskRequest taskRequest = jobQueue.poll(); final TaskRequest taskRequest = jobQueue.poll();
executorService.execute(new Runnable() { AccountingClientCallable accountingClientCallable = new AccountingClientCallable(
public void run() { taskRequest,accountingCache);
Future<TaskStatus> futureResult = executorService
.submit(accountingClientCallable);
TaskStatus result = null;
try { try {
result = futureResult.get(Constants.SERVICE_CLIENT_TIMEOUT_DEFAULT_MINUTES,
TimeUnit.MINUTES);
logger.info("AccountingClientTask: " + result);
AsyncContext asyncContext = taskRequest } catch (InterruptedException | ExecutionException e) {
.getAsyncContext(); logger.error(
ServletRequest servletRequest = asyncContext "AccountingClientTask: " + e.getLocalizedMessage(),
.getRequest(); e);
HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; } catch (TimeoutException e) {
logger.error("AccountingClientTask No response after "
AccountingCallerInterface accountingCaller; + Constants.SERVICE_CLIENT_TIMEOUT_DEFAULT_MINUTES + " minutes!");
if (Constants.DEBUG_MODE) { futureResult.cancel(true);
accountingCaller = new AccountingCallerTester();
} else {
accountingCaller = new AccountingCaller();
} }
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<String, TaskWrapper> 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);
}
}
});
} }
} }
} }

View File

@ -24,11 +24,12 @@ public class AccountingClientListener implements ServletContextListener {
private AccountingClientDaemon accountingClientDaemon = null; private AccountingClientDaemon accountingClientDaemon = null;
private Thread thread = null; private Thread thread = null;
private volatile AccountingCache accountingCache;
@Override @Override
public void contextInitialized(ServletContextEvent sce) { public void contextInitialized(ServletContextEvent sce) {
logger.info("Initializing AccountingCache"); logger.info("Initializing AccountingCache");
AccountingCache accountingCache=null; accountingCache=null;
try { try {
accountingCache = new AccountingCache(); accountingCache = new AccountingCache();
} catch (ServiceException e) { } catch (ServiceException e) {
@ -41,7 +42,7 @@ public class AccountingClientListener implements ServletContextListener {
logger.info("AccountingCache value saved in context."); logger.info("AccountingCache value saved in context.");
accountingClientDaemon = new AccountingClientDaemon(sce); accountingClientDaemon = new AccountingClientDaemon(sce,accountingCache);
thread = new Thread(accountingClientDaemon); thread = new Thread(accountingClientDaemon);
logger.info("Starting AccountingClientDaemon: " + thread); logger.info("Starting AccountingClientDaemon: " + thread);
thread.start(); thread.start();
@ -59,8 +60,20 @@ public class AccountingClientListener implements ServletContextListener {
} }
logger.info("AccountingClientDaemon successfully stopped."); 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(); ServletContext sc = sce.getServletContext();
sc.removeAttribute(SessionConstants.ACCOUNTING_CACHE); sc.removeAttribute(SessionConstants.ACCOUNTING_CACHE);
logger.info("AccountingCache value deleted from context."); logger.info("AccountingCache value deleted from context.");
} }

View File

@ -56,7 +56,7 @@ public class AccountingManagerServiceImpl extends RemoteServiceServlet
private static Logger logger = LoggerFactory private static Logger logger = LoggerFactory
.getLogger(AccountingManagerServiceImpl.class); .getLogger(AccountingManagerServiceImpl.class);
private static AccountingCache accountingCache;
/** /**
* {@inheritDoc} * {@inheritDoc}
@ -69,29 +69,12 @@ public class AccountingManagerServiceImpl extends RemoteServiceServlet
logger.info("Initializing AccountingManager"); 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 @Override
public void destroy() { public void destroy() {
super.destroy(); super.destroy();
logger.info("Clear AccountingCache");
try {
accountingCache.finalize();
} catch (Throwable e) {
logger.error(
"Error initializing AccountingCache: "
+ e.getLocalizedMessage(), e);
}
} }
/** /**
@ -158,6 +141,11 @@ public class AccountingManagerServiceImpl extends RemoteServiceServlet
+ accountingType.name() + "_" + seriesRequest.toString()); + accountingType.name() + "_" + seriesRequest.toString());
logger.info("Search Accounting data in Cache with key: " + key); 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); SeriesResponse seriesResponse = accountingCache.get(key);
if (seriesResponse == null) { if (seriesResponse == null) {
@ -240,8 +228,22 @@ public class AccountingManagerServiceImpl extends RemoteServiceServlet
} else { } else {
if (taskWrapperMap.containsKey(operationId)) { if (taskWrapperMap.containsKey(operationId)) {
TaskWrapper taskWrapper = taskWrapperMap.get(operationId); TaskWrapper taskWrapper = taskWrapperMap.get(operationId);
if(taskWrapper.getTaskStatus()!=null){
switch(taskWrapper.getTaskStatus()){
case RUNNING:
case STARTED:
case COMPLETED:
return taskWrapper.getSeriesResponse(); 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 { } else {
return null; return null;
} }
@ -254,6 +256,7 @@ public class AccountingManagerServiceImpl extends RemoteServiceServlet
logger.error("Operation Monitor(): " + e.getLocalizedMessage(), e); logger.error("Operation Monitor(): " + e.getLocalizedMessage(), e);
throw new ServiceException(e.getLocalizedMessage()); throw new ServiceException(e.getLocalizedMessage());
} }
} }
/** /**

View File

@ -0,0 +1,14 @@
package org.gcube.portlets.admin.accountingmanager.server.util;
/**
*
* @author Giancarlo Panichi email: <a
* href="mailto:g.panichi@isti.cnr.it">g.panichi@isti.cnr.it</a>
*
*/
public enum TaskStatus {
STARTED,
RUNNING,
COMPLETED,
ERROR;
}

View File

@ -14,14 +14,28 @@ public class TaskWrapper implements Serializable {
private static final long serialVersionUID = -4010108343968344171L; private static final long serialVersionUID = -4010108343968344171L;
private String operationId; private String operationId;
private TaskStatus taskStatus;
private String errorMessage;
private SeriesResponse seriesResponse; private SeriesResponse seriesResponse;
public TaskWrapper(String operationId, SeriesResponse seriesResponse) { public TaskWrapper(String operationId, TaskStatus taskStatus,
SeriesResponse seriesResponse) {
super(); super();
this.operationId = operationId; this.operationId = operationId;
this.taskStatus = taskStatus;
this.errorMessage = null;
this.seriesResponse = seriesResponse; 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() { public String getOperationId() {
return operationId; return operationId;
} }
@ -30,6 +44,14 @@ public class TaskWrapper implements Serializable {
this.operationId = operationId; this.operationId = operationId;
} }
public TaskStatus getTaskStatus() {
return taskStatus;
}
public void setTaskStatus(TaskStatus taskStatus) {
this.taskStatus = taskStatus;
}
public SeriesResponse getSeriesResponse() { public SeriesResponse getSeriesResponse() {
return seriesResponse; return seriesResponse;
} }
@ -38,10 +60,19 @@ public class TaskWrapper implements Serializable {
this.seriesResponse = seriesResponse; this.seriesResponse = seriesResponse;
} }
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
@Override @Override
public String toString() { public String toString() {
return "TaskWrapper [operationId=" + operationId + ", seriesResponse=" return "TaskWrapper [operationId=" + operationId + ", taskStatus="
+ seriesResponse + "]"; + taskStatus + ", errorMessage=" + errorMessage
+ ", seriesResponse=" + seriesResponse + "]";
} }
} }

View File

@ -0,0 +1,5 @@
package org.gcube.portlets.admin.accountingmanager.server.util;
public class TaskWrapperManager {
}

View File

@ -40,5 +40,10 @@ public class Constants {
public static final String ACCOUNTING_NAME = "AccountingManager"; public static final String ACCOUNTING_NAME = "AccountingManager";
public static final String ACCOUNTING_CATEGORY = "AccountingProfile"; 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;
} }

View File

@ -4,6 +4,10 @@
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"> version="3.0">
<listener>
<listener-class>org.gcube.portlets.admin.accountingmanager.server.AccountingClientListener</listener-class>
</listener>
<!-- Servlets --> <!-- Servlets -->
<!-- JUnit --> <!-- JUnit -->
<servlet> <servlet>
@ -15,6 +19,7 @@
<servlet> <servlet>
<servlet-name>AccountingManagerService</servlet-name> <servlet-name>AccountingManagerService</servlet-name>
<servlet-class>org.gcube.portlets.admin.accountingmanager.server.AccountingManagerServiceImpl</servlet-class> <servlet-class>org.gcube.portlets.admin.accountingmanager.server.AccountingManagerServiceImpl</servlet-class>
<async-supported>true</async-supported>
</servlet> </servlet>
<!-- ExportServlet --> <!-- ExportServlet -->