blob: d906de63ba5b1a3f651d17447ddba187ae2535bc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.servicecomb.core.invocation.endpoint;
import static com.google.common.collect.ImmutableMap.of;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import org.apache.http.client.utils.URIBuilder;
import org.apache.servicecomb.core.Endpoint;
import org.apache.servicecomb.core.SCBEngine;
import org.apache.servicecomb.core.Transport;
import org.apache.servicecomb.core.exception.Exceptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class EndpointUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(EndpointUtils.class);
private static final String HTTP = "http";
private static final String HTTPS = "https";
private static final String H2C = "h2c";
private static final String H2 = "h2";
private static final String HTTP2 = "http2";
private static final int DEFAULT_HTTP_PORT = 80;
private static final int DEFAULT_HTTPS_PORT = 443;
private static class SchemeMeta {
String protocol;
boolean ssl;
int defaultPort;
public SchemeMeta(String protocol, boolean ssl, int defaultPort) {
this.protocol = protocol;
this.ssl = ssl;
this.defaultPort = defaultPort;
}
}
private static final Map<String, SchemeMeta> SCHEME_META_MAP = of(
HTTP, new SchemeMeta(null, false, DEFAULT_HTTP_PORT),
HTTPS, new SchemeMeta(null, true, DEFAULT_HTTPS_PORT),
H2C, new SchemeMeta(HTTP2, false, DEFAULT_HTTP_PORT),
H2, new SchemeMeta(HTTP2, true, DEFAULT_HTTPS_PORT)
);
private EndpointUtils() {
}
/**
*
* @param uriEndpoint eg: rest://xxx?sslEnabled=true
* @return Endpoint object
*/
public static Endpoint parse(String uriEndpoint) {
URI uri = URI.create(uriEndpoint);
Transport transport = SCBEngine.getInstance().getTransportManager().findTransport(uri.getScheme());
if (transport == null) {
LOGGER.error("not deployed transport, uri={}.", uriEndpoint);
throw Exceptions.genericConsumer("the endpoint's transport is not found.");
}
return new Endpoint(transport, uriEndpoint);
}
/**
* <pre>
* http://xxx -> rest://xxx
* https://xxx -> rest://xxx?sslEnabled=true
*
* h2c://xxx -> rest://xxx?protocol=http2
* h2://xxx -> rest://xxx?sslEnabled=true&protocol=http2
*
* xxx -> rest://xxx:port?protocol=http2
* xxx?a=a1 -> rest://xxx:port?a=a1&protocol=http2
* other://xxx -> other://xxx
* </pre>
*
* This method provided for convenience of handling user input endpoints, and do not have a strict meaning. Make sure all unit test cases
* work before change.
**/
public static String formatFromUri(String inputUri) {
try {
return doFormatFromUri(inputUri);
} catch (URISyntaxException e) {
throw new IllegalStateException("failed to convert uri to endpoint.", e);
}
}
private static String doFormatFromUri(String inputUri) throws URISyntaxException {
URIBuilder builder = new URIBuilder(inputUri);
if (builder.getScheme() == null) {
builder.setScheme(H2C);
builder.setHost(extractHostFromPath(builder));
builder.setPath(null);
}
SchemeMeta schemeMeta = SCHEME_META_MAP.get(builder.getScheme());
if (schemeMeta == null) {
return inputUri;
}
return format(builder, schemeMeta);
}
private static String extractHostFromPath(URIBuilder builder) {
String path = builder.getPath();
if (path == null) {
return null;
}
if (path.startsWith("/")) {
path = path.substring(1);
}
if (path.contains("/")) {
path = path.substring(0, path.indexOf("/"));
}
return path;
}
private static String format(URIBuilder builder, SchemeMeta schemeMeta) throws URISyntaxException {
if (schemeMeta.ssl) {
builder.addParameter("sslEnabled", "true");
}
if (schemeMeta.protocol != null) {
builder.addParameter("protocol", schemeMeta.protocol);
}
if (builder.getPort() == -1) {
builder.setPort(schemeMeta.defaultPort);
}
return builder.setScheme("rest").build().toString();
}
}