blob: c4900a61faa003e9db1ca1a95ec05aa61c6aa449 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.servicecomb.demo.edge.service.encrypt;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import org.apache.servicecomb.demo.edge.authentication.encrypt.Hcr;
import org.apache.servicecomb.edge.core.AbstractEdgeDispatcher;
import org.apache.servicecomb.edge.core.CompatiblePathVersionMapper;
import org.apache.servicecomb.provider.pojo.Invoker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
public class EncryptEdgeDispatcher extends AbstractEdgeDispatcher {
private static final Logger LOGGER = LoggerFactory.getLogger(EncryptEdgeDispatcher.class);
private CompatiblePathVersionMapper versionMapper = new CompatiblePathVersionMapper();
private Encrypt encrypt = Invoker.createProxy("auth", "encrypt", Encrypt.class);
private String prefix = "encryptApi";
@Override
public int getOrder() {
return 10000;
}
@Override
public void init(Router router) {
{
String regex = "/" + prefix + "/([^\\\\/]+)/([^\\\\/]+)/(.*)";
// cookies handler are enabled by default start from 3.8.3
router.routeWithRegex(regex).handler(createBodyHandler());
router.routeWithRegex(regex).failureHandler(this::onFailure).handler(this::onRequest);
}
}
protected void onRequest(RoutingContext context) {
HttpServerRequest httpServerRequest = context.request();
// queryUserId always success
CompletableFuture<String> userIdFuture = queryUserId(httpServerRequest);
queryHcr(httpServerRequest).thenCombine(userIdFuture, (hcr, userId) -> {
// hcr and userId all success
routeToBackend(context, hcr, userId);
return null;
}).whenComplete((v, e) -> {
// failed to query hcr
if (e != null) {
context.response().end("failed to query hcr: " + e.getMessage());
return;
}
});
}
private CompletableFuture<String> queryUserId(HttpServerRequest httpServerRequest) {
String serviceToken = httpServerRequest.getParam("serviceToken");
if (serviceToken == null) {
// no need to query userId
return CompletableFuture.completedFuture(null);
}
CompletableFuture<String> future = new CompletableFuture<>();
encrypt.queryUserId(serviceToken).whenComplete((userId, e) -> {
if (e != null) {
// treat as success, just userId is null
LOGGER.error("Failed to query userId, serviceToken={}.", serviceToken, e);
}
future.complete(userId);
});
return future;
}
private CompletableFuture<Hcr> queryHcr(HttpServerRequest httpServerRequest) {
String hcrId = httpServerRequest.getParam("hcrId");
return encrypt.queryHcr(hcrId);
}
private void routeToBackend(RoutingContext context, Hcr hcr, String userId) {
Map<String, String> pathParams = context.pathParams();
String microserviceName = pathParams.get("param0");
String pathVersion = pathParams.get("param1");
String path = context.request().path().substring(prefix.length() + 1);
EncryptEdgeInvocation edgeInvocation = new EncryptEdgeInvocation(new EncryptContext(hcr, userId));
edgeInvocation.setVersionRule(versionMapper.getOrCreate(pathVersion).getVersionRule());
edgeInvocation.init(microserviceName, context, path, httpServerFilters);
edgeInvocation.edgeInvoke();
}
}