Search in sources :

Example 31 with ModuleDescriptor

use of org.folio.okapi.bean.ModuleDescriptor in project okapi by folio-org.

the class ModuleManager method checkInterfaceDependency.

private int checkInterfaceDependency(InterfaceDescriptor req, Map<String, ModuleDescriptor> modsAvailable, Map<String, ModuleDescriptor> modsEnabled, List<TenantModuleDescriptor> tml) {
    logger.info("checkInterfaceDependency1");
    for (Map.Entry<String, ModuleDescriptor> entry : modsEnabled.entrySet()) {
        ModuleDescriptor md = entry.getValue();
        for (InterfaceDescriptor pi : md.getProvidesList()) {
            if (req.getId().equals(pi.getId()) && pi.isCompatible(req)) {
                logger.debug("Dependency OK");
                return 0;
            }
        }
    }
    logger.info("checkInterfaceDependency2");
    ModuleDescriptor foundMd = null;
    for (Map.Entry<String, ModuleDescriptor> entry : modsAvailable.entrySet()) {
        ModuleDescriptor md = entry.getValue();
        for (InterfaceDescriptor pi : md.getProvidesList()) {
            if (req.getId().equals(pi.getId()) && pi.isCompatible(req) && (foundMd == null || md.compareTo(foundMd) > 0)) {
                // newest module
                foundMd = md;
            }
        }
    }
    if (foundMd == null) {
        return -1;
    }
    return addModuleDependencies(foundMd, modsAvailable, modsEnabled, tml);
}
Also used : ModuleDescriptor(org.folio.okapi.bean.ModuleDescriptor) TenantModuleDescriptor(org.folio.okapi.bean.TenantModuleDescriptor) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) InterfaceDescriptor(org.folio.okapi.bean.InterfaceDescriptor)

Example 32 with ModuleDescriptor

use of org.folio.okapi.bean.ModuleDescriptor in project okapi by folio-org.

the class ProxyService method getModulesForRequest.

/**
 * Builds the pipeline of modules to be invoked for a request.
 * Sets the
 * default authToken for each ModuleInstance. Later, these can be overwritten
 * by the ModuleTokens from the auth, if needed.
 *
 * @param pc
 * @param enabledModules modules enabled for the current tenant
 * @return a list of ModuleInstances. In case of error, sets up ctx and
 * returns null.
 */
private List<ModuleInstance> getModulesForRequest(ProxyContext pc, List<ModuleDescriptor> enabledModules) {
    List<ModuleInstance> mods = new ArrayList<>();
    HttpServerRequest req = pc.getCtx().request();
    final String id = req.getHeader(XOkapiHeaders.MODULE_ID);
    pc.debug("getMods: Matching " + req.method() + " " + req.absoluteURI());
    for (ModuleDescriptor md : enabledModules) {
        pc.debug("getMods:  looking at " + md.getId());
        List<RoutingEntry> rr = null;
        if (id == null) {
            rr = md.getProxyRoutingEntries();
        } else if (id.equals(md.getId())) {
            rr = md.getMultiRoutingEntries();
        }
        if (rr != null) {
            for (RoutingEntry re : rr) {
                if (match(re, req)) {
                    ModuleInstance mi = new ModuleInstance(md, re, req.uri());
                    mi.setAuthToken(pc.getCtx().request().headers().get(XOkapiHeaders.TOKEN));
                    mods.add(mi);
                    if (!resolveRedirects(pc, mods, re, enabledModules, "", req.uri(), "")) {
                        return null;
                    }
                    pc.debug("getMods:   Added " + md.getId() + " " + re.getPathPattern() + " " + re.getPath() + " " + re.getPhase() + "/" + re.getLevel());
                }
            }
        }
    }
    Comparator<ModuleInstance> cmp = (ModuleInstance a, ModuleInstance b) -> a.getRoutingEntry().getPhaseLevel().compareTo(b.getRoutingEntry().getPhaseLevel());
    mods.sort(cmp);
    // Check that our pipeline has a real module in it, not just filters,
    // so that we can return a proper 404 for requests that only hit auth
    pc.debug("Checking filters for " + req.absoluteURI());
    boolean found = false;
    for (ModuleInstance inst : mods) {
        pc.debug("getMods: Checking " + inst.getRoutingEntry().getPathPattern() + " " + "'" + inst.getRoutingEntry().getPhase() + "' " + "'" + inst.getRoutingEntry().getLevel() + "' ");
        if (inst.getRoutingEntry().getPhase() == null) {
            // No real handler should have a phase any more.
            found = true;
        // It has been deprecated for a long time, and never made any sense anyway.
        // The auth filter, the only one we have, uses phase 'auth'
        }
    }
    if (!found) {
        if (// If we defaulted to supertenant,
        "-".equals(pc.getTenant()) && !req.path().startsWith("/_/")) {
            // and not wrong okapi request
            // The /_/ test is to make sure we report same errors as before internalModule stuff
            pc.responseText(403, "Missing Tenant");
            return null;
        } else {
            pc.responseError(404, "No suitable module found for path " + req.path());
            return null;
        }
    }
    return mods;
}
Also used : ModuleDescriptor(org.folio.okapi.bean.ModuleDescriptor) RoutingEntry(org.folio.okapi.bean.RoutingEntry) HttpServerRequest(io.vertx.core.http.HttpServerRequest) ArrayList(java.util.ArrayList) ModuleInstance(org.folio.okapi.bean.ModuleInstance)

Example 33 with ModuleDescriptor

use of org.folio.okapi.bean.ModuleDescriptor in project okapi by folio-org.

the class ProxyService method resolveRedirects.

private boolean resolveRedirects(ProxyContext pc, List<ModuleInstance> mods, RoutingEntry re, List<ModuleDescriptor> enabledModules, final String loop, final String uri, final String origMod) {
    RoutingContext ctx = pc.getCtx();
    if (re.getProxyType() == ProxyType.REDIRECT) {
        // resolve redirects
        boolean found = false;
        final String redirectPath = re.getRedirectPath();
        for (ModuleDescriptor trymod : enabledModules) {
            List<RoutingEntry> rr = trymod.getProxyRoutingEntries();
            for (RoutingEntry tryre : rr) {
                if (tryre.match(redirectPath, ctx.request().method().name())) {
                    final String newUri = re.getRedirectUri(uri);
                    found = true;
                    pc.debug("resolveRedirects: " + ctx.request().method() + " " + uri + " => " + trymod + " " + newUri);
                    if (loop.contains(redirectPath + " ")) {
                        pc.responseError(500, "Redirect loop: " + loop + " -> " + redirectPath);
                        return false;
                    }
                    ModuleInstance mi = new ModuleInstance(trymod, tryre, newUri);
                    mods.add(mi);
                    if (!resolveRedirects(pc, mods, tryre, enabledModules, loop + " -> " + redirectPath, newUri, origMod)) {
                        return false;
                    }
                }
            }
        }
        if (!found) {
            String msg = "Redirecting " + uri + " to " + redirectPath + " FAILED. No suitable module found";
            pc.responseError(500, msg);
        }
        return found;
    }
    return true;
}
Also used : ModuleDescriptor(org.folio.okapi.bean.ModuleDescriptor) RoutingContext(io.vertx.ext.web.RoutingContext) RoutingEntry(org.folio.okapi.bean.RoutingEntry) ModuleInstance(org.folio.okapi.bean.ModuleInstance)

Example 34 with ModuleDescriptor

use of org.folio.okapi.bean.ModuleDescriptor in project okapi by folio-org.

the class MainVerticle method checkInternalModules.

private void checkInternalModules(Future<Void> fut) {
    final ModuleDescriptor md = InternalModule.moduleDescriptor(okapiVersion);
    final String okapiModule = md.getId();
    final String interfaceVersion = md.getProvides()[0].getVersion();
    moduleManager.get(okapiModule, gres -> {
        if (gres.succeeded()) {
            // we already have one, go on
            logger.debug("checkInternalModules: Already have " + okapiModule + " with interface version " + interfaceVersion);
            // See Okapi-359 about version checks across the cluster
            checkSuperTenant(okapiModule, fut);
            return;
        }
        if (gres.getType() != NOT_FOUND) {
            logger.warn("checkInternalModules: Could not get " + okapiModule + ": " + gres.cause());
            // something went badly wrong
            fut.fail(gres.cause());
            return;
        }
        logger.debug("Creating the internal Okapi module " + okapiModule + " with interface version " + interfaceVersion);
        moduleManager.create(md, true, ires -> {
            if (ires.failed()) {
                logger.warn("Failed to create the internal Okapi module" + okapiModule + " " + ires.cause());
                // something went badly wrong
                fut.fail(ires.cause());
                return;
            }
            checkSuperTenant(okapiModule, fut);
        });
    });
}
Also used : ModuleDescriptor(org.folio.okapi.bean.ModuleDescriptor)

Aggregations

ModuleDescriptor (org.folio.okapi.bean.ModuleDescriptor)34 TenantModuleDescriptor (org.folio.okapi.bean.TenantModuleDescriptor)24 InterfaceDescriptor (org.folio.okapi.bean.InterfaceDescriptor)7 LinkedList (java.util.LinkedList)6 DecodeException (io.vertx.core.json.DecodeException)4 HashMap (java.util.HashMap)4 Failure (org.folio.okapi.common.Failure)4 Buffer (io.vertx.core.buffer.Buffer)3 ArrayList (java.util.ArrayList)3 ModuleInstance (org.folio.okapi.bean.ModuleInstance)3 RoutingEntry (org.folio.okapi.bean.RoutingEntry)3 Tenant (org.folio.okapi.bean.Tenant)3 HttpClientRequest (io.vertx.core.http.HttpClientRequest)2 LinkedHashMap (java.util.LinkedHashMap)2 ModuleId (org.folio.okapi.common.ModuleId)2 CompList (org.folio.okapi.util.CompList)2 HttpServerRequest (io.vertx.core.http.HttpServerRequest)1 RoutingContext (io.vertx.ext.web.RoutingContext)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1