use of org.bimserver.notifications.TopicKey in project BIMserver by opensourceBIM.
the class ServiceRunnerServlet method service.
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (request.getRequestURI().endsWith("/servicelist")) {
processServiceList(request, response);
return;
}
String token = null;
if (request.getHeader("Authorization") != null) {
String a = request.getHeader("Authorization");
if (a.startsWith("Bearer")) {
token = a.substring(7);
}
}
if (token == null) {
token = request.getHeader("Token");
}
LOGGER.info("Token: " + token);
if (token == null) {
response.sendError(403, "Token required");
}
String serviceName = request.getHeader("ServiceName");
if (serviceName == null) {
serviceName = request.getRequestURI();
LOGGER.info("Request URI: " + serviceName);
if (serviceName.startsWith("/services/")) {
serviceName = serviceName.substring(10);
}
}
if (serviceName == null || serviceName.trim().contentEquals("") || serviceName.trim().contentEquals("/") || serviceName.contentEquals("/services") || serviceName.contentEquals("/services/")) {
// Get it from the token
try {
Authorization authorization = Authorization.fromToken(getBimServer().getEncryptionKey(), token);
LOGGER.info("Authorization: " + authorization);
if (authorization instanceof RunServiceAuthorization) {
RunServiceAuthorization runServiceAuthorization = (RunServiceAuthorization) authorization;
serviceName = "" + runServiceAuthorization.getSoid();
LOGGER.info("Got SOID from token (" + serviceName + ")");
}
} catch (AuthenticationException e) {
LOGGER.error("", e);
}
}
LOGGER.info("ServiceName: " + serviceName);
long serviceOid = Long.parseLong(serviceName);
String inputType = request.getHeader("Input-Type");
LOGGER.info("Input-Type: " + inputType);
Set<String> acceptedFlows = new LinkedHashSet<>();
if (request.getHeader("Accept-Flow") == null) {
// Default
acceptedFlows.add("SYNC");
} else {
String[] flows = request.getHeader("Accept-Flow").split(",");
for (String flow : flows) {
acceptedFlows.add(flow);
}
}
try (DatabaseSession session = getBimServer().getDatabase().createSession(OperationType.READ_ONLY)) {
Authorization authorization = Authorization.fromToken(getBimServer().getEncryptionKey(), token);
User user = session.get(authorization.getUoid(), OldQuery.getDefault());
if (user == null) {
LOGGER.error("Service \"" + serviceName + "\" not found for this user");
throw new UserException("No user found with uoid " + authorization.getUoid());
}
if (user.getState() == ObjectState.DELETED) {
LOGGER.error("User has been deleted");
throw new UserException("User has been deleted");
}
InternalServicePluginConfiguration foundService = null;
UserSettings userSettings = user.getUserSettings();
for (InternalServicePluginConfiguration internalServicePluginConfiguration : userSettings.getServices()) {
if (internalServicePluginConfiguration.getOid() == serviceOid) {
foundService = internalServicePluginConfiguration;
break;
}
}
if (foundService == null) {
LOGGER.info("Service \"" + serviceName + "\" not found for this user");
throw new ServletException("Service \"" + serviceName + "\" not found for this user");
}
PluginDescriptor pluginDescriptor = foundService.getPluginDescriptor();
ServicePlugin servicePlugin = getBimServer().getPluginManager().getServicePlugin(pluginDescriptor.getPluginClassName(), true);
if (servicePlugin instanceof BimBotsServiceInterface) {
LOGGER.info("Found service " + servicePlugin);
BimBotsServiceInterface bimBotsServiceInterface = (BimBotsServiceInterface) servicePlugin;
EndPoint endPoint = getBimServer().getEndPointManager().get(token);
InputStream inputStream = request.getInputStream();
String contextId = request.getHeader("Context-Id");
if (endPoint == null || !acceptedFlows.contains("ASYNC_WS")) {
// Don't use a websocket, so synchronously process bimbot
BimBotsOutput bimBotsOutput = new BimBotRunner(getBimServer(), inputStream, contextId, inputType, authorization, foundService, bimBotsServiceInterface).runBimBot();
response.setContentLength(bimBotsOutput.getData().length);
response.setHeader("Output-Type", bimBotsOutput.getSchemaName());
response.setHeader("Data-Title", bimBotsOutput.getTitle());
response.setHeader("Content-Type", bimBotsOutput.getContentType());
response.setHeader("Content-Disposition", bimBotsOutput.getContentDisposition());
if (bimBotsOutput.getContextId() != null) {
response.setHeader("Context-Id", bimBotsOutput.getContextId());
}
response.getOutputStream().write(bimBotsOutput.getData());
} else {
TopicKey topicKey = new TopicKey();
response.setHeader("Output-Type", "Async");
response.setHeader("Topic-Id", "" + topicKey.getId());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
IOUtils.copy(inputStream, baos);
// When storing bimbot runs, a streaming deserialzer is used later in the process, memory usage can be reduced by
// streaming the data, but that would require the http socket to stay open (and the response witheld), which is not an option, hence the copy.
// TODO this can only start as soon as the response has been sent
getBimServer().getExecutorService().submit(new BimBotRunner(getBimServer(), new ByteArrayInputStream(baos.toByteArray()), contextId, inputType, authorization, foundService, bimBotsServiceInterface, endPoint.getStreamingSocketInterface(), topicKey.getId(), endPoint.getEndPointId()));
}
} else {
throw new ServletException("Service \"" + serviceName + "\" does not implement the BimBotsServiceInterface");
}
} catch (AuthenticationException e) {
LOGGER.error("", e);
} catch (BimserverDatabaseException e) {
LOGGER.error("", e);
} catch (UserException e) {
LOGGER.error("", e);
}
}
Aggregations