Skip to content

Commit

Permalink
Adapt the endpoints in the server (#3574)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrproliu committed Oct 18, 2023
1 parent a6f354c commit 1c74d42
Show file tree
Hide file tree
Showing 20 changed files with 640 additions and 44 deletions.
2 changes: 1 addition & 1 deletion skywalking
Submodule skywalking updated 189 files
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException;
import org.apache.skywalking.oap.server.library.server.http.HTTPServer;
import org.apache.skywalking.oap.server.library.server.http.HTTPServerConfig;
import zipkin.server.core.services.HTTPConfigurableServer;

import java.util.Collections;

Expand Down Expand Up @@ -67,7 +68,7 @@ public void prepare() throws ServiceNotProvidedException, ModuleStartException {
.acceptQueueSize(moduleConfig.getRestAcceptQueueSize())
.maxRequestHeaderSize(moduleConfig.getRestMaxRequestHeaderSize())
.build();
httpServer = new HTTPServer(httpServerConfig);
httpServer = new HTTPConfigurableServer(httpServerConfig);
httpServer.initialize();
}
}
Expand Down
5 changes: 5 additions & 0 deletions zipkin-server/http-query-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
<artifactId>zipkin-query-plugin</artifactId>
<version>${skywalking.version}</version>
</dependency>
<dependency>
<groupId>io.zipkin</groupId>
<artifactId>zipkin-server-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public class HTTPQueryConfig extends ModuleConfig {
private String uiEnvironment = "";
private long uiDefaultLookback = 900000L;
private boolean uiSearchEnabled = true;
private String allowedOrigins = "*";

private boolean uiEnable = true;
private String uiBasePath = "/zipkin";

public ZipkinQueryConfig toSkyWalkingConfig() {
final ZipkinQueryConfig result = new ZipkinQueryConfig();
Expand Down Expand Up @@ -160,4 +164,28 @@ public int getRestMaxRequestHeaderSize() {
public void setRestMaxRequestHeaderSize(int restMaxRequestHeaderSize) {
this.restMaxRequestHeaderSize = restMaxRequestHeaderSize;
}

public String getUiBasePath() {
return uiBasePath;
}

public void setUiBasePath(String uiBasePath) {
this.uiBasePath = uiBasePath;
}

public boolean getUiEnable() {
return uiEnable;
}

public void setUiEnable(boolean uiEnable) {
this.uiEnable = uiEnable;
}

public String getAllowedOrigins() {
return allowedOrigins;
}

public void setAllowedOrigins(String allowedOrigins) {
this.allowedOrigins = allowedOrigins;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,18 @@

package zipkin.server.query.http;

import com.linecorp.armeria.common.HttpData;
import com.linecorp.armeria.common.HttpHeaderNames;
import com.linecorp.armeria.common.HttpMethod;
import com.linecorp.armeria.common.HttpStatus;
import com.linecorp.armeria.common.MediaType;
import com.linecorp.armeria.common.ServerCacheControl;
import com.linecorp.armeria.server.HttpService;
import com.linecorp.armeria.server.RedirectService;
import com.linecorp.armeria.server.cors.CorsService;
import com.linecorp.armeria.server.cors.CorsServiceBuilder;
import com.linecorp.armeria.server.file.FileService;
import com.linecorp.armeria.server.file.HttpFile;
import org.apache.skywalking.oap.query.zipkin.ZipkinQueryModule;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.server.HTTPHandlerRegister;
Expand All @@ -25,12 +36,25 @@
import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException;
import org.apache.skywalking.oap.server.library.server.http.HTTPServer;
import org.apache.skywalking.oap.server.library.server.http.HTTPServerConfig;
import zipkin.server.core.services.HTTPConfigurableServer;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

import static java.nio.charset.StandardCharsets.UTF_8;

public class HTTPQueryProvider extends ModuleProvider {
static final String DEFAULT_UI_BASEPATH = "/zipkin";

private HTTPQueryConfig moduleConfig;
private HTTPServer httpServer;

@Override
public String name() {
return "zipkin";
Expand Down Expand Up @@ -68,25 +92,88 @@ public void prepare() throws ServiceNotProvidedException, ModuleStartException {
.acceptQueueSize(moduleConfig.getRestAcceptQueueSize())
.maxRequestHeaderSize(moduleConfig.getRestMaxRequestHeaderSize())
.build();
httpServer = new HTTPServer(httpServerConfig);
httpServer = new HTTPConfigurableServer(httpServerConfig);
httpServer.initialize();
}
}

@Override
public void start() throws ServiceNotProvidedException, ModuleStartException {
HTTPConfigurableServer.ServerConfiguration corsConfiguration = (server) -> {
CorsServiceBuilder corsBuilder = CorsService.builder(moduleConfig.getAllowedOrigins().split(","))
// NOTE: The property says query, and the UI does not use POST, but we allow POST?
//
// The reason is that our former CORS implementation accidentally allowed POST. People doing
// browser-based tracing relied on this, so we can't remove it by default. In the future, we
// could split the collector's CORS policy into a different property, still allowing POST
// with content-type by default.
.allowRequestMethods(HttpMethod.GET, HttpMethod.POST)
.allowRequestHeaders(HttpHeaderNames.CONTENT_TYPE,
// Use literals to avoid a runtime dependency on armeria-grpc types
HttpHeaderNames.of("X-GRPC-WEB"))
.exposeHeaders("grpc-status", "grpc-message", "armeria.grpc.ThrowableProto-bin");
server.decorator(corsBuilder::build);
};

final HTTPQueryHandler httpService = new HTTPQueryHandler(moduleConfig, getManager());
if (httpServer != null) {
httpServer.addHandler(new HTTPQueryHandler(moduleConfig, getManager()),
Collections.singletonList(HttpMethod.GET));
} else {
getManager().find(CoreModule.NAME).provider()
.getService(HTTPHandlerRegister.class).addHandler(
new HTTPQueryHandler(moduleConfig, getManager()),
Collections.singletonList(HttpMethod.GET)
);
httpServer.addHandler(httpService, Collections.singletonList(HttpMethod.GET));
httpServer.addHandler(corsConfiguration, Arrays.asList(HttpMethod.GET, HttpMethod.POST));

if (moduleConfig.getUiEnable()) {
loadUIServices((service, methods) -> httpServer.addHandler(service, methods), httpService);
}
return;
}

final HTTPHandlerRegister httpRegister = getManager().find(CoreModule.NAME).provider()
.getService(HTTPHandlerRegister.class);
httpRegister.addHandler(httpService, Collections.singletonList(HttpMethod.GET));
httpRegister.addHandler(corsConfiguration, Arrays.asList(HttpMethod.GET, HttpMethod.POST));

if (moduleConfig.getUiEnable()) {
loadUIServices(httpRegister, httpService);
}
}

private void loadUIServices(HTTPHandlerRegister httpRegister, HTTPQueryHandler httpService) {
HttpService lensIndex;
HttpService uiFileService;

final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
URL indexPage = contextClassLoader.getResource("zipkin-lens/index.html");
if (indexPage == null) {
throw new IllegalStateException("Cannot find ui pages");
}
final String uiBasePath = moduleConfig.getUiBasePath();
try {
lensIndex = maybeIndexService(uiBasePath, indexPage);
} catch (IOException e) {
throw new IllegalStateException("Cannot load ui", e);
}

ServerCacheControl maxAgeYear =
ServerCacheControl.builder().maxAgeSeconds(TimeUnit.DAYS.toSeconds(365)).build();
uiFileService = FileService.builder(contextClassLoader, "zipkin-lens")
.cacheControl(maxAgeYear)
.build();

httpRegister.addHandler((HTTPConfigurableServer.ServerConfiguration) builder -> {
builder.annotatedService().pathPrefix(uiBasePath + "/").build(httpService);
builder.serviceUnder(uiBasePath + "/", uiFileService);

builder.service(uiBasePath+ "/", lensIndex)
.service(uiBasePath + "/index.html", lensIndex)
.service(uiBasePath + "/traces/{id}", lensIndex)
.service(uiBasePath + "/dependency", lensIndex)
.service(uiBasePath + "/traceViewer", lensIndex);

builder.service("/favicon.ico", new RedirectService(HttpStatus.FOUND, uiBasePath + "/favicon.ico"))
.service("/", new RedirectService(HttpStatus.FOUND, uiBasePath + "/"))
.service(uiBasePath, new RedirectService(HttpStatus.FOUND, uiBasePath + "/"));
}, Collections.singletonList(HttpMethod.GET));
}

@Override
public void notifyAfterCompleted() throws ServiceNotProvidedException, ModuleStartException {
if (httpServer != null) {
Expand All @@ -100,4 +187,42 @@ public String[] requiredModules() {
CoreModule.NAME,
};
}

static HttpService maybeIndexService(String basePath, URL resource) throws IOException {
String maybeContent = maybeResource(basePath, resource);
if (maybeContent == null) return null;

ServerCacheControl maxAgeMinute = ServerCacheControl.builder().maxAgeSeconds(60).build();

return HttpFile.builder(HttpData.ofUtf8(maybeContent))
.contentType(MediaType.HTML_UTF_8).cacheControl(maxAgeMinute)
.build().asService();
}

static String maybeResource(String basePath, URL resource) throws IOException {
String content = copyToString(resource, UTF_8);
if (DEFAULT_UI_BASEPATH.equals(basePath)) return content;

String baseTagValue = "/".equals(basePath) ? "/" : basePath + "/";
// html-webpack-plugin seems to strip out quotes from the base tag when compiling so be
// careful with this matcher.
return content.replaceAll(
"<base href=[^>]+>", "<base href=\"" + baseTagValue + "\">"
);
}

static String copyToString(URL in, Charset charset) throws IOException {
StringBuilder out = new StringBuilder(4096);
try (InputStream input = in.openStream(); InputStreamReader reader = new InputStreamReader(input, charset)) {
char[] buffer = new char[4096];

int charsRead;
while((charsRead = reader.read(buffer)) != -1) {
out.append(buffer, 0, charsRead);
}
}

return out.toString();
}

}
20 changes: 1 addition & 19 deletions zipkin-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
<module>receiver-zipkin-scribe</module>
<module>http-query-plugin</module>
<module>health-query-plugin</module>
<module>telemetry-zipkin</module>
</modules>

<dependencyManagement>
Expand Down Expand Up @@ -216,23 +217,4 @@
</dependency>
</dependencies>

<profiles>
<profile>
<id>include-lens</id>
<activation>
<property>
<name>!skipLens</name>
</property>
</activation>
<dependencies>
<!-- Static content for the Lens UI -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>zipkin-lens</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.skywalking.oap.server.library.server.http.HTTPServerConfig;
import org.apache.skywalking.oap.server.receiver.zipkin.handler.ZipkinSpanHTTPHandler;
import org.apache.skywalking.oap.server.receiver.zipkin.trace.SpanForward;
import zipkin.server.core.services.HTTPConfigurableServer;
import zipkin.server.core.services.ZipkinConfigService;

import java.util.Arrays;
Expand Down Expand Up @@ -73,7 +74,7 @@ public void prepare() throws ServiceNotProvidedException, ModuleStartException {
.acceptQueueSize(moduleConfig.getRestAcceptQueueSize())
.maxRequestHeaderSize(moduleConfig.getRestMaxRequestHeaderSize())
.build();
httpServer = new HTTPServer(httpServerConfig);
httpServer = new HTTPConfigurableServer(httpServerConfig);
httpServer.initialize();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void test() throws Exception {
}

int responseCode = connection.getResponseCode();
if (responseCode != HttpURLConnection.HTTP_OK) { // success
if (responseCode != HttpURLConnection.HTTP_ACCEPTED) { // success
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#
# 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.
#
#

zipkin.server.receiver.zipkin.scribe.ZipkinScribeModule
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#
# 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.
#
#

zipkin.server.receiver.zipkin.scribe.ZipkinScribeProvider
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*/
package zipkin.server.core;

import com.linecorp.armeria.common.HttpMethod;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.RunningMode;
import org.apache.skywalking.oap.server.core.analysis.meter.MeterSystem;
Expand Down Expand Up @@ -84,11 +85,13 @@
import org.apache.skywalking.oap.server.library.server.http.HTTPServerConfig;
import org.apache.skywalking.oap.server.telemetry.api.TelemetryRelatedContext;
import zipkin.server.core.services.EmptyComponentLibraryCatalogService;
import zipkin.server.core.services.EmptyHTTPHandlerRegister;
import zipkin.server.core.services.EmptyNetworkAddressAliasCache;
import zipkin.server.core.services.HTTPConfigurableServer;
import zipkin.server.core.services.HTTPInfoHandler;
import zipkin.server.core.services.ZipkinConfigService;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;

public class CoreModuleProvider extends ModuleProvider {
Expand Down Expand Up @@ -165,8 +168,10 @@ public void prepare() throws ServiceNotProvidedException, ModuleStartException {
.maxRequestHeaderSize(
moduleConfig.getRestMaxRequestHeaderSize())
.build();
httpServer = new HTTPServer(httpServerConfig);
httpServer = new HTTPConfigurableServer(httpServerConfig);
httpServer.initialize();
// "/info" handler
httpServer.addHandler(new HTTPInfoHandler(), Arrays.asList(HttpMethod.GET, HttpMethod.POST));

// grpc
if (moduleConfig.getGRPCSslEnabled()) {
Expand Down
Loading

0 comments on commit 1c74d42

Please sign in to comment.