private boolean isCacheable() { return route != null && HttpUtils.isGetReq(this) && route.cache() != null && cookies.isEmpty() && U.notEmpty(host()) && !hasToken(); }
private boolean isPublishable(Route route) { return route.isAPI() // non-API routes (e.g. pages) won't be published && !route.config().internal() // don't publish internal routes && route.config().meta().publish() // a route can be configured not to be published && !route.path().startsWith("/_"); // routes having paths starting with '/_' are considered private }
private static Tag routeRow(Route route, List<HttpVerb> verbs, boolean withHandler) { RouteConfig config = route.config(); Tag verb = td(); for (HttpVerb vrb : verbs) { verb = verb.append(verb(vrb)); } Tag path = td(route.path()); Tag zone = td(config.zone()); Tag roles = td(display(config.roles().isEmpty() ? "" : config.roles())); Tag hnd = td(route.handler()); Tag ctype = td(config.contentType().info()); String viewName = config.mvc() ? viewName(route, config) : ""; Tag view = td(viewName); Tag mvc = td(config.mvc() ? fa("check") : ""); return tr(verb, path, zone, ctype, mvc, view, roles, withHandler ? hnd : null); }
@SuppressWarnings("unchecked") public Map<String, Object> getAPIDocs() { Map<String, Object> docs = createRoot(); Map<String, Object> paths = (Map<String, Object>) docs.computeIfAbsent("paths", x -> U.map()); Map<String, Object> components = (Map<String, Object>) docs.computeIfAbsent("components", x -> U.map()); Map<String, Object> schemas = (Map<String, Object>) components.computeIfAbsent("schemas", x -> U.map()); schemas.computeIfAbsent("Error", x -> OpenAPIModel.defaultErrorSchema()); Do.group(findPublishableRoutes()).by(Route::path).forEach((path, routes) -> { paths.put(path, Do.map(routes).toMap( route -> route.verb().name().toLowerCase(), route -> descRoute(route, components) )); }); return docs; }
private Map<String, Object> defaultResponses(Route route) { RouteMeta meta = route.config().meta(); Map<String, Object> responses = U.map(); Map<String, Object> schema = U.notEmpty(meta.outputSchema()) ? meta.outputSchema().toOpenAPISchema() : U.map(); MediaType mediaType = U.or(route.config().contentType(), MediaType.JSON); String contentType = new String(mediaType.getBytes()); Map<String, Object> ok = U.map( "description", "success", "content", U.map( contentType, schema ) ); responses.put("200", ok); Map<String, Object> error = U.map( "description", "unexpected error", "content", U.map( contentType, OpenAPIModel.schemaRef("Error") ) ); responses.put("default", error); return responses; }
private static String viewName(Route route, RouteConfig config) { return config.view() != null ? config.view() : route.path().substring(1) + " (AUTO)"; }
@Override public Set<Route> allExceptInternal() { return U.set(Do.findIn(all()).all(route -> !route.isInternal())); }
private static Tag routeRow(Route route, List<HttpVerb> verbs, boolean withHandler) { RouteConfig config = route.config(); Tag verb = td(); for (HttpVerb vrb : verbs) { verb = verb.append(verb(vrb)); } Tag path = td(route.path()); Tag zone = td(config.zone()); Tag roles = td(display(config.roles().isEmpty() ? "" : config.roles())); Tag hnd = td(route.handler()); Tag ctype = td(config.contentType().info()); String viewName = config.mvc() ? viewName(route, config) : ""; Tag view = td(viewName); Tag mvc = td(config.mvc() ? fa("check") : ""); return tr(verb, path, zone, ctype, mvc, view, roles, withHandler ? hnd : null); }
private static TableTag routesOf(Set<Route> httpRoutes, boolean withHandler) { List<Route> routes = U.list(httpRoutes); sortRoutes(routes); List<Object> rows = U.list(); rows.add(tr(th("Verb"), th("Path"), th("Zone"), th("Content type"), th("MVC"), th("View name"), th("Roles"), withHandler ? th("Handler") : null)); while (!routes.isEmpty()) { Route route = U.first(routes); List<HttpVerb> verbs = U.list(route.verb()); Iterator<Route> it = routes.iterator(); while (it.hasNext()) { Route other = it.next(); if (route == other) { it.remove(); } else if (sameTarget(route, other)) { verbs.add(other.verb()); it.remove(); } } rows.add(routeRow(route, verbs, withHandler)); } return table_(rows); }
private Map<String, Object> descRoute(Route route, Map<String, Object> components) { Map<String, Object> desc = U.map(); RouteMeta meta = route.config().meta(); if (meta.summary() != null) { desc.put("summary", meta.summary()); } if (meta.description() != null) { desc.put("description", meta.description()); } if (meta.id() != null) { desc.put("operationId", meta.id()); } if (U.notEmpty(meta.tags())) { desc.put("tags", meta.tags()); } if (U.notEmpty(meta.inputSchema())) { desc.put("parameters", meta.inputSchema().toOpenAPISchema()); } desc.put("responses", U.notEmpty(meta.responses()) ? meta.responses() : defaultResponses(route)); return desc; }
private static String viewName(Route route, RouteConfig config) { return config.view() != null ? config.view() : route.path().substring(1) + " (AUTO)"; }
public static TableTag routesOf(Set<Route> httpRoutes, boolean withHandler) { List<Route> routes = U.list(httpRoutes); sortRoutes(routes); List<Object> rows = U.list(); rows.add(tr(th("Verb"), th("Path"), th("Zone"), th("Content type"), th("MVC"), th("View name"), th("Roles"), withHandler ? th("Handler") : null)); while (!routes.isEmpty()) { Route route = U.first(routes); List<HttpVerb> verbs = U.list(route.verb()); Iterator<Route> it = routes.iterator(); while (it.hasNext()) { Route other = it.next(); if (route == other) { it.remove(); } else if (sameTarget(route, other)) { verbs.add(other.verb()); it.remove(); } } rows.add(routeRow(route, verbs, withHandler)); } return table_(rows); }
@Override public Set<Route> allAdmin() { Set<Route> routes = U.set(all()); for (Iterator<Route> it = routes.iterator(); it.hasNext(); ) { Route route = it.next(); if (!route.config().zone().equalsIgnoreCase("admin")) { it.remove(); } } return routes; }
private boolean serveFromCache(ReqImpl req) { // if the HTTP request is not cacheable, the cache key will be null HTTPCacheKey cacheKey = req.cacheKey(); Route route = req.route(); if (route != null) { Cache<HTTPCacheKey, CachedResp> cache = route.cache(); if (cache != null) { if (cacheKey != null) { CachedResp resp = cache.getIfExists(cacheKey); if (resp != null) { serveCached(req, resp); return true; } } else { cache.bypass(); // notify it's not cacheable } } } return false; }
@Override public Set<Route> allNonAdmin() { Set<Route> routes = U.set(all()); for (Iterator<Route> it = routes.iterator(); it.hasNext(); ) { Route route = it.next(); if (route.config().zone().equalsIgnoreCase("admin")) { it.remove(); } } return routes; }