/*
* Copyright 2013-2017 the original author or authors.
*
* 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 org.cloudfoundry.operations.applications;
import reactor.core.publisher.Mono;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
final class RouteUtils {
private RouteUtils() {
}
static Mono<DecomposedRoute> decomposeRoute(List<DomainSummary> availableDomains, String route) {
String domain = null;
String host = null;
String path = null;
Integer port = null;
String routeWithoutPath = route;
if (availableDomains.size() == 0) {
throw new IllegalArgumentException(String.format("The route %s did not match any existing domains", route));
}
List<DomainSummary> sortedDomains = availableDomains.stream()
.sorted(Comparator.<DomainSummary>comparingInt(domainSummary -> domainSummary.getName().length()).reversed())
.collect(Collectors.toList());
if (route.contains("/")) {
int index = route.indexOf("/");
path = route.substring(index);
routeWithoutPath = route.substring(0, index);
} else if (hasPort(route)) {
port = getPort(route);
}
for (DomainSummary item : sortedDomains) {
if (routeWithoutPath.contains(item.getName())) {
domain = item.getName();
if (domain.length() < routeWithoutPath.length()) {
host = routeWithoutPath.substring(0, routeWithoutPath.lastIndexOf(domain) - 1);
}
break;
}
}
if (domain == null) {
throw new IllegalArgumentException(String.format("The route %s did not match any existing domains", route));
}
if ((host != null || path != null) && port != null) {
throw new IllegalArgumentException(String.format("The route %s is invalid: Host/path cannot be set with port", route));
}
return Mono.just(DecomposedRoute.builder()
.domain(domain)
.host(host)
.path(path)
.port(port)
.build());
}
private static Integer getPort(String route) {
Pattern pattern = Pattern.compile(":\\d+$");
Matcher matcher = pattern.matcher(route);
return Integer.valueOf(route.substring(matcher.start() + 1, matcher.end()));
}
private static Boolean hasPort(String route) {
Pattern pattern = Pattern.compile(":\\d+$");
Matcher matcher = pattern.matcher(route);
return matcher.matches();
}
}