未验证 提交 1ff25ac4 编写于 作者: H harvies 提交者: GitHub

Support mongo driver 4.x version. (#5512)

上级 c3edd3da
......@@ -47,6 +47,7 @@ jobs:
- { name: 'kotlin-coroutine-scenario', title: 'Kotlin Coroutine 1.0.1-1.3.3 (4)' }
- { name: 'lettuce-scenario', title: 'Lettuce 5.x (17)' }
- { name: 'mongodb-3.x-scenario', title: 'Mongodb 3.4.0-3.11.1 (22)' }
- { name: 'mongodb-4.x-scenario', title: 'Mongodb 4.0.0-4.1.0 (7)' }
- { name: 'netty-socketio-scenario', title: 'Netty-SocketIO 1.x (4)' }
- { name: 'postgresql-above9.4.1207-scenario', title: 'PostgreSQL 9.4.1207+ (62)' }
steps:
......
<!--
~ 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">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>apm-sdk-plugin</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>8.2.0-SNAPSHOT</version>
</parent>
<artifactId>apm-mongodb-4.x-plugin</artifactId>
<packaging>jar</packaging>
<name>mongodb-plugin</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mongodb-driver.version>4.1.0</mongodb-driver.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>${mongodb-driver.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
/*
* 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.apm.plugin.mongodb.v4.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.plugin.mongodb.v4.interceptor.MongoDBClientDelegateInterceptor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* Enhance {@code com.mongodb.client.internal.MongoClientDelegate} instance, and intercept {@code
* com.mongodb.client.internal.MongoClientDelegate#getOperationExecutor()}, this is the only way to get
* OperationExecutor which is unified entrance of execute mongo command. Inject the remotePeer into enhanced OperationExecutor.
* <p>
* support: 4.0.0 or higher
*
* @see MongoDBOperationExecutorInstrumentation
* @see MongoDBClientDelegateInterceptor
*/
public class MongoDBClientDelegateInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String WITNESS_CLASS = "com.mongodb.internal.connection.Cluster";
private static final String ENHANCE_CLASS = "com.mongodb.client.internal.MongoClientDelegate";
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.mongodb.v4.interceptor.MongoDBClientDelegateInterceptor";
@Override
protected String[] witnessClasses() {
return new String[] {WITNESS_CLASS};
}
@Override
protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
}
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[] {
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return takesArgumentWithType(0, "com.mongodb.internal.connection.Cluster");
}
@Override
public String getConstructorInterceptor() {
return INTERCEPTOR_CLASS;
}
}
};
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("getOperationExecutor");
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
}
/*
* 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.apm.plugin.mongodb.v4.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
/**
* same with org.apache.skywalking.apm.plugin.mongodb.v3.define.v38.MongoDBOperationExecutorInstrumentation
* <p>
* support: 4.0.x or higher
*/
public class MongoDBOperationExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String WITNESS_CLASS = "com.mongodb.internal.operation.FindOperation";
private static final String ENHANCE_CLASS = "com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor";
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.mongodb.v4.interceptor.MongoDBOperationExecutorInterceptor";
private static final String METHOD_NAME = "execute";
private static final String ARGUMENT_TYPE = "com.mongodb.client.ClientSession";
@Override
protected String[] witnessClasses() {
return new String[] {WITNESS_CLASS};
}
@Override
protected ClassMatch enhanceClass() {
return NameMatch.byName(ENHANCE_CLASS);
}
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return ElementMatchers
.named(METHOD_NAME)
.and(ArgumentTypeNameMatch.takesArgumentWithType(2, ARGUMENT_TYPE))
.or(ElementMatchers.<MethodDescription>named(METHOD_NAME).and(ArgumentTypeNameMatch.takesArgumentWithType(3, ARGUMENT_TYPE)));
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
}
/*
* 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.apm.plugin.mongodb.v4.interceptor;
import com.mongodb.internal.connection.Cluster;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.plugin.mongodb.v4.support.MongoRemotePeerHelper;
import java.lang.reflect.Method;
public class MongoDBClientDelegateInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor {
private static final ILog LOGGER = LogManager.getLogger(MongoDBClientDelegateInterceptor.class);
@Override
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
Cluster cluster = (Cluster) allArguments[0];
String remotePeer = MongoRemotePeerHelper.getRemotePeer(cluster);
objInst.setSkyWalkingDynamicField(remotePeer);
}
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) {
// do nothing
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) {
if (ret instanceof EnhancedInstance) {
// pass remotePeer to OperationExecutor, which has be enhanced as EnhancedInstance
// See: org.apache.skywalking.apm.plugin.mongodb.v3.define.v37.MongoDBOperationExecutorInstrumentation
EnhancedInstance retInstance = (EnhancedInstance) ret;
String remotePeer = (String) objInst.getSkyWalkingDynamicField();
if (LOGGER.isDebugEnable()) {
LOGGER.debug("Mark OperationExecutor remotePeer: {}", remotePeer);
}
retInstance.setSkyWalkingDynamicField(remotePeer);
}
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
// do nothing
}
}
/*
* 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.apm.plugin.mongodb.v4.interceptor;
import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.plugin.mongodb.v4.support.MongoSpanHelper;
import java.lang.reflect.Method;
@SuppressWarnings("Duplicates")
public class MongoDBOperationExecutorInterceptor implements InstanceMethodsAroundInterceptor {
private static final ILog LOGGER = LogManager.getLogger(MongoDBOperationExecutorInterceptor.class);
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) {
String executeMethod = allArguments[0].getClass().getSimpleName();
// OperationExecutor has included th remotePeer
// See: MongoDBClientDelegateInterceptor.afterMethod
String remotePeer = (String) objInst.getSkyWalkingDynamicField();
if (LOGGER.isDebugEnable()) {
LOGGER.debug("Mongo execute: [executeMethod: {}, remotePeer: {}]", executeMethod, remotePeer);
}
MongoSpanHelper.createExitSpan(executeMethod, remotePeer, allArguments[0]);
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) {
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
AbstractSpan activeSpan = ContextManager.activeSpan();
activeSpan.log(t);
}
}
/*
* 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.apm.plugin.mongodb.v4.support;
public class MongoConstants {
private MongoConstants() {
}
public static final String DB_TYPE = "MongoDB";
public static final String MONGO_DB_OP_PREFIX = "MongoDB/";
public static final String EMPTY = "";
}
/*
* 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.apm.plugin.mongodb.v4.support;
import com.mongodb.internal.bulk.DeleteRequest;
import com.mongodb.internal.bulk.InsertRequest;
import com.mongodb.internal.bulk.UpdateRequest;
import com.mongodb.internal.bulk.WriteRequest;
import com.mongodb.internal.operation.CountOperation;
import com.mongodb.internal.operation.CreateCollectionOperation;
import com.mongodb.internal.operation.CreateIndexesOperation;
import com.mongodb.internal.operation.CreateViewOperation;
import com.mongodb.internal.operation.DeleteOperation;
import com.mongodb.internal.operation.DistinctOperation;
import com.mongodb.internal.operation.FindAndDeleteOperation;
import com.mongodb.internal.operation.FindAndReplaceOperation;
import com.mongodb.internal.operation.FindAndUpdateOperation;
import com.mongodb.internal.operation.FindOperation;
import com.mongodb.internal.operation.InsertOperation;
import com.mongodb.internal.operation.ListCollectionsOperation;
import com.mongodb.internal.operation.MapReduceToCollectionOperation;
import com.mongodb.internal.operation.MapReduceWithInlineResultsOperation;
import com.mongodb.internal.operation.MixedBulkWriteOperation;
import com.mongodb.internal.operation.UpdateOperation;
import org.bson.BsonDocument;
import java.util.List;
@SuppressWarnings({
"deprecation",
"Duplicates"
})
public class MongoOperationHelper {
private MongoOperationHelper() {
}
/**
* Convert ReadOperation interface or WriteOperation interface to the implementation class. Get the method name and
* filter info.
* @param obj operation
* @return result
*/
public static String getTraceParam(Object obj) {
if (obj instanceof CountOperation) {
BsonDocument filter = ((CountOperation) obj).getFilter();
return limitFilter(filter.toString());
} else if (obj instanceof DistinctOperation) {
BsonDocument filter = ((DistinctOperation) obj).getFilter();
return limitFilter(filter.toString());
} else if (obj instanceof FindOperation) {
BsonDocument filter = ((FindOperation) obj).getFilter();
return limitFilter(filter.toString());
} else if (obj instanceof ListCollectionsOperation) {
BsonDocument filter = ((ListCollectionsOperation) obj).getFilter();
return limitFilter(filter.toString());
} else if (obj instanceof MapReduceWithInlineResultsOperation) {
BsonDocument filter = ((MapReduceWithInlineResultsOperation) obj).getFilter();
return limitFilter(filter.toString());
} else if (obj instanceof DeleteOperation) {
List<DeleteRequest> writeRequestList = ((DeleteOperation) obj).getDeleteRequests();
return getFilter(writeRequestList);
} else if (obj instanceof InsertOperation) {
List<InsertRequest> writeRequestList = ((InsertOperation) obj).getInsertRequests();
return getFilter(writeRequestList);
} else if (obj instanceof UpdateOperation) {
List<UpdateRequest> writeRequestList = ((UpdateOperation) obj).getUpdateRequests();
return getFilter(writeRequestList);
} else if (obj instanceof CreateCollectionOperation) {
String filter = ((CreateCollectionOperation) obj).getCollectionName();
return limitFilter(filter);
} else if (obj instanceof CreateIndexesOperation) {
List<String> filter = ((CreateIndexesOperation) obj).getIndexNames();
return limitFilter(filter.toString());
} else if (obj instanceof CreateViewOperation) {
String filter = ((CreateViewOperation) obj).getViewName();
return limitFilter(filter);
} else if (obj instanceof FindAndDeleteOperation) {
BsonDocument filter = ((FindAndDeleteOperation) obj).getFilter();
return limitFilter(filter.toString());
} else if (obj instanceof FindAndReplaceOperation) {
BsonDocument filter = ((FindAndReplaceOperation) obj).getFilter();
return limitFilter(filter.toString());
} else if (obj instanceof FindAndUpdateOperation) {
BsonDocument filter = ((FindAndUpdateOperation) obj).getFilter();
return limitFilter(filter.toString());
} else if (obj instanceof MapReduceToCollectionOperation) {
BsonDocument filter = ((MapReduceToCollectionOperation) obj).getFilter();
return limitFilter(filter.toString());
} else if (obj instanceof MixedBulkWriteOperation) {
List<? extends WriteRequest> writeRequestList = ((MixedBulkWriteOperation) obj).getWriteRequests();
return getFilter(writeRequestList);
} else {
return MongoConstants.EMPTY;
}
}
private static String getFilter(List<? extends WriteRequest> writeRequestList) {
StringBuilder params = new StringBuilder();
for (WriteRequest request : writeRequestList) {
if (request instanceof InsertRequest) {
params.append(((InsertRequest) request).getDocument().toString()).append(",");
} else if (request instanceof DeleteRequest) {
params.append(((DeleteRequest) request).getFilter()).append(",");
} else if (request instanceof UpdateRequest) {
params.append(((UpdateRequest) request).getFilter()).append(",");
}
final int filterLengthLimit = MongoPluginConfig.Plugin.MongoDB.FILTER_LENGTH_LIMIT;
if (filterLengthLimit > 0 && params.length() > filterLengthLimit) {
return params.substring(0, filterLengthLimit) + "...";
}
}
return params.toString();
}
private static String limitFilter(String filter) {
final StringBuilder params = new StringBuilder();
final int filterLengthLimit = MongoPluginConfig.Plugin.MongoDB.FILTER_LENGTH_LIMIT;
if (filterLengthLimit > 0 && filter.length() > filterLengthLimit) {
return params.append(filter, 0, filterLengthLimit).append("...").toString();
} else {
return filter;
}
}
}
/*
* 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.apm.plugin.mongodb.v4.support;
import org.apache.skywalking.apm.agent.core.boot.PluginConfig;
public class MongoPluginConfig {
public static class Plugin {
@PluginConfig(root = MongoPluginConfig.class)
public static class MongoDB {
/**
* If true, trace all the parameters in MongoDB access, default is false. Only trace the operation, not
* include parameters.
*/
public static boolean TRACE_PARAM = false;
/**
* For the sake of performance, SkyWalking won't save the entire parameters string into the tag, but only
* the first {@code FILTER_LENGTH_LIMIT} characters.
* <p>
* Set a negative number to save the complete parameter string to the tag.
*/
public static int FILTER_LENGTH_LIMIT = 256;
}
}
}
/*
* 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.apm.plugin.mongodb.v4.support;
import com.mongodb.ServerAddress;
import com.mongodb.connection.ServerDescription;
import com.mongodb.internal.connection.Cluster;
@SuppressWarnings("deprecation")
public class MongoRemotePeerHelper {
private MongoRemotePeerHelper() {
}
/**
*
* @param cluster cluster
* @return result
*/
public static String getRemotePeer(Cluster cluster) {
StringBuilder peersBuilder = new StringBuilder();
for (ServerDescription description : cluster.getDescription().getServerDescriptions()) {
ServerAddress address = description.getAddress();
peersBuilder.append(address.getHost()).append(":").append(address.getPort()).append(";");
}
return peersBuilder.substring(0, peersBuilder.length() - 1);
}
}
/*
* 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.apm.plugin.mongodb.v4.support;
import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
public class MongoSpanHelper {
private MongoSpanHelper() {
}
/**
* createExitSpan
* @param executeMethod executeMethod
* @param remotePeer remotePeer
* @param operation operation
*/
public static void createExitSpan(String executeMethod, String remotePeer, Object operation) {
AbstractSpan span = ContextManager.createExitSpan(
MongoConstants.MONGO_DB_OP_PREFIX + executeMethod, new ContextCarrier(), remotePeer);
span.setComponent(ComponentsDefine.MONGO_DRIVER);
Tags.DB_TYPE.set(span, MongoConstants.DB_TYPE);
SpanLayer.asDB(span);
if (MongoPluginConfig.Plugin.MongoDB.TRACE_PARAM) {
Tags.DB_BIND_VARIABLES.set(span, MongoOperationHelper.getTraceParam(operation));
}
}
}
# 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.
# v4.0.0~
mongodb-4.x=org.apache.skywalking.apm.plugin.mongodb.v4.define.MongoDBClientDelegateInstrumentation
mongodb-4.x=org.apache.skywalking.apm.plugin.mongodb.v4.define.MongoDBOperationExecutorInstrumentation
/*
* 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.apm.plugin.mongodb.v4;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.plugin.mongodb.v4.interceptor.MongoDBClientDelegateInterceptor;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Mockito.when;
@RunWith(PowerMockRunner.class)
public class MongoDBClientDelegateInterceptorTest {
private MongoDBClientDelegateInterceptor interceptor;
@Mock
private EnhancedInstance clientDelegateEnhancedInstance;
private EnhancedInstance retEnhancedInstance;
private final static String REMOTE_PEER = "127.0.0.1:27017";
@Before
public void setUp() {
interceptor = new MongoDBClientDelegateInterceptor();
retEnhancedInstance = new FieldEnhancedInstance();
when(clientDelegateEnhancedInstance.getSkyWalkingDynamicField()).thenReturn(REMOTE_PEER);
}
@Test
public void testAfterMethod() {
interceptor.afterMethod(clientDelegateEnhancedInstance, null, null, null, retEnhancedInstance);
Assert.assertEquals(REMOTE_PEER, retEnhancedInstance.getSkyWalkingDynamicField());
}
private static class FieldEnhancedInstance implements EnhancedInstance {
private Object skyWalkingDynamicField;
@Override
public Object getSkyWalkingDynamicField() {
return skyWalkingDynamicField;
}
@Override
public void setSkyWalkingDynamicField(Object value) {
this.skyWalkingDynamicField = value;
}
}
}
/*
* 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.apm.plugin.mongodb.v4;
import com.mongodb.MongoNamespace;
import com.mongodb.ReadConcern;
import com.mongodb.client.internal.OperationExecutor;
import com.mongodb.internal.operation.FindOperation;
import com.mongodb.internal.operation.WriteOperation;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.apache.skywalking.apm.agent.core.context.util.TagValuePair;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
import org.apache.skywalking.apm.plugin.mongodb.v4.interceptor.MongoDBOperationExecutorInterceptor;
import org.apache.skywalking.apm.plugin.mongodb.v4.support.MongoPluginConfig;
import org.bson.BsonDocument;
import org.bson.BsonString;
import org.bson.codecs.Decoder;
import org.hamcrest.CoreMatchers;
import org.hamcrest.MatcherAssert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import java.lang.reflect.Method;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.when;
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
public class MongoDBOperationExecutorInterceptorTest {
@SegmentStoragePoint
private SegmentStorage segmentStorage;
@Rule
public AgentServiceRule serviceRule = new AgentServiceRule();
@Mock
private EnhancedInstance enhancedInstance;
private MongoDBOperationExecutorInterceptor interceptor;
private Object[] arguments;
private Class[] argumentTypes;
@Before
public void setUp() {
interceptor = new MongoDBOperationExecutorInterceptor();
MongoPluginConfig.Plugin.MongoDB.TRACE_PARAM = true;
when(enhancedInstance.getSkyWalkingDynamicField()).thenReturn("127.0.0.1:27017");
BsonDocument document = new BsonDocument();
document.append("name", new BsonString("by"));
MongoNamespace mongoNamespace = new MongoNamespace("test.user");
Decoder decoder = PowerMockito.mock(Decoder.class);
FindOperation findOperation = new FindOperation(mongoNamespace, decoder);
findOperation.filter(document);
arguments = new Object[] {findOperation};
argumentTypes = new Class[] {findOperation.getClass()};
}
@Test
public void testIntercept() throws Throwable {
interceptor.beforeMethod(enhancedInstance, getMethod(), arguments, argumentTypes, null);
interceptor.afterMethod(enhancedInstance, getMethod(), arguments, argumentTypes, null);
MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1));
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
assertMongoSpan(spans.get(0));
}
@Test
public void testInterceptWithException() throws Throwable {
interceptor.beforeMethod(enhancedInstance, getMethod(), arguments, argumentTypes, null);
interceptor.handleMethodException(
enhancedInstance, getMethod(), arguments, argumentTypes, new RuntimeException());
interceptor.afterMethod(enhancedInstance, getMethod(), arguments, argumentTypes, null);
MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1));
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
assertMongoSpan(spans.get(0));
List<LogDataEntity> logDataEntities = SpanHelper.getLogs(spans.get(0));
assertThat(logDataEntities.size(), is(1));
SpanAssert.assertException(logDataEntities.get(0), RuntimeException.class);
}
private void assertMongoSpan(AbstractTracingSpan span) {
assertThat(span.getOperationName(), is("MongoDB/FindOperation"));
assertThat(SpanHelper.getComponentId(span), is(42));
List<TagValuePair> tags = SpanHelper.getTags(span);
assertThat(tags.get(1).getValue(), is("{\"name\": \"by\"}"));
assertThat(tags.get(0).getValue(), is("MongoDB"));
assertThat(span.isExit(), is(true));
assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.DB));
}
private Method getMethod() throws Exception {
return OperationExecutor.class.getMethod("execute", WriteOperation.class, ReadConcern.class);
}
}
......@@ -36,6 +36,7 @@
<module>tomcat-7.x-8.x-plugin</module>
<module>motan-plugin</module>
<module>mongodb-3.x-plugin</module>
<module>mongodb-4.x-plugin</module>
<module>feign-default-http-9.x-plugin</module>
<module>okhttp-3.x-plugin</module>
<module>spring-plugins</module>
......
......@@ -41,6 +41,7 @@
- memcache-2.x
- mongodb-2.x
- mongodb-3.x
- mongodb-4.x
- motan-0.x
- mysql-5.x
- mysql-6.x
......
......@@ -58,7 +58,7 @@
* [Jedis](https://github.com/xetorthio/jedis) 2.x
* [Redisson](https://github.com/redisson/redisson) Easy Java Redis client 3.5.2+
* [Lettuce](https://github.com/lettuce-io/lettuce-core) 5.x
* [MongoDB Java Driver](https://github.com/mongodb/mongo-java-driver) 2.13-2.14, 3.4.0-3.11.1
* [MongoDB Java Driver](https://github.com/mongodb/mongo-java-driver) 2.13-2.14, 3.4.0-3.11.1, 4.0.0-4.1.0
* Memcached Client
* [Spymemcached](https://github.com/couchbase/spymemcached) 2.x
* [Xmemcached](https://github.com/killme2008/xmemcached) 2.x
......
#!/bin/bash
#
# 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.
home="$(cd "$(dirname $0)"; pwd)"
java -jar ${agent_opts} -Dskywalking.plugin.mongodb.trace_param=true ${home}/../libs/mongodb-4.x-scenario.jar &
\ No newline at end of file
# 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.
segmentItems:
- serviceName: mongodb-4.x-scenario
segmentSize: ge 2
segments:
- segmentId: not null
spans:
- operationName: MongoDB/CreateCollectionOperation
operationId: 0
parentSpanId: 0
spanId: 1
spanLayer: Database
startTime: nq 0
endTime: nq 0
componentId: 42
isError: false
spanType: Exit
peer: mongodb-server:27017
tags:
- {key: db.type, value: MongoDB}
- {key: db.bind_vars, value: 'testCollection'}
skipAnalysis: 'false'
- operationName: MongoDB/MixedBulkWriteOperation
operationId: 0
parentSpanId: 0
spanId: 2
spanLayer: Database
startTime: nq 0
endTime: nq 0
componentId: 42
isError: false
spanType: Exit
peer: mongodb-server:27017
tags:
- {key: db.type, value: MongoDB}
- {key: db.bind_vars, value: not null}
skipAnalysis: 'false'
- operationName: MongoDB/FindOperation
operationId: 0
parentSpanId: 0
spanId: 3
spanLayer: Database
startTime: nq 0
endTime: nq 0
componentId: 42
isError: false
spanType: Exit
peer: mongodb-server:27017
tags:
- {key: db.type, value: MongoDB}
- {key: db.bind_vars, value: '{"name": "org"}'}
skipAnalysis: 'false'
- operationName: MongoDB/MixedBulkWriteOperation
operationId: 0
parentSpanId: 0
spanId: 4
spanLayer: Database
startTime: nq 0
endTime: nq 0
componentId: 42
isError: false
spanType: Exit
peer: mongodb-server:27017
tags:
- {key: db.type, value: MongoDB}
- {key: db.bind_vars, value: '{"name": "org"},'}
skipAnalysis: 'false'
- operationName: MongoDB/FindOperation
operationId: 0
parentSpanId: 0
spanId: 5
spanLayer: Database
startTime: nq 0
endTime: nq 0
componentId: 42
isError: false
spanType: Exit
peer: mongodb-server:27017
tags:
- {key: db.type, value: MongoDB}
- {key: db.bind_vars, value: '{"name": "testA"}'}
skipAnalysis: 'false'
- operationName: MongoDB/MixedBulkWriteOperation
operationId: 0
parentSpanId: 0
spanId: 6
spanLayer: Database
startTime: nq 0
endTime: nq 0
componentId: 42
isError: false
spanType: Exit
peer: mongodb-server:27017
tags:
- {key: db.type, value: MongoDB}
- {key: db.bind_vars, value: '{"id": "1"},'}
skipAnalysis: 'false'
- operationName: MongoDB/DropDatabaseOperation
operationId: 0
parentSpanId: 0
spanId: 7
spanLayer: Database
startTime: nq 0
endTime: nq 0
componentId: 42
isError: false
spanType: Exit
peer: mongodb-server:27017
tags:
- {key: db.type, value: MongoDB}
- {key: db.bind_vars, value: null}
skipAnalysis: 'false'
- operationName: /mongodb-4.x-scenario/case/mongodb-4.x-scenario
operationId: 0
parentSpanId: -1
spanId: 0
spanLayer: Http
startTime: nq 0
endTime: nq 0
componentId: 1
isError: false
spanType: Entry
peer: ''
tags:
- {key: url, value: 'http://localhost:8080/mongodb-4.x-scenario/case/mongodb-4.x-scenario'}
- {key: http.method, value: GET}
skipAnalysis: 'false'
# 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.
type: jvm
entryService: http://localhost:8080/mongodb-4.x-scenario/case/mongodb-4.x-scenario
healthCheck: http://localhost:8080/mongodb-4.x-scenario/case/healthCheck
startScript: ./bin/startup.sh
dependencies:
mongodb-server:
image: mongo:4.2
hostname: mongodb-server
<?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">
<groupId>org.apache.skywalking.apm.testcase</groupId>
<artifactId>mongodb-4.x-scenario</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<compiler.version>1.8</compiler.version>
<test.framework.version>4.0.0</test.framework.version>
<spring-boot-version>2.1.6.RELEASE</spring-boot-version>
<lombok.version>1.18.10</lombok.version>
</properties>
<name>skywalking-mongodb-4.x-scenario</name>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-core</artifactId>
<version>${test.framework.version}</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>${test.framework.version}</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>bson</artifactId>
<version>${test.framework.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-core</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>bson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>mongodb-4.x-scenario</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${compiler.version}</source>
<target>${compiler.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
<outputDirectory>./target/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
<?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.
~
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>./bin</directory>
<fileMode>0775</fileMode>
</fileSet>
</fileSets>
<files>
<file>
<source>${project.build.directory}/mongodb-4.x-scenario.jar</source>
<outputDirectory>./libs</outputDirectory>
<fileMode>0775</fileMode>
</file>
</files>
</assembly>
/*
* 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.apm.testcase.mongodb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
try {
SpringApplication.run(Application.class, args);
} catch (Exception e) {
// Never do this
}
}
}
/*
* 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.apm.testcase.mongodb.controller;
import com.mongodb.client.*;
import org.bson.BsonDocument;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static com.mongodb.client.model.Filters.eq;
@RestController
@RequestMapping("/case")
public class CaseController {
@Value(value = "${mongodb.uri}")
private String connectionString;
@GetMapping("/healthCheck")
public String health() {
// check connect to mongodb server
try (MongoClient mongoClient = MongoClients.create(connectionString)) {
return "success";
}
}
@RequestMapping("/mongodb-4.x-scenario")
public String mongoDBCase() {
try (MongoClient mongoClient = MongoClients.create(connectionString)) {
MongoDatabase db = mongoClient.getDatabase("test-database");
// CreateCollectionOperation
db.createCollection("testCollection");
MongoCollection<Document> collection = db.getCollection("testCollection");
Document document = Document.parse("{id: 1, name: \"test\"}");
// MixedBulkWriteOperation
collection.insertOne(document);
// FindOperation
FindIterable<Document> findIterable = collection.find(eq("name", "org"));
findIterable.first();
// MixedBulkWriteOperation
collection.updateOne(eq("name", "org"), BsonDocument.parse("{ $set : { \"name\": \"testA\"} }"));
// FindOperation
findIterable = collection.find(eq("name", "testA"));
findIterable.first();
// MixedBulkWriteOperation
collection.deleteOne(eq("id", "1"));
// DropDatabaseOperation
mongoClient.getDatabase("test-database").drop();
}
return "success";
}
}
#
# 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: 8080
servlet:
context-path: /mongodb-4.x-scenario
logging:
config: classpath:log4j2.xml
mongodb:
uri: mongodb://mongodb-server/test
\ No newline at end of file
<?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.
~
-->
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="WARN">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
# 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.
4.0.0
4.0.1
4.0.2
4.0.3
4.0.4
4.0.5
4.1.0
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册