| /* |
| * 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(); |
| } |
| } |