You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
6.5 KiB
151 lines
6.5 KiB
4 years ago
|
package com.fr.plugin.pack.http;
|
||
|
|
||
|
import com.finebi.activate.foundation.StableManager;
|
||
|
import com.finebi.base.concurrent.DefaultThreadFactory;
|
||
|
import com.finebi.common.api.vo.table.parameter.Parameters;
|
||
|
import com.finebi.dashboard.api.bean.widget.WidgetBean;
|
||
|
import com.finebi.dashboard.api.service.FineDashBoardService;
|
||
|
import com.finebi.dashboard.api.service.FineWidgetExecutorService;
|
||
|
import com.finebi.dashboard.api.structure.result.preview.BIPreViewResult;
|
||
|
import com.finebi.dashboard.impl.helper.FineDashBoardUtils;
|
||
|
import com.finebi.foundation.api.reponse.FineRespond;
|
||
|
import com.finebi.foundation.api.service.FineService;
|
||
|
import com.finebi.selector.api.DirectSourceEngineFactory;
|
||
|
import com.finebi.utils.CollectionUtils;
|
||
|
import com.finebi.utils.StringUtils;
|
||
|
import com.finebi.web.action.v5.BaseAction;
|
||
|
import com.fr.decision.authority.data.User;
|
||
|
import com.fr.decision.fun.impl.BaseHttpHandler;
|
||
|
import com.fr.general.IOUtils;
|
||
|
import com.fr.invoke.Reflect;
|
||
|
import com.fr.log.FineLoggerFactory;
|
||
|
import com.fr.plugin.pack.bean.WidgetsBean;
|
||
|
import com.fr.plugin.pack.conf.PackPluginConfig;
|
||
|
import com.fr.plugin.pack.exception.ReportExceedException;
|
||
|
import com.fr.plugin.pack.exception.WidgetExceedException;
|
||
|
import com.fr.plugin.pack.source.PackDBSourceEngine;
|
||
|
import com.fr.plugin.pack.traffic.PackTraffic;
|
||
|
import com.fr.plugin.pack.traffic.PackTrafficFactory;
|
||
|
import com.fr.third.fasterxml.jackson.databind.ObjectMapper;
|
||
|
import com.fr.third.springframework.web.bind.annotation.RequestMethod;
|
||
|
import com.fr.web.utils.WebUtils;
|
||
|
|
||
|
import javax.servlet.http.HttpServletRequest;
|
||
|
import javax.servlet.http.HttpServletResponse;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.HashMap;
|
||
|
import java.util.List;
|
||
|
import java.util.Map;
|
||
|
import java.util.Set;
|
||
|
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 java.util.stream.Collectors;
|
||
|
|
||
|
/**
|
||
|
* @author Jonas
|
||
|
* @version 5.1.3
|
||
|
* Created by Jonas on 2020-10-19
|
||
|
*/
|
||
|
public class PackHttpHandler extends BaseHttpHandler {
|
||
|
private PackTraffic reportTraffic = PackTrafficFactory.getReportTraffic();
|
||
|
public static String PATH = "/widgets/data";
|
||
|
private ExecutorService executorService = Executors.newCachedThreadPool(new DefaultThreadFactory("pack-widget-execute"));
|
||
|
|
||
|
{
|
||
|
DirectSourceEngineFactory.INSTANCE.register(new PackDBSourceEngine());
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public RequestMethod getMethod() {
|
||
|
return RequestMethod.POST;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public String getPath() {
|
||
|
return PATH;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean isPublic() {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void handle(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||
|
ObjectMapper mapper = new ObjectMapper();
|
||
|
String reportId = null;
|
||
|
try {
|
||
|
String body = IOUtils.inputStream2String(request.getInputStream());
|
||
|
WidgetsBean widgetsBean = mapper.readValue(body, WidgetsBean.class);
|
||
|
|
||
|
Map<String, Object> result = new HashMap<>();
|
||
|
Set<String> reportIds = widgetsBean.getWidgets().values().stream().map(WidgetBean::getReportId).collect(Collectors.toSet());
|
||
|
if (CollectionUtils.isEmpty(reportIds)) {
|
||
|
throw new UnsupportedOperationException();
|
||
|
} else {
|
||
|
reportId = reportIds.iterator().next();
|
||
|
if (StringUtils.isEmpty(reportId)) {
|
||
|
throw new UnsupportedOperationException("reportId must be not emtpy");
|
||
|
}
|
||
|
}
|
||
|
if (!reportTraffic.offer(reportId)) {
|
||
|
throw new ReportExceedException();
|
||
|
}
|
||
|
try {
|
||
|
List<Future<?>> futures = new ArrayList<>();
|
||
|
for (Map.Entry<String, WidgetBean> entry : widgetsBean.getWidgets().entrySet()) {
|
||
|
WidgetBean widgetBean = entry.getValue();
|
||
|
User user = FineDashBoardUtils.getUserFromReq(request, widgetBean.getReportId());
|
||
|
boolean mobile = FineDashBoardUtils.isMobile(request);
|
||
|
Parameters parameterFromRequest = FineDashBoardUtils.getParameterFromRequest(request);
|
||
|
String widgetId = entry.getKey();
|
||
|
Future<?> future = executorService.submit(() -> {
|
||
|
try {
|
||
|
BIPreViewResult widgetData = Reflect.on(FineDashBoardUtils.class)
|
||
|
.call("getWidgetData", widgetBean, user, mobile, parameterFromRequest,
|
||
|
getBean(FineDashBoardService.class), getBean(FineWidgetExecutorService.class))
|
||
|
.get();
|
||
|
result.put(widgetId, FineRespond.success(widgetData));
|
||
|
} catch (Exception e) {
|
||
|
FineLoggerFactory.getLogger().debug(e.getMessage(), e);
|
||
|
result.put(widgetId, handleException(e));
|
||
|
}
|
||
|
});
|
||
|
futures.add(future);
|
||
|
}
|
||
|
for (Future<?> future : futures) {
|
||
|
try {
|
||
|
// 设置超时时间,不能一直在等着
|
||
|
future.get(PackPluginConfig.getInstance().getWidgetQueryTimeout(), TimeUnit.MILLISECONDS);
|
||
|
} catch (TimeoutException e) {
|
||
|
future.cancel(true);
|
||
|
}
|
||
|
}
|
||
|
WebUtils.printAsString(response, mapper.writeValueAsString(FineRespond.success(result)));
|
||
|
} finally {
|
||
|
reportTraffic.release(reportId);
|
||
|
}
|
||
|
} catch (Exception e) {
|
||
|
e.printStackTrace();
|
||
|
WebUtils.printAsString(response, mapper.writeValueAsString(FineRespond.fail("500", mapper.writeValueAsString(handleException(e)))));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static FineRespond handleException(Exception e) {
|
||
|
if (e instanceof ReportExceedException) {
|
||
|
return FineRespond.fail(((ReportExceedException) e).errorCode(), e.getMessage());
|
||
|
}
|
||
|
if (e instanceof WidgetExceedException) {
|
||
|
return FineRespond.fail(((WidgetExceedException) e).errorCode(), e.getMessage());
|
||
|
}
|
||
|
return Reflect.on(BaseAction.class).call("getExceptionRespond", e).get();
|
||
|
}
|
||
|
|
||
|
private static <T extends FineService> T getBean(Class<T> annotatedClass) {
|
||
|
return StableManager.getContext().getServiceBean(annotatedClass);
|
||
|
}
|
||
|
}
|