Search in sources :

Example 1 with ApiRequest

use of com.bluenimble.platform.api.ApiRequest in project serverless by bluenimble.

the class JettyPlugin method init.

@Override
public void init(final ApiServer server) throws Exception {
    Log.setLog(new JettyLogger(this));
    // load favicon
    InputStream favicon = null;
    try {
        favicon = new FileInputStream(new File(home, FavIcon));
        FavIconContent = IOUtils.toByteArray(favicon);
    } finally {
        IOUtils.closeQuietly(favicon);
    }
    Integer poolIdleTimeout = Json.getInteger(pool, Pool.IdleTimeout, 300);
    /*
		It is very important to limit the task queue of Jetty. By default, the queue is unbounded! As a result, 
		if under high load in excess of the processing power of the webapp, jetty will keep a lot of requests on the queue. 
		Even after the load has stopped, Jetty will appear to have stopped responding to new requests as it still has lots of requests on 
		the queue to handle.
		
		For a high reliability system, it should reject the excess requests immediately (fail fast) by using a queue with 
		a bounded capability. The capability (maximum queue length) should be calculated according to the "no-response" time tolerable. 
		For example, if the webapp can handle 100 requests per second, and if you can allow it one minute to recover from excessive high load, 
		you can set the queue capability to 60*100=6000. If it is set too low, it will reject requests too soon and can't handle normal load 
		spike.
		
		Below is a sample configuration:
		
		<Configure id="Server" class="org.eclipse.jetty.server.Server">
		    <Set name="ThreadPool">
		      <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
		        <!-- specify a bounded queue -->
		        <Arg>
		           <New class="java.util.concurrent.ArrayBlockingQueue">
		              <Arg type="int">6000</Arg>
		           </New>
		      </Arg>
		        <Set name="minThreads">10</Set>
		        <Set name="maxThreads">200</Set>
		        <Set name="detailedDump">false</Set>
		      </New>
		    </Set>
		</Configure>
		Configure the number of threads according to the webapp. 
		That is, how many threads it needs in order to achieve the best performance. 
		Configure with mind to limiting memory usage maximum available. Typically >50 and <500.
		 */
    int capacity = server.weight() + 2;
    QueuedThreadPool tp = new QueuedThreadPool(capacity, capacity, poolIdleTimeout * 1000, new ArrayBlockingQueue<Runnable>(capacity * 2));
    tp.setDetailedDump(false);
    tp.setThreadsPriority(Thread.NORM_PRIORITY);
    httpServer = new Server(tp);
    ServerConnector connector = new ServerConnector(httpServer);
    connector.setPort(port);
    connector.setIdleTimeout(idleTimeout * 1000);
    httpServer.addConnector(connector);
    if (ssl != null && !Lang.isNullOrEmpty(ssl.getString(Ssl.Keystore)) && !Lang.isNullOrEmpty(ssl.getString(Ssl.Password))) {
        HttpConfiguration https = new HttpConfiguration();
        https.addCustomizer(new SecureRequestCustomizer());
        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStorePath(new File(ssl.getString(Ssl.Keystore)).getAbsolutePath());
        sslContextFactory.setKeyStorePassword(Json.getString(ssl, Ssl.Password));
        sslContextFactory.setKeyManagerPassword(Json.getString(ssl, Ssl.StorePassword, Json.getString(ssl, Ssl.Password)));
        sslContextFactory.setKeyStoreType(Json.getString(ssl, Ssl.StoreType, "JKS"));
        String[] aCiphers = null;
        // include ciphers
        JsonArray ciphers = Json.getArray(Json.getObject(ssl, Ssl.ciphers.class.getSimpleName()), Ssl.ciphers.Include);
        if (ciphers != null && !ciphers.isEmpty()) {
            aCiphers = new String[ciphers.count()];
            for (int i = 0; i < ciphers.count(); i++) {
                aCiphers[i] = (String) ciphers.get(i);
            }
            sslContextFactory.setIncludeCipherSuites(aCiphers);
        }
        // exclude ciphers
        ciphers = Json.getArray(Json.getObject(ssl, Ssl.ciphers.class.getSimpleName()), Ssl.ciphers.Exclude);
        if (ciphers != null && !ciphers.isEmpty()) {
            aCiphers = new String[ciphers.count()];
            for (int i = 0; i < ciphers.count(); i++) {
                aCiphers[i] = (String) ciphers.get(i);
            }
            sslContextFactory.setExcludeCipherSuites(aCiphers);
        }
        ServerConnector sslConnector = new ServerConnector(httpServer, new SslConnectionFactory(sslContextFactory, "http/1.1"), new HttpConnectionFactory(https));
        int sslPort = Json.getInteger(ssl, Ssl.Port, 443);
        sslConnector.setPort(sslPort);
        sslConnector.setIdleTimeout(Json.getInteger(ssl, Ssl.IdleTimeout, idleTimeout) * 1000);
        httpServer.addConnector(sslConnector);
    }
    for (Connector cn : httpServer.getConnectors()) {
        for (ConnectionFactory x : cn.getConnectionFactories()) {
            if (x instanceof HttpConnectionFactory) {
                ((HttpConnectionFactory) x).getHttpConfiguration().setSendServerVersion(false);
                ((HttpConnectionFactory) x).getHttpConfiguration().setSendXPoweredBy(false);
            }
        }
    }
    ServletContextHandler sContext = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
    sContext.setContextPath(context);
    if (gzip) {
        sContext.setGzipHandler(new GzipHandler());
    }
    httpServer.setHandler(sContext);
    ServletHolder apiHolder = new ServletHolder(new HttpServlet() {

        private static final long serialVersionUID = -4391155835460802144L;

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            if (FavIconPath.equals(req.getRequestURI())) {
                resp.getOutputStream().write(FavIconContent);
                return;
            }
            execute(req, resp);
        }

        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            execute(req, resp);
        }

        @Override
        protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            execute(req, resp);
        }

        @Override
        protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            execute(req, resp);
        }

        protected void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            try {
                ApiRequest request = new HttpApiRequest(req, tracer());
                request.getNode().set(ApiRequest.Fields.Node.Id, server.id());
                request.getNode().set(ApiRequest.Fields.Node.Type, server.type());
                request.getNode().set(ApiRequest.Fields.Node.Version, server.version());
                server.execute(request, new HttpApiResponse(request.getNode(), request.getId(), resp), CodeExecutor.Mode.Async);
            } catch (Exception e) {
                throw new ServletException(e.getMessage(), e);
            }
        }
    });
    sContext.addServlet(apiHolder, Lang.SLASH + Lang.STAR);
    // cross origin
    FilterHolder holder = new FilterHolder(CORSFilter.class);
    holder.setName("CORS");
    holder.setInitParameter("cors.supportedMethods", "GET, POST, HEAD, PUT, DELETE, PATCH, OPTIONS");
    holder.setInitParameter("cors.exposedHeaders", "Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,BN-Execution-Time,BN-Node-Id,BN-Node-Type");
    sContext.addFilter(holder, "/*", EnumSet.of(DispatcherType.INCLUDE, DispatcherType.FORWARD, DispatcherType.REQUEST, DispatcherType.ERROR));
    // monitor
    if (monitor) {
        MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
        httpServer.addEventListener(mbContainer);
        httpServer.addBean(mbContainer);
        httpServer.addBean(Log.getLog());
    }
    // start server
    httpServer.start();
    httpServer.join();
}
Also used : ServerConnector(org.eclipse.jetty.server.ServerConnector) Connector(org.eclipse.jetty.server.Connector) FilterHolder(org.eclipse.jetty.servlet.FilterHolder) ApiServer(com.bluenimble.platform.server.ApiServer) Server(org.eclipse.jetty.server.Server) ServletHolder(org.eclipse.jetty.servlet.ServletHolder) HttpConfiguration(org.eclipse.jetty.server.HttpConfiguration) SslConnectionFactory(org.eclipse.jetty.server.SslConnectionFactory) ApiRequest(com.bluenimble.platform.api.ApiRequest) HttpApiRequest(com.bluenimble.platform.plugins.inbound.http.impl.HttpApiRequest) ServerConnector(org.eclipse.jetty.server.ServerConnector) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletException(javax.servlet.ServletException) HttpApiResponse(com.bluenimble.platform.plugins.inbound.http.impl.HttpApiResponse) SslContextFactory(org.eclipse.jetty.util.ssl.SslContextFactory) HttpConnectionFactory(org.eclipse.jetty.server.HttpConnectionFactory) SslConnectionFactory(org.eclipse.jetty.server.SslConnectionFactory) ConnectionFactory(org.eclipse.jetty.server.ConnectionFactory) QueuedThreadPool(org.eclipse.jetty.util.thread.QueuedThreadPool) MBeanContainer(org.eclipse.jetty.jmx.MBeanContainer) HttpApiRequest(com.bluenimble.platform.plugins.inbound.http.impl.HttpApiRequest) SecureRequestCustomizer(org.eclipse.jetty.server.SecureRequestCustomizer) HttpConnectionFactory(org.eclipse.jetty.server.HttpConnectionFactory) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) HttpServlet(javax.servlet.http.HttpServlet) HttpServletResponse(javax.servlet.http.HttpServletResponse) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) JsonArray(com.bluenimble.platform.json.JsonArray) GzipHandler(org.eclipse.jetty.server.handler.gzip.GzipHandler) ServletContextHandler(org.eclipse.jetty.servlet.ServletContextHandler) File(java.io.File)

Example 2 with ApiRequest

use of com.bluenimble.platform.api.ApiRequest in project serverless by bluenimble.

the class SecurityUtils method onFinish.

public static ApiOutput onFinish(Api api, ApiConsumer consumer, ApiRequest pRequest, final JsonObject onFinish, JsonObject account) throws ApiServiceExecutionException {
    if (onFinish == null || onFinish.isEmpty()) {
        return null;
    }
    ApiRequest request = api.space().request(pRequest, consumer, new Endpoint() {

        @Override
        public String space() {
            return Json.getString(onFinish, Config.onFinish.Space, api.space().getNamespace());
        }

        @Override
        public String api() {
            return Json.getString(onFinish, Config.onFinish.Api, api.getNamespace());
        }

        @Override
        public String[] resource() {
            String resource = Json.getString(onFinish, Config.onFinish.Resource);
            if (resource.startsWith(Lang.SLASH)) {
                resource = resource.substring(1);
            }
            if (resource.endsWith(Lang.SLASH)) {
                resource = resource.substring(0, resource.length() - 1);
            }
            if (Lang.isNullOrEmpty(resource)) {
                return null;
            }
            return Lang.split(resource, Lang.SLASH);
        }

        @Override
        public ApiVerb verb() {
            try {
                return ApiVerb.valueOf(Json.getString(onFinish, Config.onFinish.Verb, ApiVerb.POST.name()).toUpperCase());
            } catch (Exception ex) {
                return ApiVerb.POST;
            }
        }
    });
    request.set(ApiRequest.Payload, account);
    return api.call(request);
}
Also used : Endpoint(com.bluenimble.platform.api.ApiSpace.Endpoint) ApiRequest(com.bluenimble.platform.api.ApiRequest) ApiVerb(com.bluenimble.platform.api.ApiVerb) ApiServiceExecutionException(com.bluenimble.platform.api.ApiServiceExecutionException) ApiManagementException(com.bluenimble.platform.api.ApiManagementException)

Example 3 with ApiRequest

use of com.bluenimble.platform.api.ApiRequest in project serverless by bluenimble.

the class DefaultCodeExecutor method describe.

@Override
public JsonObject describe() {
    if (service == null) {
        return null;
    }
    JsonObject oThreads = new JsonObject();
    Thread[] threads = listThreads();
    if (threads == null) {
        return null;
    }
    for (Thread t : threads) {
        if (t == null) {
            continue;
        }
        String status = t.getState().name();
        if (State.WAITING.equals(t.getState())) {
            status = StateAvailable;
        }
        JsonObject oth = (JsonObject) new JsonObject().set(Describe.Worker.Id, t.getId()).set(Describe.Worker.Name, t.getName()).set(Describe.Worker.Status, status);
        if (t instanceof SpaceThread) {
            SpaceThread st = (SpaceThread) t;
            ApiRequest request = st.getRequest();
            if (request != null) {
                JsonObject oRequest = new JsonObject();
                oRequest.set(ApiRequest.Fields.Id, request.getId());
                oRequest.set(ApiRequest.Fields.Verb, request.getVerb().name());
                oRequest.set(ApiRequest.Fields.Endpoint, request.getEndpoint());
                oRequest.set(ApiRequest.Fields.Timestamp, Lang.toUTC(request.getTimestamp()));
                oth.set(Describe.Worker.request.class.getSimpleName(), oRequest);
                if (request.getService() != null) {
                    JsonObject oService = new JsonObject();
                    String script = Json.getString(request.getService().getRuntime(), Api.Spec.Runtime.Function);
                    oService.set(Api.Spec.Runtime.Function, script);
                    if (script == null) {
                        oService.set(Api.Spec.Runtime.Function, request.getService().getSpi().getClass().getSimpleName());
                    }
                    oService.set(ApiService.Spec.Endpoint, request.getService().getEndpoint());
                    oth.set(Describe.Worker.Service, oService);
                }
            }
        }
        oThreads.set(t.getName(), oth);
    }
    return oThreads;
}
Also used : Describe(com.bluenimble.platform.api.impls.ApiSpaceImpl.Describe) JsonObject(com.bluenimble.platform.json.JsonObject) ApiRequest(com.bluenimble.platform.api.ApiRequest)

Example 4 with ApiRequest

use of com.bluenimble.platform.api.ApiRequest in project serverless by bluenimble.

the class DefaultTracer method addFields.

private void addFields() {
    // add namespace, reques and api to the context
    ThreadContext.put(Fields.Namespace, namespace);
    if (Thread.currentThread() instanceof SpaceThread) {
        ApiRequest request = ((SpaceThread) Thread.currentThread()).getRequest();
        if (request != null) {
            ThreadContext.put(Fields.Api, request.getApi());
            ThreadContext.put(Fields.Request, request.getId());
        }
    }
}
Also used : SpaceThread(com.bluenimble.platform.api.impls.SpaceThread) ApiRequest(com.bluenimble.platform.api.ApiRequest)

Example 5 with ApiRequest

use of com.bluenimble.platform.api.ApiRequest in project serverless by bluenimble.

the class ApiUtils method call.

public static ApiOutput call(final Api api, final ApiConsumer consumer, final ApiRequest pRequest, final JsonObject oRequest) throws ApiServiceExecutionException {
    ApiRequest request = api.space().request(pRequest, consumer, new Endpoint() {

        @Override
        public String space() {
            return Json.getString(oRequest, Spec.Space, api.space().getNamespace());
        }

        @Override
        public String api() {
            return Json.getString(oRequest, Spec.Api, api.getNamespace());
        }

        @Override
        public String[] resource() {
            String resource = Json.getString(oRequest, Spec.Service);
            if (resource.startsWith(Lang.SLASH)) {
                resource = resource.substring(1);
            }
            if (resource.endsWith(Lang.SLASH)) {
                resource = resource.substring(0, resource.length() - 1);
            }
            if (Lang.isNullOrEmpty(resource)) {
                return null;
            }
            return Lang.split(resource, Lang.SLASH);
        }

        @Override
        public ApiVerb verb() {
            try {
                return ApiVerb.valueOf(Json.getString(oRequest, Spec.Verb, ApiVerb.POST.name()).toUpperCase());
            } catch (Exception ex) {
                return ApiVerb.POST;
            }
        }
    });
    JsonObject parameters = Json.getObject(oRequest, Spec.Parameters);
    if (!Json.isNullOrEmpty(parameters)) {
        Iterator<String> keys = parameters.keys();
        while (keys.hasNext()) {
            String key = keys.next();
            request.set(key, parameters.get(key));
        }
    }
    JsonObject headers = Json.getObject(oRequest, Spec.Headers);
    if (!Json.isNullOrEmpty(headers)) {
        Iterator<String> keys = headers.keys();
        while (keys.hasNext()) {
            String key = keys.next();
            request.set(key, headers.get(key), Scope.Header);
        }
    }
    return api.call(request);
}
Also used : Endpoint(com.bluenimble.platform.api.ApiSpace.Endpoint) JsonObject(com.bluenimble.platform.json.JsonObject) ApiRequest(com.bluenimble.platform.api.ApiRequest) ApiVerb(com.bluenimble.platform.api.ApiVerb) ApiServiceExecutionException(com.bluenimble.platform.api.ApiServiceExecutionException)

Aggregations

ApiRequest (com.bluenimble.platform.api.ApiRequest)5 ApiServiceExecutionException (com.bluenimble.platform.api.ApiServiceExecutionException)2 Endpoint (com.bluenimble.platform.api.ApiSpace.Endpoint)2 ApiVerb (com.bluenimble.platform.api.ApiVerb)2 JsonObject (com.bluenimble.platform.json.JsonObject)2 ApiManagementException (com.bluenimble.platform.api.ApiManagementException)1 Describe (com.bluenimble.platform.api.impls.ApiSpaceImpl.Describe)1 SpaceThread (com.bluenimble.platform.api.impls.SpaceThread)1 JsonArray (com.bluenimble.platform.json.JsonArray)1 HttpApiRequest (com.bluenimble.platform.plugins.inbound.http.impl.HttpApiRequest)1 HttpApiResponse (com.bluenimble.platform.plugins.inbound.http.impl.HttpApiResponse)1 ApiServer (com.bluenimble.platform.server.ApiServer)1 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 ServletException (javax.servlet.ServletException)1 HttpServlet (javax.servlet.http.HttpServlet)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1