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:
parent
6f10b2670b
commit
ca2e1ac6dc
|
@ -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<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.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<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
|
||||
@SuppressWarnings("unused")
|
||||
private void doSaveDataOnWorkspace(ExportRequestEvent event) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
+ "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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<TaskStatus> 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<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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.");
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package org.gcube.portlets.admin.accountingmanager.server.util;
|
||||
|
||||
public class TaskWrapperManager {
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||
version="3.0">
|
||||
|
||||
<listener>
|
||||
<listener-class>org.gcube.portlets.admin.accountingmanager.server.AccountingClientListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<!-- Servlets -->
|
||||
<!-- JUnit -->
|
||||
<servlet>
|
||||
|
@ -15,8 +19,9 @@
|
|||
<servlet>
|
||||
<servlet-name>AccountingManagerService</servlet-name>
|
||||
<servlet-class>org.gcube.portlets.admin.accountingmanager.server.AccountingManagerServiceImpl</servlet-class>
|
||||
<async-supported>true</async-supported>
|
||||
</servlet>
|
||||
|
||||
|
||||
<!-- ExportServlet -->
|
||||
<servlet>
|
||||
<servlet-name>ExportServlet</servlet-name>
|
||||
|
@ -42,7 +47,7 @@
|
|||
<servlet-name>ExportServlet</servlet-name>
|
||||
<url-pattern>/accountingman/ExportServlet</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
|
||||
|
||||
<!-- Default page to serve -->
|
||||
<welcome-file-list>
|
||||
|
|
Loading…
Reference in New Issue