-
-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
837 additions
and
167 deletions.
There are no files selected for viewing
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
116 changes: 116 additions & 0 deletions
116
services-api/src/main/java/io/scalecube/services/api/DynamicQualifier.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,116 @@ | ||
package io.scalecube.services.api; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.StringJoiner; | ||
import java.util.regex.Pattern; | ||
|
||
public final class DynamicQualifier { | ||
|
||
private final String qualifier; | ||
private final Pattern pattern; | ||
private final List<String> pathVariables; | ||
private final int size; | ||
|
||
public DynamicQualifier(String qualifier) { | ||
if (!qualifier.contains(":")) { | ||
throw new IllegalArgumentException("Illegal dynamic qualifier: " + qualifier); | ||
} | ||
|
||
final var pathVariables = new ArrayList<String>(); | ||
final var sb = new StringBuilder(); | ||
for (var s : qualifier.split("/")) { | ||
if (s.startsWith(":")) { | ||
final var pathVar = s.substring(1); | ||
sb.append("(?<").append(pathVar).append(">.*?)"); | ||
pathVariables.add(pathVar); | ||
} else { | ||
sb.append(s); | ||
} | ||
sb.append("/"); | ||
} | ||
sb.setLength(sb.length() - 1); | ||
|
||
this.qualifier = qualifier; | ||
this.pattern = Pattern.compile(sb.toString()); | ||
this.pathVariables = Collections.unmodifiableList(pathVariables); | ||
this.size = sizeOf(qualifier); | ||
} | ||
|
||
public String qualifier() { | ||
return qualifier; | ||
} | ||
|
||
public Pattern pattern() { | ||
return pattern; | ||
} | ||
|
||
public List<String> pathVariables() { | ||
return pathVariables; | ||
} | ||
|
||
public int size() { | ||
return size; | ||
} | ||
|
||
public Map<String, String> matchQualifier(String input) { | ||
if (size != sizeOf(input)) { | ||
return null; | ||
} | ||
|
||
final var matcher = pattern.matcher(input); | ||
if (!matcher.matches()) { | ||
return null; | ||
} | ||
|
||
final var map = new LinkedHashMap<String, String>(); | ||
for (var pathVar : pathVariables) { | ||
final var value = matcher.group(pathVar); | ||
Objects.requireNonNull( | ||
value, "Path variable value must not be null, path variable: " + pathVar); | ||
map.put(pathVar, value); | ||
} | ||
|
||
return map; | ||
} | ||
|
||
private static int sizeOf(String value) { | ||
int count = 0; | ||
for (int i = 0, length = value.length(); i < length; i++) { | ||
if (value.charAt(i) == '/') { | ||
count++; | ||
} | ||
} | ||
return count; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
return Objects.equals(qualifier, ((DynamicQualifier) o).qualifier); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hashCode(qualifier); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return new StringJoiner(", ", DynamicQualifier.class.getSimpleName() + "[", "]") | ||
.add("qualifier='" + qualifier + "'") | ||
.add("pattern=" + pattern) | ||
.add("pathVariables=" + pathVariables) | ||
.add("size=" + size) | ||
.toString(); | ||
} | ||
} |
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
62 changes: 62 additions & 0 deletions
62
services-api/src/main/java/io/scalecube/services/methods/RequestContext.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,62 @@ | ||
package io.scalecube.services.methods; | ||
|
||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.StringJoiner; | ||
import reactor.core.publisher.Mono; | ||
|
||
public class RequestContext { | ||
|
||
private final Map<String, String> headers; | ||
private final Object principal; | ||
private final Map<String, String> pathVars; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param headers message headers | ||
* @param principal authenticated principal (optional) | ||
* @param pathVars path variables (optional) | ||
*/ | ||
public RequestContext( | ||
Map<String, String> headers, Object principal, Map<String, String> pathVars) { | ||
this.headers = Collections.unmodifiableMap(new HashMap<>(headers)); | ||
this.principal = principal; | ||
this.pathVars = pathVars != null ? Map.copyOf(pathVars) : null; | ||
} | ||
|
||
public Map<String, String> headers() { | ||
return headers; | ||
} | ||
|
||
public String header(String name) { | ||
return headers.get(name); | ||
} | ||
|
||
public <T> T principal() { | ||
//noinspection unchecked | ||
return (T) principal; | ||
} | ||
|
||
public Map<String, String> pathVars() { | ||
return pathVars; | ||
} | ||
|
||
public String pathVar(String name) { | ||
return pathVars != null ? pathVars.get(name) : null; | ||
} | ||
|
||
public static Mono<RequestContext> deferContextual() { | ||
return Mono.deferContextual(context -> Mono.just(context.get(RequestContext.class))); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return new StringJoiner(", ", RequestContext.class.getSimpleName() + "[", "]") | ||
.add("headers=" + headers) | ||
.add("principal=" + principal) | ||
.add("pathVars=" + pathVars) | ||
.toString(); | ||
} | ||
} |
Oops, something went wrong.