Search in sources :

Example 1 with ModuleDescriptor

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

the class ModuleManager method checkAllConflicts.

/**
 * Check a module list for conflicts.
 *
 * @param modlist modules to be checked
 * @return error message listing conflicts, or "" if no problems
 */
public String checkAllConflicts(Map<String, ModuleDescriptor> modlist) {
    // interface name to module name
    Map<String, String> provs = new HashMap<>();
    StringBuilder conflicts = new StringBuilder();
    for (ModuleDescriptor md : modlist.values()) {
        InterfaceDescriptor[] provides = md.getProvidesList();
        for (InterfaceDescriptor mi : provides) {
            if (mi.isRegularHandler()) {
                String confl = provs.get(mi.getId());
                if (confl == null || confl.isEmpty()) {
                    provs.put(mi.getId(), md.getId());
                } else {
                    String msg = "Interface " + mi.getId() + " is provided by " + md.getId() + " and " + confl + ". ";
                    conflicts.append(msg);
                }
            }
        }
    }
    logger.debug("checkAllConflicts: " + conflicts.toString());
    return conflicts.toString();
}
Also used : ModuleDescriptor(org.folio.okapi.bean.ModuleDescriptor) TenantModuleDescriptor(org.folio.okapi.bean.TenantModuleDescriptor) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) InterfaceDescriptor(org.folio.okapi.bean.InterfaceDescriptor)

Example 2 with ModuleDescriptor

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

the class ModuleManager method resolveModuleConflicts.

private int resolveModuleConflicts(ModuleDescriptor md, Map<String, ModuleDescriptor> modsEnabled, List<TenantModuleDescriptor> tml, List<ModuleDescriptor> fromModule) {
    int v = 0;
    Iterator<String> it = modsEnabled.keySet().iterator();
    while (it.hasNext()) {
        String runningmodule = it.next();
        ModuleDescriptor rm = modsEnabled.get(runningmodule);
        if (md.getProduct().equals(rm.getProduct())) {
            logger.info("resolveModuleConflicts from " + runningmodule);
            fromModule.add(rm);
            modsEnabled.remove(runningmodule);
            it = modsEnabled.keySet().iterator();
            v++;
        } else {
            for (InterfaceDescriptor pi : rm.getProvidesList()) {
                if (pi.isRegularHandler()) {
                    String confl = pi.getId();
                    for (InterfaceDescriptor mi : md.getProvidesList()) {
                        if (mi.getId().equals(confl) && mi.isRegularHandler() && modsEnabled.containsKey(runningmodule)) {
                            logger.info("resolveModuleConflicts remove " + runningmodule);
                            TenantModuleDescriptor tm = new TenantModuleDescriptor();
                            tm.setAction("disable");
                            tm.setId(runningmodule);
                            tml.add(tm);
                            modsEnabled.remove(runningmodule);
                            it = modsEnabled.keySet().iterator();
                            v++;
                        }
                    }
                }
            }
        }
    }
    return v;
}
Also used : TenantModuleDescriptor(org.folio.okapi.bean.TenantModuleDescriptor) ModuleDescriptor(org.folio.okapi.bean.ModuleDescriptor) TenantModuleDescriptor(org.folio.okapi.bean.TenantModuleDescriptor) InterfaceDescriptor(org.folio.okapi.bean.InterfaceDescriptor)

Example 3 with ModuleDescriptor

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

the class ModuleManager method removeModuleDependencies.

public int removeModuleDependencies(ModuleDescriptor md, Map<String, ModuleDescriptor> modsEnabled, List<TenantModuleDescriptor> tml) {
    int sum = 0;
    logger.info("removeModuleDependencies " + md.getId());
    if (!modsEnabled.containsKey(md.getId())) {
        return 0;
    }
    InterfaceDescriptor[] provides = md.getProvidesList();
    for (InterfaceDescriptor prov : provides) {
        if (prov.isRegularHandler()) {
            Iterator<String> it = modsEnabled.keySet().iterator();
            while (it.hasNext()) {
                String runningmodule = it.next();
                ModuleDescriptor rm = modsEnabled.get(runningmodule);
                InterfaceDescriptor[] requires = rm.getRequiresList();
                for (InterfaceDescriptor ri : requires) {
                    if (prov.getId().equals(ri.getId())) {
                        sum += removeModuleDependencies(rm, modsEnabled, tml);
                        it = modsEnabled.keySet().iterator();
                    }
                }
            }
        }
    }
    modsEnabled.remove(md.getId());
    TenantModuleDescriptor tm = new TenantModuleDescriptor();
    tm.setAction("disable");
    tm.setId(md.getId());
    tml.add(tm);
    return sum + 1;
}
Also used : TenantModuleDescriptor(org.folio.okapi.bean.TenantModuleDescriptor) ModuleDescriptor(org.folio.okapi.bean.ModuleDescriptor) TenantModuleDescriptor(org.folio.okapi.bean.TenantModuleDescriptor) InterfaceDescriptor(org.folio.okapi.bean.InterfaceDescriptor)

Example 4 with ModuleDescriptor

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

the class ProxyService method callSystemInterface.

/**
 * Make a request to a system interface, like _tenant. Part 1: Check that we
 * are working as the right tenant, and if not so, change identity to the
 * correct one.
 *
 * @param tenant to make the request for
 * @param inst carries the moduleDescriptor, RoutingEntry, and getPath to be
 * called
 * @param request body to send in the request
 * @param pc ProxyContext for logging, and returning resp headers
 * @param fut Callback with the OkapiClient that contains the body, headers,
 * and/or errors
 */
public void callSystemInterface(Tenant tenant, ModuleInstance inst, String request, ProxyContext pc, Handler<ExtendedAsyncResult<OkapiClient>> fut) {
    // the tenant we are about to enable
    String tenantId = tenant.getId();
    // is often the supertenant
    String curTenantId = pc.getTenant();
    String authToken = pc.getCtx().request().headers().get(XOkapiHeaders.TOKEN);
    pc.debug("callSystemInterface on " + Json.encode(inst) + " for " + tenantId + " as " + curTenantId + " with authToken " + authToken);
    if (tenantId.equals(curTenantId)) {
        pc.debug("callSystemInterface: Same tenant, no need for trickery");
        doCallSystemInterface(tenantId, authToken, inst, null, request, pc, fut);
        return;
    }
    // Check if the actual tenant has auth enabled. If yes, get a token for it.
    // If we have auth for current (super)tenant is irrelevant here!
    pc.debug("callSystemInterface: Checking if " + tenantId + " has auth");
    moduleManager.getEnabledModules(tenant, mres -> {
        if (mres.failed()) {
            // Should not happen
            pc.warn("callSystemInterface: getEnabledModules failed: ", mres.cause());
            fut.handle(new Failure<>(mres.getType(), mres.cause()));
            return;
        }
        List<ModuleDescriptor> enabledModules = mres.result();
        for (ModuleDescriptor md : enabledModules) {
            RoutingEntry[] filters = md.getFilters();
            if (filters != null) {
                for (RoutingEntry filt : filters) {
                    if ("auth".equals(filt.getPhase())) {
                        pc.debug("callSystemInterface: Found auth filter in " + md.getId());
                        authForSystemInterface(md, filt, tenantId, inst, request, pc, fut);
                        return;
                    }
                }
            }
        }
        pc.debug("callSystemInterface: No auth for " + tenantId + " calling with tenant header only");
        doCallSystemInterface(tenantId, null, inst, null, request, pc, fut);
    });
}
Also used : ModuleDescriptor(org.folio.okapi.bean.ModuleDescriptor) RoutingEntry(org.folio.okapi.bean.RoutingEntry)

Example 5 with ModuleDescriptor

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

the class ProxyService method proxy.

public void proxy(RoutingContext ctx) {
    ctx.request().pause();
    ReadStream<Buffer> stream = ctx.request();
    // Pause the request data stream before doing any slow ops, otherwise
    // it will get read into a buffer somewhere.
    ProxyContext pc = new ProxyContext(ctx);
    // It would be nice to pass the request-id to the client, so it knows what
    // to look for in Okapi logs. But that breaks the schemas, and RMB-based
    // modules will not accept the response. Maybe later...
    String tenantId = tenantHeader(pc);
    if (tenantId == null) {
        stream.resume();
        // Error code already set in ctx
        return;
    }
    sanitizeAuthHeaders(ctx.request().headers());
    tenantManager.get(tenantId, gres -> {
        if (gres.failed()) {
            stream.resume();
            pc.responseText(400, "No such Tenant " + tenantId);
            return;
        }
        Tenant tenant = gres.result();
        moduleManager.getEnabledModules(tenant, mres -> {
            if (mres.failed()) {
                stream.resume();
                pc.responseError(mres.getType(), mres.cause());
                return;
            }
            List<ModuleDescriptor> enabledModules = mres.result();
            String metricKey = "proxy." + tenantId + "." + ctx.request().method() + "." + ctx.normalisedPath();
            DropwizardHelper.markEvent(metricKey);
            List<ModuleInstance> l = getModulesForRequest(pc, enabledModules);
            if (l == null) {
                stream.resume();
                // ctx already set up
                return;
            }
            pc.setModList(l);
            pc.logRequest(ctx, tenantId);
            ctx.request().headers().add(XOkapiHeaders.URL, okapiUrl);
            ctx.request().headers().remove(XOkapiHeaders.MODULE_ID);
            resolveUrls(l.iterator(), res -> {
                if (res.failed()) {
                    stream.resume();
                    pc.responseError(res.getType(), res.cause());
                } else {
                    proxyR(l.iterator(), pc, stream, null);
                }
            });
        });
    });
}
Also used : Buffer(io.vertx.core.buffer.Buffer) ModuleDescriptor(org.folio.okapi.bean.ModuleDescriptor) Tenant(org.folio.okapi.bean.Tenant) ProxyContext(org.folio.okapi.util.ProxyContext) ModuleInstance(org.folio.okapi.bean.ModuleInstance)

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