use of io.gravitee.definition.model.endpoint.HttpEndpoint in project gravitee-management-rest-api by gravitee-io.
the class ApiServiceImpl method create.
@Override
public ApiEntity create(NewApiEntity newApiEntity, String userId) throws ApiAlreadyExistsException {
UpdateApiEntity apiEntity = new UpdateApiEntity();
apiEntity.setName(newApiEntity.getName());
apiEntity.setDescription(newApiEntity.getDescription());
apiEntity.setVersion(newApiEntity.getVersion());
// check the existence of groups
if (newApiEntity.getGroups() != null && !newApiEntity.getGroups().isEmpty()) {
try {
groupService.findByIds(newApiEntity.getGroups());
} catch (GroupsNotFoundException gnfe) {
throw new InvalidDataException("Groups [" + newApiEntity.getGroups() + "] does not exist");
}
}
apiEntity.setGroups(newApiEntity.getGroups());
Proxy proxy = new Proxy();
proxy.setContextPath(newApiEntity.getContextPath());
proxy.setEndpoints(new LinkedHashSet<>());
proxy.getEndpoints().add(new HttpEndpoint("default", newApiEntity.getEndpoint()));
apiEntity.setProxy(proxy);
List<String> declaredPaths = (newApiEntity.getPaths() != null) ? newApiEntity.getPaths() : new ArrayList<>();
if (!declaredPaths.contains("/")) {
declaredPaths.add(0, "/");
}
// Initialize with a default path and provided paths
Map<String, Path> paths = declaredPaths.stream().map(sPath -> {
Path path = new Path();
path.setPath(sPath);
return path;
}).collect(Collectors.toMap(Path::getPath, path -> path));
apiEntity.setPaths(paths);
return create0(apiEntity, userId);
}
use of io.gravitee.definition.model.endpoint.HttpEndpoint in project gravitee-gateway by gravitee-io.
the class ApiDeployerStatement method loadApi.
private Api loadApi(String apiDescriptorPath) throws Exception {
URL jsonFile = ApiDeployerStatement.class.getResource(apiDescriptorPath);
Api api = new GraviteeMapper().readValue(jsonFile, Api.class);
if (ApiLoaderInterceptor.class.isAssignableFrom(target.getClass())) {
ApiLoaderInterceptor loader = (ApiLoaderInterceptor) target;
loader.before(api);
}
boolean enhanceHttpPort = target.getClass().getAnnotation(ApiDescriptor.class).enhanceHttpPort();
if (enhanceHttpPort) {
List<Endpoint> endpoints = new ArrayList<>(api.getProxy().getEndpoints());
List<Integer> bindPorts = SocketUtils.getBindPorts();
for (int i = 0; i < bindPorts.size(); i++) {
int port = SocketUtils.getBindPorts().get(i);
if (i < endpoints.size()) {
Endpoint edpt = endpoints.get(i);
URL target = new URL(edpt.getTarget());
URL newTarget = new URL(target.getProtocol(), target.getHost(), port, target.getFile());
edpt.setTarget(newTarget.toString());
edpt.setName(UUID.random().toString());
} else {
// Use the first defined endpoint as reference
HttpEndpoint first = (HttpEndpoint) endpoints.get(0);
URL target = new URL(first.getTarget());
URL newTarget = new URL(target.getProtocol(), target.getHost(), port, target.getFile());
HttpEndpoint edpt = new HttpEndpoint(UUID.random().toString(), newTarget.toString());
edpt.setHttpClientOptions(first.getHttpClientOptions());
api.getProxy().getEndpoints().add(edpt);
}
}
}
if (ApiLoaderInterceptor.class.isAssignableFrom(target.getClass())) {
ApiLoaderInterceptor loader = (ApiLoaderInterceptor) target;
loader.after(api);
}
return api;
}
use of io.gravitee.definition.model.endpoint.HttpEndpoint in project gravitee-gateway by gravitee-io.
the class ProxyValidatorTest method validate_proxy_correctContextPathAndTarget.
/*
@Test(expected = ValidationException.class)
public void validate_proxy_badTarget() {
Proxy proxyDefinition = new Proxy();
proxyDefinition.setContextPath("/");
proxyDefinition.setEndpoint("toto");
Api definition = new Api();
definition.setProxy(proxyDefinition);
new ProxyValidator().validate(definition);
}
*/
@Test
public void validate_proxy_correctContextPathAndTarget() {
Proxy proxyDefinition = new Proxy();
proxyDefinition.setContextPath("/context-path");
proxyDefinition.setEndpoints(new LinkedHashSet<>());
proxyDefinition.getEndpoints().add(new HttpEndpoint("name", "http://localhost"));
Api definition = new Api();
definition.setProxy(proxyDefinition);
new ProxyValidator().validate(definition);
}
use of io.gravitee.definition.model.endpoint.HttpEndpoint in project gravitee-gateway by gravitee-io.
the class EndpointHealthcheckResolver method resolve.
/**
* Returns a {@link Stream} of {@link Endpoint} which have to be health-checked.
*
* @param api
* @return
*/
public List<EndpointRule> resolve(Api api) {
HealthCheckService rootHealthCheck = api.getServices().get(HealthCheckService.class);
Stream<Endpoint> endpoints = api.getProxy().getEndpoints().stream();
// Only HTTP endpoint
Stream<HttpEndpoint> httpEndpoints = endpoints.filter(endpoint -> endpoint.getType() == EndpointType.HTTP).map(endpoint -> (HttpEndpoint) endpoint);
// Filtering endpoints according to tenancy configuration
if (gatewayConfiguration.tenant().isPresent()) {
String tenant = gatewayConfiguration.tenant().get();
httpEndpoints = httpEndpoints.filter(endpoint -> endpoint.getTenants() != null && endpoint.getTenants().contains(tenant));
}
// Remove backup endpoints
httpEndpoints = httpEndpoints.filter(endpoint -> !endpoint.isBackup());
// Keep only endpoints where health-check is enabled or not settled (inherit from service)
httpEndpoints = httpEndpoints.filter(endpoint -> (endpoint.getHealthCheck() == null) || (endpoint.getHealthCheck() != null && endpoint.getHealthCheck().isEnabled()));
return httpEndpoints.map((Function<HttpEndpoint, EndpointRule>) endpoint -> new DefaultEndpointRule(api.getId(), endpoint, (endpoint.getHealthCheck() == null || endpoint.getHealthCheck().isInherit()) ? rootHealthCheck : endpoint.getHealthCheck())).collect(Collectors.toList());
}
use of io.gravitee.definition.model.endpoint.HttpEndpoint in project gravitee-gateway by gravitee-io.
the class HttpEndpointRuleHandler method handle.
@Override
public void handle(Long timer) {
HttpEndpoint endpoint = (HttpEndpoint) rule.endpoint();
logger.debug("Running health-check for endpoint: {} [{}]", endpoint.getName(), endpoint.getTarget());
// Run request for each step
for (io.gravitee.definition.model.services.healthcheck.Step step : rule.steps()) {
try {
URI hcRequestUri = create(endpoint.getTarget(), step.getRequest());
// Prepare HTTP client
HttpClientOptions httpClientOptions = new HttpClientOptions().setMaxPoolSize(1).setKeepAlive(false).setTcpKeepAlive(false);
if (endpoint.getHttpClientOptions() != null) {
httpClientOptions.setIdleTimeout((int) (endpoint.getHttpClientOptions().getIdleTimeout() / 1000)).setConnectTimeout((int) endpoint.getHttpClientOptions().getConnectTimeout()).setTryUseCompression(endpoint.getHttpClientOptions().isUseCompression());
}
// Configure HTTP proxy
HttpProxy proxy = endpoint.getHttpProxy();
if (proxy != null && proxy.isEnabled()) {
ProxyOptions proxyOptions = new ProxyOptions().setHost(proxy.getHost()).setPort(proxy.getPort()).setUsername(proxy.getUsername()).setPassword(proxy.getPassword()).setType(ProxyType.valueOf(proxy.getType().name()));
httpClientOptions.setProxyOptions(proxyOptions);
}
// Configure TLS if required
HttpClientSslOptions sslOptions = endpoint.getHttpClientSslOptions();
if (sslOptions != null && sslOptions.isEnabled()) {
httpClientOptions.setSsl(sslOptions.isEnabled()).setVerifyHost(sslOptions.isHostnameVerifier()).setTrustAll(sslOptions.isTrustAll());
if (sslOptions.getPem() != null && !sslOptions.getPem().isEmpty()) {
httpClientOptions.setPemTrustOptions(new PemTrustOptions().addCertValue(io.vertx.core.buffer.Buffer.buffer(sslOptions.getPem())));
}
} else if (HTTPS_SCHEME.equalsIgnoreCase(hcRequestUri.getScheme())) {
// SSL is not configured but the endpoint scheme is HTTPS so let's enable the SSL on Vert.x HTTP client
// automatically
httpClientOptions.setSsl(true).setTrustAll(true);
}
HttpClient httpClient = vertx.createHttpClient(httpClientOptions);
final int port = hcRequestUri.getPort() != -1 ? hcRequestUri.getPort() : (HTTPS_SCHEME.equals(hcRequestUri.getScheme()) ? 443 : 80);
String relativeUri = (hcRequestUri.getRawQuery() == null) ? hcRequestUri.getRawPath() : hcRequestUri.getRawPath() + '?' + hcRequestUri.getRawQuery();
// Run health-check
HttpClientRequest healthRequest = httpClient.request(HttpMethod.valueOf(step.getRequest().getMethod().name().toUpperCase()), port, hcRequestUri.getHost(), relativeUri);
// Set timeout on request
if (endpoint.getHttpClientOptions() != null) {
healthRequest.setTimeout(endpoint.getHttpClientOptions().getReadTimeout());
}
// Prepare request
if (step.getRequest().getHeaders() != null) {
step.getRequest().getHeaders().forEach(httpHeader -> healthRequest.headers().set(httpHeader.getName(), httpHeader.getValue()));
}
final EndpointStatus.Builder healthBuilder = EndpointStatus.forEndpoint(rule.api(), endpoint.getName()).on(System.currentTimeMillis());
long startTime = System.currentTimeMillis();
Request request = new Request();
request.setMethod(step.getRequest().getMethod());
request.setUri(hcRequestUri.toString());
healthRequest.handler(response -> response.bodyHandler(buffer -> {
long endTime = System.currentTimeMillis();
logger.debug("Health-check endpoint returns a response with a {} status code", response.statusCode());
String body = buffer.toString();
EndpointStatus.StepBuilder stepBuilder = validateAssertions(step, new EvaluableHttpResponse(response, body));
stepBuilder.request(request);
stepBuilder.responseTime(endTime - startTime);
Response healthResponse = new Response();
healthResponse.setStatus(response.statusCode());
// If validation fail, store request and response data
if (!stepBuilder.isSuccess()) {
request.setBody(step.getRequest().getBody());
if (step.getRequest().getHeaders() != null) {
HttpHeaders reqHeaders = new HttpHeaders();
step.getRequest().getHeaders().forEach(httpHeader -> reqHeaders.put(httpHeader.getName(), Collections.singletonList(httpHeader.getValue())));
request.setHeaders(reqHeaders);
}
// Extract headers
HttpHeaders headers = new HttpHeaders();
response.headers().names().forEach(headerName -> headers.put(headerName, response.headers().getAll(headerName)));
healthResponse.setHeaders(headers);
// Store body
healthResponse.setBody(body);
}
stepBuilder.response(healthResponse);
// Append step stepBuilder
healthBuilder.step(stepBuilder.build());
report(healthBuilder.build());
// Close client
httpClient.close();
}));
healthRequest.exceptionHandler(event -> {
long endTime = System.currentTimeMillis();
EndpointStatus.StepBuilder stepBuilder = EndpointStatus.forStep(step.getName());
stepBuilder.fail(event.getMessage());
Response healthResponse = new Response();
// Extract request information
request.setBody(step.getRequest().getBody());
if (step.getRequest().getHeaders() != null) {
HttpHeaders reqHeaders = new HttpHeaders();
step.getRequest().getHeaders().forEach(httpHeader -> reqHeaders.put(httpHeader.getName(), Collections.singletonList(httpHeader.getValue())));
request.setHeaders(reqHeaders);
}
if (event instanceof ConnectTimeoutException) {
stepBuilder.fail(event.getMessage());
healthResponse.setStatus(HttpStatusCode.REQUEST_TIMEOUT_408);
} else {
healthResponse.setStatus(HttpStatusCode.SERVICE_UNAVAILABLE_503);
}
Step result = stepBuilder.build();
result.setResponse(healthResponse);
result.setRequest(request);
result.setResponseTime(endTime - startTime);
// Append step result
healthBuilder.step(result);
report(healthBuilder.build());
try {
// Close client
httpClient.close();
} catch (IllegalStateException ise) {
// Do not take care about exception when closing client
}
});
// Send request
logger.debug("Execute health-check request: {}", healthRequest);
if (step.getRequest().getBody() != null && !step.getRequest().getBody().isEmpty()) {
healthRequest.end(step.getRequest().getBody());
} else {
healthRequest.end();
}
} catch (Exception ex) {
logger.error("An unexpected error occurs", ex);
}
}
}
Aggregations