support http api for upstream trace. (#4399)
* support http api. * e2e Co-authored-by: 吴晟 Wu Sheng <wu.sheng@foxmail.com> Co-authored-by: kezhenxu94 <kezhenxu94@apache.org>
This commit is contained in:
parent
0df2d0a5e9
commit
aa21765628
|
|
@ -116,6 +116,8 @@ jobs:
|
|||
./mvnw --batch-mode -f test/e2e/pom.xml -pl e2e-base clean install
|
||||
- name: 6.x Agents & 7.x Backend
|
||||
run: export E2E_VERSION=jdk8-1.5 && bash -x test/e2e/run.sh e2e-6.x-agent-7.x-oap-compatibility
|
||||
- name: Http API with Nginx Lua Tests In Single Node Mode(JDK8)
|
||||
run: export E2E_VERSION=jdk8-1.5 && bash -x test/e2e/run.sh e2e-http-api-with-nginx-lua
|
||||
|
||||
Profile:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
|||
|
|
@ -20,3 +20,4 @@ OALLexer.tokens
|
|||
.externalToolBuilders
|
||||
/test/plugin/dist
|
||||
/test/plugin/workspace
|
||||
e2e-*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
# HTTP API Protocol
|
||||
|
||||
HTTP API Protocol defines the API data format, including api request and response data format.
|
||||
|
||||
### Do register
|
||||
|
||||
Detail information about data format can be found in [Register service](https://github.com/apache/skywalking-data-collect-protocol/tree/master/register/Register.proto).
|
||||
And register steps followings [SkyWalking Trace Data Protocol v2](Trace-Data-Protocol-v2.md).
|
||||
|
||||
- Service Register
|
||||
|
||||
> POST http://localhost:12800/v2/service/register
|
||||
|
||||
Input:
|
||||
|
||||
```json
|
||||
{
|
||||
"services": [
|
||||
{
|
||||
"type": "normal",
|
||||
"serviceName": "Service Name"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Output JSON Array:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"key": "Service Name",
|
||||
"value": 2
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
- Service instance Register
|
||||
|
||||
> POST http://localhost:12800/v2/instance/register
|
||||
|
||||
Input:
|
||||
|
||||
```json
|
||||
{
|
||||
"instances": [
|
||||
{
|
||||
"time": 1582428603392,
|
||||
"instanceUUID": "NAME:Service Instance Name",
|
||||
"properties": [
|
||||
{
|
||||
"key": "language",
|
||||
"value": "Lua"
|
||||
}
|
||||
],
|
||||
"serviceId": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
OutPut:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"key": "NAME:Service Instance Name",
|
||||
"value": 0
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
- Service instance heartbeat
|
||||
|
||||
> POST http://localhost:12800/v2/instance/heartbeat
|
||||
|
||||
Input:
|
||||
|
||||
```json
|
||||
{
|
||||
"serviceInstanceId":20,
|
||||
"time": 1582428603392,
|
||||
"serviceInstanceUUID":"NAME:Service Instance Name"
|
||||
}
|
||||
```
|
||||
|
||||
OutPut:
|
||||
|
||||
```json
|
||||
{}
|
||||
```
|
||||
If your instance does not exist, you need to clean your local service instance metadata in your application and re-do register:
|
||||
|
||||
```json
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "ServiceMetadataReset",
|
||||
"args": [
|
||||
{
|
||||
"key": "SerialNumber",
|
||||
"value": "44bd2664-03c7-46bc-8652-52fcde0e7699"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Trace Report
|
||||
|
||||
### POST http://localhost:12800/v2/segments
|
||||
|
||||
Input:
|
||||
|
||||
```json
|
||||
{
|
||||
"spans": [
|
||||
{
|
||||
"operationName": "/tier2/lb",
|
||||
"startTime": 1582461179910,
|
||||
"tags": [],
|
||||
"endTime": 1582461179922,
|
||||
"spanType": "Exit",
|
||||
"logs":[],
|
||||
"spanId": 1,
|
||||
"isError": false,
|
||||
"parentSpanId": 0,
|
||||
"componentId": 6000,
|
||||
"peer": "User Service Name-nginx:upstream_ip:port",
|
||||
"spanLayer": "HTTP"
|
||||
},
|
||||
{
|
||||
"operationName": "/tier2/lb",
|
||||
"startTime": 1582461179910,
|
||||
"tags": [
|
||||
{
|
||||
"key": "http.method",
|
||||
"value": "GET"
|
||||
},
|
||||
{
|
||||
"key": "http.params",
|
||||
"value": "http://127.0.0.1/tier2/lb"
|
||||
}
|
||||
],
|
||||
"endTime": 1582461179922,
|
||||
"spanType": "Entry",
|
||||
"logs": [],
|
||||
"spanId": 0,
|
||||
"isError": false,
|
||||
"parentSpanId": -1,
|
||||
"componentId": 6000,
|
||||
"refs": [
|
||||
{
|
||||
"parentTraceSegmentId": {
|
||||
"idParts": [
|
||||
1582461179038,
|
||||
794206293,
|
||||
69887
|
||||
]
|
||||
},
|
||||
"parentEndpointId": 0,
|
||||
"entryEndpointId": 0,
|
||||
"parentServiceInstanceId": 1,
|
||||
"parentEndpoint": "/ingress",
|
||||
"networkAddress": "#User Service Name-nginx:upstream_ip:port",
|
||||
"parentSpanId": 1,
|
||||
"entryServiceInstanceId": 1,
|
||||
"networkAddressId": 0,
|
||||
"entryEndpoint": "/ingress"
|
||||
}
|
||||
],
|
||||
"spanLayer": "HTTP"
|
||||
}
|
||||
],
|
||||
"serviceInstanceId": 1,
|
||||
"serviceId": 1,
|
||||
"traceSegmentId": {
|
||||
"idParts": [
|
||||
1582461179044,
|
||||
794206293,
|
||||
69887
|
||||
]
|
||||
},
|
||||
"globalTraceIds": [
|
||||
{
|
||||
"idParts": [
|
||||
1582461179038,
|
||||
794206293,
|
||||
69887
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
OutPut:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
|
@ -7,6 +7,9 @@ Trace data protocol is defined and provided in [gRPC format](https://github.com/
|
|||
For each agent/SDK, it needs to register service id and service instance id before reporting any kind of trace
|
||||
or metrics data.
|
||||
|
||||
Since SkyWalking v7.x, SkyWalking provided register and uplink trace data through HTTP API way.
|
||||
[HTTP API Protocol](HTTP-API-Protocol.md) defined the API data format.
|
||||
|
||||
### Step 1. Do register
|
||||
[Register service](https://github.com/apache/skywalking-data-collect-protocol/tree/master/register/Register.proto) takes charge of
|
||||
all register methods. At step 1, we need `doServiceRegister`, then `doServiceInstanceRegister`.
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@
|
|||
<javaassist.version>3.25.0-GA</javaassist.version>
|
||||
|
||||
<zookeeper.image.version>3.5</zookeeper.image.version>
|
||||
<protobuf-java-util.version>3.11.4</protobuf-java-util.version>
|
||||
|
||||
</properties>
|
||||
|
||||
|
|
@ -263,6 +264,13 @@
|
|||
<artifactId>grpc-protobuf</artifactId>
|
||||
<version>${grpc.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java-util</artifactId>
|
||||
<version>${protobuf-java-util.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-stub</artifactId>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
package org.apache.skywalking.oap.server.library.server.jetty;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Enumeration;
|
||||
|
|
@ -84,25 +85,25 @@ public abstract class JettyJsonHandler extends JettyHandler {
|
|||
|
||||
@Override
|
||||
protected final void doDelete(HttpServletRequest req,
|
||||
HttpServletResponse resp) throws ServletException, IOException {
|
||||
HttpServletResponse resp) throws ServletException, IOException {
|
||||
super.doDelete(req, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void doOptions(HttpServletRequest req,
|
||||
HttpServletResponse resp) throws ServletException, IOException {
|
||||
HttpServletResponse resp) throws ServletException, IOException {
|
||||
super.doOptions(req, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void doTrace(HttpServletRequest req,
|
||||
HttpServletResponse resp) throws ServletException, IOException {
|
||||
HttpServletResponse resp) throws ServletException, IOException {
|
||||
super.doTrace(req, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void service(HttpServletRequest req,
|
||||
HttpServletResponse resp) throws ServletException, IOException {
|
||||
HttpServletResponse resp) throws ServletException, IOException {
|
||||
super.service(req, resp);
|
||||
}
|
||||
|
||||
|
|
@ -189,4 +190,14 @@ public abstract class JettyJsonHandler extends JettyHandler {
|
|||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
public String getJsonBody(HttpServletRequest req) throws IOException {
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
String line = null;
|
||||
BufferedReader reader = req.getReader();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
stringBuffer.append(line);
|
||||
}
|
||||
return stringBuffer.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
<properties>
|
||||
<ststem-rules.version>1.18.0</ststem-rules.version>
|
||||
<protobuf-java.version>3.11.4</protobuf-java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
|
@ -53,5 +54,16 @@
|
|||
<version>${ststem-rules.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
<version>${protobuf-java.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java-util</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.skywalking.oap.server.library.util;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
import com.google.protobuf.util.JsonFormat;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ProtoBufJsonUtils {
|
||||
|
||||
public static String toJSON(Message sourceMessage) throws IOException {
|
||||
return JsonFormat.printer().print(sourceMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract data from a JSON String and use them to construct a Protocol Buffers Message.
|
||||
*
|
||||
* @param json A JSON data string to parse
|
||||
* @param targetBuilder A Message builder to use to construct the resulting Message
|
||||
* @throws com.google.protobuf.InvalidProtocolBufferException Thrown in case of invalid Message data
|
||||
*/
|
||||
public static void fromJSON(String json, Message.Builder targetBuilder) throws IOException {
|
||||
JsonFormat.parser()
|
||||
.usingTypeRegistry(JsonFormat.TypeRegistry.newBuilder()
|
||||
.add(targetBuilder.getDescriptorForType())
|
||||
.build())
|
||||
.ignoringUnknownFields()
|
||||
.merge(json, targetBuilder);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,12 +20,16 @@ package org.apache.skywalking.oap.server.receiver.register.provider;
|
|||
|
||||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.server.GRPCHandlerRegister;
|
||||
import org.apache.skywalking.oap.server.core.server.JettyHandlerRegister;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleDefine;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleProvider;
|
||||
import org.apache.skywalking.oap.server.receiver.register.module.RegisterModule;
|
||||
import org.apache.skywalking.oap.server.receiver.register.provider.handler.v6.grpc.RegisterServiceHandler;
|
||||
import org.apache.skywalking.oap.server.receiver.register.provider.handler.v6.grpc.ServiceInstancePingServiceHandler;
|
||||
import org.apache.skywalking.oap.server.receiver.register.provider.handler.v6.rest.ServiceInstancePingServletHandler;
|
||||
import org.apache.skywalking.oap.server.receiver.register.provider.handler.v6.rest.ServiceInstanceRegisterServletHandler;
|
||||
import org.apache.skywalking.oap.server.receiver.register.provider.handler.v6.rest.ServiceRegisterServletHandler;
|
||||
import org.apache.skywalking.oap.server.receiver.sharing.server.SharingServerModule;
|
||||
|
||||
public class RegisterModuleProvider extends ModuleProvider {
|
||||
|
|
@ -56,6 +60,13 @@ public class RegisterModuleProvider extends ModuleProvider {
|
|||
.getService(GRPCHandlerRegister.class);
|
||||
grpcHandlerRegister.addHandler(new RegisterServiceHandler(getManager()));
|
||||
grpcHandlerRegister.addHandler(new ServiceInstancePingServiceHandler(getManager()));
|
||||
|
||||
JettyHandlerRegister jettyHandlerRegister = getManager().find(SharingServerModule.NAME)
|
||||
.provider()
|
||||
.getService(JettyHandlerRegister.class);
|
||||
jettyHandlerRegister.addHandler(new ServiceRegisterServletHandler(getManager()));
|
||||
jettyHandlerRegister.addHandler(new ServiceInstanceRegisterServletHandler(getManager()));
|
||||
jettyHandlerRegister.addHandler(new ServiceInstancePingServletHandler(getManager()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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.skywalking.oap.server.receiver.register.provider.handler.v6.rest;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.apache.skywalking.apm.network.common.Command;
|
||||
import org.apache.skywalking.apm.network.common.Commands;
|
||||
import org.apache.skywalking.apm.network.register.v2.ServiceInstancePingPkg;
|
||||
import org.apache.skywalking.apm.network.trace.component.command.ServiceResetCommand;
|
||||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.cache.ServiceInstanceInventoryCache;
|
||||
import org.apache.skywalking.oap.server.core.command.CommandService;
|
||||
import org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory;
|
||||
import org.apache.skywalking.oap.server.core.register.service.IServiceInstanceInventoryRegister;
|
||||
import org.apache.skywalking.oap.server.core.register.service.IServiceInventoryRegister;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||
import org.apache.skywalking.oap.server.library.server.jetty.ArgumentsParseException;
|
||||
import org.apache.skywalking.oap.server.library.server.jetty.JettyJsonHandler;
|
||||
import org.apache.skywalking.oap.server.library.util.ProtoBufJsonUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ServiceInstancePingServletHandler extends JettyJsonHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ServiceInstancePingServletHandler.class);
|
||||
|
||||
private final IServiceInstanceInventoryRegister serviceInstanceInventoryRegister;
|
||||
private final ServiceInstanceInventoryCache serviceInstanceInventoryCache;
|
||||
private final IServiceInventoryRegister serviceInventoryRegister;
|
||||
private final CommandService commandService;
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
public ServiceInstancePingServletHandler(ModuleManager moduleManager) {
|
||||
this.serviceInstanceInventoryRegister = moduleManager.find(CoreModule.NAME).provider().getService(
|
||||
IServiceInstanceInventoryRegister.class);
|
||||
this.serviceInstanceInventoryCache = moduleManager.find(CoreModule.NAME).provider().getService(
|
||||
ServiceInstanceInventoryCache.class);
|
||||
this.serviceInventoryRegister = moduleManager.find(CoreModule.NAME).provider().getService(
|
||||
IServiceInventoryRegister.class);
|
||||
this.commandService = moduleManager.find(CoreModule.NAME).provider().getService(CommandService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pathSpec() {
|
||||
return "/v2/instance/heartbeat";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement doGet(HttpServletRequest req) throws ArgumentsParseException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement doPost(HttpServletRequest req) throws ArgumentsParseException, IOException {
|
||||
JsonObject responseJson = new JsonObject();
|
||||
|
||||
try {
|
||||
ServiceInstancePingPkg.Builder builder = ServiceInstancePingPkg.newBuilder();
|
||||
ProtoBufJsonUtils.fromJSON(getJsonBody(req), builder);
|
||||
ServiceInstancePingPkg instancePingPkg = builder.build();
|
||||
|
||||
int serviceInstanceId = instancePingPkg.getServiceInstanceId();
|
||||
long heartBeatTime = instancePingPkg.getTime();
|
||||
String serviceInstanceUUID = instancePingPkg.getServiceInstanceUUID();
|
||||
serviceInstanceInventoryRegister.heartbeat(serviceInstanceId, heartBeatTime);
|
||||
|
||||
ServiceInstanceInventory serviceInstanceInventory = serviceInstanceInventoryCache.get(serviceInstanceId);
|
||||
if (Objects.nonNull(serviceInstanceInventory)) {
|
||||
serviceInventoryRegister.heartbeat(serviceInstanceInventory.getServiceId(), heartBeatTime);
|
||||
} else {
|
||||
logger.warn(
|
||||
"Can't found service by service instance id from cache, service instance id is: {}",
|
||||
serviceInstanceId
|
||||
);
|
||||
|
||||
final ServiceResetCommand resetCommand = commandService.newResetCommand(
|
||||
serviceInstanceId, heartBeatTime, serviceInstanceUUID);
|
||||
final Command command = resetCommand.serialize().build();
|
||||
final Commands nextCommands = Commands.newBuilder().addCommands(command).build();
|
||||
return gson.fromJson(ProtoBufJsonUtils.toJSON(nextCommands), JsonElement.class);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
responseJson.addProperty("error", e.getMessage());
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return responseJson;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* 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.skywalking.oap.server.receiver.register.provider.handler.v6.rest;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.apache.skywalking.apm.network.common.KeyStringValuePair;
|
||||
import org.apache.skywalking.apm.network.register.v2.ServiceInstance;
|
||||
import org.apache.skywalking.apm.network.register.v2.ServiceInstances;
|
||||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.cache.ServiceInventoryCache;
|
||||
import org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory;
|
||||
import org.apache.skywalking.oap.server.core.register.ServiceInventory;
|
||||
import org.apache.skywalking.oap.server.core.register.service.IServiceInstanceInventoryRegister;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||
import org.apache.skywalking.oap.server.library.server.jetty.ArgumentsParseException;
|
||||
import org.apache.skywalking.oap.server.library.server.jetty.JettyJsonHandler;
|
||||
import org.apache.skywalking.oap.server.library.util.ProtoBufJsonUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory.PropertyUtil.HOST_NAME;
|
||||
import static org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory.PropertyUtil.IPV4S;
|
||||
import static org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory.PropertyUtil.LANGUAGE;
|
||||
import static org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory.PropertyUtil.OS_NAME;
|
||||
import static org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory.PropertyUtil.PROCESS_NO;
|
||||
|
||||
public class ServiceInstanceRegisterServletHandler extends JettyJsonHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ServiceInstanceRegisterServletHandler.class);
|
||||
private static final String INSTANCE_CUSTOMIZED_NAME_PREFIX = "NAME:";
|
||||
|
||||
private final IServiceInstanceInventoryRegister serviceInstanceInventoryRegister;
|
||||
private final ServiceInventoryCache serviceInventoryCache;
|
||||
|
||||
private static final String KEY = "key";
|
||||
private static final String VALUE = "value";
|
||||
|
||||
public ServiceInstanceRegisterServletHandler(ModuleManager moduleManager) {
|
||||
this.serviceInventoryCache = moduleManager.find(CoreModule.NAME)
|
||||
.provider()
|
||||
.getService(ServiceInventoryCache.class);
|
||||
this.serviceInstanceInventoryRegister = moduleManager.find(CoreModule.NAME).provider().getService(
|
||||
IServiceInstanceInventoryRegister.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pathSpec() {
|
||||
return "/v2/instance/register";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement doGet(HttpServletRequest req) throws ArgumentsParseException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement doPost(HttpServletRequest req) throws ArgumentsParseException {
|
||||
|
||||
JsonObject responseJson = new JsonObject();
|
||||
JsonArray jsonArray = new JsonArray();
|
||||
|
||||
try {
|
||||
ServiceInstances.Builder builder = ServiceInstances.newBuilder();
|
||||
ProtoBufJsonUtils.fromJSON(getJsonBody(req), builder);
|
||||
List<ServiceInstance> serviceInstances = builder.build().getInstancesList();
|
||||
|
||||
serviceInstances.forEach(instance -> {
|
||||
long time = instance.getTime();
|
||||
int serviceId = instance.getServiceId();
|
||||
String instanceUUID = instance.getInstanceUUID();
|
||||
|
||||
JsonObject instanceProperties = new JsonObject();
|
||||
List<String> ipv4s = new ArrayList<>();
|
||||
|
||||
for (KeyStringValuePair property : instance.getPropertiesList()) {
|
||||
String key = property.getKey();
|
||||
switch (key) {
|
||||
case HOST_NAME:
|
||||
instanceProperties.addProperty(HOST_NAME, property.getValue());
|
||||
break;
|
||||
case OS_NAME:
|
||||
instanceProperties.addProperty(OS_NAME, property.getValue());
|
||||
break;
|
||||
case LANGUAGE:
|
||||
instanceProperties.addProperty(LANGUAGE, property.getValue());
|
||||
break;
|
||||
case "ipv4":
|
||||
ipv4s.add(property.getValue());
|
||||
break;
|
||||
case PROCESS_NO:
|
||||
instanceProperties.addProperty(PROCESS_NO, property.getValue());
|
||||
break;
|
||||
default:
|
||||
instanceProperties.addProperty(key, property.getValue());
|
||||
}
|
||||
}
|
||||
instanceProperties.addProperty(IPV4S, ServiceInstanceInventory.PropertyUtil.ipv4sSerialize(ipv4s));
|
||||
|
||||
String instanceName = null;
|
||||
if (instanceUUID.startsWith(INSTANCE_CUSTOMIZED_NAME_PREFIX)) {
|
||||
instanceName = instanceUUID.substring(INSTANCE_CUSTOMIZED_NAME_PREFIX.length());
|
||||
}
|
||||
|
||||
ServiceInventory serviceInventory = serviceInventoryCache.get(serviceId);
|
||||
|
||||
if (instanceName == null) {
|
||||
instanceName = serviceInventory.getName();
|
||||
if (instanceProperties.has(PROCESS_NO)) {
|
||||
instanceName += "-pid:" + instanceProperties.get(PROCESS_NO).getAsString();
|
||||
}
|
||||
if (instanceProperties.has(HOST_NAME)) {
|
||||
instanceName += "@" + instanceProperties.get(HOST_NAME).getAsString();
|
||||
}
|
||||
}
|
||||
int instanceId = serviceInstanceInventoryRegister.getOrCreate(
|
||||
serviceId, instanceName, instanceUUID, time, instanceProperties);
|
||||
|
||||
responseJson.addProperty(KEY, instanceUUID);
|
||||
responseJson.addProperty(VALUE, instanceId);
|
||||
jsonArray.add(responseJson);
|
||||
});
|
||||
|
||||
return jsonArray;
|
||||
} catch (IOException e) {
|
||||
responseJson.addProperty("error", e.getMessage());
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return responseJson;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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.skywalking.oap.server.receiver.register.provider.handler.v6.rest;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.apache.skywalking.apm.network.register.v2.Service;
|
||||
import org.apache.skywalking.apm.network.register.v2.Services;
|
||||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.register.NodeType;
|
||||
import org.apache.skywalking.oap.server.core.register.service.IServiceInventoryRegister;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||
import org.apache.skywalking.oap.server.library.server.jetty.ArgumentsParseException;
|
||||
import org.apache.skywalking.oap.server.library.server.jetty.JettyJsonHandler;
|
||||
import org.apache.skywalking.oap.server.library.util.ProtoBufJsonUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ServiceRegisterServletHandler extends JettyJsonHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ServiceRegisterServletHandler.class);
|
||||
|
||||
private final IServiceInventoryRegister serviceInventoryRegister;
|
||||
|
||||
private static final String KEY = "key";
|
||||
private static final String VALUE = "value";
|
||||
|
||||
public ServiceRegisterServletHandler(ModuleManager moduleManager) {
|
||||
serviceInventoryRegister = moduleManager.find(CoreModule.NAME)
|
||||
.provider()
|
||||
.getService(IServiceInventoryRegister.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pathSpec() {
|
||||
return "/v2/service/register";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement doGet(HttpServletRequest req) throws ArgumentsParseException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement doPost(HttpServletRequest req) throws ArgumentsParseException {
|
||||
JsonArray responseArray = new JsonArray();
|
||||
|
||||
try {
|
||||
Services.Builder builder = Services.newBuilder();
|
||||
ProtoBufJsonUtils.fromJSON(getJsonBody(req), builder);
|
||||
List<Service> serviceList = builder.build().getServicesList();
|
||||
|
||||
serviceList.forEach(service -> {
|
||||
int serviceId = serviceInventoryRegister.getOrCreate(service.getServiceName(),
|
||||
NodeType.fromRegisterServiceType(
|
||||
service.getType()), null
|
||||
);
|
||||
|
||||
JsonObject mapping = new JsonObject();
|
||||
mapping.addProperty(KEY, service.getServiceName());
|
||||
mapping.addProperty(VALUE, serviceId);
|
||||
responseArray.add(mapping);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
JsonObject mapping = new JsonObject();
|
||||
mapping.addProperty("error", e.getMessage());
|
||||
responseArray.add(mapping);
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return responseArray;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,10 +18,12 @@
|
|||
|
||||
package org.apache.skywalking.oap.server.receiver.trace.provider;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.apache.skywalking.oap.server.configuration.api.ConfigurationModule;
|
||||
import org.apache.skywalking.oap.server.configuration.api.DynamicConfigurationService;
|
||||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.server.GRPCHandlerRegister;
|
||||
import org.apache.skywalking.oap.server.core.server.JettyHandlerRegister;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleDefine;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleProvider;
|
||||
|
|
@ -30,6 +32,7 @@ import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedExcepti
|
|||
import org.apache.skywalking.oap.server.receiver.sharing.server.SharingServerModule;
|
||||
import org.apache.skywalking.oap.server.receiver.trace.module.TraceModule;
|
||||
import org.apache.skywalking.oap.server.receiver.trace.provider.handler.v6.grpc.TraceSegmentReportServiceHandler;
|
||||
import org.apache.skywalking.oap.server.receiver.trace.provider.handler.v6.rest.TraceSegmentCollectServletHandler;
|
||||
import org.apache.skywalking.oap.server.receiver.trace.provider.parser.ISegmentParserService;
|
||||
import org.apache.skywalking.oap.server.receiver.trace.provider.parser.SegmentParseV2;
|
||||
import org.apache.skywalking.oap.server.receiver.trace.provider.parser.SegmentParserListenerManager;
|
||||
|
|
@ -41,8 +44,6 @@ import org.apache.skywalking.oap.server.receiver.trace.provider.parser.listener.
|
|||
import org.apache.skywalking.oap.server.receiver.trace.provider.parser.standardization.SegmentStandardizationWorker;
|
||||
import org.apache.skywalking.oap.server.telemetry.TelemetryModule;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TraceModuleProvider extends ModuleProvider {
|
||||
|
||||
private final TraceServiceModuleConfig moduleConfig;
|
||||
|
|
@ -80,7 +81,8 @@ public class TraceModuleProvider extends ModuleProvider {
|
|||
|
||||
segmentProducerV2 = new SegmentParseV2.Producer(getManager(), listenerManager(), moduleConfig);
|
||||
|
||||
this.registerServiceImplementation(ISegmentParserService.class, new SegmentParserServiceImpl(segmentProducerV2));
|
||||
this.registerServiceImplementation(
|
||||
ISegmentParserService.class, new SegmentParserServiceImpl(segmentProducerV2));
|
||||
}
|
||||
|
||||
public SegmentParserListenerManager listenerManager() {
|
||||
|
|
@ -99,19 +101,28 @@ public class TraceModuleProvider extends ModuleProvider {
|
|||
public void start() throws ModuleStartException {
|
||||
DynamicConfigurationService dynamicConfigurationService = getManager().find(ConfigurationModule.NAME)
|
||||
.provider()
|
||||
.getService(DynamicConfigurationService.class);
|
||||
.getService(
|
||||
DynamicConfigurationService.class);
|
||||
GRPCHandlerRegister grpcHandlerRegister = getManager().find(SharingServerModule.NAME)
|
||||
.provider()
|
||||
.getService(GRPCHandlerRegister.class);
|
||||
JettyHandlerRegister jettyHandlerRegister = getManager().find(SharingServerModule.NAME)
|
||||
.provider()
|
||||
.getService(JettyHandlerRegister.class);
|
||||
try {
|
||||
dynamicConfigurationService.registerConfigChangeWatcher(thresholds);
|
||||
dynamicConfigurationService.registerConfigChangeWatcher(uninstrumentedGatewaysConfig);
|
||||
|
||||
grpcHandlerRegister.addHandler(new TraceSegmentReportServiceHandler(segmentProducerV2, getManager()));
|
||||
|
||||
SegmentStandardizationWorker standardizationWorkerV2 = new SegmentStandardizationWorker(getManager(), segmentProducerV2, moduleConfig
|
||||
.getBufferPath(), moduleConfig.getBufferOffsetMaxFileSize(), moduleConfig.getBufferDataMaxFileSize(), moduleConfig
|
||||
.isBufferFileCleanWhenRestart());
|
||||
jettyHandlerRegister.addHandler(new TraceSegmentCollectServletHandler(segmentProducerV2));
|
||||
|
||||
SegmentStandardizationWorker standardizationWorkerV2 = new SegmentStandardizationWorker(
|
||||
getManager(), segmentProducerV2, moduleConfig
|
||||
.getBufferPath(), moduleConfig.getBufferOffsetMaxFileSize(), moduleConfig.getBufferDataMaxFileSize(),
|
||||
moduleConfig
|
||||
.isBufferFileCleanWhenRestart()
|
||||
);
|
||||
segmentProducerV2.setStandardizationWorker(standardizationWorkerV2);
|
||||
} catch (IOException e) {
|
||||
throw new ModuleStartException(e.getMessage(), e);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.skywalking.oap.server.receiver.trace.provider.handler.v6.rest;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import java.io.BufferedReader;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.apache.skywalking.apm.network.language.agent.UpstreamSegment;
|
||||
import org.apache.skywalking.oap.server.library.server.jetty.JettyJsonHandler;
|
||||
import org.apache.skywalking.oap.server.receiver.trace.provider.handler.v6.rest.reader.UpstreamSegmentJsonReader;
|
||||
import org.apache.skywalking.oap.server.receiver.trace.provider.parser.SegmentParseV2;
|
||||
import org.apache.skywalking.oap.server.receiver.trace.provider.parser.SegmentSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TraceSegmentCollectServletHandler extends JettyJsonHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(TraceSegmentCollectServletHandler.class);
|
||||
|
||||
private final SegmentParseV2.Producer segmentProducer;
|
||||
|
||||
private UpstreamSegmentJsonReader upstreamSegmentJsonReader = new UpstreamSegmentJsonReader();
|
||||
|
||||
public TraceSegmentCollectServletHandler(SegmentParseV2.Producer segmentProducer) {
|
||||
this.segmentProducer = segmentProducer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pathSpec() {
|
||||
return "/v2/segments";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement doGet(HttpServletRequest req) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement doPost(HttpServletRequest req) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("receive stream segment");
|
||||
}
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
String line = null;
|
||||
try {
|
||||
BufferedReader reader = req.getReader();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
stringBuilder.append(line);
|
||||
}
|
||||
UpstreamSegment upstreamSegment = upstreamSegmentJsonReader.read(stringBuilder.toString()).build();
|
||||
|
||||
segmentProducer.send(upstreamSegment, SegmentSource.Agent);
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.skywalking.oap.server.receiver.trace.provider.handler.v6.rest.reader;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.apache.skywalking.apm.network.language.agent.v2.SegmentObject;
|
||||
import org.apache.skywalking.oap.server.library.util.ProtoBufJsonUtils;
|
||||
|
||||
public class SegmentJsonReader implements StreamJsonReader<SegmentObject.Builder> {
|
||||
|
||||
@Override
|
||||
public SegmentObject.Builder read(String json) throws IOException {
|
||||
SegmentObject.Builder builder = SegmentObject.newBuilder();
|
||||
ProtoBufJsonUtils.fromJSON(json, builder);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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.skywalking.oap.server.receiver.trace.provider.handler.v6.rest.reader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface StreamJsonReader<T> {
|
||||
T read(String json) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.skywalking.oap.server.receiver.trace.provider.handler.v6.rest.reader;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.apache.skywalking.apm.network.language.agent.UpstreamSegment;
|
||||
import org.apache.skywalking.apm.network.language.agent.v2.SegmentObject;
|
||||
import org.apache.skywalking.oap.server.library.util.ProtoBufJsonUtils;
|
||||
|
||||
public class UpstreamSegmentJsonReader implements StreamJsonReader<UpstreamSegment.Builder> {
|
||||
|
||||
private final SegmentJsonReader segmentJsonReader = new SegmentJsonReader();
|
||||
|
||||
@Override
|
||||
public UpstreamSegment.Builder read(String json) throws IOException {
|
||||
UpstreamSegment.Builder upstreamSegmentBuilder = UpstreamSegment.newBuilder();
|
||||
ProtoBufJsonUtils.fromJSON(json, upstreamSegmentBuilder);
|
||||
|
||||
SegmentObject.Builder segmentBuilder = segmentJsonReader.read(json);
|
||||
|
||||
upstreamSegmentBuilder.setSegment(segmentBuilder.build().toByteString());
|
||||
|
||||
return upstreamSegmentBuilder;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* 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.skywalking.oap.server.receiver.trace.provider.parser.listener.segment;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.apache.skywalking.apm.network.common.Command;
|
||||
import org.apache.skywalking.apm.network.common.Commands;
|
||||
import org.apache.skywalking.apm.network.language.agent.UpstreamSegment;
|
||||
import org.apache.skywalking.apm.network.language.agent.v2.SegmentObject;
|
||||
import org.apache.skywalking.oap.server.library.util.ProtoBufJsonUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ProtoBufJsonUtilsTest {
|
||||
@Test
|
||||
public void testProtoBuf() {
|
||||
String json = "{\n" +
|
||||
" \"spans\": [\n" +
|
||||
" {\n" +
|
||||
" \"operationName\": \"/tier2/lb\",\n" +
|
||||
" \"startTime\": 1582526028207,\n" +
|
||||
" \"endTime\": 1582526028221,\n" +
|
||||
" \"spanType\": \"Exit\",\n" +
|
||||
" \"spanId\": 1,\n" +
|
||||
" \"isError\": false,\n" +
|
||||
" \"parentSpanId\": 0,\n" +
|
||||
" \"componentId\": 6000,\n" +
|
||||
" \"peer\": \"User Service Name-nginx:upstream_ip:port\",\n" +
|
||||
" \"spanLayer\": \"HTTP\"\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"operationName\": \"/tier2/lb\",\n" +
|
||||
" \"startTime\": 1582526028207,\n" +
|
||||
" \"tags\": [\n" +
|
||||
" {\n" +
|
||||
" \"key\": \"http.method\",\n" +
|
||||
" \"value\": \"GET\"\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"key\": \"http.params\",\n" +
|
||||
" \"value\": \"http://127.0.0.1/tier2/lb\"\n" +
|
||||
" }\n" +
|
||||
" ],\n" +
|
||||
" \"endTime\": 1582526028221,\n" +
|
||||
" \"spanType\": \"Entry\",\n" +
|
||||
" \"spanId\": 0,\n" +
|
||||
" \"isError\": false,\n" +
|
||||
" \"parentSpanId\": -1,\n" +
|
||||
" \"componentId\": 6000,\n" +
|
||||
" \"refs\": [\n" +
|
||||
" {\n" +
|
||||
" \"parentTraceSegmentId\": {\n" +
|
||||
" \"idParts\": [\n" +
|
||||
" 1582526028032,\n" +
|
||||
" 794206293,\n" +
|
||||
" 69887\n" +
|
||||
" ]\n" +
|
||||
" },\n" +
|
||||
" \"parentEndpointId\": 0,\n" +
|
||||
" \"entryEndpointId\": 0,\n" +
|
||||
" \"parentServiceInstanceId\": 1,\n" +
|
||||
" \"parentEndpoint\": \"/ingress\",\n" +
|
||||
" \"networkAddress\": \"#User Service Name-nginx:upstream_ip:port\",\n" +
|
||||
" \"parentSpanId\": 1,\n" +
|
||||
" \"entryServiceInstanceId\": 1,\n" +
|
||||
" \"networkAddressId\": 0,\n" +
|
||||
" \"entryEndpoint\": \"/ingress\"\n" +
|
||||
" }\n" +
|
||||
" ],\n" +
|
||||
" \"spanLayer\": \"HTTP\"\n" +
|
||||
" }\n" +
|
||||
" ],\n" +
|
||||
" \"serviceInstanceId\": 1,\n" +
|
||||
" \"serviceId\": 1,\n" +
|
||||
" \"traceSegmentId\": {\n" +
|
||||
" \"idParts\": [\n" +
|
||||
" 1582526028040,\n" +
|
||||
" 794206293,\n" +
|
||||
" 69887\n" +
|
||||
" ]\n" +
|
||||
" },\n" +
|
||||
" \"globalTraceIds\": [\n" +
|
||||
" {\n" +
|
||||
" \"idParts\": [\n" +
|
||||
" 1582526028032,\n" +
|
||||
" 794206293,\n" +
|
||||
" 69887\n" +
|
||||
" ]\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
"}";
|
||||
|
||||
UpstreamSegment.Builder builder = UpstreamSegment.newBuilder();
|
||||
try {
|
||||
ProtoBufJsonUtils.fromJSON(json, builder);
|
||||
UpstreamSegment upstreamSegment = builder.build();
|
||||
Assert.assertEquals(1582526028032L, upstreamSegment.getGlobalTraceIds(0).getIdParts(0));
|
||||
|
||||
SegmentObject.Builder segBuilder = SegmentObject.newBuilder();
|
||||
ProtoBufJsonUtils.fromJSON(json, segBuilder);
|
||||
SegmentObject segmentObject = segBuilder.build();
|
||||
Assert.assertEquals(2, segmentObject.getSpansCount());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToJson() {
|
||||
String json = "{\n" +
|
||||
" \"commands\": [{\n" +
|
||||
" }]\n" +
|
||||
"}";
|
||||
try {
|
||||
Command command = Command.newBuilder().build();
|
||||
final Commands nextCommands = Commands.newBuilder().addCommands(command).build();
|
||||
Assert.assertEquals(json, ProtoBufJsonUtils.toJSON(nextCommands));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>apache-skywalking-e2e</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>e2e-http-api-with-nginx-lua</artifactId>
|
||||
|
||||
<properties>
|
||||
<e2e.container.version>1.1</e2e.container.version>
|
||||
<e2e.container.name.prefix>skywalking-e2e-container-${build.id}-http-api-with-nginx-lua
|
||||
</e2e.container.name.prefix>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>e2e-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<configuration>
|
||||
<executable>true</executable>
|
||||
<addResources>true</addResources>
|
||||
<excludeDevtools>true</excludeDevtools>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<containerNamePattern>%a-%t-%i</containerNamePattern>
|
||||
<images>
|
||||
<image>
|
||||
<name>skyapm/e2e-container:${e2e.container.version}</name>
|
||||
<alias>e2e-container-app-for-nginx-lua</alias>
|
||||
<run>
|
||||
<env>
|
||||
<INSTRUMENTED_SERVICE>${project.build.finalName}.jar</INSTRUMENTED_SERVICE>
|
||||
<INSTRUMENTED_SERVICE_OPTS>-Dskywalking.agent.cool_down_threshold=1
|
||||
</INSTRUMENTED_SERVICE_OPTS>
|
||||
</env>
|
||||
<ports>
|
||||
<port>+webapp.host:webapp.port:8080</port>
|
||||
<port>+client.host:client.port:9090</port>
|
||||
</ports>
|
||||
<volumes>
|
||||
<bind>
|
||||
<volume>${sw.home}:/sw</volume>
|
||||
<volume>${project.build.directory}:/home</volume>
|
||||
<volume>
|
||||
${project.basedir}/src/docker/rc.d/rc1-startup.sh:/rc.d/rc1-startup.sh:ro
|
||||
</volume>
|
||||
</bind>
|
||||
</volumes>
|
||||
<wait>
|
||||
<http>
|
||||
<url>
|
||||
http://${docker.host.address}:${client.port}/e2e/info
|
||||
</url>
|
||||
<method>GET</method>
|
||||
<status>200</status>
|
||||
</http>
|
||||
<time>300000</time>
|
||||
</wait>
|
||||
</run>
|
||||
</image>
|
||||
|
||||
<image>
|
||||
<name>openresty/openresty</name>
|
||||
<alias>${e2e.container.name.prefix}-openresty</alias>
|
||||
|
||||
<run>
|
||||
<env>
|
||||
<SKYWALKING_NINGX_LUA_GIT_COMMIT_ID>c6aca516200573a64db7060cefb5d3608c571c3a
|
||||
</SKYWALKING_NINGX_LUA_GIT_COMMIT_ID>
|
||||
</env>
|
||||
<links>
|
||||
<link>e2e-container-app-for-nginx-lua:upstream</link>
|
||||
</links>
|
||||
<ports>
|
||||
<port>+nginx.host:nginx.port:8080</port>
|
||||
</ports>
|
||||
<volumes>
|
||||
<bind>
|
||||
<volume>${project.basedir}/src/docker/rc.d:/rc.d:ro</volume>
|
||||
</bind>
|
||||
</volumes>
|
||||
<wait>
|
||||
<http>
|
||||
<url>
|
||||
http://${docker.host.address}:${nginx.port}
|
||||
</url>
|
||||
</http>
|
||||
<time>3000000</time>
|
||||
</wait>
|
||||
<cmd>/rc.d/rc0-prepare.sh</cmd>
|
||||
</run>
|
||||
</image>
|
||||
</images>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- set the system properties that can be used in test codes -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<sw.webapp.host>
|
||||
${webapp.host}
|
||||
</sw.webapp.host>
|
||||
<sw.webapp.port>
|
||||
${webapp.port}
|
||||
</sw.webapp.port>
|
||||
<client.host>
|
||||
${client.host}
|
||||
</client.host>
|
||||
<client.port>
|
||||
${client.port}
|
||||
</client.port>
|
||||
<nginx.port>
|
||||
${nginx.port}
|
||||
</nginx.port>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<ping.url>
|
||||
http://${nginx.host}:${nginx.port}/ingress
|
||||
</ping.url>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
#!/usr/bin/env bash
|
||||
# Licensed to the SkyAPM 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.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
var_application_file="/var/nginx/conf.d/nginx.conf"
|
||||
|
||||
var_upstream_ip=$(cat /etc/hosts|grep upstream|awk '{print $1'})
|
||||
|
||||
apt-get update && apt-get -y install git
|
||||
|
||||
echo 'git clone skyalking-nginx-lua lib from https://github.com/apache/skywalking-nginx-lua.git'
|
||||
|
||||
git clone https://github.com/apache/skywalking-nginx-lua.git /usr/share/skywalking-nginx-lua \
|
||||
&& cd /usr/share/skywalking-nginx-lua \
|
||||
&& git checkout ${SKYWALKING_NINGX_LUA_GIT_COMMIT_ID} \
|
||||
&& ls ./ \
|
||||
&& mkdir -p /var/nginx/conf.d
|
||||
|
||||
|
||||
generateNginxConf() {
|
||||
cat <<EOT >> ${var_application_file}
|
||||
worker_processes 1;
|
||||
daemon off;
|
||||
error_log /dev/stdout error;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
http {
|
||||
lua_package_path "/usr/share/skywalking-nginx-lua/lib/skywalking/?.lua;;";
|
||||
# Buffer represents the register inform and the queue of the finished segment
|
||||
lua_shared_dict tracing_buffer 100m;
|
||||
|
||||
# Init is the timer setter and keeper
|
||||
# Setup an infinite loop timer to do register and trace report.
|
||||
init_worker_by_lua_block {
|
||||
local metadata_buffer = ngx.shared.tracing_buffer
|
||||
|
||||
metadata_buffer:set('serviceName', 'User_Service_Name')
|
||||
-- Instance means the number of Nginx deloyment, does not mean the worker instances
|
||||
metadata_buffer:set('serviceInstanceName', 'User_Service_Instance_Name')
|
||||
|
||||
require("client"):startBackendTimer("http://${var_upstream_ip}:12800")
|
||||
}
|
||||
log_format sw_trace escape=json "$uri $request_body";
|
||||
|
||||
server {
|
||||
listen 8080;
|
||||
|
||||
location /nginx/e2e/info {
|
||||
|
||||
rewrite_by_lua_block {
|
||||
require("tracer"):start("User_Service_Name")
|
||||
}
|
||||
|
||||
proxy_pass http://upstream:9090/e2e/info;
|
||||
|
||||
body_filter_by_lua_block {
|
||||
require("tracer"):finish()
|
||||
}
|
||||
|
||||
log_by_lua_block {
|
||||
require("tracer"):prepareForReport()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOT
|
||||
}
|
||||
|
||||
generateNginxConf;
|
||||
|
||||
echo 'generated nginx.conf:'
|
||||
|
||||
cat ${var_application_file}
|
||||
|
||||
/usr/bin/openresty -c ${var_application_file}
|
||||
sync
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env bash
|
||||
# Licensed to the SkyAPM 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.
|
||||
|
||||
echo 'starting OAP server...' \
|
||||
&& SW_STORAGE_ES_BULK_ACTIONS=1 \
|
||||
&& SW_STORAGE_ES_FLUSH_INTERVAL=1 \
|
||||
&& SW_RECEIVER_BUFFER_PATH=/tmp/oap/trace_buffer1 \
|
||||
&& SW_SERVICE_MESH_BUFFER_PATH=/tmp/oap/mesh_buffer1 \
|
||||
&& start_oap 'init'
|
||||
|
||||
echo 'starting Web app...' \
|
||||
&& start_webapp '0.0.0.0' 8080
|
||||
|
||||
echo 'starting instrumented services...' \
|
||||
&& start_instrumented_services
|
||||
|
||||
check_tcp 127.0.0.1 \
|
||||
9090 \
|
||||
60 \
|
||||
10 \
|
||||
"waiting for the instrumented service to be ready"
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "instrumented service failed to start in 30 * 10 seconds: "
|
||||
cat ${SERVICE_LOG}/*
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "SkyWalking e2e container is ready for tests"
|
||||
|
||||
tail -f ${OAP_LOG_DIR}/* \
|
||||
${WEBAPP_LOG_DIR}/* \
|
||||
${SERVICE_LOG}/* \
|
||||
${ES_HOME}/logs/stdout.log
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.skywalking.e2e.sample.client;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SampleClientApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SampleClientApplication.class, args);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.skywalking.e2e.sample.client;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/e2e")
|
||||
public class TestController {
|
||||
@GetMapping("/info")
|
||||
public String hello() {
|
||||
return "e2e-container-info";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# 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.
|
||||
|
||||
server:
|
||||
port: 9090
|
||||
|
||||
spring:
|
||||
main:
|
||||
banner-mode: 'off'
|
||||
|
|
@ -0,0 +1,386 @@
|
|||
/*
|
||||
* 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.skywalking.e2e;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.skywalking.e2e.metrics.AtLeastOneOfMetricsMatcher;
|
||||
import org.apache.skywalking.e2e.metrics.Metrics;
|
||||
import org.apache.skywalking.e2e.metrics.MetricsQuery;
|
||||
import org.apache.skywalking.e2e.metrics.MetricsValueMatcher;
|
||||
import org.apache.skywalking.e2e.service.Service;
|
||||
import org.apache.skywalking.e2e.service.ServicesMatcher;
|
||||
import org.apache.skywalking.e2e.service.ServicesQuery;
|
||||
import org.apache.skywalking.e2e.service.endpoint.Endpoint;
|
||||
import org.apache.skywalking.e2e.service.endpoint.EndpointQuery;
|
||||
import org.apache.skywalking.e2e.service.endpoint.Endpoints;
|
||||
import org.apache.skywalking.e2e.service.endpoint.EndpointsMatcher;
|
||||
import org.apache.skywalking.e2e.service.instance.Instance;
|
||||
import org.apache.skywalking.e2e.service.instance.Instances;
|
||||
import org.apache.skywalking.e2e.service.instance.InstancesMatcher;
|
||||
import org.apache.skywalking.e2e.service.instance.InstancesQuery;
|
||||
import org.apache.skywalking.e2e.topo.Call;
|
||||
import org.apache.skywalking.e2e.topo.ServiceInstanceTopoData;
|
||||
import org.apache.skywalking.e2e.topo.ServiceInstanceTopoMatcher;
|
||||
import org.apache.skywalking.e2e.topo.ServiceInstanceTopoQuery;
|
||||
import org.apache.skywalking.e2e.topo.TopoData;
|
||||
import org.apache.skywalking.e2e.topo.TopoMatcher;
|
||||
import org.apache.skywalking.e2e.topo.TopoQuery;
|
||||
import org.apache.skywalking.e2e.trace.Trace;
|
||||
import org.apache.skywalking.e2e.trace.TracesMatcher;
|
||||
import org.apache.skywalking.e2e.trace.TracesQuery;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyMetrics;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENDPOINT_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_INSTANCE_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_CLIENT_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_SERVER_METRICS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class SampleVerificationITCase {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SampleVerificationITCase.class);
|
||||
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
private final int retryInterval = 30;
|
||||
|
||||
private SimpleQueryClient queryClient;
|
||||
private String nginxServiceUrl;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final String swWebappHost = System.getProperty("sw.webapp.host", "127.0.0.1");
|
||||
final String swWebappPort = System.getProperty("sw.webapp.port", "32783");
|
||||
final String nginxHost = System.getProperty("nginx.host", "127.0.0.1");
|
||||
final String nginxPort = System.getProperty("nginx.port", "32782");
|
||||
queryClient = new SimpleQueryClient(swWebappHost, swWebappPort);
|
||||
nginxServiceUrl = "http://" + nginxHost + ":" + nginxPort;
|
||||
}
|
||||
|
||||
@Test(timeout = 1200000)
|
||||
@DirtiesContext
|
||||
public void verify() throws Exception {
|
||||
final LocalDateTime minutesAgo = LocalDateTime.now(ZoneOffset.UTC);
|
||||
|
||||
while (true) {
|
||||
final List<Service> services = queryClient.services(
|
||||
new ServicesQuery().start(minutesAgo).end(LocalDateTime.now()));
|
||||
|
||||
if (!services.isEmpty() && services.size() >= 2) {
|
||||
break;
|
||||
}
|
||||
Thread.sleep(10000L);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
final Map<String, String> user = new HashMap<>();
|
||||
user.put("name", "SkyWalking");
|
||||
final ResponseEntity<String> responseEntity = restTemplate.getForEntity(
|
||||
nginxServiceUrl + "/nginx/e2e/info", String.class);
|
||||
LOGGER.info("responseEntity: {}", responseEntity);
|
||||
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(responseEntity.getBody()).isEqualTo("e2e-container-info");
|
||||
final List<Trace> traces = queryClient.traces(new TracesQuery().start(minutesAgo)
|
||||
.end(LocalDateTime.now())
|
||||
.orderByDuration());
|
||||
if (!traces.isEmpty() && traces.size() >= 2) {
|
||||
break;
|
||||
}
|
||||
Thread.sleep(10000L);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
doRetryableVerification(() -> {
|
||||
try {
|
||||
verifyTraces(minutesAgo);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn(e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
|
||||
doRetryableVerification(() -> {
|
||||
try {
|
||||
verifyServices(minutesAgo);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn(e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
|
||||
doRetryableVerification(() -> {
|
||||
try {
|
||||
verifyTopo(minutesAgo);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn(e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
|
||||
doRetryableVerification(() -> {
|
||||
try {
|
||||
verifyServiceInstanceTopo(minutesAgo);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn(e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void verifyTopo(LocalDateTime minutesAgo) throws Exception {
|
||||
final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
|
||||
|
||||
final TopoData topoData = queryClient.topo(new TopoQuery().stepByMinute()
|
||||
.start(minutesAgo.minusDays(1))
|
||||
.end(now));
|
||||
LOGGER.info("topoData: {}", topoData);
|
||||
|
||||
InputStream expectedInputStream = new ClassPathResource(
|
||||
"expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.topo.yml")
|
||||
.getInputStream();
|
||||
|
||||
final TopoMatcher topoMatcher = new Yaml().loadAs(expectedInputStream, TopoMatcher.class);
|
||||
topoMatcher.verify(topoData);
|
||||
verifyServiceRelationMetrics(topoData.getCalls(), minutesAgo);
|
||||
}
|
||||
|
||||
private void verifyServiceInstanceTopo(LocalDateTime minutesAgo) throws Exception {
|
||||
final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
|
||||
|
||||
final ServiceInstanceTopoData topoData = queryClient.serviceInstanceTopo(
|
||||
new ServiceInstanceTopoQuery().stepByMinute()
|
||||
.start(minutesAgo
|
||||
.minusDays(1))
|
||||
.end(now)
|
||||
.clientServiceId("1")
|
||||
.serverServiceId("3"));
|
||||
LOGGER.info("instanceTopoData: {}", topoData);
|
||||
|
||||
InputStream expectedInputStream = new ClassPathResource(
|
||||
"expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.serviceInstanceTopo.yml")
|
||||
.getInputStream();
|
||||
|
||||
final ServiceInstanceTopoMatcher topoMatcher = new Yaml().loadAs(
|
||||
expectedInputStream, ServiceInstanceTopoMatcher.class);
|
||||
topoMatcher.verify(topoData);
|
||||
verifyServiceInstanceRelationMetrics(topoData.getCalls(), minutesAgo);
|
||||
}
|
||||
|
||||
private void verifyServices(LocalDateTime minutesAgo) throws Exception {
|
||||
final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
|
||||
|
||||
final List<Service> services = queryClient.services(new ServicesQuery().start(minutesAgo).end(now));
|
||||
LOGGER.info("services: {}", services);
|
||||
|
||||
InputStream expectedInputStream = new ClassPathResource(
|
||||
"expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.services.yml")
|
||||
.getInputStream();
|
||||
|
||||
final ServicesMatcher servicesMatcher = new Yaml().loadAs(expectedInputStream, ServicesMatcher.class);
|
||||
servicesMatcher.verify(services);
|
||||
|
||||
for (Service service : services) {
|
||||
LOGGER.info("verifying service instances: {}", service);
|
||||
|
||||
verifyServiceMetrics(service);
|
||||
|
||||
Instances instances = verifyServiceInstances(minutesAgo, now, service);
|
||||
|
||||
verifyInstancesMetrics(instances);
|
||||
|
||||
Endpoints endpoints = verifyServiceEndpoints(minutesAgo, now, service);
|
||||
|
||||
verifyEndpointsMetrics(endpoints);
|
||||
}
|
||||
}
|
||||
|
||||
private Instances verifyServiceInstances(LocalDateTime minutesAgo, LocalDateTime now,
|
||||
Service service) throws Exception {
|
||||
Instances instances = queryClient.instances(new InstancesQuery().serviceId(service.getKey())
|
||||
.start(minutesAgo)
|
||||
.end(now));
|
||||
LOGGER.info("instances: {}", instances);
|
||||
InputStream expectedInputStream;
|
||||
if ("User_Service_Name".equals(service.getLabel())) {
|
||||
expectedInputStream = new ClassPathResource(
|
||||
"expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.nginxInstances.yml")
|
||||
.getInputStream();
|
||||
} else {
|
||||
expectedInputStream = new ClassPathResource(
|
||||
"expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.instances.yml")
|
||||
.getInputStream();
|
||||
}
|
||||
final InstancesMatcher instancesMatcher = new Yaml().loadAs(expectedInputStream, InstancesMatcher.class);
|
||||
instancesMatcher.verify(instances);
|
||||
return instances;
|
||||
}
|
||||
|
||||
private Endpoints verifyServiceEndpoints(LocalDateTime minutesAgo, LocalDateTime now,
|
||||
Service service) throws Exception {
|
||||
Endpoints endpoints = queryClient.endpoints(new EndpointQuery().serviceId(service.getKey()));
|
||||
LOGGER.info("instances: {}", endpoints);
|
||||
InputStream expectedInputStream;
|
||||
|
||||
if ("/e2e/health-check".equals(endpoints.getEndpoints().get(0).getLabel())) {
|
||||
expectedInputStream = new ClassPathResource(
|
||||
"org.apache.skywalking.e2e.SampleVerificationITCase.nginxEndpoints.yml")
|
||||
.getInputStream();
|
||||
} else {
|
||||
expectedInputStream = new ClassPathResource(
|
||||
"expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.endpoints.yml")
|
||||
.getInputStream();
|
||||
}
|
||||
final EndpointsMatcher endpointsMatcher = new Yaml().loadAs(expectedInputStream, EndpointsMatcher.class);
|
||||
endpointsMatcher.verify(endpoints);
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
private void verifyInstancesMetrics(Instances instances) throws Exception {
|
||||
for (Instance instance : instances.getInstances()) {
|
||||
for (String metricsName : ALL_INSTANCE_METRICS) {
|
||||
LOGGER.info("verifying service instance response time: {}", instance);
|
||||
final Metrics instanceMetrics = queryClient.metrics(new MetricsQuery().stepByMinute()
|
||||
.metricsName(metricsName)
|
||||
.id(instance.getKey()));
|
||||
LOGGER.info("instanceMetrics: {}", instanceMetrics);
|
||||
AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
|
||||
MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
|
||||
greaterThanZero.setValue("ge 0");
|
||||
instanceRespTimeMatcher.setValue(greaterThanZero);
|
||||
instanceRespTimeMatcher.verify(instanceMetrics);
|
||||
LOGGER.info("{}: {}", metricsName, instanceMetrics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyEndpointsMetrics(Endpoints endpoints) throws Exception {
|
||||
for (Endpoint endpoint : endpoints.getEndpoints()) {
|
||||
if (!endpoint.getLabel().equals("/e2e/info") || !endpoint.getLabel()
|
||||
.equals("/nginx/e2e/info")) {
|
||||
continue;
|
||||
}
|
||||
for (String metricName : ALL_ENDPOINT_METRICS) {
|
||||
LOGGER.info("verifying endpoint {}, metrics: {}", endpoint, metricName);
|
||||
final Metrics metrics = queryClient.metrics(new MetricsQuery().stepByMinute()
|
||||
.metricsName(metricName)
|
||||
.id(endpoint.getKey()));
|
||||
LOGGER.info("metrics: {}", metrics);
|
||||
AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
|
||||
MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
|
||||
greaterThanZero.setValue("ge 0");
|
||||
instanceRespTimeMatcher.setValue(greaterThanZero);
|
||||
instanceRespTimeMatcher.verify(metrics);
|
||||
LOGGER.info("{}: {}", metricName, metrics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyServiceMetrics(Service service) throws Exception {
|
||||
for (String metricName : ALL_SERVICE_METRICS) {
|
||||
LOGGER.info("verifying service {}, metrics: {}", service, metricName);
|
||||
final Metrics serviceMetrics = queryClient.metrics(new MetricsQuery().stepByMinute()
|
||||
.metricsName(metricName)
|
||||
.id(service.getKey()));
|
||||
LOGGER.info("serviceMetrics: {}", serviceMetrics);
|
||||
AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
|
||||
MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
|
||||
greaterThanZero.setValue("ge 0");
|
||||
instanceRespTimeMatcher.setValue(greaterThanZero);
|
||||
instanceRespTimeMatcher.verify(serviceMetrics);
|
||||
LOGGER.info("{}: {}", metricName, serviceMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyTraces(LocalDateTime minutesAgo) throws Exception {
|
||||
final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
|
||||
|
||||
final List<Trace> traces = queryClient.traces(new TracesQuery().start(minutesAgo).end(now).orderByDuration());
|
||||
LOGGER.info("traces: {}", traces);
|
||||
|
||||
InputStream expectedInputStream = new ClassPathResource(
|
||||
"expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.traces.yml")
|
||||
.getInputStream();
|
||||
|
||||
final TracesMatcher tracesMatcher = new Yaml().loadAs(expectedInputStream, TracesMatcher.class);
|
||||
tracesMatcher.verifyLoosely(traces);
|
||||
}
|
||||
|
||||
private void verifyServiceInstanceRelationMetrics(List<Call> calls,
|
||||
final LocalDateTime minutesAgo) throws Exception {
|
||||
verifyRelationMetrics(
|
||||
calls, minutesAgo, ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS,
|
||||
ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS
|
||||
);
|
||||
}
|
||||
|
||||
private void verifyServiceRelationMetrics(List<Call> calls, final LocalDateTime minutesAgo) throws Exception {
|
||||
verifyRelationMetrics(
|
||||
calls, minutesAgo, ALL_SERVICE_RELATION_CLIENT_METRICS, ALL_SERVICE_RELATION_SERVER_METRICS);
|
||||
}
|
||||
|
||||
private void verifyRelationMetrics(List<Call> calls, final LocalDateTime minutesAgo, String[] relationClientMetrics,
|
||||
String[] relationServerMetrics) throws Exception {
|
||||
for (Call call : calls) {
|
||||
for (String detectPoint : call.getDetectPoints()) {
|
||||
switch (detectPoint) {
|
||||
case "CLIENT": {
|
||||
for (String metricName : relationClientMetrics) {
|
||||
verifyMetrics(queryClient, metricName, call.getId(), minutesAgo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SERVER": {
|
||||
for (String metricName : relationServerMetrics) {
|
||||
verifyMetrics(queryClient, metricName, call.getId(), minutesAgo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doRetryableVerification(Runnable runnable) throws InterruptedException {
|
||||
while (true) {
|
||||
try {
|
||||
runnable.run();
|
||||
break;
|
||||
} catch (Throwable ignored) {
|
||||
Thread.sleep(retryInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# 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.
|
||||
|
||||
# 1 health-check by docker-maven-plugin
|
||||
# 1 drop table if exists, because we have `ddl-auto: create-drop`
|
||||
# 1 drop sequence
|
||||
# 1 create sequence
|
||||
# 1 create table statement
|
||||
|
||||
endpoints:
|
||||
- key: not null
|
||||
label: /e2e/info
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# 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.
|
||||
|
||||
# 1 health-check by docker-maven-plugin
|
||||
# 1 drop table if exists, because we have `ddl-auto: create-drop`
|
||||
# 1 drop sequence
|
||||
# 1 create sequence
|
||||
# 1 create table statement
|
||||
|
||||
instances:
|
||||
- key: 2
|
||||
label: not null
|
||||
attributes:
|
||||
- name: os_name
|
||||
value: not null
|
||||
- name: host_name
|
||||
value: not null
|
||||
- name: process_no
|
||||
value: gt 0
|
||||
- name: ipv4s
|
||||
value: not null
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# 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.
|
||||
|
||||
# 1 health-check by docker-maven-plugin
|
||||
# 1 drop table if exists, because we have `ddl-auto: create-drop`
|
||||
# 1 drop sequence
|
||||
# 1 create sequence
|
||||
# 1 create table statement
|
||||
|
||||
nodes:
|
||||
- id: 1
|
||||
name: User
|
||||
type: USER
|
||||
serviceId: 1
|
||||
serviceName: User
|
||||
isReal: false
|
||||
- id: 3
|
||||
name: not null
|
||||
serviceId: 3
|
||||
serviceName: User_Service_Name
|
||||
type: not null
|
||||
isReal: true
|
||||
calls:
|
||||
- id: 1_3
|
||||
source: 1
|
||||
detectPoints:
|
||||
- SERVER
|
||||
target: 3
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# 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.
|
||||
|
||||
# 1 health-check by docker-maven-plugin
|
||||
# 1 drop table if exists, because we have `ddl-auto: create-drop`
|
||||
# 1 drop sequence
|
||||
# 1 create sequence
|
||||
# 1 create table statement
|
||||
|
||||
services:
|
||||
- key: 2
|
||||
label: "Your_ApplicationName"
|
||||
- key: 3
|
||||
label: "User_Service_Name"
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
# 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.
|
||||
|
||||
# 1 health-check by docker-maven-plugin
|
||||
# 1 drop table if exists, because we have `ddl-auto: create-drop`
|
||||
# 1 drop sequence
|
||||
# 1 create sequence
|
||||
# 1 create table statement
|
||||
|
||||
nodes:
|
||||
- id: 1
|
||||
name: User
|
||||
type: USER
|
||||
isReal: false
|
||||
- id: 2
|
||||
name: Your_ApplicationName
|
||||
type: Tomcat
|
||||
isReal: true
|
||||
- id: 3
|
||||
name: User_Service_Name
|
||||
type: Nginx
|
||||
isReal: true
|
||||
calls:
|
||||
- id: 1_3
|
||||
source: 1
|
||||
detectPoints:
|
||||
- SERVER
|
||||
target: 3
|
||||
- id: 3_2
|
||||
source: 3
|
||||
detectPoints:
|
||||
- CLIENT
|
||||
- SERVER
|
||||
target: 2
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# 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.
|
||||
|
||||
# 1 health-check by docker-maven-plugin
|
||||
# 1 drop table if exists, because we have `ddl-auto: create-drop`
|
||||
# 1 drop sequence
|
||||
# 1 create sequence
|
||||
# 1 create table statement
|
||||
|
||||
traces:
|
||||
- key: not null
|
||||
endpointNames:
|
||||
- /e2e/info
|
||||
duration: ge 0
|
||||
start: gt 0
|
||||
isError: false
|
||||
traceIds:
|
||||
- not null
|
||||
|
||||
- key: not null
|
||||
endpointNames:
|
||||
- /nginx/e2e/info
|
||||
duration: ge 0
|
||||
start: gt 0
|
||||
isError: false
|
||||
traceIds:
|
||||
- not null
|
||||
|
|
@ -44,6 +44,7 @@
|
|||
<module>e2e-6.x-agent-7.x-oap-compatibility</module>
|
||||
<module>e2e-profile</module>
|
||||
<module>e2e-protocol</module>
|
||||
<module>e2e-http-api-with-nginx-lua</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
|
|
|||
|
|
@ -142,7 +142,8 @@ opencensus-contrib-grpc-metrics-0.24.0.jar
|
|||
parent-join-client-7.0.0.jar
|
||||
perfmark-api-0.19.0.jar
|
||||
proto-google-common-protos-1.12.0.jar
|
||||
protobuf-java-3.4.0.jar
|
||||
protobuf-java-3.11.4.jar
|
||||
protobuf-java-util-3.11.4.jar
|
||||
rank-eval-client-7.0.0.jar
|
||||
reactive-streams-1.0.2.jar
|
||||
reflectasm-1.11.7.jar
|
||||
|
|
|
|||
|
|
@ -140,7 +140,8 @@ opencensus-contrib-grpc-metrics-0.24.0.jar
|
|||
parent-join-client-6.3.2.jar
|
||||
perfmark-api-0.19.0.jar
|
||||
proto-google-common-protos-1.12.0.jar
|
||||
protobuf-java-3.4.0.jar
|
||||
protobuf-java-3.11.4.jar
|
||||
protobuf-java-util-3.11.4.jar
|
||||
rank-eval-client-6.3.2.jar
|
||||
reactive-streams-1.0.2.jar
|
||||
reflectasm-1.11.7.jar
|
||||
|
|
|
|||
Loading…
Reference in New Issue