2016-11-25 15:42:29 +01:00
|
|
|
package org.gcube.smartgears.handlers.application.request;
|
|
|
|
|
|
|
|
import static org.gcube.smartgears.Constants.called_method_header;
|
|
|
|
|
|
|
|
import javax.xml.bind.annotation.XmlRootElement;
|
|
|
|
|
|
|
|
import org.gcube.accounting.datamodel.UsageRecord.OperationResult;
|
|
|
|
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
|
|
|
|
import org.gcube.accounting.persistence.AccountingPersistence;
|
|
|
|
import org.gcube.accounting.persistence.AccountingPersistenceFactory;
|
2016-11-30 17:27:21 +01:00
|
|
|
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
2022-03-17 17:17:15 +01:00
|
|
|
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
2016-11-25 15:42:29 +01:00
|
|
|
import org.gcube.common.scope.api.ScopeProvider;
|
|
|
|
import org.gcube.smartgears.Constants;
|
2022-02-07 09:44:31 +01:00
|
|
|
import org.gcube.smartgears.configuration.Mode;
|
2016-11-25 15:42:29 +01:00
|
|
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
|
|
import org.gcube.smartgears.handlers.application.RequestEvent;
|
|
|
|
import org.gcube.smartgears.handlers.application.RequestHandler;
|
|
|
|
import org.gcube.smartgears.handlers.application.ResponseEvent;
|
2017-07-28 12:09:32 +02:00
|
|
|
import org.gcube.smartgears.utils.InnerMethodName;
|
2016-11-25 15:42:29 +01:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
@XmlRootElement(name = Constants.request_accounting)
|
|
|
|
public class RequestAccounting extends RequestHandler {
|
|
|
|
|
|
|
|
private static Logger log = LoggerFactory.getLogger(RequestAccounting.class);
|
|
|
|
|
|
|
|
private static ThreadLocal<Long> startCallThreadLocal = new ThreadLocal<Long>();
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getName() {
|
|
|
|
return Constants.request_accounting;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void handleRequest(RequestEvent e) {
|
|
|
|
ApplicationContext context = e.context();
|
2016-11-30 17:27:21 +01:00
|
|
|
|
2016-11-25 15:42:29 +01:00
|
|
|
String calledMethod = e.request().getHeader(called_method_header);
|
|
|
|
if (calledMethod==null){
|
|
|
|
calledMethod = e.request().getRequestURI().substring(e.request().getContextPath().length());
|
2016-12-12 17:28:17 +01:00
|
|
|
if (calledMethod.isEmpty())
|
|
|
|
calledMethod = "/";
|
2020-11-18 18:50:49 +01:00
|
|
|
calledMethod= e.request().getMethod()+" "+calledMethod;
|
2016-11-25 15:42:29 +01:00
|
|
|
}
|
2017-07-28 12:09:32 +02:00
|
|
|
InnerMethodName.instance.set(calledMethod);
|
2022-03-17 17:17:15 +01:00
|
|
|
String caller = SecretManagerProvider.instance.get().getUser().getUsername();
|
2016-11-25 15:42:29 +01:00
|
|
|
startCallThreadLocal.set(System.currentTimeMillis());
|
|
|
|
log.info("REQUEST START ON {}:{}({}) CALLED FROM {}@{} IN SCOPE {} ",
|
2017-07-28 12:09:32 +02:00
|
|
|
context.configuration().name(),context.configuration().serviceClass(), InnerMethodName.instance.get(),
|
2016-11-25 15:42:29 +01:00
|
|
|
caller, e.request().getRemoteHost(), ScopeProvider.instance.get());
|
2016-11-30 17:27:21 +01:00
|
|
|
|
2016-11-25 15:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void handleResponse(ResponseEvent e) {
|
|
|
|
ApplicationContext context = e.context();
|
2016-11-30 17:27:21 +01:00
|
|
|
|
|
|
|
boolean resetScope = false;
|
|
|
|
if (ScopeProvider.instance.get()==null && SecurityTokenProvider.instance.get()==null){
|
|
|
|
String infrastructure = e.context().container().configuration().infrastructure();
|
|
|
|
ScopeProvider.instance.set("/"+infrastructure);
|
|
|
|
resetScope = true;
|
|
|
|
}
|
|
|
|
|
2022-03-17 17:17:15 +01:00
|
|
|
String caller = SecretManagerProvider.instance.get().getUser().getUsername();
|
|
|
|
String callerQualifier = "UNKNOWN";
|
2016-11-25 15:42:29 +01:00
|
|
|
//retieves caller Ip when there is a proxy
|
|
|
|
String callerIp = e.request().getHeader("x-forwarded-for");
|
|
|
|
if(callerIp==null)
|
|
|
|
callerIp=e.request().getRemoteHost();
|
2019-01-16 15:37:56 +01:00
|
|
|
|
|
|
|
boolean success = e.response().getStatus()<400;
|
2022-02-07 09:44:31 +01:00
|
|
|
|
|
|
|
if (context.container().configuration().mode()!=Mode.offline)
|
|
|
|
generateAccounting(caller,callerQualifier,callerIp==null?"UNKNOWN":callerIp , success, context);
|
2016-11-25 15:42:29 +01:00
|
|
|
|
2019-01-16 15:37:56 +01:00
|
|
|
log.info("REQUEST SERVED ON {}:{}({}) CALLED FROM {}@{} IN SCOPE {} {}(CODE {}) IN {} millis",
|
2017-07-28 12:09:32 +02:00
|
|
|
context.configuration().name(),context.configuration().serviceClass(), InnerMethodName.instance.get(),
|
2019-01-16 15:37:56 +01:00
|
|
|
caller, callerIp, ScopeProvider.instance.get(), success?"SUCCEDED":"FAILED", e.response().getStatus(), System.currentTimeMillis()-startCallThreadLocal.get());
|
2016-11-25 15:42:29 +01:00
|
|
|
startCallThreadLocal.remove();
|
2017-07-28 12:09:32 +02:00
|
|
|
InnerMethodName.instance.reset();
|
2016-11-30 17:27:21 +01:00
|
|
|
if (resetScope)
|
|
|
|
ScopeProvider.instance.reset();
|
2016-11-25 15:42:29 +01:00
|
|
|
}
|
|
|
|
|
2019-01-16 15:37:56 +01:00
|
|
|
void generateAccounting(String caller, String callerQualifier, String remoteHost, boolean success, ApplicationContext context){
|
2022-03-17 17:17:15 +01:00
|
|
|
AccountingPersistenceFactory.setFallbackLocation(context.container().configuration().accountingFallbackLocation());
|
2016-11-25 15:42:29 +01:00
|
|
|
AccountingPersistence persistence = AccountingPersistenceFactory.getPersistence();
|
|
|
|
ServiceUsageRecord serviceUsageRecord = new ServiceUsageRecord();
|
|
|
|
try{
|
|
|
|
|
|
|
|
serviceUsageRecord.setConsumerId(caller);
|
|
|
|
serviceUsageRecord.setCallerQualifier(callerQualifier);
|
|
|
|
serviceUsageRecord.setScope(ScopeProvider.instance.get());
|
|
|
|
serviceUsageRecord.setServiceClass(context.configuration().serviceClass());
|
|
|
|
serviceUsageRecord.setServiceName(context.configuration().name());
|
2019-01-16 15:37:56 +01:00
|
|
|
|
2016-11-25 15:42:29 +01:00
|
|
|
serviceUsageRecord.setHost(context.container().configuration().hostname()+":"+context.container().configuration().port());
|
2017-07-28 12:09:32 +02:00
|
|
|
serviceUsageRecord.setCalledMethod(InnerMethodName.instance.get());
|
2016-11-25 15:42:29 +01:00
|
|
|
serviceUsageRecord.setCallerHost(remoteHost);
|
2019-01-16 15:37:56 +01:00
|
|
|
serviceUsageRecord.setOperationResult(success?OperationResult.SUCCESS:OperationResult.FAILED);
|
2016-11-25 15:42:29 +01:00
|
|
|
serviceUsageRecord.setDuration(System.currentTimeMillis()-startCallThreadLocal.get());
|
|
|
|
persistence.account(serviceUsageRecord);
|
|
|
|
|
|
|
|
}catch(Exception ex){
|
|
|
|
log.warn("invalid record passed to accounting ",ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-30 17:27:21 +01:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return getName();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-11-25 15:42:29 +01:00
|
|
|
}
|