Skip to content
Permalink
Browse files
feat: complete the filter and response body (#7)
  • Loading branch information
tzssangglass committed May 24, 2021
1 parent ebfdd5c commit a288d2147ff43aa6b8852209e8629a3a88198779
Showing 10 changed files with 329 additions and 170 deletions.
@@ -19,23 +19,55 @@

import com.google.common.cache.Cache;
import io.github.api7.A6.PrepareConf.Req;
import io.github.api7.A6.TextEntry;
import lombok.RequiredArgsConstructor;
import org.apache.apisix.plugin.runner.A6Conf;
import org.apache.apisix.plugin.runner.A6ConfigRequest;
import org.apache.apisix.plugin.runner.A6ConfigResponse;
import org.apache.apisix.plugin.runner.A6Request;
import org.apache.apisix.plugin.runner.A6Response;
import org.apache.apisix.plugin.runner.filter.PluginFilter;
import org.apache.apisix.plugin.runner.filter.PluginFilterChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* Handle APISIX configuration request.
*/
@RequiredArgsConstructor
public class A6ConfigHandler implements Handler {
private final Cache<Long, Req> cache;
private final Logger logger = LoggerFactory.getLogger(A6ConfigHandler.class);

private final Cache<Long, A6Conf> cache;
private final Map<String, PluginFilter> filters;

@Override
public void handle(A6Request request, A6Response response) {
Req req = ((A6ConfigRequest) request).getReq();
long token = ((A6ConfigResponse) response).getConfToken();
cache.put(token, req);
PluginFilterChain chain = createFilterChain(req);
A6Conf config = new A6Conf(req, chain);
cache.put(token, config);

}

private PluginFilterChain createFilterChain(Req req) {
List<PluginFilter> chainFilters = new ArrayList<>();
for (int i = 0; i < req.confLength(); i++) {
TextEntry conf = req.conf(i);
PluginFilter filter = filters.get(conf.name());
if (Objects.isNull(filter)) {
logger.error("receive undefined filter: {}, skip it", conf.name());
continue;
}
chainFilters.add(filter);
}
return new PluginFilterChain(chainFilters);
}

}
@@ -19,22 +19,23 @@

import com.google.common.cache.Cache;
import io.github.api7.A6.Err.Code;
import io.github.api7.A6.PrepareConf.Req;
import org.apache.apisix.plugin.runner.A6Conf;
import org.apache.apisix.plugin.runner.A6ConfigResponse;
import org.apache.apisix.plugin.runner.A6ErrRequest;
import org.apache.apisix.plugin.runner.A6ErrResponse;
import org.apache.apisix.plugin.runner.A6Response;
import org.apache.apisix.plugin.runner.HttpRequest;
import org.apache.apisix.plugin.runner.HttpResponse;
import org.apache.apisix.plugin.runner.filter.FilterBean;
import org.apache.apisix.plugin.runner.filter.FilterChain;
import org.apache.apisix.plugin.runner.filter.PluginFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

@@ -43,35 +44,18 @@ public class A6HandlerConfiguration {
private final Logger logger = LoggerFactory.getLogger(A6HandlerConfiguration.class);

@Bean
public A6ConfigHandler createConfigHandler(Cache<Long, Req> cache) {
return new A6ConfigHandler(cache);
}

@Bean
public A6HttpCallHandler createHttpHandler(ObjectProvider<FilterBean> beanProvider, Cache<Long, Req> cache) {
List<FilterBean> filterList = beanProvider.orderedStream().collect(Collectors.toList());
FilterChain chain = null;
if (!filterList.isEmpty()) {
for (int i = filterList.size() - 1; i >= 0; i--) {
chain = new FilterChain(filterList.get(i), chain);
}
public A6ConfigHandler createConfigHandler(Cache<Long, A6Conf> cache, ObjectProvider<PluginFilter> beanProvider) {
List<PluginFilter> pluginFilterList = beanProvider.orderedStream().collect(Collectors.toList());
Map<String, PluginFilter> filterMap = new HashMap<>();
for (PluginFilter filter : pluginFilterList) {
filterMap.put(filter.getClass().getSimpleName(), filter);
}
return new A6HttpCallHandler(cache, chain);
return new A6ConfigHandler(cache, filterMap);
}

@Bean
public FilterBean testFilter() {
return new FilterBean() {
@Override
public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {

}

@Override
public int getOrder() {
return 0;
}
};
public A6HttpCallHandler createHttpHandler(Cache<Long, A6Conf> cache) {
return new A6HttpCallHandler(cache);
}

@Bean
@@ -19,38 +19,42 @@

import com.google.common.cache.Cache;
import io.github.api7.A6.Err.Code;
import io.github.api7.A6.PrepareConf.Req;
import lombok.RequiredArgsConstructor;
import org.apache.apisix.plugin.runner.A6Config;
import org.apache.apisix.plugin.runner.A6Conf;
import org.apache.apisix.plugin.runner.A6ErrResponse;
import org.apache.apisix.plugin.runner.A6Request;
import org.apache.apisix.plugin.runner.A6Response;
import org.apache.apisix.plugin.runner.HttpRequest;
import org.apache.apisix.plugin.runner.HttpResponse;
import org.apache.apisix.plugin.runner.filter.FilterChain;
import org.apache.apisix.plugin.runner.filter.PluginFilterChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

@RequiredArgsConstructor
public class A6HttpCallHandler implements Handler {
private final Cache<Long, Req> cache;
private final Logger logger = LoggerFactory.getLogger(A6HttpCallHandler.class);

private final FilterChain chain;
private final Cache<Long, A6Conf> cache;

@Override
public void handle(A6Request request, A6Response response) {
HttpRequest req = (HttpRequest) request;
HttpResponse rsp = (HttpResponse) response;

long confToken = ((HttpRequest) request).getConfToken();
io.github.api7.A6.PrepareConf.Req conf = cache.getIfPresent(confToken);
if (null == conf) {
A6Conf conf = cache.getIfPresent(confToken);
if (Objects.isNull(conf)) {
logger.error("cannot find conf-token: {}", confToken);
A6ErrResponse errResponse = new A6ErrResponse(Code.CONF_TOKEN_NOT_FOUND);
rsp.setErrResponse(errResponse);
return;
}

A6Config config = new A6Config(conf);
req.setConfig(config);
chain.doFilter(req, rsp);

req.initCtx(rsp, conf.getReq());
PluginFilterChain chain = conf.getChain();
chain.filter(req, rsp);
}

}
@@ -19,7 +19,7 @@

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import io.github.api7.A6.PrepareConf.Req;
import org.apache.apisix.plugin.runner.A6Conf;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -28,10 +28,10 @@

@Configuration
public class CacheConfiguration {

@Bean
public Cache<Long, Req> configurationCache(@Value("${cache.config.expired:5000}") long expired,
@Value("${cache.config.capacity:500}") int capacity) {
public Cache<Long, A6Conf> configurationCache(@Value("${cache.config.expired:5000}") long expired,
@Value("${cache.config.capacity:500}") int capacity) {
return CacheBuilder.newBuilder().expireAfterWrite(Duration.ofMillis(expired)).maximumSize(capacity).build();
}
}
@@ -19,13 +19,25 @@

import io.github.api7.A6.PrepareConf.Req;
import io.github.api7.A6.TextEntry;
import org.apache.apisix.plugin.runner.filter.PluginFilterChain;

public class A6Config {
public class A6Conf {

public Req getReq() {
return req;
}

private final Req req;

public A6Config(Req req) {
public PluginFilterChain getChain() {
return chain;
}

private final PluginFilterChain chain;

public A6Conf(Req req, PluginFilterChain chain) {
this.req = req;
this.chain = chain;
}

public String get(String key) {
@@ -18,58 +18,115 @@
package org.apache.apisix.plugin.runner;

import io.github.api7.A6.HTTPReqCall.Req;
import lombok.Setter;
import io.github.api7.A6.TextEntry;
import org.apache.apisix.plugin.runner.filter.PluginFilter;

import java.nio.ByteBuffer;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

// @Readable
public class HttpRequest implements A6Request {

private final Req req;

private int id;
private HttpResponse response;

private io.github.api7.A6.PrepareConf.Req config;

private Long requestId;

private String sourceIP;

private Method method;

private String path;

private Map<String, String> parameter;

private Map<String, String> headers;

private long confToken;

@Setter
private A6Config config;

private Map<String, Object> data;
private Map<String, String> args;

public HttpRequest(Req req) {
this.req = req;
}

public String getConfig(PluginFilter filter) {
for (int i = 0; i < config.confLength(); i++) {
TextEntry conf = config.conf(i);
if (conf.name().equals(filter.getClass().getSimpleName())) {
return conf.value();
}
}
return null;
}

public long getRequestId() {
return req.id();
if (Objects.isNull(requestId)) {
requestId = req.id();

}
return requestId;
}

public String getSourceIP() {
return ""; // TODO
if (Objects.isNull(sourceIP)) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < req.srcIpLength(); i++) {
builder.append(req.srcIp(i)).append('.');
}
sourceIP = builder.substring(0, builder.length() - 1);
}

return sourceIP;
}

public Method getMethod() {
return Method.values()[req.method()];
if (Objects.isNull(method)) {
method = Method.values()[req.method()];
}
return method;
}

public String getPath() {
return req.path(); // FiXME
if (Objects.isNull(path)) {
path = req.path();
}
return path;
}

public String getParameter(String name) {
return parameter.get(name);
public void setPath(String path) {
response.setPath(path);
}

public Map<String, String> getHeaders() {
if (Objects.isNull(headers)) {
headers = new HashMap<>();
for (int i = 0; i < req.headersLength(); i++) {
TextEntry header = req.headers(i);
headers.put(header.name(), header.value());
}
}
return headers;
}

public void setHeader(String headerKey, String headerValue) {
response.setReqHeader(headerKey, headerValue);
}

public Map<String, String> getArgs() {
if (Objects.isNull(args)) {
args = new HashMap<>();
for (int i = 0; i < req.argsLength(); i++) {
TextEntry arg = req.args(i);
args.put(arg.name(), arg.value());
}
}
return args;
}

public void setArg(String argKey, String argValue) {
response.setArgs(argKey, argValue);
}

public Map getParameterMap() {
@@ -93,6 +150,11 @@ public static HttpRequest from(ByteBuffer buffer) {
return new HttpRequest(req);
}

public void initCtx(HttpResponse response, io.github.api7.A6.PrepareConf.Req config) {
this.response = response;
this.config = config;
}

@Override
public byte getType() {
return 2;

0 comments on commit a288d21

Please sign in to comment.