Skip to content

Commit

Permalink
#606 - Draft commit to analyze implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
almeidast committed Aug 20, 2024
1 parent 3952a9e commit 5c67bb0
Show file tree
Hide file tree
Showing 7 changed files with 458 additions and 266 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Copyright 2024 by Swiss Post, Information Technology
*/

package org.swisspush.gateleen.hook;

import io.vertx.core.json.JsonObject;
import io.vertx.core.net.ProxyOptions;

import javax.annotation.Nullable;
import java.util.Optional;

/**
* Represents the configuration for a destination in the routing or hook system.
*
* @author almeidast
*/
public class DestinationConfig {
private String destinationUri;
private Optional<ProxyOptions> proxyOptions;
private boolean fullUrl;
private Integer connectionPoolSize;
private Integer maxWaitQueueSize;
private Integer timeout;

/**
* Constructor for creating a DestinationConfig with the given parameters.
*
* @param destinationUri The URI of the destination.
* @param proxyOptions Optional proxy settings for this destination.
* @param fullUrl Indicates whether to use the full URL when forwarding.
* @param connectionPoolSize The size of the connection pool.
* @param maxWaitQueueSize The maximum number of requests in the wait queue.
* @param timeout The timeout for requests in milliseconds.
*/
public DestinationConfig(String destinationUri, @Nullable ProxyOptions proxyOptions, boolean fullUrl,
@Nullable Integer connectionPoolSize, @Nullable Integer maxWaitQueueSize, @Nullable Integer timeout) {
this.destinationUri = destinationUri;
this.proxyOptions = Optional.ofNullable(proxyOptions);
this.fullUrl = fullUrl;
this.connectionPoolSize = connectionPoolSize;
this.maxWaitQueueSize = maxWaitQueueSize;
this.timeout = timeout;
}

/**
* Gets the destination URI.
*
* @return The destination URI.
*/
public String getDestinationUri() {
return destinationUri;
}

/**
* Gets the proxy options for this destination, if any.
*
* @return An Optional containing the proxy options if present.
*/
public Optional<ProxyOptions> getProxyOptions() {
return proxyOptions;
}

/**
* Returns whether the full URL should be used when forwarding.
*
* @return true if the full URL should be used, false otherwise.
*/
public boolean isFullUrl() {
return fullUrl;
}

/**
* Gets the connection pool size.
*
* @return The connection pool size, or null if not set.
*/
@Nullable
public Integer getConnectionPoolSize() {
return connectionPoolSize;
}

/**
* Gets the maximum number of requests allowed in the wait queue.
*
* @return The maximum wait queue size, or null if not set.
*/
@Nullable
public Integer getMaxWaitQueueSize() {
return maxWaitQueueSize;
}

/**
* Gets the timeout for requests in milliseconds.
*
* @return The timeout, or null if not set.
*/
@Nullable
public Integer getTimeout() {
return timeout;
}

/**
* Creates a DestinationConfig from a JSON object.
*
* @param jsonObject The JSON object containing the configuration.
* @return A DestinationConfig object.
*/
public static DestinationConfig fromJson(JsonObject jsonObject) {
String destinationUri = jsonObject.getString("destinationUri");
ProxyOptions proxyOptions = jsonObject.containsKey("proxyOptions")
? new ProxyOptions(jsonObject.getJsonObject("proxyOptions"))
: null;
boolean fullUrl = jsonObject.getBoolean("fullUrl", false);
Integer connectionPoolSize = jsonObject.getInteger("connectionPoolSize");
Integer maxWaitQueueSize = jsonObject.getInteger("maxWaitQueueSize");
Integer timeout = jsonObject.getInteger("timeout");

return new DestinationConfig(destinationUri, proxyOptions, fullUrl, connectionPoolSize, maxWaitQueueSize, timeout);
}

/**
* Converts this DestinationConfig to a JSON object.
*
* @return A JSON object representing this configuration.
*/
public JsonObject toJson() {
JsonObject jsonObject = new JsonObject()
.put("destinationUri", destinationUri)
.put("fullUrl", fullUrl);

if (proxyOptions.isPresent()) {
jsonObject.put("proxyOptions", proxyOptions.get().toJson());
}

if (connectionPoolSize != null) {
jsonObject.put("connectionPoolSize", connectionPoolSize);
}

if (maxWaitQueueSize != null) {
jsonObject.put("maxWaitQueueSize", maxWaitQueueSize);
}

if (timeout != null) {
jsonObject.put("timeout", timeout);
}

return jsonObject;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -790,21 +790,6 @@ private void callListener(RoutingContext ctx, final Buffer buffer, final List<Li
path = request.uri().replace(listener.getMonitoredUrl(), "");
}

String targetUri;

// internal
if (listener.getHook().getDestination().startsWith("/")) {
targetUri = listener.getListener() + path;
log.debug(" > internal target: {}", targetUri);
}
// external
else {
targetUri = hookRootUri + LISTENER_HOOK_TARGET_PATH + listener.getListener() + path;
log.debug(" > external target: {}", targetUri);
}

// Create a new multimap, copied from the original request,
// so that the original request is not overridden with the new values.
HeadersMultiMap queueHeaders = new HeadersMultiMap();
queueHeaders.addAll(request.headers());

Expand All @@ -831,28 +816,44 @@ private void callListener(RoutingContext ctx, final Buffer buffer, final List<Li

QueueingStrategy queueingStrategy = listener.getHook().getQueueingStrategy();

if (queueingStrategy instanceof DefaultQueueingStrategy) {
requestQueue.enqueue(new HttpRequest(request.method(), targetUri, queueHeaders, buffer.getBytes()), queue, handler);
} else if (queueingStrategy instanceof DiscardPayloadQueueingStrategy) {
if (HttpRequestHeader.containsHeader(queueHeaders, CONTENT_LENGTH)) {
queueHeaders.set(CONTENT_LENGTH.getName(), "0");
// Process each destination
for (DestinationConfig destinationConfig : listener.getHook().getDestinations()) {
String targetUri;

// internal
if (destinationConfig.getDestinationUri().startsWith("/")) {
targetUri = listener.getListener() + path;
log.debug(" > internal target: {}", targetUri);
}
// external
else {
targetUri = destinationConfig.getDestinationUri() + path;
log.debug(" > external target: {}", targetUri);
}
requestQueue.enqueue(new HttpRequest(request.method(), targetUri, queueHeaders, null), queue, handler);
} else if (queueingStrategy instanceof ReducedPropagationQueueingStrategy) {
if (reducedPropagationManager != null) {
reducedPropagationManager.processIncomingRequest(request.method(), targetUri, queueHeaders, buffer,
queue, ((ReducedPropagationQueueingStrategy) queueingStrategy).getPropagationIntervalMs(), handler);

if (queueingStrategy instanceof DefaultQueueingStrategy) {
requestQueue.enqueue(new HttpRequest(request.method(), targetUri, queueHeaders, buffer.getBytes()), queue, handler);
} else if (queueingStrategy instanceof DiscardPayloadQueueingStrategy) {
if (HttpRequestHeader.containsHeader(queueHeaders, CONTENT_LENGTH)) {
queueHeaders.set(CONTENT_LENGTH.getName(), "0");
}
requestQueue.enqueue(new HttpRequest(request.method(), targetUri, queueHeaders, null), queue, handler);
} else if (queueingStrategy instanceof ReducedPropagationQueueingStrategy) {
if (reducedPropagationManager != null) {
reducedPropagationManager.processIncomingRequest(request.method(), targetUri, queueHeaders, buffer,
queue, ((ReducedPropagationQueueingStrategy) queueingStrategy).getPropagationIntervalMs(), handler);
} else {
log.error("ReducedPropagationQueueingStrategy without configured ReducedPropagationManager. " +
"Not going to handle (enqueue) anything!");
}
} else {
log.error("ReducedPropagationQueueingStrategy without configured ReducedPropagationManager. " +
"Not going to handle (enqueue) anything!");
log.error("QueueingStrategy '{}' is not handled. Could be an error, check the source code!",
queueingStrategy.getClass().getSimpleName());
}
} else {
log.error("QueueingStrategy '{}' is not handled. Could be an error, check the source code!",
queueingStrategy.getClass().getSimpleName());
}
}

// if for e.g. the beforListeners are empty,
// if for e.g. the beforeListeners are empty,
// we have to ensure, that the original request
// is executed. This way the after handler will
// also be called properly.
Expand Down Expand Up @@ -1341,7 +1342,6 @@ private void registerListener(Buffer buffer) {
JsonObject jsonHook = storageObject.getJsonObject(HOOK);
JsonArray jsonMethods = jsonHook.getJsonArray(METHODS);


HttpHook hook = new HttpHook(jsonHook.getString(DESTINATION));
if (jsonMethods != null) {
hook.setMethods(jsonMethods.getList());
Expand All @@ -1366,8 +1366,13 @@ private void registerListener(Buffer buffer) {
}
}

if (jsonHook.containsKey(FILTER)) {
hook.setFilter(jsonHook.getString(FILTER));
if (jsonHook.containsKey("destinations")) {
JsonArray jsonDestinations = jsonHook.getJsonArray("destinations");
for (int i = 0; i < jsonDestinations.size(); i++) {
JsonObject jsonDestination = jsonDestinations.getJsonObject(i);
DestinationConfig destinationConfig = DestinationConfig.fromJson(jsonDestination);
hook.getDestinations().add(destinationConfig);
}
}

if (jsonHook.getInteger(QUEUE_EXPIRE_AFTER) != null) {
Expand Down Expand Up @@ -1441,7 +1446,6 @@ private void registerListener(Buffer buffer) {
* appropriate property in the hook object.
* <p>
* This is the same concept as in gateleen-routing:
* {@link org.swisspush.gateleen.routing.RuleFactory#setProxyOptions(Rule, JsonObject)}}
*/
private void extractAndAddProxyOptionsToHook(final JsonObject jsonHook, final HttpHook hook) {
JsonObject proxyOptions = jsonHook.getJsonObject("proxyOptions");
Expand All @@ -1455,7 +1459,6 @@ private void extractAndAddProxyOptionsToHook(final JsonObject jsonHook, final Ht
* appropriate list in the hook object.
* <p>
* This is the same concept as in gateleen-routing:
* {@link org.swisspush.gateleen.routing.RuleFactory#setStaticHeaders(Rule, JsonObject)}}
*/
private void extractAndAddStaticHeadersToHook(final JsonObject jsonHook, final HttpHook hook) {
final JsonArray headers = jsonHook.getJsonArray("headers");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public class HttpHook {
private Integer maxWaitQueueSize = null;
private ProxyOptions proxyOptions = null;
private Integer timeout = null;

// New field for handling multiple destinations
private List<DestinationConfig> destinations = new ArrayList<>();

/**
* Creates a new hook.
*
Expand Down Expand Up @@ -338,5 +342,25 @@ public void setTimeout(Integer timeout) {
*
* @param proxyOptions the custom proxy options to set
*/
public void setProxyOptions(ProxyOptions proxyOptions) { this.proxyOptions = proxyOptions; }
public void setProxyOptions(ProxyOptions proxyOptions) {
this.proxyOptions = proxyOptions;
}

/**
* Returns the list of destinations for the hook.
*
* @return a list of DestinationConfig objects
*/
public List<DestinationConfig> getDestinations() {
return destinations;
}

/**
* Sets the list of destinations for the hook.
*
* @param destinations a list of DestinationConfig objects
*/
public void setDestinations(List<DestinationConfig> destinations) {
this.destinations = destinations;
}
}
Loading

0 comments on commit 5c67bb0

Please sign in to comment.