Merge branch 'master' of https://github.com/naver/pinpoint into filter

This commit is contained in:
Jaehong Kim
2015-08-27 16:30:34 +09:00
51 changed files with 1239 additions and 771 deletions
+2 -1
View File
@@ -55,7 +55,8 @@ For details, please refer to the [quick-start guide](quickstart/README.md "Pinpo
* JDK 7+ installed
* Maven 3.2.x+ installed
* JAVA_6_HOME environment variable set to JDK 6 home directory.
* JAVA_7_HOME environment variable set to JDK 7+ home directory.
* JAVA_7_HOME environment variable set to JDK 7 home directory.
* JAVA_8_HOME environment variable set to JDK 8 home directory.
**Prerequisites**
+10
View File
@@ -90,6 +90,16 @@
<version>2.0.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<scope>test</scope>
</dependency>
<!-- HTTP Client -->
<dependency>
@@ -0,0 +1,108 @@
/*
* Copyright 2015 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.plugin.mybatis;
import static org.mockito.Mockito.*;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.defaults.DefaultSqlSession;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import com.navercorp.pinpoint.common.Version;
import com.navercorp.pinpoint.test.plugin.Dependency;
import com.navercorp.pinpoint.test.plugin.PinpointAgent;
import com.navercorp.pinpoint.test.plugin.PinpointPluginTestSuite;
/**
* Tests against mybatis 3.0.3+. Prior versions are missing some APIs that are called during the IT. (Most notably,
* SqlSession's select and selectMap methods)
*
* @author HyunGil Jeong
*/
@RunWith(PinpointPluginTestSuite.class)
@PinpointAgent("agent/target/pinpoint-agent-" + Version.VERSION)
@Dependency({ "org.mybatis:mybatis:[3.0.3,)", "org.mockito:mockito-all:1.8.4" })
public class DefaultSqlSessionIT extends SqlSessionTestBase {
@Mock
private Configuration configuration;
@Mock
private ObjectFactory objectFactory;
@Mock
private Executor executor;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(this.configuration.getObjectFactory()).thenReturn(this.objectFactory);
}
@Override
protected SqlSession getSqlSession() {
return new DefaultSqlSession(this.configuration, this.executor, false);
}
@Test
public void methodCallWithNullSqlIdShouldOnlyTraceMethodName() throws Exception {
super.testAndVerifyInsertWithNullParameter();
}
@Test
public void selectShouldBeTraced() throws Exception {
super.testAndVerifySelect();
}
@Test
public void selectOneShouldBeTraced() throws Exception {
super.testAndVerifySelectOne();
}
@Test
public void selectListShouldBeTraced() throws Exception {
super.testAndVerifySelectList();
}
@Test
public void selectMapShouldBeTraced() throws Exception {
super.testAndVerifySelectMap();
}
@Test
public void insertShouldBeTraced() throws Exception {
super.testAndVerifyInsert();
}
@Test
public void updateShouldBeTraced() throws Exception {
super.testAndVerifyUpdate();
}
@Test
public void deleteShouldBeTraced() throws Exception {
super.testAndVerifyDelete();
}
}
@@ -0,0 +1,120 @@
/*
* Copyright 2015 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.plugin.mybatis;
import static org.mockito.Mockito.*;
import javax.sql.DataSource;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.TransactionFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mybatis.spring.SqlSessionTemplate;
import com.navercorp.pinpoint.common.Version;
import com.navercorp.pinpoint.test.plugin.Dependency;
import com.navercorp.pinpoint.test.plugin.PinpointAgent;
import com.navercorp.pinpoint.test.plugin.PinpointPluginTestSuite;
/**
* Tests against mybatis-spring 1.1.0+. Prior versions do not handle mocked SqlSession proxies well.
*
* @author HyunGil Jeong
*/
@RunWith(PinpointPluginTestSuite.class)
@PinpointAgent("agent/target/pinpoint-agent-" + Version.VERSION)
@Dependency({ "org.mybatis:mybatis-spring:[1.1.0,)", "org.mybatis:mybatis:3.2.7",
"org.springframework:spring-jdbc:[4.1.7.RELEASE]", "org.mockito:mockito-all:1.8.4" })
public class SqlSessionTemplateIT extends SqlSessionTestBase {
private static final ExecutorType EXECUTOR_TYPE = ExecutorType.SIMPLE;
@Mock
private SqlSessionFactory sqlSessionFactory;
@Mock
private SqlSession sqlSessionProxy;
private SqlSessionTemplate sqlSessionTemplate;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
Configuration configuration = mock(Configuration.class);
TransactionFactory transactionFactory = mock(TransactionFactory.class);
DataSource dataSource = mock(DataSource.class);
Environment environment = new Environment("test", transactionFactory, dataSource);
when(configuration.getEnvironment()).thenReturn(environment);
when(this.sqlSessionFactory.getConfiguration()).thenReturn(configuration);
when(this.sqlSessionFactory.openSession(EXECUTOR_TYPE)).thenReturn(this.sqlSessionProxy);
this.sqlSessionTemplate = new SqlSessionTemplate(this.sqlSessionFactory, EXECUTOR_TYPE);
}
@Override
protected SqlSession getSqlSession() {
return this.sqlSessionTemplate;
}
@Test
public void methodCallWithNullSqlIdShouldOnlyTraceMethodName() throws Exception {
super.testAndVerifyInsertWithNullParameter();
}
@Test
public void selectShouldBeTraced() throws Exception {
super.testAndVerifySelect();
}
@Test
public void selectOneShouldBeTraced() throws Exception {
super.testAndVerifySelectOne();
}
@Test
public void selectListShouldBeTraced() throws Exception {
super.testAndVerifySelectList();
}
@Test
public void selectMapShouldBeTraced() throws Exception {
super.testAndVerifySelectMap();
}
@Test
public void insertShouldBeTraced() throws Exception {
super.testAndVerifyInsert();
}
@Test
public void updateShouldBeTraced() throws Exception {
super.testAndVerifyUpdate();
}
@Test
public void deleteShouldBeTraced() throws Exception {
super.testAndVerifyDelete();
}
}
@@ -0,0 +1,169 @@
/*
* Copyright 2015 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.plugin.mybatis;
import static com.navercorp.pinpoint.bootstrap.plugin.test.Expectations.event;
import java.lang.reflect.Method;
import org.apache.ibatis.executor.result.DefaultResultHandler;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import com.navercorp.pinpoint.bootstrap.plugin.test.Expectations;
import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifier;
import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifierHolder;
/**
* @author HyunGil Jeong
*/
public abstract class SqlSessionTestBase {
protected abstract SqlSession getSqlSession();
protected final void testAndVerifyInsertWithNullParameter() throws Exception {
// Given
SqlSession sqlSession = getSqlSession();
// When
sqlSession.insert(null);
// Then
PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
Method insert = sqlSession.getClass().getDeclaredMethod("insert", String.class);
verifier.verifyTrace(event("MYBATIS", insert));
}
protected final void testAndVerifySelect() throws Exception {
// Given
final String selectId = "selectId";
SqlSession sqlSession = getSqlSession();
// When
sqlSession.select(selectId, new DefaultResultHandler());
sqlSession.select(selectId, new Object(), new DefaultResultHandler());
sqlSession.select(selectId, new Object(), RowBounds.DEFAULT, new DefaultResultHandler());
// Then
PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
Method select1 = sqlSession.getClass().getDeclaredMethod("select", String.class, ResultHandler.class);
verifier.verifyTrace(event("MYBATIS", select1, Expectations.cachedArgs(selectId)));
Method select2 = sqlSession.getClass().getDeclaredMethod("select", String.class, Object.class,
ResultHandler.class);
verifier.verifyTrace(event("MYBATIS", select2, Expectations.cachedArgs(selectId)));
Method select3 = sqlSession.getClass().getDeclaredMethod("select", String.class, Object.class, RowBounds.class,
ResultHandler.class);
verifier.verifyTrace(event("MYBATIS", select3, Expectations.cachedArgs(selectId)));
}
protected final void testAndVerifySelectOne() throws Exception {
// Given
final String selectOneId = "selectOneId";
SqlSession sqlSession = getSqlSession();
// When
sqlSession.selectOne(selectOneId);
sqlSession.selectOne(selectOneId, new Object());
// Then
PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
Method selectOne1 = sqlSession.getClass().getDeclaredMethod("selectOne", String.class);
Method selectOne2 = sqlSession.getClass().getDeclaredMethod("selectOne", String.class, Object.class);
verifier.verifyTrace(event("MYBATIS", selectOne1, Expectations.cachedArgs(selectOneId)));
verifier.verifyTrace(event("MYBATIS", selectOne2, Expectations.cachedArgs(selectOneId)));
}
protected final void testAndVerifySelectList() throws Exception {
// Given
final String selectListId = "selectListId";
SqlSession sqlSession = getSqlSession();
// When
sqlSession.selectList(selectListId);
sqlSession.selectList(selectListId, new Object());
sqlSession.selectList(selectListId, new Object(), RowBounds.DEFAULT);
// Then
PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
Method selectList1 = sqlSession.getClass().getDeclaredMethod("selectList", String.class);
Method selectList2 = sqlSession.getClass().getDeclaredMethod("selectList", String.class, Object.class);
Method selectList3 = sqlSession.getClass().getDeclaredMethod("selectList", String.class, Object.class,
RowBounds.class);
verifier.verifyTrace(event("MYBATIS", selectList1, Expectations.cachedArgs(selectListId)));
verifier.verifyTrace(event("MYBATIS", selectList2, Expectations.cachedArgs(selectListId)));
verifier.verifyTrace(event("MYBATIS", selectList3, Expectations.cachedArgs(selectListId)));
}
protected final void testAndVerifySelectMap() throws Exception {
// Given
final String selectMapId = "selectListId";
SqlSession sqlSession = getSqlSession();
// When
sqlSession.selectMap(selectMapId, "key");
sqlSession.selectMap(selectMapId, new Object(), "key");
sqlSession.selectMap(selectMapId, new Object(), "key", RowBounds.DEFAULT);
// Then
PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
Method selectMap1 = sqlSession.getClass().getDeclaredMethod("selectMap", String.class, String.class);
Method selectMap2 = sqlSession.getClass().getDeclaredMethod("selectMap", String.class, Object.class,
String.class);
Method selectMap3 = sqlSession.getClass().getDeclaredMethod("selectMap", String.class, Object.class,
String.class, RowBounds.class);
verifier.verifyTrace(event("MYBATIS", selectMap1, Expectations.cachedArgs(selectMapId)));
verifier.verifyTrace(event("MYBATIS", selectMap2, Expectations.cachedArgs(selectMapId)));
verifier.verifyTrace(event("MYBATIS", selectMap3, Expectations.cachedArgs(selectMapId)));
}
protected final void testAndVerifyInsert() throws Exception {
// Given
final String insertId = "insertId";
SqlSession sqlSession = getSqlSession();
// When
sqlSession.insert(insertId);
sqlSession.insert(insertId, new Object());
// Then
PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
Method insert1 = sqlSession.getClass().getDeclaredMethod("insert", String.class);
Method insert2 = sqlSession.getClass().getDeclaredMethod("insert", String.class, Object.class);
verifier.verifyTrace(event("MYBATIS", insert1, Expectations.cachedArgs(insertId)));
verifier.verifyTrace(event("MYBATIS", insert2, Expectations.cachedArgs(insertId)));
}
protected final void testAndVerifyUpdate() throws Exception {
// Given
final String updateId = "updateId";
SqlSession sqlSession = getSqlSession();
// When
sqlSession.update(updateId);
sqlSession.update(updateId, new Object());
// Then
PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
Method update1 = sqlSession.getClass().getDeclaredMethod("update", String.class);
Method update2 = sqlSession.getClass().getDeclaredMethod("update", String.class, Object.class);
verifier.verifyTrace(event("MYBATIS", update1, Expectations.cachedArgs(updateId)));
verifier.verifyTrace(event("MYBATIS", update2, Expectations.cachedArgs(updateId)));
}
protected final void testAndVerifyDelete() throws Exception {
// Given
final String deleteId = "deleteId";
SqlSession sqlSession = getSqlSession();
// When
sqlSession.delete(deleteId);
sqlSession.delete(deleteId, new Object());
// Then
PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
Method delete1 = sqlSession.getClass().getDeclaredMethod("delete", String.class);
Method delete2 = sqlSession.getClass().getDeclaredMethod("delete", String.class, Object.class);
verifier.verifyTrace(event("MYBATIS", delete1, Expectations.cachedArgs(deleteId)));
verifier.verifyTrace(event("MYBATIS", delete2, Expectations.cachedArgs(deleteId)));
}
}
@@ -281,7 +281,7 @@ public class ServiceType {
// xBatis
// 5500 iBatis
// 5501 iBatis-Spring
public static final ServiceType MYBATIS = of(5510, "MYBATIS", NORMAL_SCHEMA);
// 5510 MyBatis
// DBCP
public static final ServiceType DBCP = of(6050, "DBCP", NORMAL_SCHEMA);
@@ -42,8 +42,6 @@ public class DefaultDisplayArgument {
// FIXME replaced with IBATIS_SPRING under IBatis Plugin - kept for backwards compatibility
public static final DisplayArgumentMatcher SPRING_ORM_IBATIS_MATCHER = createArgumentMatcher(ServiceType.SPRING_ORM_IBATIS, AnnotationKey.ARGS0);
public static final DisplayArgumentMatcher MYBATIS_MATCHER = createArgumentMatcher(ServiceType.MYBATIS, AnnotationKey.ARGS0);
public static final DisplayArgumentMatcher MEMCACHED_MATCHER = createArgumentMatcher(ServiceType.MEMCACHED, ARGS_MATCHER);
public static final DisplayArgumentMatcher HTTP_CLIENT_MATCHER = createArgumentMatcher(ServiceType.ASYNC_HTTP_CLIENT, AnnotationKey.HTTP_URL);
+4
View File
@@ -0,0 +1,4 @@
/target/
/.settings/
/.classpath
/.project
+5
View File
@@ -0,0 +1,5 @@
RMRqrdbgbKFhbaVnDxHUdDQvrOQXxIBklnvcmahheubVC
mh2KM35CLkwUHS4DH7QVhxy52J5hnWbyEm6Cyd3KkF<mV
RmmnSVOqOMnOnMMrmMqwXomoroNrqPNRrPSsWwtUxXuUU
sRONqpnmqmUUnqonmstsmmmmmUUnqonmstsmmmmmUUGfk
mlfkqUUnmmmm
+75
View File
@@ -0,0 +1,75 @@
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.navercorp.pinpoint</groupId>
<artifactId>pom</artifactId>
<version>1.5.0-SNAPSHOT</version>
</parent>
<artifactId>pinpoint-java8-test</artifactId>
<name>pinpoint-integration-test-java8</name>
<!-- this module contains integration tests. if we set packaging to pom,
tests are not run. so we set it to jar even though the project will not be
packaged as a jar. -->
<packaging>jar</packaging>
<properties>
<jdk.version>1.8</jdk.version>
<jdk.home>${env.JAVA_8_HOME}</jdk.home>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources</directory>
</resource>
<resource>
<directory>${basedir}/src/main/resources-${env}</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- AbstractPinpointPluginTestSuite needs this to resolve
path of required jars -->
<useSystemClassLoader>false</useSystemClassLoader>
<failIfNoTests>true</failIfNoTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,47 @@
/*
* Copyright 2014 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.jdk8.lambda;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class LambdaIT {
@Test
public void test() throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("lambda-test.xml");
Maru maru = context.getBean(Maru.class);
Morae morae = context.getBean(Morae.class);
maru.test(morae);
// PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
// verifier.printCache();
//
// verifier.verifyTrace(Expectations.event("SPRING_BEAN", Maru.class.getMethod("test", Morae.class)));
// verifier.verifyTrace(Expectations.event("SPRING_BEAN", Morae.class.getMethod("test", Predicate.class)));
// verifier.verifyTrace(Expectations.event("SPRING_BEAN", Mozzi.class.getMethod("getAge")));
//
// verifier.verifyTraceCount(0);
}
public static void main(String args[]) throws Exception {
new LambdaIT().test();
}
}
@@ -1,25 +1,25 @@
/*
/**
* Copyright 2014 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.profiler.modifier.orm.mybatis.interceptor;
package com.navercorp.pinpoint.jdk8.lambda;
/**
* @author Hyun Jeong
* @author Jongho Moon
*
*/
public class MyBatisScope {
public static final String SCOPE = "myBatisScope";
}
public class Maru {
public boolean test(Morae morae) {
return morae.test((m) -> m.getAge() > 1);
}
}
@@ -14,19 +14,19 @@
* limitations under the License.
*/
package com.navercorp.pinpoint.profiler.modifier.orm.mybatis.interceptor;
package com.navercorp.pinpoint.jdk8.lambda;
import com.navercorp.pinpoint.common.trace.ServiceType;
import com.navercorp.pinpoint.profiler.modifier.orm.SqlMapOperationInterceptor;
import java.util.function.Predicate;
/**
* @author Hyun Jeong
* @author netspider
*/
public class MyBatisSqlMapOperationInterceptor extends SqlMapOperationInterceptor {
public MyBatisSqlMapOperationInterceptor(ServiceType serviceType) {
super(serviceType, MyBatisSqlMapOperationInterceptor.class);
public class Morae {
private final Mozzi mozzi;
public Morae(Mozzi mozzi) {
this.mozzi = mozzi;
}
public boolean test(Predicate<Mozzi> predicate) {
return predicate.test(mozzi);
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2014 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.jdk8.lambda;
import org.springframework.stereotype.Controller;
@Controller
public class Mozzi {
private final int age;
public Mozzi(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="maru" class="com.navercorp.pinpoint.jdk8.lambda.Maru"/>
<bean id="morae" class="com.navercorp.pinpoint.jdk8.lambda.Morae">
<constructor-arg ref="mozzi"/>
</bean>
<bean id="mozzi" class="com.navercorp.pinpoint.jdk8.lambda.Mozzi" scope="prototype">
<constructor-arg value="4"/>
</bean>
</beans>
@@ -0,0 +1,209 @@
#
# Pinpoint agent configuration
#
###########################################################
# Collector server #
###########################################################
profiler.collector.ip=127.0.0.1
# placeHolder support "${key}"
profiler.collector.span.ip=${profiler.collector.ip}
profiler.collector.span.port=9996
# placeHolder support "${key}"
profiler.collector.stat.ip=${profiler.collector.ip}
profiler.collector.stat.port=9995
# placeHolder support "${key}"
profiler.collector.tcp.ip=${profiler.collector.ip}
profiler.collector.tcp.port=9994
###########################################################
# Profiler Global Configuration #
###########################################################
profiler.enable=true
profiler.jvm.collect.interval=1000
profiler.sampling.enable=true
# Set sampling rate. If you set it to 10, 1 out of 10 transaction will be sampled.
profiler.sampling.rate=1
profiler.io.buffering.enable=true
profiler.io.buffering.buffersize=20
profiler.spandatasender.write.queue.size=5120
#profiler.spandatasender.socket.sendbuffersize=1048576
#profiler.spandatasender.socket.timeout=3000
profiler.spandatasender.chunk.size=16384
profiler.statdatasender.write.queue.size=5120
#profiler.statdatasender.socket.sendbuffersize=1048576
#profiler.statdatasender.socket.timeout=3000
profiler.statdatasender.chunk.size=16384
profiler.agentInfo.send.retry.interval=300000
# Allows TCP data command
profiler.tcpdatasender.command.accept.enable=true
###########################################################
# application type #
###########################################################
#profiler.applicationservertype=TOMCAT
#profiler.applicationservertype=BLOC
###########################################################
# application type detect order #
###########################################################
profiler.type.detect.order=
profiler.plugin.disable=
###########################################################
# user defined classes #
###########################################################
profiler.include=
###########################################################
# TOMCAT #
###########################################################
profiler.tomcat.hidepinpointheader=true
profiler.tomcat.excludeurl=/aa/test.html, /bb/exclude.html
###########################################################
# JDBC #
###########################################################
profiler.jdbc=true
profiler.jdbc.sqlcachesize=1024
profiler.jdbc.maxsqlbindvaluesize=1024
#
# MYSQL
#
profiler.jdbc.mysql=true
profiler.jdbc.mysql.setautocommit=true
profiler.jdbc.mysql.commit=true
profiler.jdbc.mysql.rollback=true
#
# MSSQL Jtds
#
profiler.jdbc.jtds=true
profiler.jdbc.jtds.setautocommit=true
profiler.jdbc.jtds.commit=true
profiler.jdbc.jtds.rollback=true
#
# Oracle
#
profiler.jdbc.oracle=true
profiler.jdbc.oracle.setautocommit=true
profiler.jdbc.oracle.commit=true
profiler.jdbc.oracle.rollback=true
#
# CUBRID
#
profiler.jdbc.cubrid=true
profiler.jdbc.cubrid.setautocommit=true
profiler.jdbc.cubrid.commit=true
profiler.jdbc.cubrid.rollback=true
#
# DBCP
#
profiler.jdbc.dbcp=true
profiler.jdbc.dbcp.connectionclose=true
###########################################################
# Apache HTTP Client 4.x #
###########################################################
profiler.apache.httpclient4=true
profiler.apache.httpclient4.cookie=true
# When cookies should be dumped. It could be ALWAYS or EXCEPTION.
profiler.apache.httpclient4.cookie.dumptype=ALWAYS
profiler.apache.httpclient4.cookie.sampling.rate=1
# Dump entities of POST or PUT request. limited to entities which is HttpEntity.isRepeatable() == true.
profiler.apache.httpclient4.entity=true
# When entities should be dumped. ALWAYS or EXCEPTION.
profiler.apache.httpclient4.entity.dumptype=ALWAYS
profiler.apache.httpclient4.entity.sampling.rate=1
profiler.apache.nio.httpclient4=true
###########################################################
# JDK HTTPURLConnection #
###########################################################
profiler.jdk.httpurlconnection=true
###########################################################
# Ning Async HTTP Client #
###########################################################
profiler.ning.asynchttpclient=true
profiler.ning.asynchttpclient.cookie=true
profiler.ning.asynchttpclient.cookie.dumptype=ALWAYS
profiler.ning.asynchttpclient.cookie.dumpsize=1024
profiler.ning.asynchttpclient.cookie.sampling.rate=1
profiler.ning.asynchttpclient.entity=true
profiler.ning.asynchttpclient.entity.dumptype=ALWAYS
profiler.ning.asynchttpclient.entity.dumpsize=1024
profiler.ning.asynchttpclient.entity.sampling.rate=1
profiler.ning.asynchttpclient.param=true
profiler.ning.asynchttpclient.param.dumptype=ALWAYS
profiler.ning.asynchttpclient.param.dumpsize=1024
profiler.ning.asynchttpclient.param.sampling.rate=1
###########################################################
# Arcus #
###########################################################
profiler.arcus=true
profiler.arcus.keytrace=true
###########################################################
# Memcached #
###########################################################
profiler.memcached=true
profiler.memcached.keytrace=true
###########################################################
# ibatis #
###########################################################
profiler.orm.ibatis=true
###########################################################
# mybatis #
###########################################################
profiler.orm.mybatis=true
###########################################################
# spring-beans
###########################################################
profiler.spring.beans=true
profiler.spring.beans.name.pattern=ma.*, outer
profiler.spring.beans.class.pattern=.*Morae
profiler.spring.beans.annotation=org.springframework.stereotype.Component
###########################################################
# log4j
###########################################################
profiler.log4j.logging.transactioninfo=false
###########################################################
# logback
###########################################################
profiler.logback.logging.transactioninfo=false
@@ -19,20 +19,18 @@ package com.navercorp.pinpoint.plugin.ibatis.interceptor;
import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder;
import com.navercorp.pinpoint.bootstrap.context.TraceContext;
import com.navercorp.pinpoint.bootstrap.interceptor.MethodDescriptor;
import com.navercorp.pinpoint.bootstrap.interceptor.SpanEventSimpleAroundInterceptor;
import com.navercorp.pinpoint.bootstrap.interceptor.SpanEventSimpleAroundInterceptorForPlugin;
import com.navercorp.pinpoint.common.trace.ServiceType;
/**
* @author HyunGil Jeong
*/
public class SqlMapOperationInterceptor extends SpanEventSimpleAroundInterceptor {
public class SqlMapOperationInterceptor extends SpanEventSimpleAroundInterceptorForPlugin {
private final ServiceType serviceType;
public SqlMapOperationInterceptor(TraceContext context, MethodDescriptor descriptor, ServiceType serviceType) {
super(SqlMapOperationInterceptor.class);
setTraceContext(context);
setMethodDescriptor(descriptor);
super(context, descriptor);
this.serviceType = serviceType;
}
+5
View File
@@ -0,0 +1,5 @@
/target/
/.settings/
/.classpath
/.project
/*.iml
+5
View File
@@ -0,0 +1,5 @@
RMRqrdbgbKFhbaVnDxHUdDQvrOQXxIBklnvcmahheubVC
mh2KM35CLkwUHS4DH7QVhxy52J5hnWbyEm6Cyd3KkF<mV
RmmnSVOqOMnOnMMrmMqwXomoroNrqPNRrPSsWwtUxXuUU
sRONqpnmqmUUnqonmstsmmmmmUUnqonmstsmmmmmUUGfk
mlfkqUUnmmmm
+22
View File
@@ -0,0 +1,22 @@
<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>
<groupId>com.navercorp.pinpoint</groupId>
<artifactId>pom</artifactId>
<relativePath>../..</relativePath>
<version>1.5.0-SNAPSHOT</version>
</parent>
<artifactId>pinpoint-mybatis-plugin</artifactId>
<name>pinpoint-mybatis-plugin</name>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.navercorp.pinpoint</groupId>
<artifactId>pinpoint-bootstrap-core</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,34 @@
/*
* Copyright 2015 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.plugin.mybatis;
import static com.navercorp.pinpoint.common.trace.AnnotationKeyMatcher.*;
import com.navercorp.pinpoint.common.trace.TraceMetadataProvider;
import com.navercorp.pinpoint.common.trace.TraceMetadataSetupContext;
/**
* @author HyunGil Jeong
*/
public class MyBatisMetadataProvider implements TraceMetadataProvider {
@Override
public void setup(TraceMetadataSetupContext context) {
context.addServiceType(MyBatisPlugin.MYBATIS, ARGS_MATCHER);
}
}
@@ -0,0 +1,85 @@
/*
* Copyright 2015 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.plugin.mybatis;
import static com.navercorp.pinpoint.common.trace.HistogramSchema.NORMAL_SCHEMA;
import java.security.ProtectionDomain;
import java.util.List;
import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig;
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass;
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException;
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentMethod;
import com.navercorp.pinpoint.bootstrap.instrument.MethodFilter;
import com.navercorp.pinpoint.bootstrap.instrument.MethodFilters;
import com.navercorp.pinpoint.bootstrap.interceptor.group.ExecutionPolicy;
import com.navercorp.pinpoint.bootstrap.interceptor.group.InterceptorGroup;
import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin;
import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginInstrumentContext;
import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext;
import com.navercorp.pinpoint.bootstrap.plugin.transformer.PinpointClassFileTransformer;
import com.navercorp.pinpoint.common.trace.ServiceType;
/**
* @author HyunGil Jeong
*/
public class MyBatisPlugin implements ProfilerPlugin {
public static final ServiceType MYBATIS = ServiceType.of(5510, "MYBATIS", NORMAL_SCHEMA);
private static final String MYBATIS_SCOPE = "MYBATIS_SCOPE";
@Override
public void setup(ProfilerPluginSetupContext context) {
ProfilerConfig profilerConfig = context.getConfig();
if (profilerConfig.isMyBatisEnabled()) {
addInterceptorsForSqlSession(context);
}
}
// SqlSession implementations
private void addInterceptorsForSqlSession(ProfilerPluginSetupContext context) {
final MethodFilter methodFilter = MethodFilters.name("selectOne", "selectList", "selectMap", "select",
"insert", "update", "delete");
final String[] sqlSessionImpls = { "org.apache.ibatis.session.defaults.DefaultSqlSession",
"org.mybatis.spring.SqlSessionTemplate" };
for (final String sqlSession : sqlSessionImpls) {
context.addClassFileTransformer(sqlSession, new PinpointClassFileTransformer() {
@Override
public byte[] transform(ProfilerPluginInstrumentContext instrumentContext, ClassLoader loader,
String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws InstrumentException {
final InstrumentClass target = instrumentContext.getInstrumentClass(loader, sqlSession, classfileBuffer);
final InterceptorGroup group = instrumentContext.getInterceptorGroup(MYBATIS_SCOPE);
final List<InstrumentMethod> methodsToTrace = target.getDeclaredMethods(methodFilter);
for (InstrumentMethod methodToTrace : methodsToTrace) {
String sqlSessionOperationInterceptor = "com.navercorp.pinpoint.plugin.mybatis.interceptor.SqlSessionOperationInterceptor";
methodToTrace.addInterceptor(sqlSessionOperationInterceptor, group, ExecutionPolicy.BOUNDARY);
}
return target.toBytecode();
}
});
}
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 2015 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.plugin.mybatis.interceptor;
import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder;
import com.navercorp.pinpoint.bootstrap.context.TraceContext;
import com.navercorp.pinpoint.bootstrap.interceptor.MethodDescriptor;
import com.navercorp.pinpoint.bootstrap.interceptor.SpanEventSimpleAroundInterceptorForPlugin;
import com.navercorp.pinpoint.plugin.mybatis.MyBatisPlugin;
/**
* @author HyunGil Jeong
*/
public class SqlSessionOperationInterceptor extends SpanEventSimpleAroundInterceptorForPlugin {
public SqlSessionOperationInterceptor(TraceContext context, MethodDescriptor descriptor) {
super(context, descriptor);
}
@Override
protected void doInBeforeTrace(SpanEventRecorder recorder, Object target, Object[] args) {
// do nothing
}
@Override
protected void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] args, Object result,
Throwable throwable) {
recorder.recordServiceType(MyBatisPlugin.MYBATIS);
recorder.recordException(throwable);
if (args != null && args.length > 0) {
recorder.recordApiCachedString(getMethodDescriptor(), (String)args[0], 0);
} else {
recorder.recordApi(getMethodDescriptor());
}
}
}
@@ -0,0 +1 @@
com.navercorp.pinpoint.plugin.mybatis.MyBatisPlugin
@@ -0,0 +1 @@
com.navercorp.pinpoint.plugin.mybatis.MyBatisMetadataProvider
+6
View File
@@ -29,6 +29,7 @@
<module>jetty</module>
<module>spring-beans</module>
<module>ibatis</module>
<module>mybatis</module>
</modules>
<dependencies>
@@ -117,6 +118,11 @@
<artifactId>pinpoint-ibatis-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.navercorp.pinpoint</groupId>
<artifactId>pinpoint-mybatis-plugin</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
@@ -21,7 +21,7 @@ import org.apache.thrift.TBase;
import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder;
import com.navercorp.pinpoint.bootstrap.context.TraceContext;
import com.navercorp.pinpoint.bootstrap.interceptor.MethodDescriptor;
import com.navercorp.pinpoint.bootstrap.interceptor.SpanEventSimpleAroundInterceptor;
import com.navercorp.pinpoint.bootstrap.interceptor.SpanEventSimpleAroundInterceptorForPlugin;
import com.navercorp.pinpoint.bootstrap.util.StringUtils;
import com.navercorp.pinpoint.plugin.thrift.ThriftConstants;
@@ -32,16 +32,13 @@ import com.navercorp.pinpoint.plugin.thrift.ThriftConstants;
*
* @author HyunGil Jeong
*/
public class TServiceClientReceiveBaseInterceptor extends SpanEventSimpleAroundInterceptor implements ThriftConstants {
public class TServiceClientReceiveBaseInterceptor extends SpanEventSimpleAroundInterceptorForPlugin implements ThriftConstants {
private final boolean traceServiceResult;
public TServiceClientReceiveBaseInterceptor(TraceContext context, MethodDescriptor descriptor, boolean traceServiceResult) {
super(TServiceClientReceiveBaseInterceptor.class);
super(context, descriptor);
this.traceServiceResult = traceServiceResult;
setTraceContext(context);
setMethodDescriptor(descriptor);
}
@Override
+4
View File
@@ -45,6 +45,7 @@
<module>thrift</module>
<module>test</module>
<module>web</module>
<module>java8-test</module>
</modules>
<properties>
@@ -777,6 +778,9 @@
<requireEnvironmentVariable>
<variableName>JAVA_7_HOME</variableName>
</requireEnvironmentVariable>
<requireEnvironmentVariable>
<variableName>JAVA_8_HOME</variableName>
</requireEnvironmentVariable>
</rules>
<fail>true</fail>
</configuration>
-12
View File
@@ -117,18 +117,6 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
@@ -153,9 +153,6 @@ public class ClassFileTransformerDispatcher implements ClassFileTransformer, Ret
// rpc
modifierRepository.addConnectorModifier();
// orm
modifierRepository.addOrmModifier();
// log4j
modifierRepository.addLog4jModifier();
@@ -53,7 +53,6 @@ import com.navercorp.pinpoint.profiler.modifier.db.oracle.PhysicalConnectionModi
import com.navercorp.pinpoint.profiler.modifier.log.log4j.LoggingEventOfLog4jModifier;
import com.navercorp.pinpoint.profiler.modifier.log.logback.LoggingEventOfLogbackModifier;
import com.navercorp.pinpoint.profiler.modifier.method.MethodModifier;
import com.navercorp.pinpoint.profiler.modifier.orm.mybatis.MyBatisModifier;
import com.navercorp.pinpoint.profiler.modifier.servlet.SpringFrameworkServletModifier;
import com.navercorp.pinpoint.profiler.util.JavaAssistUtils;
@@ -244,19 +243,6 @@ public class DefaultModifierRegistry implements ModifierRegistry {
}
}
/**
* Support ORM(iBatis, myBatis, etc.)
*/
public void addOrmModifier() {
addMyBatisSupport();
}
private void addMyBatisSupport() {
if (profilerConfig.isMyBatisEnabled()) {
addModifier(new MyBatisModifier(byteCodeInstrumentor, agent));
}
}
public void addLog4jModifier() {
if (profilerConfig.isLog4jLoggingTransactionInfo()) {
addModifier(new LoggingEventOfLog4jModifier(byteCodeInstrumentor, agent));
@@ -1,50 +0,0 @@
/*
* Copyright 2014 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.profiler.modifier.orm;
import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder;
import com.navercorp.pinpoint.bootstrap.interceptor.*;
import com.navercorp.pinpoint.common.trace.ServiceType;
/**
* @author Hyun Jeong
* @author netspider
*/
public abstract class SqlMapOperationInterceptor extends SpanEventSimpleAroundInterceptor {
private final ServiceType serviceType;
public SqlMapOperationInterceptor(ServiceType serviceType, Class<? extends SpanEventSimpleAroundInterceptor> childClazz) {
super(childClazz);
this.serviceType = serviceType;
}
@Override
public final void doInBeforeTrace(SpanEventRecorder recorder, final Object target, Object[] args) {
}
@Override
public final void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] args, Object result, Throwable throwable) {
recorder.recordServiceType(this.serviceType);
recorder.recordException(throwable);
if (args != null && args.length > 0) {
recorder.recordApiCachedString(getMethodDescriptor(), (String)args[0], 0);
} else {
recorder.recordApi(getMethodDescriptor());
}
}
}
@@ -1,87 +0,0 @@
/*
* Copyright 2014 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.profiler.modifier.orm.mybatis;
import com.navercorp.pinpoint.bootstrap.Agent;
import com.navercorp.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass;
import com.navercorp.pinpoint.bootstrap.instrument.MethodFilter;
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentMethod;
import com.navercorp.pinpoint.bootstrap.instrument.matcher.Matcher;
import com.navercorp.pinpoint.bootstrap.instrument.matcher.Matchers;
import com.navercorp.pinpoint.bootstrap.interceptor.Interceptor;
import com.navercorp.pinpoint.common.trace.ServiceType;
import com.navercorp.pinpoint.profiler.modifier.AbstractModifier;
import com.navercorp.pinpoint.profiler.modifier.orm.mybatis.filter.SqlSessionMethodFilter;
import com.navercorp.pinpoint.profiler.modifier.orm.mybatis.interceptor.MyBatisScope;
import com.navercorp.pinpoint.profiler.modifier.orm.mybatis.interceptor.MyBatisSqlMapOperationInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.ProtectionDomain;
import java.util.List;
/**
* @author Hyun Jeong
*/
public class MyBatisModifier extends AbstractModifier {
private static final ServiceType serviceType = ServiceType.MYBATIS;
private static final String SCOPE = MyBatisScope.SCOPE;
private static final MethodFilter sqlSessionMethodFilter = new SqlSessionMethodFilter();
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public static final String DEFAULT_SQL_SESSION = "org/apache/ibatis/session/defaults/DefaultSqlSession";
public static final String SQL_SESSION_TEMPLATE = "org/mybatis/spring/SqlSessionTemplate";
public MyBatisModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) {
super(byteCodeInstrumentor, agent);
}
private MethodFilter getSqlSessionMethodFilter() {
return sqlSessionMethodFilter;
}
@Override
public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
if (logger.isInfoEnabled()) {
logger.info("Modifying. {}", javassistClassName);
}
try {
InstrumentClass myBatisClientImpl = byteCodeInstrumentor.getClass(classLoader, javassistClassName, classFileBuffer);
List<InstrumentMethod> declaredMethods = myBatisClientImpl.getDeclaredMethods(getSqlSessionMethodFilter());
for (InstrumentMethod method : declaredMethods) {
Interceptor sqlSessionInterceptor = new MyBatisSqlMapOperationInterceptor(serviceType);
myBatisClientImpl.addGroupInterceptor(method.getName(), method.getParameterTypes(), sqlSessionInterceptor, SCOPE);
}
return myBatisClientImpl.toBytecode();
} catch (Throwable e) {
logger.warn("{} modifier error. Cause:{}", javassistClassName, e.getMessage(), e);
return null;
}
}
@Override
public Matcher getMatcher() {
return Matchers.newMultiClassNameMatcher(SQL_SESSION_TEMPLATE, DEFAULT_SQL_SESSION);
}
}
@@ -1,59 +0,0 @@
/*
* Copyright 2014 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.profiler.modifier.orm.mybatis.filter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import com.navercorp.pinpoint.bootstrap.instrument.MethodFilter;
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentMethod;
/**
* @author Hyun Jeong
*/
public class SqlSessionMethodFilter implements MethodFilter {
private static final Set<String> WHITE_LIST_API = createWhiteListApi();
private static Set<String> createWhiteListApi() {
return new HashSet<String>(Arrays.asList(
"selectOne",
"selectList",
"selectMap",
"select",
"insert",
"update",
"delete"
// "commit",
// "rollback",
// "flushStatements",
// "close",
// "getConfiguration",
// "getMapper",
// "getConnection"
));
}
@Override
public boolean accept(InstrumentMethod ctMethod) {
if (WHITE_LIST_API.contains(ctMethod.getName())) {
return ACCEPT;
}
return REJECT;
}
}
@@ -1,59 +0,0 @@
/*
* Copyright 2014 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.profiler.modifier.orm.mybatis;
import static org.mockito.Mockito.*;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.defaults.DefaultSqlSession;
import org.apache.ibatis.transaction.Transaction;
import org.junit.Test;
import org.mockito.Mock;
/**
* @author Hyun Jeong
*/
public class DefaultSqlSessionModifierTest extends MyBatisClientModifierTest {
@Mock
private Configuration configuration;
@Mock
private Executor executor;
@Override
protected SqlSession getSqlSession() {
return new DefaultSqlSession(this.configuration, this.executor);
}
@Override
@Test
public void selectMapShouldBeTraced() throws Exception {
ObjectFactory objectFactory = mock(ObjectFactory.class);
when(this.configuration.getObjectFactory()).thenReturn(objectFactory);
super.selectMapShouldBeTraced();
}
@Override
@Test
public void getConnectionShouldBeTraced() throws Exception {
Transaction mockTransaction = mock(Transaction.class);
when(this.executor.getTransaction()).thenReturn(mockTransaction);
}
}
@@ -1,292 +0,0 @@
/*
* Copyright 2014 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.profiler.modifier.orm.mybatis;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.MockitoAnnotations;
import com.navercorp.pinpoint.common.bo.AnnotationBo;
import com.navercorp.pinpoint.common.bo.SpanEventBo;
import com.navercorp.pinpoint.common.trace.AnnotationKey;
import com.navercorp.pinpoint.test.junit4.BasePinpointTest;
/**
* @author Hyun Jeong
*/
public abstract class MyBatisClientModifierTest extends BasePinpointTest {
public static final int NOT_CACHED = 0;
protected abstract SqlSession getSqlSession();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@After
public void cleanUp() throws Exception {
getSqlSession().close();
}
@Test
public void nullParameterShouldNotBeTraced() throws Exception {
// When
getSqlSession().insert(null);
// Then
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(1));
// Check Method
final SpanEventBo insertSpanEventBo = spanEvents.get(0);
assertThat(insertSpanEventBo.getApiId(), not(NOT_CACHED));
// Check Parameter
assertNull(insertSpanEventBo.getAnnotationBoList());
}
@Test
public void selectOneShouldBeTraced() throws Exception {
// When
getSqlSession().selectOne("selectOne");
getSqlSession().selectOne("selectOne", null);
// Then
assertNOperations(2);
}
@Test
public void selectListShouldBeTraced() throws Exception {
// When
getSqlSession().selectList("selectList");
getSqlSession().selectList("selectList", null);
getSqlSession().selectList("selectList", null, null);
// Then
assertNOperations(3);
}
@Test
public void selectMapShouldBeTraced() throws Exception {
// Given
// When
getSqlSession().selectMap("selectMap", null);
getSqlSession().selectMap("selectMap", null, null);
getSqlSession().selectMap("selectMap", null, null, null);
// Then
assertNOperations(3);
}
@Test
public void selectShouldBeTraced() throws Exception {
// When
getSqlSession().select("select", null);
getSqlSession().select("select", null, null);
getSqlSession().select("select", null, null, null);
// Then
assertNOperations(3);
}
@Test
public void insertShouldBeTraced() throws Exception {
// When
getSqlSession().insert("insert");
getSqlSession().insert("insert", new Object());
// Then
assertNOperations(2);
}
@Test
public void updateShouldBeTraced() throws Exception {
// When
getSqlSession().update("update");
getSqlSession().update("update", new Object());
// Then
assertNOperations(2);
}
@Test
public void deleteShouldBeTraced() throws Exception {
// When
getSqlSession().delete("delete");
getSqlSession().delete("delete", new Object());
// Then
assertNOperations(2);
}
@Ignore // Changed to trace only query operations
@Test
public void commitShouldBeTraced() throws Exception {
// When
getSqlSession().commit();
getSqlSession().commit(true);
// Then
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(2));
// Check InstrumentMethod
final SpanEventBo commitWith0ArgSpanEvent = spanEvents.get(0);
final SpanEventBo commitWith1ArgSpanEvent = spanEvents.get(1);
assertThat(commitWith0ArgSpanEvent.getApiId(), not(NOT_CACHED));
assertThat(commitWith1ArgSpanEvent.getApiId(), not(NOT_CACHED));
assertThat(commitWith0ArgSpanEvent.getApiId(), not(commitWith1ArgSpanEvent.getApiId()));
// Check Parameter
assertNull(commitWith0ArgSpanEvent.getAnnotationBoList());
assertThat(commitWith1ArgSpanEvent.getAnnotationBoList().get(0).getKey(), is(AnnotationKey.CACHE_ARGS0.getCode()));
}
@Ignore // Changed to trace only query operations
@Test
public void rollbackShouldBeTraced() throws Exception {
// When
getSqlSession().rollback();
getSqlSession().rollback(true);
// Then
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(2));
// Check InstrumentMethod
final SpanEventBo rollbackWith0ArgSpanEvent = spanEvents.get(0);
final SpanEventBo rollbackWith1ArgSpanEvent = spanEvents.get(1);
assertThat(rollbackWith0ArgSpanEvent.getApiId(), not(NOT_CACHED));
assertThat(rollbackWith1ArgSpanEvent.getApiId(), not(NOT_CACHED));
assertThat(rollbackWith0ArgSpanEvent.getApiId(), not(rollbackWith1ArgSpanEvent.getApiId()));
// Check Parameter
assertNull(rollbackWith0ArgSpanEvent.getAnnotationBoList());
assertThat(rollbackWith1ArgSpanEvent.getAnnotationBoList().get(0).getKey(), is(AnnotationKey.CACHE_ARGS0.getCode()));
}
@Ignore // Changed to trace only query operations
@Test
public void flushStatementsShouldBeTraced() throws Exception {
// When
getSqlSession().flushStatements();
// Then
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(1));
// Check InstrumentMethod
final SpanEventBo flushStatementsSpanEvent = spanEvents.get(0);
assertThat(flushStatementsSpanEvent.getApiId(), not(NOT_CACHED));
// Check Parameter
assertNull(flushStatementsSpanEvent.getAnnotationBoList());
}
@Ignore // Changed to trace only query operations
@Test
public void closeShouldBeTraced() throws Exception {
// When
getSqlSession().close();
// Then
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(1));
// Check InstrumentMethod
final SpanEventBo closeSpanEvent = spanEvents.get(0);
assertThat(closeSpanEvent.getApiId(), not(NOT_CACHED));
// Check Parameter
assertNull(closeSpanEvent.getAnnotationBoList());
}
@Ignore // Changed to trace only query operations
@Test
public void getConfigurationShouldBeTraced() throws Exception {
// When
getSqlSession().getConfiguration();
// Then
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(1));
// Check InstrumentMethod
final SpanEventBo getConfigurationSpanEvent = spanEvents.get(0);
assertThat(getConfigurationSpanEvent.getApiId(), not(NOT_CACHED));
// Check Parameter
assertNull(getConfigurationSpanEvent.getAnnotationBoList());
}
@Ignore // Changed to trace only query operations
@Test
public void getMapperShouldBeTraced() throws Exception {
// Given
class SomeBean {}
// When
getSqlSession().getMapper(SomeBean.class);
// Then
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(1));
// Check InstrumentMethod
final SpanEventBo getConnectionSpanEvent = spanEvents.get(0);
assertThat(getConnectionSpanEvent.getApiId(), not(NOT_CACHED));
// Check Parameter
assertThat(getConnectionSpanEvent.getAnnotationBoList().get(0).getKey(), is(AnnotationKey.CACHE_ARGS0.getCode()));
}
@Ignore // Changed to trace only query operations
@Test
public void getConnectionShouldBeTraced() throws Exception {
// When
getSqlSession().getConnection();
// Then
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(1));
// Check InstrumentMethod
final SpanEventBo getConnectionSpanEvent = spanEvents.get(0);
assertThat(getConnectionSpanEvent.getApiId(), not(NOT_CACHED));
// Check Parameter
assertNull(getConnectionSpanEvent.getAnnotationBoList());
}
private void assertNOperations(int numOperations) {
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(numOperations));
final Set<Integer> uniqueApiIds = new HashSet<Integer>();
for (int n = 0; n < numOperations; ++n) {
final SpanEventBo apiSpanEvent = spanEvents.get(n);
uniqueApiIds.add(apiSpanEvent.getApiId());
// Check InstrumentMethod
assertThat(apiSpanEvent.getApiId(), not(NOT_CACHED));
// Check Parameter
final List<AnnotationBo> apiAnnotations = apiSpanEvent.getAnnotationBoList();
assertThat(apiAnnotations.size(), is(1));
final AnnotationBo apiParameterAnnotation = apiAnnotations.get(0);
assertThat(apiParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode()));
}
assertThat(uniqueApiIds.size(), is(numOperations));
}
}
@@ -1,139 +0,0 @@
/*
* Copyright 2014 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.profiler.modifier.orm.mybatis;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import java.util.List;
import javax.sql.DataSource;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.TransactionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mock;
import org.mybatis.spring.SqlSessionTemplate;
import com.navercorp.pinpoint.common.bo.SpanEventBo;
/**
* @author Hyun Jeong
*/
public class SqlSessionTemplateModifierTest extends MyBatisClientModifierTest {
private static final ExecutorType executorType = ExecutorType.SIMPLE;
private SqlSessionTemplate sqlSessionTemplate;
@Mock
private SqlSessionFactory sqlSessionFactory;
@Mock
private SqlSession sqlSession;
@Override
protected SqlSession getSqlSession() {
return this.sqlSessionTemplate;
}
@Override
@Before
public void setUp() throws Exception {
super.setUp();
setUpSqlSessionFactory();
setUpSqlSession();
this.sqlSessionTemplate = new SqlSessionTemplate(this.sqlSessionFactory, executorType);
}
private void setUpSqlSessionFactory() throws Exception {
Configuration configuration = mock(Configuration.class);
TransactionFactory transactionFactory = mock(TransactionFactory.class);
DataSource dataSource = mock(DataSource.class);
Environment environment = new Environment("test", transactionFactory, dataSource);
when(this.sqlSessionFactory.getConfiguration()).thenReturn(configuration);
when(configuration.getEnvironment()).thenReturn(environment);
}
private void setUpSqlSession() throws Exception {
when(this.sqlSessionFactory.openSession(executorType)).thenReturn(this.sqlSession);
}
@Override
@After
public void cleanUp() throws Exception {
// Should not manually close SqlSessionTemplate
}
@Ignore // Changed to trace only query operations
@Override
@Test
public void commitShouldBeTraced() throws Exception {
try {
super.commitShouldBeTraced();
fail("SqlSessionTemplate cannot manually call commit.");
} catch (UnsupportedOperationException e) {
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(1));
final SpanEventBo commitSpanEventBo = spanEvents.get(0);
assertThat(commitSpanEventBo.hasException(), is(true));
assertThat(commitSpanEventBo.getExceptionId(), not(NOT_CACHED));
}
}
@Ignore // Changed to trace only query operations
@Override
@Test
public void rollbackShouldBeTraced() throws Exception {
try {
super.rollbackShouldBeTraced();
fail("SqlSessionTemplate cannot manually call rollback.");
} catch (UnsupportedOperationException e) {
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(1));
final SpanEventBo rollbackSpanEventBo = spanEvents.get(0);
assertThat(rollbackSpanEventBo.hasException(), is(true));
assertThat(rollbackSpanEventBo.getExceptionId(), not(NOT_CACHED));
}
}
@Ignore // Changed to trace only query operations
@Override
@Test
public void closeShouldBeTraced() throws Exception {
try {
super.closeShouldBeTraced();
} catch (UnsupportedOperationException e) {
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertThat(spanEvents.size(), is(1));
final SpanEventBo closeSpanEventBo = spanEvents.get(0);
assertThat(closeSpanEventBo.hasException(), is(true));
assertThat(closeSpanEventBo.getExceptionId(), not(NOT_CACHED));
}
}
}
@@ -15,7 +15,9 @@
*/
package com.navercorp.pinpoint.web.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
@@ -82,12 +84,18 @@ public class UserController {
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public Object getUser(@RequestParam(value="userId", required=false) String userId) {
public Object getUser(@RequestParam(value="userId", required=false) String userId, @RequestParam(value="userName", required=false) String userName, @RequestParam(value="department", required=false) String department) {
try {
if(userId == null) {
return userService.selectUser();
if(userId != null) {
List<User> users = new ArrayList<User>(1);
users.add(userService.selectUserByUserId(userId));
return users;
} else if (userName != null) {
return userService.selectUserByUserName(userName);
} else if (department != null) {
return userService.selectUserByDepartment(department);
} else {
return userService.selectUserByUserId(userId);
return userService.selectUser();
}
} catch (Exception e) {
logger.error("can't select user", e);
@@ -26,11 +26,20 @@ public interface UserDao {
void insertUser(User user);
void inserUserList(List<User> users);
void deleteUser(User user);
List<User> selectUser();
void updateUser(User user);
List<User> selectUserByDepartment(String department);
User selectUserByUserId(String userId);
List<User> selectUserByUserName(String userName);
void updateUser(User user);
}
@@ -42,6 +42,11 @@ public class MysqlUserDao implements UserDao {
sqlSessionTemplate.insert(NAMESPACE + "insertUser", user);
}
@Override
public void inserUserList(List<User> users) {
sqlSessionTemplate.insert(NAMESPACE + "insertUserList", users);
}
@Override
public void deleteUser(User user) {
sqlSessionTemplate.delete(NAMESPACE + "deleteUser", user);
@@ -63,4 +68,13 @@ public class MysqlUserDao implements UserDao {
return sqlSessionTemplate.selectOne(NAMESPACE + "selectUserByUserId", userId);
}
@Override
public List<User> selectUserByDepartment(String department) {
return sqlSessionTemplate.selectList(NAMESPACE + "selectUserByDepartment", department);
}
@Override
public List<User> selectUserByUserName(String userName) {
return sqlSessionTemplate.selectList(NAMESPACE + "selectUserByUserName", userName);
}
}
@@ -28,10 +28,14 @@ public interface UserService {
void deleteUser(User user);
List<User> selectUser();
void updateUser(User user);
List<User> selectUser();
User selectUserByUserId(String userId);
List<User> selectUserByUserName(String userName);
List<User> selectUserByDepartment(String department);
}
@@ -56,7 +56,16 @@ public class UserServiceImpl implements UserService {
@Override
public User selectUserByUserId(String userId) {
return userDao.selectUserByUserId(userId);
}
@Override
public List<User> selectUserByUserName(String userName) {
return userDao.selectUserByUserName(userName);
}
@Override
public List<User> selectUserByDepartment(String department) {
return userDao.selectUserByDepartment(department);
}
}
@@ -57,4 +57,10 @@ public class User {
public void setEmail(String email) {
this.email = email;
}
public void removeHyphenForPhoneNumber() {
if(phoneNumber.contains("-")) {
phoneNumber.replace("-", "");
}
}
}
@@ -8,6 +8,13 @@
INSERT INTO user
VALUES (#{userId}, #{name}, #{department}, #{phoneNumber}, #{email})
</insert>
<insert id="insertUserList">
<foreach collection="list" item="User">
INSERT INTO user_temp
VALUES (#{userId}, #{name}, #{department}, #{phoneNumber}, #{email})
</foreach>
</insert>
<delete id="deleteUser" parameterType="User">
DELETE
@@ -25,6 +32,18 @@
FROM user
WHERE user_id = #{userId}
</select>
<select id="selectUserByDepartment" resultType="User">
SELECT *
FROM user
WHERE department = #{department}
</select>
<select id="selectUserByUserName" resultType="User">
SELECT *
FROM user
WHERE name = #{name}
</select>
<update id="updateUser" parameterType="User">
UPDATE user
@@ -2,7 +2,7 @@
<div class="some-list-header header-sky">
<button class="btn btn-info left" ng-click="onRefresh()"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button>
<span class="title">Group Member<span class="total"></span></span>
<button class="btn btn-primary right" style="visibility:hidden;"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
<button class="btn btn-info right" style="visibility:hidden;"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
<div class="some-list-content">
<div class="wrapper"><ul>
@@ -12,8 +12,8 @@
</ul></div>
<div class="filter-input">
<input type="text" placeholder="Filter group member" ng-keydown="onInputFilter($event)"/>
<button class="btn btn-primary disabled trash" ng-click="onFilterEmpty()"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button>
<button class="btn btn-primary" ng-click="onFilterGroup()" style="margin-right:2px"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button>
<button class="btn btn-info disabled trash" ng-click="onFilterEmpty()"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button>
<button class="btn btn-info" ng-click="onFilterGroup()" style="margin-right:2px"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button>
</div>
</div>
<div class="some-loading has-not-edit">
@@ -10,16 +10,15 @@
pinpointApp.constant('ConfigurationConfig', {
menu: {
GENERAL: "general",
ALARM: "alarm"
ALARM: "alarm",
HELP: "help",
}
});
pinpointApp.controller('ConfigurationCtrl', [ '$scope','$element', 'ConfigurationConfig',
function ($scope, $element, $constant) {
//@TODO
//통계 추가할 것.
//$at($at.FILTEREDMAP_PAGE);
var $elBody = $element.find(".modal-body");
$scope.descriptionOfCurrentTab = "Set your option";
$scope.currentTab = $constant.menu.GENERAL;
@@ -44,14 +43,21 @@
switch( tab ) {
case $constant.menu.GENERAL:
$at( $at.MAIN, $at.CLK_GENERAL );
$elBody.css("background-color", "#e9eaed");
$scope.descriptionOfCurrentTab = "Set your option";
$scope.$broadcast( "general.configuration.show");
break;
case $constant.menu.ALARM:
$at( $at.MAIN, $at.CLK_ALARM );
$elBody.css("background-color", "#e9eaed");
$scope.descriptionOfCurrentTab = "Set your alarm rules";
$scope.$broadcast( "alarmUserGroup.configuration.show");
break;
case $constant.menu.HELP:
$at( $at.MAIN, $at.CLK_HELP );
$elBody.css("background-color", "#FFF");
$scope.descriptionOfCurrentTab = "";
break;
}
}
$scope.$on("configuration.show", function() {
@@ -0,0 +1,29 @@
(function($) {
'use strict';
/**
* (en)HelpCtrl
* @ko HelpCtrl
* @group Controller
* @name HelpCtrl
* @class
*/
pinpointApp.controller('HelpCtrl', [ '$scope','$element',
function ($scope, $element) {
$scope.enHelpList = [
{ "title": "Quick start guide", "link": "https://github.com/naver/pinpoint/blob/master/quickstart/README.md" },
{ "title": "Technical Overview of Pinpoint", "link": "https://github.com/naver/pinpoint/wiki/Technical-Overview-Of-Pinpoint" },
{ "title": "Using Pinpont with Docker", "link": "http://yous.be/2015/05/05/using-pinpoint-with-docker/" },
{ "title": "Notes on Jetty Plugin for Pinpoint ", "link": "https://github.com/cijung/Docs/blob/master/JettyPluginNotes.md" }
];
$scope.koHelpList = [
{ "title": "Pinpoint 개발자가 작성한 Pinpoint 기술문서", "link": "http://helloworld.naver.com/helloworld/1194202" },
{ "title": "소개 및 설치 가이드", "link": "http://dev2.prompt.co.kr/33" },
{ "title": "Pinpoint 사용 경험", "link": "http://www.barney.pe.kr/blog/category/development/page/2/" },
{ "title": "설치 가이드 동영상 강좌 1", "link": "https://www.youtube.com/watch?v=hrvKaEaDEGs" },
{ "title": "설치 가이드 동영상 강좌 2", "link": "https://www.youtube.com/watch?v=fliKPGHGXK4" },
{ "title": "AWS Ubuntu 14.04 설치 가이드 ", "link": "http://lky1001.tistory.com/132" }
];
}
]);
})(jQuery);
+25 -2
View File
@@ -335,15 +335,16 @@
<li ng-class="{true: 'active'}[isGeneral()]" ng-click="setCurrentTab('general')">General</li>
<li ng-class="{true: 'active'}[isAlarm()]" ng-click="setCurrentTab('alarm')">Alarm</li>
<li class="description">{{descriptionOfCurrentTab}}</li>
<li ng-class="{true: 'active'}[isHelp()]" ng-click="setCurrentTab('help')" style="float:right">Help</li>
</ul>
</div>
<div class="modal-body" style="padding-top:50px;">
<div class="modal-body">
<div id="config-general" ng-show="isGeneral()" ng-controller="GeneralCtrl">
<div style="text-align:center;font-family:verdana;">
<h1>Add General Setting</h1>
</div>
</div>
<div id="config-alram" ng-show="isAlarm()">
<div id="config-alram" ng-show="isAlarm()" style="margin-top:10px;">
<alarm-user-group-directive></alarm-user-group-directive>
<div class="tabbable tabs-left" style="padding-left:20px;">
<ul class="nav nav-tabs">
@@ -362,6 +363,27 @@
</div>
<div style="clear:both;display:block;"></div>
</div>
<div id="config-help" ng-show="isHelp()" ng-controller="HelpCtrl">
<div style="font-family:verdana;">
<a href="https://github.com/naver/pinpoint/wiki/FAQ" target="_blank" class="link-title"><i class="xi-clip"></i> FAQ</a>
<a href="https://github.com/naver/pinpoint/issues" class="link-title"><i class="xi-info-circle"></i> Issues</a></h4>
<a href="https://groups.google.com/forum/#!forum/pinpoint_user" class="link-title"><i class="xi-pen"></i> User Group</a>
<hr/>
<h4>English</h4>
<ul>
<li ng-repeat="helpLink in enHelpList">
<a href="{{helpLink.link}}" target="_balnk"><span class="glyphicon glyphicon-file" aria-hidden="true"></span>{{helpLink.title}}</a>
</li>
</ul>
<hr/>
<h4>한글</h4>
<ul>
<li ng-repeat="helpLink in koHelpList">
<a href="{{helpLink.link}}" target="_balnk"><span class="glyphicon glyphicon-file" aria-hidden="true"></span>{{helpLink.title}}</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
@@ -418,6 +440,7 @@
<script src="features/cpuLoadChart/cpu-load-chart.directive.js?v=${buildTime}"></script>
<script src="features/loading/loading.directive.js?v=${buildTime}"></script>
<script src="features/configuration/configuration.controller.js?v=${buildTime}"></script>
<script src="features/configuration/help/help.controller.js?v=${buildTime}"></script>
<script src="features/configuration/general/general.controller.js?v=${buildTime}"></script>
<script src="features/configuration/alarm/alarm-user-group.directive.js?v=${buildTime}"></script>
<script src="features/configuration/alarm/alarm-group-member.directive.js?v=${buildTime}"></script>
@@ -54,6 +54,7 @@
$at.CLK_CONFIGURATION = "ClickConfiguration";
$at.CLK_GENERAL = "ClickConfigurationGeneral";
$at.CLK_ALARM = "ClickConfigurationAlarm";
$at.CLK_HELP = "ClickConfigurationHelp";
$at.CLK_ALARM_CREATE_USER_GROUP = "ClickAlarmCreateUserGroup";
$at.CLK_ALARM_REFRESH_USER_GROUP = "ClickAlarmRefreshUserGroup";
$at.CLK_ALARM_FILTER_USER_GROUP = "ClickAlarmFilterUserGroup";
+25 -2
View File
@@ -78,10 +78,10 @@
#pinpoint-configuration .header-blue {
background-color: #D0E9FF;
background-color: #EEE;
}
#pinpoint-configuration .header-sky {
background-color: #DAF7FF;
background-color: #EEE;
}
#pinpoint-configuration .hide-me {
display:none;
@@ -436,4 +436,27 @@
#pinpoint-configuration .some-table .some-list-content input {
width: 100%;
margin-left: -2px;
}
#config-help .link-title {
font-size: 18px;
margin-right: 30px;
}
#config-help li {
list-style: none;
}
#config-help li span.glyphicon {
margin-right: 4px;
margin-top: 4px;
}
#config-help a:hover {
color: rgb(43, 46, 74);
}
#config-help a:link {
color: rgb(144, 55, 73);
}
#config-help a:visited {
color: rgb(232, 69, 69);
}
#config-help a:active {
color: rgb(83, 53, 74);
}
@@ -103,6 +103,35 @@ public class UserControllerTest {
.andExpect(jsonPath("$[0]", hasKey("email")))
.andReturn();
this.mockMvc.perform(get("/user.pinpoint?userName=" + USER_NAME).contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$[0]", hasKey("userId")))
.andExpect(jsonPath("$[0]", hasKey("name")))
.andExpect(jsonPath("$[0]", hasKey("department")))
.andExpect(jsonPath("$[0]", hasKey("phoneNumber")))
.andExpect(jsonPath("$[0]", hasKey("email")))
.andReturn();
this.mockMvc.perform(get("/user.pinpoint?userId=" + USER_ID).contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$[0]", hasKey("userId")))
.andExpect(jsonPath("$[0]", hasKey("name")))
.andExpect(jsonPath("$[0]", hasKey("department")))
.andExpect(jsonPath("$[0]", hasKey("phoneNumber")))
.andExpect(jsonPath("$[0]", hasKey("email")))
.andReturn();
this.mockMvc.perform(get("/user.pinpoint?department=" + USER_DEPARTMENT).contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$[0]", hasKey("userId")))
.andExpect(jsonPath("$[0]", hasKey("name")))
.andExpect(jsonPath("$[0]", hasKey("department")))
.andExpect(jsonPath("$[0]", hasKey("phoneNumber")))
.andExpect(jsonPath("$[0]", hasKey("email")))
.andReturn();
this.mockMvc.perform(delete("/user.pinpoint").contentType(MediaType.APPLICATION_JSON).content("{\"userId\" : \"" + USER_ID + "\"}"))
.andExpect(status().isOk())