Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(gateway-engine): Allow policies to mutate certain connector prop…
…erties Adds IConnectorConfig, which we can expand to allow twiddling of various connector configuration aspects by policies. Signed-off-by: Marc Savy <marc@rhymewithgravy.com>
- Loading branch information
Showing
24 changed files
with
535 additions
and
101 deletions.
There are no files selected for viewing
70 changes: 70 additions & 0 deletions
70
gateway/engine/core/src/main/java/io/apiman/gateway/engine/IConnectorConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* Copyright 2018 JBoss Inc | ||
* | ||
* Licensed 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 io.apiman.gateway.engine; | ||
|
||
import java.util.Set; | ||
|
||
/** | ||
* Allows policies to mutate certain HTTP connector attributes. | ||
* | ||
* @author Marc Savy {@literal <marc@rhymewithgravy.com>} | ||
*/ | ||
public interface IConnectorConfig { | ||
/** | ||
* Suppress the named request header | ||
* | ||
* @param headerName the header name | ||
*/ | ||
void suppressRequestHeader(String headerName); | ||
|
||
/** | ||
* Suppress the named response header | ||
* | ||
* @param headerName the header name | ||
*/ | ||
void suppressResponseHeader(String headerName); | ||
|
||
/** | ||
* Permit a request header that may be suppressed. | ||
* | ||
* @param headerName the header name | ||
*/ | ||
void permitRequestHeader(String headerName); | ||
|
||
/** | ||
* Permit a response header that may be suppressed. | ||
* | ||
* @param headerName the header name | ||
*/ | ||
void permitResponseHeader(String headerName); | ||
|
||
/** | ||
* Unmodifiable request headers. | ||
* | ||
* @return the suppressed request headers | ||
*/ | ||
Set<String> getSuppressedRequestHeaders(); | ||
|
||
/** | ||
* Unmodifiable response headers. | ||
* | ||
* @return the suppressed response headers | ||
*/ | ||
Set<String> getSuppressedResponseHeaders(); | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
gateway/engine/core/src/main/java/io/apiman/gateway/engine/impl/AbstractConnectorConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* | ||
* Copyright 2018 JBoss Inc | ||
* | ||
* Licensed 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 io.apiman.gateway.engine.impl; | ||
|
||
import io.apiman.gateway.engine.IConnectorConfig; | ||
|
||
import java.util.Collections; | ||
import java.util.Set; | ||
import java.util.TreeSet; | ||
|
||
/** | ||
* Connector configuration with lazy initialisation of customised suppressions. | ||
* | ||
* Implementors should provide a static immutable default maps to {@link AbstractConnectorConfig}. | ||
* This will be copied when needed into a mutable map (i.e. when the user adds/removes something). | ||
* | ||
* Future work could include caching common suppression maps, potentially. | ||
* | ||
* @author Marc Savy {@literal <marc@rhymewithgravy.com>} | ||
*/ | ||
public abstract class AbstractConnectorConfig implements IConnectorConfig { | ||
|
||
Set<String> suppressedRequestHeaders; | ||
boolean modifiedDefaultRequestHeaders = false; | ||
|
||
Set<String> suppressedResponseHeaders; | ||
boolean modifiedDefaultResponseHeaders = false; | ||
|
||
// TODO: cache common request and response suppression maps. Some quick and dirty way of looking it up? | ||
// static LRUMap<String, Set<String>> cache = new LRUMap<String, Set<String>>(1000) { | ||
// private static final long serialVersionUID = -18620070710843930L; | ||
// | ||
// @Override | ||
// protected void handleRemovedElem(java.util.Map.Entry<String, Set<String>> eldest) { | ||
// // Don't need to do anything. | ||
// } | ||
// }; | ||
|
||
/** | ||
* Suppressed request headers | ||
* Suppressed response headers | ||
* | ||
* @param suppressedRequestHeaders request headers to suppress | ||
* @param suppressedResponseHeaders response headers to suppress | ||
*/ | ||
public AbstractConnectorConfig(Set<String> suppressedRequestHeaders, Set<String> suppressedResponseHeaders) { | ||
this.suppressedRequestHeaders = suppressedRequestHeaders; | ||
this.suppressedResponseHeaders = suppressedResponseHeaders; | ||
} | ||
|
||
/** | ||
* Construct no suppressed request nor response headers. | ||
*/ | ||
public AbstractConnectorConfig() { | ||
this.suppressedRequestHeaders = Collections.emptySet(); | ||
this.suppressedResponseHeaders = Collections.emptySet(); | ||
} | ||
|
||
@Override | ||
public void suppressRequestHeader(String headerName) { | ||
if (!suppressedRequestHeaders.contains(headerName)) { | ||
copyRequestMap(); | ||
suppressedRequestHeaders.add(headerName); | ||
} | ||
} | ||
|
||
@Override | ||
public void suppressResponseHeader(String headerName) { | ||
if (!suppressedResponseHeaders.contains(headerName)) { | ||
copyResponseMap(); | ||
suppressedResponseHeaders.add(headerName); | ||
} | ||
} | ||
|
||
@Override | ||
public void permitRequestHeader(String headerName) { | ||
if (suppressedRequestHeaders.contains(headerName)) { | ||
copyRequestMap(); | ||
suppressedRequestHeaders.remove(headerName); | ||
} | ||
} | ||
|
||
@Override | ||
public void permitResponseHeader(String headerName) { | ||
if (suppressedResponseHeaders.contains(headerName)) { | ||
copyResponseMap(); | ||
suppressedResponseHeaders.remove(headerName); | ||
} | ||
} | ||
|
||
@Override | ||
public Set<String> getSuppressedRequestHeaders() { | ||
return Collections.unmodifiableSet(suppressedRequestHeaders); | ||
} | ||
|
||
@Override | ||
public Set<String> getSuppressedResponseHeaders() { | ||
return Collections.unmodifiableSet(suppressedResponseHeaders); | ||
} | ||
|
||
private void copyRequestMap() { | ||
if (!modifiedDefaultRequestHeaders) { | ||
TreeSet<String> reqCopy = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); | ||
reqCopy.addAll(suppressedRequestHeaders); | ||
modifiedDefaultRequestHeaders = true; | ||
this.suppressedRequestHeaders = reqCopy; | ||
} | ||
} | ||
|
||
private void copyResponseMap() { | ||
if (!modifiedDefaultResponseHeaders) { | ||
TreeSet<String> resCopy = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); | ||
resCopy.addAll(suppressedResponseHeaders); | ||
modifiedDefaultResponseHeaders = true; | ||
this.suppressedResponseHeaders = resCopy; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
gateway/engine/core/src/test/java/io/apiman/gateway/engine/impl/TestConnectorConfigImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright 2018 JBoss Inc | ||
* | ||
* Licensed 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 io.apiman.gateway.engine.impl; | ||
|
||
import io.apiman.gateway.engine.IConnectorConfig; | ||
|
||
import java.util.Set; | ||
import java.util.TreeSet; | ||
/** | ||
* Test implementation of {@link IConnectorConfig} | ||
* | ||
* @author Marc Savy {@literal <marc@rhymewithgravy.com>} | ||
*/ | ||
@SuppressWarnings("nls") | ||
public class TestConnectorConfigImpl extends AbstractConnectorConfig { | ||
static final Set<String> REQUEST = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); | ||
static final Set<String> RESPONSE = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); | ||
|
||
static { | ||
REQUEST.add("Transfer-Encoding"); | ||
REQUEST.add("X-API-Key"); | ||
REQUEST.add("Host"); | ||
|
||
RESPONSE.add("Transfer-Encoding"); | ||
RESPONSE.add("Connection"); | ||
} | ||
|
||
public TestConnectorConfigImpl() { | ||
super(REQUEST, RESPONSE); | ||
} | ||
} |
Oops, something went wrong.