Search in sources :

Example 6 with BimBotsOutput

use of org.bimserver.bimbots.BimBotsOutput 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);
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ServicePlugin(org.bimserver.plugins.services.ServicePlugin) User(org.bimserver.models.store.User) AuthenticationException(org.bimserver.webservices.authorization.AuthenticationException) DatabaseSession(org.bimserver.database.DatabaseSession) EndPoint(org.bimserver.endpoints.EndPoint) BimBotsServiceInterface(org.bimserver.bimbots.BimBotsServiceInterface) RunServiceAuthorization(org.bimserver.webservices.authorization.RunServiceAuthorization) Authorization(org.bimserver.webservices.authorization.Authorization) ServletException(javax.servlet.ServletException) BimserverDatabaseException(org.bimserver.BimserverDatabaseException) TopicKey(org.bimserver.notifications.TopicKey) UserException(org.bimserver.shared.exceptions.UserException) UserSettings(org.bimserver.models.store.UserSettings) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) RunServiceAuthorization(org.bimserver.webservices.authorization.RunServiceAuthorization) ByteArrayOutputStream(java.io.ByteArrayOutputStream) PluginDescriptor(org.bimserver.models.store.PluginDescriptor) ByteArrayInputStream(java.io.ByteArrayInputStream) InternalServicePluginConfiguration(org.bimserver.models.store.InternalServicePluginConfiguration) BimBotsOutput(org.bimserver.bimbots.BimBotsOutput)

Aggregations

BimBotsOutput (org.bimserver.bimbots.BimBotsOutput)6 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 IOException (java.io.IOException)2 ByteArrayOutputStream (org.apache.commons.io.output.ByteArrayOutputStream)2 BimserverDatabaseException (org.bimserver.BimserverDatabaseException)2 BimBotContext (org.bimserver.bimbots.BimBotContext)2 BimBotsException (org.bimserver.bimbots.BimBotsException)2 BimBotsInput (org.bimserver.bimbots.BimBotsInput)2 BimBotsServiceInterface (org.bimserver.bimbots.BimBotsServiceInterface)2 DatabaseSession (org.bimserver.database.DatabaseSession)2 IfcModelInterface (org.bimserver.emf.IfcModelInterface)2 SExtendedData (org.bimserver.interfaces.objects.SExtendedData)2 SExtendedDataSchema (org.bimserver.interfaces.objects.SExtendedDataSchema)2 SFile (org.bimserver.interfaces.objects.SFile)2 SProject (org.bimserver.interfaces.objects.SProject)2 InternalServicePluginConfiguration (org.bimserver.models.store.InternalServicePluginConfiguration)2 PluginConfiguration (org.bimserver.plugins.PluginConfiguration)2 UserException (org.bimserver.shared.exceptions.UserException)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1