use of org.folio.okapi.bean.ModuleInstance in project okapi by folio-org.
the class ProxyContext method logRequest.
/* Helpers for logging and building responses */
public final void logRequest(RoutingContext ctx, String tenant) {
StringBuilder mods = new StringBuilder();
if (modList != null && !modList.isEmpty()) {
for (ModuleInstance mi : modList) {
mods.append(" ").append(mi.getModuleDescriptor().getId());
}
}
logger.info(reqId + " REQ " + ctx.request().remoteAddress() + " " + tenant + " " + ctx.request().method() + " " + ctx.request().path() + mods.toString());
}
use of org.folio.okapi.bean.ModuleInstance in project okapi by folio-org.
the class ProxyService method resolveUrls.
private void resolveUrls(Iterator<ModuleInstance> it, Handler<ExtendedAsyncResult<Void>> fut) {
if (!it.hasNext()) {
fut.handle(new Success<>());
} else {
ModuleInstance mi = it.next();
if (mi.getRoutingEntry().getProxyType() == ProxyType.INTERNAL) {
mi.setUrl("");
resolveUrls(it, fut);
return;
}
discoveryManager.get(mi.getModuleDescriptor().getId(), res -> {
if (res.failed()) {
fut.handle(new Failure<>(res.getType(), res.cause()));
} else {
DeploymentDescriptor instance = pickInstance(res.result());
if (instance == null) {
fut.handle(new Failure<>(NOT_FOUND, "No running module instance found for " + mi.getModuleDescriptor().getId()));
return;
}
mi.setUrl(instance.getUrl());
resolveUrls(it, fut);
}
});
}
}
use of org.folio.okapi.bean.ModuleInstance in project okapi by folio-org.
the class ProxyService method authHeaders.
/**
* Set up special auth headers. Get the auth bits from the module list into
* X-Okapi-Permissions-Required and X-Okapi-Permissions-Desired headers. Also
* X-Okapi-Module-Permissions for each module that has such.
*/
private void authHeaders(List<ModuleInstance> modlist, MultiMap requestHeaders, ProxyContext pc) {
// Sanitize important headers from the incoming request
sanitizeAuthHeaders(requestHeaders);
Set<String> req = new HashSet<>();
Set<String> want = new HashSet<>();
Set<String> extraperms = new HashSet<>();
// !!
Map<String, String[]> modperms = new HashMap<>(modlist.size());
for (ModuleInstance mod : modlist) {
RoutingEntry re = mod.getRoutingEntry();
String[] reqp = re.getPermissionsRequired();
if (reqp != null) {
req.addAll(Arrays.asList(reqp));
}
String[] wap = re.getPermissionsDesired();
if (wap != null) {
want.addAll(Arrays.asList(wap));
}
String[] modp = re.getModulePermissions();
if (modp != null) {
if (re.getProxyType() == ProxyType.REDIRECT) {
extraperms.addAll(Arrays.asList(modp));
} else {
modperms.put(mod.getModuleDescriptor().getId(), modp);
}
}
}
// mod loop
if (!req.isEmpty()) {
pc.debug("authHeaders: " + XOkapiHeaders.PERMISSIONS_REQUIRED + " " + String.join(",", req));
requestHeaders.add(XOkapiHeaders.PERMISSIONS_REQUIRED, String.join(",", req));
}
if (!want.isEmpty()) {
pc.debug("authHeaders: " + XOkapiHeaders.PERMISSIONS_DESIRED + " " + String.join(",", want));
requestHeaders.add(XOkapiHeaders.PERMISSIONS_DESIRED, String.join(",", want));
}
// Add the X-Okapi-Module-Permissions even if empty. That causes auth to return
// an empty X-Okapi-Module-Token, which will tell us that we have done the mod
// perms, and no other module should be allowed to do the same.
String mpj = Json.encode(modperms);
pc.debug("authHeaders: " + XOkapiHeaders.MODULE_PERMISSIONS + " " + mpj);
requestHeaders.add(XOkapiHeaders.MODULE_PERMISSIONS, mpj);
if (!extraperms.isEmpty()) {
String epj = Json.encode(extraperms);
pc.debug("authHeaders: " + XOkapiHeaders.EXTRA_PERMISSIONS + " " + epj);
requestHeaders.add(XOkapiHeaders.EXTRA_PERMISSIONS, epj);
}
}
use of org.folio.okapi.bean.ModuleInstance in project okapi by folio-org.
the class ProxyService method authForSystemInterface.
/**
* Helper to get a new authtoken before invoking doCallSystemInterface.
*/
private void authForSystemInterface(ModuleDescriptor authMod, RoutingEntry filt, String tenantId, ModuleInstance inst, String request, ProxyContext pc, Handler<ExtendedAsyncResult<OkapiClient>> fut) {
pc.debug("Calling doCallSystemInterface to get auth token");
RoutingEntry re = inst.getRoutingEntry();
String modPerms = "";
if (re != null) {
String[] modulePermissions = re.getModulePermissions();
Map<String, String[]> mpMap = new HashMap<>();
if (modulePermissions != null) {
mpMap.put(inst.getModuleDescriptor().getId(), modulePermissions);
logger.debug("authForSystemInterface: Found modPerms:" + modPerms);
} else {
logger.debug("authForSystemInterface: Got RoutingEntry, but null modulePermissions");
}
modPerms = Json.encode(mpMap);
} else {
logger.debug("authForSystemInterface: re is null, can't find modPerms");
}
ModuleInstance authInst = new ModuleInstance(authMod, filt, inst.getPath());
doCallSystemInterface(tenantId, null, authInst, modPerms, "", pc, res -> {
if (res.failed()) {
pc.warn("Auth check for systemInterface failed!");
fut.handle(new Failure<>(res.getType(), res.cause()));
return;
}
OkapiClient cli = res.result();
String deftok = cli.getRespHeaders().get(XOkapiHeaders.TOKEN);
logger.debug("authForSystemInterface:" + Json.encode(cli.getRespHeaders().entries()));
String modTok = cli.getRespHeaders().get(XOkapiHeaders.MODULE_TOKENS);
JsonObject jo = new JsonObject(modTok);
String token = jo.getString(inst.getModuleDescriptor().getId(), deftok);
logger.debug("authForSystemInterface: Got token " + token);
doCallSystemInterface(tenantId, token, inst, null, request, pc, fut);
});
}
use of org.folio.okapi.bean.ModuleInstance in project okapi by folio-org.
the class ProxyService method proxyHeaders.
private void proxyHeaders(Iterator<ModuleInstance> it, ProxyContext pc, ReadStream<Buffer> stream, Buffer bcontent, ModuleInstance mi) {
RoutingContext ctx = pc.getCtx();
HttpClientRequest cReq = httpClient.requestAbs(ctx.request().method(), makeUrl(mi, ctx), res -> {
if (res.statusCode() < 200 || res.statusCode() >= 300) {
proxyResponseImmediate(pc, res, mi);
if (bcontent == null) {
stream.resume();
}
} else if (it.hasNext()) {
relayToRequest(res, pc, mi);
makeTraceHeader(mi, res.statusCode(), pc);
res.endHandler(x -> proxyR(it, pc, stream, bcontent));
} else {
relayToResponse(ctx.response(), res);
makeTraceHeader(mi, res.statusCode(), pc);
if (bcontent == null) {
stream.handler(data -> {
ctx.response().write(data);
pc.trace("ProxyHeaders request chunk '" + data.toString() + "'");
});
stream.endHandler(v -> {
ctx.response().end();
pc.trace("ProxyHeaders request end");
});
stream.exceptionHandler(e -> pc.warn("proxyHeaders: content exception ", e));
stream.resume();
} else {
pc.trace("ProxyHeaders request buf '" + bcontent + "'");
ctx.response().end(bcontent);
}
}
});
cReq.exceptionHandler(e -> {
pc.warn("proxyHeaders failure: " + mi.getUrl() + ": ", e);
pc.responseText(500, "proxyHeaders failure: " + mi.getModuleDescriptor().getId() + " " + mi.getUrl() + ": " + e + " " + e.getMessage());
});
cReq.headers().setAll(ctx.request().headers());
cReq.headers().remove("Content-Length");
cReq.end();
log(pc, cReq);
}
Aggregations