Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
梦中观雨
cat
提交
a2dc6adb
C
cat
项目概览
梦中观雨
/
cat
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
cat
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a2dc6adb
编写于
5月 30, 2013
作者:
F
Frankie Wu
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #63 from atellwu/abtest3
完成网络通讯,初步完成演示的demo
上级
013e321f
fa550b5e
变更
40
隐藏空白更改
内联
并排
Showing
40 changed file
with
1122 addition
and
157 deletion
+1122
-157
abtest-sample/pom.xml
abtest-sample/pom.xml
+32
-0
abtest-sample/src/main/java/com/dianping/abtest/sample/ABTestSampleServlet.java
.../java/com/dianping/abtest/sample/ABTestSampleServlet.java
+47
-0
abtest-sample/src/main/java/com/dianping/abtest/sample/IPDistributionStrategy.java
...va/com/dianping/abtest/sample/IPDistributionStrategy.java
+62
-0
abtest-sample/src/main/java/com/dianping/abtest/sample/IPUtils.java
...ple/src/main/java/com/dianping/abtest/sample/IPUtils.java
+88
-0
abtest-sample/src/main/resources/META-INF/MANIFEST.MF
abtest-sample/src/main/resources/META-INF/MANIFEST.MF
+3
-0
abtest-sample/src/main/resources/META-INF/cat/client.xml
abtest-sample/src/main/resources/META-INF/cat/client.xml
+3
-0
abtest-sample/src/main/resources/META-INF/cat/config.xsd
abtest-sample/src/main/resources/META-INF/cat/config.xsd
+59
-0
abtest-sample/src/main/webapp/WEB-INF/web.xml
abtest-sample/src/main/webapp/WEB-INF/web.xml
+30
-0
abtest-sample/src/main/webapp/index.jsp
abtest-sample/src/main/webapp/index.jsp
+5
-0
abtest-sample/src/main/webapp/index2.jsp
abtest-sample/src/main/webapp/index2.jsp
+5
-0
abtest-sample/src/test/java/com/dianping/abtest/sample/ABTestServer.java
...rc/test/java/com/dianping/abtest/sample/ABTestServer.java
+42
-0
abtest-sample/src/test/java/com/dianping/abtest/sample/ABTestServerConfigurator.java
.../com/dianping/abtest/sample/ABTestServerConfigurator.java
+30
-0
abtest-sample/src/test/resources/com/dianping/abtest/sample/ABTestServer.xml
...est/resources/com/dianping/abtest/sample/ABTestServer.xml
+10
-0
cat-core/src/main/java/com/dianping/cat/abtest/ABTestManager.java
.../src/main/java/com/dianping/cat/abtest/ABTestManager.java
+9
-1
cat-core/src/main/java/com/dianping/cat/abtest/annotation/UserID.java
.../main/java/com/dianping/cat/abtest/annotation/UserID.java
+12
-0
cat-core/src/main/java/com/dianping/cat/abtest/repository/ABTestEntityRepository.java
...ianping/cat/abtest/repository/ABTestEntityRepository.java
+6
-3
cat-core/src/main/java/com/dianping/cat/abtest/repository/DefaultABTestEntityRepository.java
.../cat/abtest/repository/DefaultABTestEntityRepository.java
+127
-15
cat-core/src/main/java/com/dianping/cat/abtest/repository/ProtocolMessage.java
...a/com/dianping/cat/abtest/repository/ProtocolMessage.java
+9
-0
cat-core/src/main/java/com/dianping/cat/abtest/repository/ProtocolNames.java
...ava/com/dianping/cat/abtest/repository/ProtocolNames.java
+13
-0
cat-core/src/main/java/com/dianping/cat/abtest/spi/ABTestEntity.java
...c/main/java/com/dianping/cat/abtest/spi/ABTestEntity.java
+66
-49
cat-core/src/main/java/com/dianping/cat/abtest/spi/internal/ABTestEntityManager.java
...dianping/cat/abtest/spi/internal/ABTestEntityManager.java
+1
-0
cat-core/src/main/java/com/dianping/cat/abtest/spi/internal/DefaultABTestContextManager.java
.../cat/abtest/spi/internal/DefaultABTestContextManager.java
+0
-1
cat-core/src/main/java/com/dianping/cat/abtest/spi/internal/DefaultABTestEntityManager.java
...g/cat/abtest/spi/internal/DefaultABTestEntityManager.java
+20
-54
cat-core/src/main/java/com/dianping/cat/build/ABTestComponentConfigurator.java
...a/com/dianping/cat/build/ABTestComponentConfigurator.java
+3
-2
cat-core/src/main/resources/META-INF/plexus/components.xml
cat-core/src/main/resources/META-INF/plexus/components.xml
+9
-8
cat-core/src/test/java/com/dianping/cat/abtest/repository/ABTestRepositoryTest.java
.../dianping/cat/abtest/repository/ABTestRepositoryTest.java
+75
-0
cat-core/src/test/java/com/dianping/cat/abtest/spi/internal/ABTestEntityManagerTest.java
...ping/cat/abtest/spi/internal/ABTestEntityManagerTest.java
+1
-1
cat-core/src/test/resources/com/dianping/cat/abtest/demo/annotation/heartbeat.xml
...ces/com/dianping/cat/abtest/demo/annotation/heartbeat.xml
+32
-0
cat-core/src/test/resources/com/dianping/cat/abtest/demo/annotation/strategy-config.xml
...m/dianping/cat/abtest/demo/annotation/strategy-config.xml
+16
-0
cat-home/pom.xml
cat-home/pom.xml
+5
-0
cat-home/src/main/java/com/dianping/cat/CatHomeModule.java
cat-home/src/main/java/com/dianping/cat/CatHomeModule.java
+9
-2
cat-home/src/main/java/com/dianping/cat/build/CatDatabaseConfigurator.java
.../java/com/dianping/cat/build/CatDatabaseConfigurator.java
+1
-1
cat-home/src/main/java/com/dianping/cat/build/ServiceComponentConfigurator.java
.../com/dianping/cat/build/ServiceComponentConfigurator.java
+10
-0
cat-home/src/main/java/com/dianping/cat/system/page/abtest/Handler.java
...ain/java/com/dianping/cat/system/page/abtest/Handler.java
+18
-0
cat-home/src/main/java/com/dianping/cat/system/page/abtest/server/ABTestEntityServer.java
...ing/cat/system/page/abtest/server/ABTestEntityServer.java
+9
-0
cat-home/src/main/java/com/dianping/cat/system/page/abtest/server/DefaultABTestEntityServer.java
.../system/page/abtest/server/DefaultABTestEntityServer.java
+210
-0
cat-home/src/main/resources/META-INF/dal/jdbc/report-codegen.xml
...e/src/main/resources/META-INF/dal/jdbc/report-codegen.xml
+7
-6
cat-home/src/main/resources/META-INF/plexus/components.xml
cat-home/src/main/resources/META-INF/plexus/components.xml
+21
-3
cat-home/src/main/resources/META-INF/wizard/jdbc/wizard.xml
cat-home/src/main/resources/META-INF/wizard/jdbc/wizard.xml
+3
-3
cat-home/src/main/webapp/jsp/system/abtestAllTest.jsp
cat-home/src/main/webapp/jsp/system/abtestAllTest.jsp
+14
-8
未找到文件。
abtest-sample/pom.xml
0 → 100644
浏览文件 @
a2dc6adb
<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>
<groupId>
com.dianping.cat
</groupId>
<artifactId>
abtest-sample
</artifactId>
<packaging>
war
</packaging>
<version>
0.0.1-SNAPSHOT
</version>
<name>
abtest-sample Maven Webapp
</name>
<url>
http://maven.apache.org
</url>
<dependencies>
<dependency>
<groupId>
com.dianping.cat
</groupId>
<artifactId>
cat-core
</artifactId>
<version>
0.5.2.10
</version>
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<version>
4.8.1
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.unidal.framework
</groupId>
<artifactId>
test-framework
</artifactId>
<version>
2.0.2
</version>
<scope>
test
</scope>
</dependency>
</dependencies>
<build>
<finalName>
abtest-sample
</finalName>
</build>
</project>
abtest-sample/src/main/java/com/dianping/abtest/sample/ABTestSampleServlet.java
0 → 100644
浏览文件 @
a2dc6adb
package
com.dianping.abtest.sample
;
import
java.io.IOException
;
import
javax.servlet.RequestDispatcher
;
import
javax.servlet.ServletException
;
import
javax.servlet.http.HttpServlet
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
com.dianping.cat.abtest.ABTest
;
import
com.dianping.cat.abtest.ABTestId
;
import
com.dianping.cat.abtest.ABTestManager
;
public
class
ABTestSampleServlet
extends
HttpServlet
{
private
static
final
long
serialVersionUID
=
-
6472784609174835547L
;
private
ABTest
m_abtest
=
ABTestManager
.
getTest
(
MyABTestId
.
CASE1
);
@Override
public
void
service
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
ServletException
,
IOException
{
if
(
m_abtest
.
isGroupA
())
{
RequestDispatcher
rd
=
getServletContext
().
getRequestDispatcher
(
"/index2.jsp"
);
rd
.
forward
(
request
,
response
);
// Cat.logMetric(...);
}
else
{
RequestDispatcher
rd
=
getServletContext
().
getRequestDispatcher
(
"/index.jsp"
);
rd
.
forward
(
request
,
response
);
// Cat.logMetric(...);
}
}
public
static
enum
MyABTestId
implements
ABTestId
{
CASE1
(
0
);
private
int
m_id
;
private
MyABTestId
(
int
id
)
{
m_id
=
id
;
}
@Override
public
int
getValue
()
{
return
m_id
;
}
}
}
abtest-sample/src/main/java/com/dianping/abtest/sample/IPDistributionStrategy.java
0 → 100644
浏览文件 @
a2dc6adb
package
com.dianping.abtest.sample
;
import
java.util.List
;
import
javax.servlet.http.HttpServletRequest
;
import
org.unidal.helper.Splitters
;
import
org.unidal.lookup.util.StringUtils
;
import
com.dianping.cat.abtest.spi.ABTestContext
;
import
com.dianping.cat.abtest.spi.ABTestEntity
;
import
com.dianping.cat.abtest.spi.ABTestGroupStrategy
;
public
class
IPDistributionStrategy
implements
ABTestGroupStrategy
{
public
static
final
String
ID
=
"ip-distribution"
;
public
IPDistributionStrategy
(){
System
.
out
.
println
(
"new "
+
ID
+
" created"
);
}
@Override
public
void
apply
(
ABTestContext
ctx
)
{
ABTestEntity
entity
=
ctx
.
getEntity
();
String
config
=
entity
.
getGroupStrategyConfiguration
();
List
<
String
>
ips
=
Splitters
.
by
(
','
).
trim
().
split
(
config
);
HttpServletRequest
req
=
ctx
.
getHttpServletRequest
();
String
address
=
getRemoteAddr
(
req
);
for
(
String
ip
:
ips
)
{
if
(
ip
.
equals
(
address
))
{
ctx
.
setGroupName
(
"A"
);
return
;
}
}
}
public
String
getRemoteAddr
(
HttpServletRequest
req
)
{
String
ip
=
req
.
getHeader
(
"X-Forwarded-For"
);
if
(
StringUtils
.
isEmpty
(
ip
)
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
req
.
getHeader
(
"Proxy-Client-IP"
);
}
if
(
StringUtils
.
isEmpty
(
ip
)
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
req
.
getHeader
(
"WL-Proxy-Client-IP"
);
}
if
(
StringUtils
.
isEmpty
(
ip
)
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
req
.
getHeader
(
"HTTP_CLIENT_IP"
);
}
if
(
StringUtils
.
isEmpty
(
ip
)
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
req
.
getHeader
(
"HTTP_X_FORWARDED_FOR"
);
}
if
(
StringUtils
.
isEmpty
(
ip
)
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
req
.
getRemoteAddr
();
if
(
ip
.
equals
(
"127.0.0.1"
)){
ip
=
IPUtils
.
getFirstNoLoopbackIP4Address
();
}
}
return
ip
;
}
}
abtest-sample/src/main/java/com/dianping/abtest/sample/IPUtils.java
0 → 100644
浏览文件 @
a2dc6adb
package
com.dianping.abtest.sample
;
/**
* Project: puma-server
*
* File Created at 2012-7-24
* $Id$
*
* Copyright 2010 dianping.com.
* All rights reserved.
*
* This software is the confidential and proprietary information of
* Dianping Company. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with dianping.com.
*/
import
java.net.Inet6Address
;
import
java.net.InetAddress
;
import
java.net.NetworkInterface
;
import
java.net.SocketException
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Enumeration
;
/**
* @author Leo Liang
*
*/
public
final
class
IPUtils
{
private
IPUtils
()
{
}
/**
* 获取第一个no loop address
*
* @return first no loop address, or null if not exists
*/
public
static
String
getFirstNoLoopbackIP4Address
()
{
Collection
<
String
>
allNoLoopbackIP4Addresses
=
getNoLoopbackIP4Addresses
();
if
(
allNoLoopbackIP4Addresses
.
isEmpty
())
{
return
null
;
}
return
allNoLoopbackIP4Addresses
.
iterator
().
next
();
}
public
static
Collection
<
String
>
getNoLoopbackIP4Addresses
()
{
Collection
<
String
>
noLoopbackIP4Addresses
=
new
ArrayList
<
String
>();
Collection
<
InetAddress
>
allInetAddresses
=
getAllHostAddress
();
for
(
InetAddress
address
:
allInetAddresses
)
{
if
(!
address
.
isLoopbackAddress
()
&&
!
address
.
isSiteLocalAddress
()
&&
!
Inet6Address
.
class
.
isInstance
(
address
))
{
noLoopbackIP4Addresses
.
add
(
address
.
getHostAddress
());
}
}
if
(
noLoopbackIP4Addresses
.
isEmpty
())
{
// 降低过滤标准,将site local address纳入结果
for
(
InetAddress
address
:
allInetAddresses
)
{
if
(!
address
.
isLoopbackAddress
()
&&
!
Inet6Address
.
class
.
isInstance
(
address
))
{
noLoopbackIP4Addresses
.
add
(
address
.
getHostAddress
());
}
}
}
return
noLoopbackIP4Addresses
;
}
public
static
Collection
<
InetAddress
>
getAllHostAddress
()
{
try
{
Enumeration
<
NetworkInterface
>
networkInterfaces
=
NetworkInterface
.
getNetworkInterfaces
();
Collection
<
InetAddress
>
addresses
=
new
ArrayList
<
InetAddress
>();
while
(
networkInterfaces
.
hasMoreElements
())
{
NetworkInterface
networkInterface
=
networkInterfaces
.
nextElement
();
Enumeration
<
InetAddress
>
inetAddresses
=
networkInterface
.
getInetAddresses
();
while
(
inetAddresses
.
hasMoreElements
())
{
InetAddress
inetAddress
=
inetAddresses
.
nextElement
();
addresses
.
add
(
inetAddress
);
}
}
return
addresses
;
}
catch
(
SocketException
e
)
{
throw
new
RuntimeException
(
e
.
getMessage
(),
e
);
}
}
}
\ No newline at end of file
abtest-sample/src/main/resources/META-INF/MANIFEST.MF
0 → 100755
浏览文件 @
a2dc6adb
Manifest-Version: 1.0
Class-Path:
Main-Class: com.dianping.cat.Server
abtest-sample/src/main/resources/META-INF/cat/client.xml
0 → 100755
浏览文件 @
a2dc6adb
<config
mode=
"client"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema"
xsi:noNamespaceSchemaLocation=
"config.xsd"
>
<domain
id=
"Cat"
/>
</config>
abtest-sample/src/main/resources/META-INF/cat/config.xsd
0 → 100755
浏览文件 @
a2dc6adb
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
xmlns:xs=
"http://www.w3.org/2001/XMLSchema"
elementFormDefault=
"qualified"
attributeFormDefault=
"unqualified"
>
<xs:element
name=
"config"
type=
"ConfigType"
/>
<xs:complexType
name=
"ConfigType"
>
<xs:sequence>
<xs:element
name=
"base-log-dir"
type=
"xs:string"
minOccurs=
"0"
maxOccurs=
"1"
/>
<xs:element
name=
"servers"
>
<xs:complexType>
<xs:sequence
minOccurs=
"0"
maxOccurs=
"unbounded"
>
<xs:element
name=
"server"
type=
"ServerType"
/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element
minOccurs=
"0"
maxOccurs=
"unbounded"
name=
"domain"
type=
"DomainType"
/>
<xs:element
name=
"bind"
type=
"BindType"
minOccurs=
"0"
maxOccurs=
"1"
/>
<xs:element
name=
"properties"
>
<xs:complexType>
<xs:sequence
minOccurs=
"0"
maxOccurs=
"unbounded"
>
<xs:element
name=
"property"
type=
"PropertyType"
/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute
name=
"mode"
type=
"xs:string"
use=
"required"
/>
</xs:complexType>
<xs:complexType
name=
"ServerType"
>
<xs:simpleContent>
<xs:extension
base=
"xs:string"
>
<xs:attribute
name=
"ip"
type=
"xs:string"
/>
<xs:attribute
name=
"port"
type=
"xs:int"
default=
"2280"
/>
<xs:attribute
name=
"enabled"
type=
"xs:boolean"
default=
"true"
/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType
name=
"DomainType"
>
<xs:simpleContent>
<xs:extension
base=
"xs:string"
>
<xs:attribute
name=
"id"
type=
"xs:string"
/>
<xs:attribute
name=
"ip"
type=
"xs:string"
/>
<xs:attribute
name=
"enabled"
type=
"xs:boolean"
/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType
name=
"BindType"
>
<xs:simpleContent>
<xs:extension
base=
"xs:string"
>
<xs:attribute
name=
"ip"
type=
"xs:string"
/>
<xs:attribute
name=
"port"
type=
"xs:string"
default=
"2280"
/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType
name=
"PropertyType"
>
<xs:simpleContent>
<xs:extension
base=
"xs:string"
>
<xs:attribute
name=
"name"
type=
"xs:string"
/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
abtest-sample/src/main/webapp/WEB-INF/web.xml
0 → 100644
浏览文件 @
a2dc6adb
<web-app>
<display-name>
Archetype Created Web Application
</display-name>
<listener>
<listener-class>
com.dianping.cat.servlet.CatListener
</listener-class>
</listener>
<filter>
<filter-name>
cat-filter
</filter-name>
<filter-class>
com.dianping.cat.servlet.CatFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>
cat-filter
</filter-name>
<url-pattern>
/*
</url-pattern>
<dispatcher>
REQUEST
</dispatcher>
<dispatcher>
FORWARD
</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>
ABTestSampleServlet
</servlet-name>
<servlet-class>
com.dianping.abtest.sample.ABTestSampleServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
ABTestSampleServlet
</servlet-name>
<url-pattern>
/
</url-pattern>
</servlet-mapping>
</web-app>
abtest-sample/src/main/webapp/index.jsp
0 → 100644
浏览文件 @
a2dc6adb
<html>
<body>
<h2>
Hello World!
</h2>
</body>
</html>
abtest-sample/src/main/webapp/index2.jsp
0 → 100644
浏览文件 @
a2dc6adb
<html>
<body>
<h2>
Congratulation!
</h2>
</body>
</html>
abtest-sample/src/test/java/com/dianping/abtest/sample/ABTestServer.java
0 → 100644
浏览文件 @
a2dc6adb
package
com.dianping.abtest.sample
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.JUnit4
;
import
org.unidal.test.jetty.JettyServer
;
@RunWith
(
JUnit4
.
class
)
public
class
ABTestServer
extends
JettyServer
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
ABTestServer
server
=
new
ABTestServer
();
System
.
setProperty
(
"devMode"
,
"true"
);
server
.
startServer
();
server
.
startWebApp
();
server
.
stopServer
();
}
@Before
public
void
before
()
throws
Exception
{
System
.
setProperty
(
"devMode"
,
"true"
);
super
.
startServer
();
}
@Override
protected
String
getContextPath
()
{
return
"/abtest-sample"
;
}
@Override
protected
int
getServerPort
()
{
return
8081
;
}
@Test
public
void
startWebApp
()
throws
Exception
{
// open the page in the default browser
display
(
"/abtest-sample"
);
waitForAnyKey
();
}
}
abtest-sample/src/test/java/com/dianping/abtest/sample/ABTestServerConfigurator.java
0 → 100644
浏览文件 @
a2dc6adb
package
com.dianping.abtest.sample
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.unidal.lookup.configuration.AbstractResourceConfigurator
;
import
org.unidal.lookup.configuration.Component
;
import
com.dianping.cat.abtest.spi.ABTestGroupStrategy
;
public
class
ABTestServerConfigurator
extends
AbstractResourceConfigurator
{
@Override
public
List
<
Component
>
defineComponents
()
{
List
<
Component
>
all
=
new
ArrayList
<
Component
>();
all
.
add
(
C
(
ABTestGroupStrategy
.
class
,
IPDistributionStrategy
.
ID
,
IPDistributionStrategy
.
class
)
.
is
(
PER_LOOKUP
));
return
all
;
}
@Override
protected
Class
<?>
getTestClass
()
{
return
ABTestServer
.
class
;
}
public
static
void
main
(
String
[]
args
)
{
generatePlexusComponentsXmlFile
(
new
ABTestServerConfigurator
());
}
}
abtest-sample/src/test/resources/com/dianping/abtest/sample/ABTestServer.xml
0 → 100644
浏览文件 @
a2dc6adb
<plexus>
<components>
<component>
<role>
com.dianping.cat.abtest.spi.ABTestGroupStrategy
</role>
<role-hint>
ip-distribution
</role-hint>
<implementation>
com.dianping.abtest.sample.IPDistributionStrategy
</implementation>
<instantiation-strategy>
per-lookup
</instantiation-strategy>
</component>
</components>
</plexus>
cat-core/src/main/java/com/dianping/cat/abtest/ABTestManager.java
浏览文件 @
a2dc6adb
...
...
@@ -2,9 +2,11 @@ package com.dianping.cat.abtest;
import
javax.servlet.http.HttpServletRequest
;
import
org.codehaus.plexus.PlexusContainer
;
import
org.unidal.lookup.ContainerLoader
;
import
com.dianping.cat.abtest.internal.DefaultABTest
;
import
com.dianping.cat.abtest.repository.ABTestEntityRepository
;
import
com.dianping.cat.abtest.spi.internal.ABTestContextManager
;
public
final
class
ABTestManager
{
...
...
@@ -22,7 +24,13 @@ public final class ABTestManager {
if
(
s_contextManager
==
null
)
{
try
{
// it could be time-consuming due to load entities from the repository, i.e. database.
s_contextManager
=
ContainerLoader
.
getDefaultContainer
().
lookup
(
ABTestContextManager
.
class
);
PlexusContainer
container
=
ContainerLoader
.
getDefaultContainer
();
s_contextManager
=
container
.
lookup
(
ABTestContextManager
.
class
);
ABTestEntityRepository
repository
=
container
.
lookup
(
ABTestEntityRepository
.
class
);
repository
.
start
();
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"Error when initializing ABTestContextManager!"
,
e
);
}
...
...
cat-core/src/main/java/com/dianping/cat/abtest/annotation/UserID.java
0 → 100644
浏览文件 @
a2dc6adb
package
com.dianping.cat.abtest.annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
FIELD
)
public
@interface
UserID
{
String
[]
value
();
}
cat-core/src/main/java/com/dianping/cat/abtest/repository/ABTestEntityRepository.java
浏览文件 @
a2dc6adb
package
com.dianping.cat.abtest.repository
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
import
com.dianping.cat.abtest.spi.ABTestEntity
;
public
interface
ABTestEntityRepository
{
public
List
<
ABTestEntity
>
getEntities
(
Date
from
,
Date
to
);
public
Map
<
Integer
,
ABTestEntity
>
getEntities
();
public
void
start
();
}
cat-core/src/main/java/com/dianping/cat/abtest/repository/DefaultABTestEntityRepository.java
浏览文件 @
a2dc6adb
package
com.dianping.cat.abtest.repository
;
import
java.net.InetSocketAddress
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
org.codehaus.plexus.logging.LogEnabled
;
import
org.codehaus.plexus.logging.Logger
;
import
org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable
;
import
org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException
;
import
org.codehaus.plexus.util.StringUtils
;
import
org.unidal.helper.Splitters
;
import
org.unidal.lookup.ContainerHolder
;
import
org.unidal.lookup.annotation.Inject
;
import
org.unidal.socket.MessageInboundHandler
;
import
org.unidal.socket.udp.UdpSocket
;
import
com.dianping.cat.Cat
;
import
com.dianping.cat.abtest.model.entity.AbtestModel
;
import
com.dianping.cat.abtest.model.entity.Case
;
import
com.dianping.cat.abtest.model.entity.Run
;
import
com.dianping.cat.abtest.model.transform.BaseVisitor
;
import
com.dianping.cat.abtest.model.transform.DefaultSaxParser
;
import
com.dianping.cat.abtest.spi.ABTestEntity
;
import
com.dianping.cat.abtest.spi.ABTestGroupStrategy
;
import
com.dianping.cat.configuration.ClientConfigManager
;
import
com.dianping.cat.message.Heartbeat
;
import
com.dianping.cat.message.Message
;
public
class
DefaultABTestEntityRepository
implements
ABTestEntityRepository
,
Initializable
{
public
class
DefaultABTestEntityRepository
extends
ContainerHolder
implements
ABTestEntityRepository
,
Initializable
,
LogEnabled
,
MessageInboundHandler
<
ProtocolMessage
>
{
@Inject
private
ClientConfigManager
m_configManager
;
@Inject
private
InetSocketAddress
m_address
=
new
InetSocketAddress
(
"228.0.0.3"
,
2283
);
@Inject
private
Logger
m_logger
;
private
UdpSocket
m_socket
;
private
String
m_domain
;
private
List
<
ABTestEntity
>
m_entities
=
new
ArrayList
<
ABTestEntity
>();
private
Map
<
Integer
,
ABTestEntity
>
m_entities
=
new
HashMap
<
Integer
,
ABTestEntity
>();
private
Map
<
String
,
ABTestGroupStrategy
>
m_strategies
=
new
HashMap
<
String
,
ABTestGroupStrategy
>();
@Override
public
List
<
ABTestEntity
>
getEntities
(
Date
from
,
Date
to
)
{
return
null
;
public
Map
<
Integer
,
ABTestEntity
>
getEntities
(
)
{
return
m_entities
;
}
@Override
public
void
initialize
()
throws
InitializationException
{
m_domain
=
m_configManager
.
getFirstDomain
().
getId
();
}
// for test purpose
void
setDomain
(
String
domain
)
{
m_domain
=
domain
;
}
@Override
public
void
start
()
{
m_socket
=
new
UdpSocket
();
m_socket
.
setName
(
"ABTest"
);
m_socket
.
setCodec
(
new
ProtocolMessageCodec
());
m_socket
.
onMessage
(
new
ProtocolHandler
()
);
m_socket
.
onMessage
(
this
);
m_socket
.
listenOn
(
m_address
);
System
.
out
.
println
(
"ABTestRepository init..."
);
ProtocolMessage
hi
=
new
ProtocolMessage
();
hi
.
setName
(
ProtocolNames
.
HI
);
hi
.
addHeader
(
ProtocolNames
.
HEARTBEAT
,
m_domain
);
m_socket
.
send
(
hi
);
}
public
void
setAddress
(
String
address
)
{
...
...
@@ -54,17 +89,94 @@ public class DefaultABTestEntityRepository implements ABTestEntityRepository, In
m_address
=
new
InetSocketAddress
(
host
,
Integer
.
parseInt
(
port
));
}
class
ProtocolHandler
implements
MessageInboundHandler
<
ProtocolMessage
>
{
@Override
public
void
handle
(
ProtocolMessage
message
)
{
String
name
=
message
.
getName
();
@Override
public
void
handle
(
ProtocolMessage
message
)
{
String
name
=
message
.
getName
();
if
(
ProtocolNames
.
HEARTBEAT
.
equalsIgnoreCase
(
name
))
{
Heartbeat
h
=
Cat
.
newHeartbeat
(
"abtest-heartbeat"
,
message
.
getName
());
// TODO .getFrom()
h
.
addData
(
message
.
toString
());
h
.
setStatus
(
Message
.
SUCCESS
);
h
.
complete
();
String
content
=
message
.
getContent
();
if
(
StringUtils
.
isNotBlank
(
content
))
{
try
{
AbtestModel
abtest
=
DefaultSaxParser
.
parse
(
content
);
ABTestVisitor
visitor
=
new
ABTestVisitor
(
m_domain
);
abtest
.
accept
(
visitor
);
//switch the entities
m_entities
=
visitor
.
getEntities
();
}
catch
(
Exception
e
)
{
Cat
.
logError
(
e
);
}
}
}
else
{
m_logger
.
warn
(
String
.
format
(
"Unknown command(%s) found in %s!"
,
name
,
message
));
}
}
if
(
"hi"
.
equals
(
name
))
{
}
else
if
(
"heartbeat"
.
equals
(
name
))
{
List
<
ABTestEntity
>
entities
=
new
ArrayList
<
ABTestEntity
>();
class
ABTestVisitor
extends
BaseVisitor
{
private
String
m_domain
;
private
Map
<
Integer
,
ABTestEntity
>
m_entities
;
public
ABTestVisitor
(
String
domain
)
{
m_domain
=
domain
;
m_entities
=
new
HashMap
<
Integer
,
ABTestEntity
>();
}
m_entities
=
entities
;
@Override
public
void
visitCase
(
Case
_case
)
{
for
(
Run
run
:
_case
.
getRuns
())
{
// filter abtest-entities by domain
if
(
run
.
getDomains
()
!=
null
&&
run
.
getDomains
().
contains
(
m_domain
))
{
ABTestEntity
entity
=
new
ABTestEntity
(
_case
,
run
);
String
strategyKey
=
String
.
format
(
"%s+%s+%s"
,
_case
.
getId
(),
entity
.
getGroupStrategyName
(),
entity
.
getGroupStrategyConfiguration
());
ABTestGroupStrategy
strategy
=
m_strategies
.
get
(
strategyKey
);
if
(
strategy
!=
null
)
{
entity
.
setGroupStrategy
(
strategy
);
}
else
{
try
{
strategy
=
lookup
(
ABTestGroupStrategy
.
class
,
entity
.
getGroupStrategyName
());
entity
.
setGroupStrategy
(
strategy
);
m_strategies
.
put
(
strategyKey
,
strategy
);
}
catch
(
Exception
e
)
{
Cat
.
logError
(
e
);
ABTestEntity
origin
=
DefaultABTestEntityRepository
.
this
.
m_entities
.
get
(
_case
.
getId
());
if
(
origin
!=
null
)
{
entity
=
origin
;
}
else
{
entity
.
setDisabled
(
true
);
}
}
}
m_entities
.
put
(
entity
.
getId
(),
entity
);
}
}
}
public
Map
<
Integer
,
ABTestEntity
>
getEntities
()
{
return
m_entities
;
}
}
@Override
public
void
enableLogging
(
Logger
logger
)
{
m_logger
=
logger
;
}
}
cat-core/src/main/java/com/dianping/cat/abtest/repository/ProtocolMessage.java
浏览文件 @
a2dc6adb
...
...
@@ -6,6 +6,11 @@ import java.util.Map;
import
org.unidal.socket.Message
;
public
class
ProtocolMessage
implements
Message
{
public
static
final
String
HELLO_NAME
=
"hello"
;
public
static
final
String
HEARTBEAT_NAME
=
"heartbeat"
;
private
String
m_name
;
private
String
m_content
;
...
...
@@ -15,6 +20,10 @@ public class ProtocolMessage implements Message {
public
String
getContent
()
{
return
m_content
;
}
public
void
addHeader
(
String
header
,
String
value
){
m_headers
.
put
(
header
,
value
);
}
public
Map
<
String
,
String
>
getHeaders
()
{
return
m_headers
;
...
...
cat-core/src/main/java/com/dianping/cat/abtest/repository/ProtocolNames.java
0 → 100644
浏览文件 @
a2dc6adb
package
com.dianping.cat.abtest.repository
;
public
class
ProtocolNames
{
// protocol method
public
static
final
String
HI
=
"hi"
;
public
static
final
String
HEARTBEAT
=
"heartbeat"
;
// protocol headers
public
static
final
String
DOMAIN
=
"domain"
;
}
cat-core/src/main/java/com/dianping/cat/abtest/spi/ABTestEntity.java
浏览文件 @
a2dc6adb
...
...
@@ -6,39 +6,37 @@ import com.dianping.cat.abtest.model.entity.Case;
import
com.dianping.cat.abtest.model.entity.Run
;
public
class
ABTestEntity
{
private
Case
m_case
;
private
int
m_id
;
private
String
m_name
;
private
String
m_groupStrategyName
;
private
Run
m_run
;
private
ABTestGroupStrategy
m_groupStrategy
;
public
ABTestEntity
()
{
m_case
=
new
Case
();
m_run
=
new
Run
();
m_run
.
setDisabled
(
true
);
}
public
ABTestEntity
(
Case
_case
,
Run
run
)
{
m_case
=
_case
;
m_id
=
_case
.
getId
();
m_name
=
_case
.
getName
();
m_groupStrategyName
=
_case
.
getGroupStrategy
();
m_run
=
run
;
}
public
String
getGroupStrategyName
()
{
return
m_
case
.
getGroupStrategy
()
!=
null
?
m_case
.
getGroupStrategy
()
:
null
;
return
m_
groupStrategyName
!=
null
?
m_groupStrategyName
:
null
;
}
public
String
getGroupStrategyConfiguration
()
{
return
m_run
.
getGroupStrategyConfiguration
()
!=
null
?
m_run
.
getGroupStrategyConfiguration
()
:
null
;
}
public
int
getId
()
{
return
m_case
.
getId
();
}
public
String
getName
()
{
return
m_case
.
getName
();
}
public
Date
getEndDate
()
{
return
m_run
.
getEndDate
();
}
...
...
@@ -77,56 +75,75 @@ public class ABTestEntity {
m_run
.
setDisabled
(
disabled
);
}
public
void
setGroupStrategyName
(
String
groupStrategy
)
{
m_case
.
setGroupStrategy
(
groupStrategy
)
;
public
ABTestGroupStrategy
getGroupStrategy
(
)
{
return
m_groupStrategy
;
}
public
void
setGroupStrategy
Configuration
(
String
groupStrategyConfiguration
)
{
m_
run
.
setGroupStrategyConfiguration
(
groupStrategyConfiguration
)
;
public
void
setGroupStrategy
(
ABTestGroupStrategy
groupStrategy
)
{
m_
groupStrategy
=
groupStrategy
;
}
public
void
setId
(
int
id
)
{
m_
case
.
setId
(
id
)
;
public
void
setId
(
int
id
){
m_
id
=
id
;
}
public
void
setName
(
String
name
)
{
m_case
.
setName
(
name
)
;
public
int
getId
(
)
{
return
m_id
;
}
public
ABTestGroupStrategy
getGroupStrategy
()
{
return
m_groupStrategy
;
}
public
String
getName
()
{
return
m_name
;
}
public
void
setGroupStrategy
(
ABTestGroupStrategy
groupStrategy
)
{
m_groupStrategy
=
groupStrategy
;
public
Run
getRun
(
)
{
return
m_run
;
}
@Override
public
String
toString
()
{
return
String
.
format
(
"%s[id=%s, name=%s, groupStrategy=%s, configuation=%s]"
,
getClass
().
getSimpleName
(),
getId
(),
getName
(),
getGroupStrategyName
(),
getGroupStrategyConfiguration
());
}
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
((
m_groupStrategyName
==
null
)
?
0
:
m_groupStrategyName
.
hashCode
());
result
=
prime
*
result
+
m_id
;
result
=
prime
*
result
+
((
m_name
==
null
)
?
0
:
m_name
.
hashCode
());
result
=
prime
*
result
+
((
m_run
==
null
)
?
0
:
m_run
.
hashCode
());
return
result
;
}
@Override
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
getId
();
return
result
;
}
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
ABTestEntity
other
=
(
ABTestEntity
)
obj
;
if
(
m_groupStrategyName
==
null
)
{
if
(
other
.
m_groupStrategyName
!=
null
)
return
false
;
}
else
if
(!
m_groupStrategyName
.
equals
(
other
.
m_groupStrategyName
))
return
false
;
if
(
m_id
!=
other
.
m_id
)
return
false
;
if
(
m_name
==
null
)
{
if
(
other
.
m_name
!=
null
)
return
false
;
}
else
if
(!
m_name
.
equals
(
other
.
m_name
))
return
false
;
if
(
m_run
==
null
)
{
if
(
other
.
m_run
!=
null
)
return
false
;
}
else
if
(!
m_run
.
equals
(
other
.
m_run
))
return
false
;
return
true
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
ABTestEntity
other
=
(
ABTestEntity
)
obj
;
if
(
getId
()
!=
other
.
getId
())
return
false
;
return
true
;
}
public
String
toString
()
{
return
"ABTestEntity [m_id="
+
m_id
+
", m_name="
+
m_name
+
", m_groupStrategyName="
+
m_groupStrategyName
+
", m_run="
+
m_run
+
"]"
;
}
}
\ No newline at end of file
cat-core/src/main/java/com/dianping/cat/abtest/spi/internal/ABTestEntityManager.java
浏览文件 @
a2dc6adb
...
...
@@ -6,6 +6,7 @@ import com.dianping.cat.abtest.ABTestId;
import
com.dianping.cat.abtest.spi.ABTestEntity
;
public
interface
ABTestEntityManager
{
public
ABTestEntity
getEntity
(
ABTestId
id
);
public
List
<
ABTestEntity
>
getEntityList
();
...
...
cat-core/src/main/java/com/dianping/cat/abtest/spi/internal/DefaultABTestContextManager.java
浏览文件 @
a2dc6adb
...
...
@@ -134,5 +134,4 @@ public class DefaultABTestContextManager extends ContainerHolder implements ABTe
m_req
=
req
;
}
}
}
cat-core/src/main/java/com/dianping/cat/abtest/spi/internal/DefaultABTestEntityManager.java
浏览文件 @
a2dc6adb
package
com.dianping.cat.abtest.spi.internal
;
import
java.io.InputStream
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable
;
import
org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException
;
import
org.unidal.lookup.ContainerHolder
;
import
org.unidal.lookup.annotation.Inject
;
import
com.dianping.cat.Cat
;
import
com.dianping.cat.abtest.ABTestId
;
import
com.dianping.cat.abtest.model.entity.AbtestModel
;
import
com.dianping.cat.abtest.model.entity.Case
;
import
com.dianping.cat.abtest.model.entity.Run
;
import
com.dianping.cat.abtest.model.transform.BaseVisitor
;
import
com.dianping.cat.abtest.model.transform.DefaultSaxParser
;
import
com.dianping.cat.abtest.repository.ABTestEntityRepository
;
import
com.dianping.cat.abtest.spi.ABTestEntity
;
import
com.dianping.cat.abtest.spi.ABTestGroupStrategy
;
public
class
DefaultABTestEntityManager
extends
ContainerHolder
implements
ABTestEntityManager
,
Initializable
{
private
Map
<
Integer
,
ABTestEntity
>
m_entities
=
new
HashMap
<
Integer
,
ABTestEntity
>();
private
List
<
ABTestEntity
>
m_entityList
=
new
ArrayList
<
ABTestEntity
>();
@Inject
private
ABTestEntityRepository
m_repository
;
@Override
public
ABTestEntity
getEntity
(
ABTestId
id
)
{
ABTestEntity
entity
=
m_
entities
.
get
(
id
.
getValue
());
ABTestEntity
entity
=
m_
repository
.
getEntities
()
.
get
(
id
.
getValue
());
if
(
entity
==
null
)
{
entity
=
new
ABTestEntity
();
entity
.
setId
(
id
.
getValue
());
entity
.
setDisabled
(
true
);
m_
entities
.
put
(
id
.
getValue
(),
entity
);
m_
repository
.
getEntities
()
.
put
(
id
.
getValue
(),
entity
);
}
return
entity
;
}
@Override
public
List
<
ABTestEntity
>
getEntityList
()
{
return
m_entityList
;
List
<
ABTestEntity
>
entitiesList
=
new
ArrayList
<
ABTestEntity
>();
for
(
ABTestEntity
entity
:
m_repository
.
getEntities
().
values
())
{
entitiesList
.
add
(
entity
);
}
return
entitiesList
;
}
@Override
public
void
initialize
()
throws
InitializationException
{
try
{
InputStream
in
=
getClass
().
getResourceAsStream
(
"abtest.xml"
);
AbtestModel
abtest
=
DefaultSaxParser
.
parse
(
in
);
ABTestVisitor
visitor
=
new
ABTestVisitor
(
m_entities
,
m_entityList
);
abtest
.
accept
(
visitor
);
for
(
ABTestEntity
entity
:
m_entityList
)
{
try
{
ABTestGroupStrategy
groupStrategy
=
lookup
(
ABTestGroupStrategy
.
class
,
entity
.
getGroupStrategyName
());
entity
.
setGroupStrategy
(
groupStrategy
);
}
catch
(
Exception
e
)
{
Cat
.
logError
(
e
);
entity
.
setDisabled
(
true
);
}
for
(
ABTestEntity
entity
:
m_repository
.
getEntities
().
values
())
{
try
{
ABTestGroupStrategy
groupStrategy
=
lookup
(
ABTestGroupStrategy
.
class
,
entity
.
getGroupStrategyName
());
entity
.
setGroupStrategy
(
groupStrategy
);
}
catch
(
Exception
e
)
{
Cat
.
logError
(
e
);
entity
.
setDisabled
(
true
);
}
}
catch
(
Exception
e
)
{
throw
new
InitializationException
(
"Error when loading resource(abtest.xml)!"
,
e
);
}
}
static
class
ABTestVisitor
extends
BaseVisitor
{
private
Map
<
Integer
,
ABTestEntity
>
m_entities
;
private
List
<
ABTestEntity
>
m_entityList
;
public
ABTestVisitor
(
Map
<
Integer
,
ABTestEntity
>
entities
,
List
<
ABTestEntity
>
entityList
)
{
m_entities
=
entities
;
m_entityList
=
entityList
;
}
@Override
public
void
visitCase
(
Case
_case
)
{
for
(
Run
run
:
_case
.
getRuns
())
{
ABTestEntity
abTestEntity
=
new
ABTestEntity
(
_case
,
run
);
m_entities
.
put
(
abTestEntity
.
getId
(),
abTestEntity
);
m_entityList
.
add
(
abTestEntity
);
}
}
}
}
\ No newline at end of file
cat-core/src/main/java/com/dianping/cat/build/ABTestComponentConfigurator.java
浏览文件 @
a2dc6adb
...
...
@@ -22,12 +22,13 @@ class ABTestComponentConfigurator extends AbstractResourceConfigurator {
all
.
add
(
C
(
ABTestContextManager
.
class
,
DefaultABTestContextManager
.
class
)
//
.
req
(
ABTestEntityManager
.
class
));
all
.
add
(
C
(
ABTestEntityManager
.
class
,
DefaultABTestEntityManager
.
class
));
all
.
add
(
C
(
ABTestEntityRepository
.
class
,
DefaultABTestEntityRepository
.
class
)
//
.
req
(
ClientConfigManager
.
class
)
//
.
config
(
E
(
"address"
).
value
(
"228.0.0.3:2283"
)));
all
.
add
(
C
(
ABTestEntityManager
.
class
,
DefaultABTestEntityManager
.
class
)
//
.
req
(
ABTestEntityRepository
.
class
));
return
all
;
}
}
cat-core/src/main/resources/META-INF/plexus/components.xml
浏览文件 @
a2dc6adb
...
...
@@ -312,12 +312,8 @@
</requirements>
</component>
<component>
<role>
com.dianping.cat.abtest.spi.internal.ABTestEntityManager
</role>
<implementation>
com.dianping.cat.abtest.spi.internal.DefaultABTestEntityManager
</implementation>
</component>
<component>
<role>
com.dianping.cat.abtest.spi.internal.ABTestEntityRepository
</role>
<implementation>
com.dianping.cat.abtest.spi.internal.DefaultABTestEntityRepository
</implementation>
<role>
com.dianping.cat.abtest.repository.ABTestEntityRepository
</role>
<implementation>
com.dianping.cat.abtest.repository.DefaultABTestEntityRepository
</implementation>
<configuration>
<address>
228.0.0.3:2283
</address>
</configuration>
...
...
@@ -325,9 +321,14 @@
<requirement>
<role>
com.dianping.cat.configuration.ClientConfigManager
</role>
</requirement>
</requirements>
</component>
<component>
<role>
com.dianping.cat.abtest.spi.internal.ABTestEntityManager
</role>
<implementation>
com.dianping.cat.abtest.spi.internal.DefaultABTestEntityManager
</implementation>
<requirements>
<requirement>
<role>
org.unidal.socket.udp.UdpSocket
</role>
<role-hint>
abtest
</role-hint>
<role>
com.dianping.cat.abtest.repository.ABTestEntityRepository
</role>
</requirement>
</requirements>
</component>
...
...
cat-core/src/test/java/com/dianping/cat/abtest/repository/ABTestRepositoryTest.java
0 → 100644
浏览文件 @
a2dc6adb
package
com.dianping.cat.abtest.repository
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.List
;
import
junit.framework.Assert
;
import
org.junit.Test
;
import
org.unidal.helper.Splitters
;
import
org.unidal.lookup.ComponentTestCase
;
import
com.dianping.cat.abtest.model.entity.AbtestModel
;
import
com.dianping.cat.abtest.model.entity.Case
;
import
com.dianping.cat.abtest.model.entity.Run
;
import
com.dianping.cat.abtest.spi.ABTestEntity
;
public
class
ABTestRepositoryTest
extends
ComponentTestCase
{
private
void
checkHandler
(
String
expected
,
String
...
keys
)
throws
Exception
{
DefaultABTestEntityRepository
repository
=
(
DefaultABTestEntityRepository
)
lookup
(
ABTestEntityRepository
.
class
);
ProtocolMessage
message
=
new
ProtocolMessage
();
repository
.
setDomain
(
"domain2"
);
message
.
setName
(
"heartbeat"
);
AbtestModel
abtest
=
new
AbtestModel
();
for
(
String
key
:
keys
)
{
List
<
String
>
parts
=
Splitters
.
by
(
':'
).
trim
().
split
(
key
);
int
index
=
0
;
int
id
=
Integer
.
parseInt
(
parts
.
get
(
index
++));
String
name
=
parts
.
get
(
index
++);
List
<
String
>
domains
=
Splitters
.
by
(
','
).
noEmptyItem
().
trim
().
split
(
parts
.
get
(
index
++));
Case
_case
=
new
Case
(
id
).
setName
(
name
);
_case
.
getDomains
().
addAll
(
domains
);
Run
run
=
new
Run
(
id
);
run
.
getDomains
().
addAll
(
domains
);
_case
.
addRun
(
run
);
abtest
.
addCase
(
_case
);
}
message
.
setContent
(
abtest
.
toString
());
repository
.
handle
(
message
);
StringBuilder
sb
=
new
StringBuilder
(
1024
);
List
<
ABTestEntity
>
values
=
new
ArrayList
<
ABTestEntity
>(
repository
.
getEntities
().
values
());
boolean
first
=
true
;
Collections
.
sort
(
values
,
new
Comparator
<
ABTestEntity
>()
{
@Override
public
int
compare
(
ABTestEntity
o1
,
ABTestEntity
o2
)
{
return
o1
.
getName
().
compareTo
(
o1
.
getName
());
}
});
for
(
ABTestEntity
entity
:
values
)
{
if
(
first
)
{
first
=
false
;
}
else
{
sb
.
append
(
','
);
}
sb
.
append
(
entity
.
getName
());
}
Assert
.
assertEquals
(
expected
,
sb
.
toString
());
}
@Test
public
void
testHandler
()
throws
Exception
{
checkHandler
(
"case2,case3"
,
"1:case1:domain1"
,
"2:case2:domain2"
,
"3:case3:domain2,domain3"
);
}
}
cat-core/src/test/java/com/dianping/cat/abtest/spi/internal/
Default
ABTestEntityManagerTest.java
→
cat-core/src/test/java/com/dianping/cat/abtest/spi/internal/ABTestEntityManagerTest.java
浏览文件 @
a2dc6adb
...
...
@@ -10,7 +10,7 @@ import org.unidal.lookup.ComponentTestCase;
import
com.dianping.cat.abtest.spi.ABTestEntity
;
public
class
Default
ABTestEntityManagerTest
extends
ComponentTestCase
{
public
class
ABTestEntityManagerTest
extends
ComponentTestCase
{
private
static
final
String
PATTERN
=
"yyyy-MM-dd hh:mm:ss"
;
...
...
cat-core/src/test/resources/com/dianping/cat/abtest/demo/annotation/heartbeat.xml
0 → 100644
浏览文件 @
a2dc6adb
<heartbeat>
<ip>
192.168.0.1
</ip>
<!-- 看看能不能主动获得IP -->
<domain>
tuangou
</domain>
<whoami>
client/server
</whoami>
<entities>
<entity
id=
"1001"
name=
"Mock1"
start-date=
"2013-04-10 17:00:00"
end-date=
"2013-12-30 18:00:00"
disabled=
"false"
>
<description>
This is a mock ABTest for test
</description>
<group-strategy
name=
"roundrobin"
>
<strategy-config>
<users>
<id>
1001
</id>
<id>
1002
</id>
<id></id>
</users>
<age>
<begin>
20
</begin>
<end>
40
</end>
</age>
<cookies>
<cookie>
cityId
</cookie>
<cookie>
gender
</cookie>
<cookie></cookie>
</cookies>
</strategy-config>
</group-strategy>
<domain>
Cat
</domain>
<domain>
TuanGouWeb
</domain>
</entity>
</entities>
<configuration>
<![CDATA[This is the configuration]]>
</configuration>
</heartbeat>
\ No newline at end of file
cat-core/src/test/resources/com/dianping/cat/abtest/demo/annotation/strategy-config.xml
0 → 100644
浏览文件 @
a2dc6adb
<strategy-config>
<users>
<id>
1001
</id>
<id>
1002
</id>
<id></id>
</users>
<age>
<begin>
20
</begin>
<end>
40
</end>
</age>
<cookies>
<cookie>
cityId
</cookie>
<cookie>
gender
</cookie>
<cookie></cookie>
</cookies>
</strategy-config>
\ No newline at end of file
cat-home/pom.xml
浏览文件 @
a2dc6adb
...
...
@@ -10,6 +10,11 @@
<name>
CAT Home
</name>
<packaging>
war
</packaging>
<dependencies>
<dependency>
<groupId>
org.unidal.framework
</groupId>
<artifactId>
foundation-service
</artifactId>
<version>
2.0.3-SNAPSHOT
</version>
</dependency>
<dependency>
<groupId>
com.dianping.cat
</groupId>
<artifactId>
cat-consumer
</artifactId>
...
...
cat-home/src/main/java/com/dianping/cat/CatHomeModule.java
浏览文件 @
a2dc6adb
...
...
@@ -21,14 +21,13 @@ import com.dianping.cat.system.alarm.threshold.listener.ServiceDataListener;
import
com.dianping.cat.system.alarm.threshold.listener.ThresholdAlertListener
;
import
com.dianping.cat.system.event.EventListenerRegistry
;
import
com.dianping.cat.system.notify.ScheduledMailTask
;
import
com.dianping.cat.system.page.abtest.server.ABTestEntityServer
;
public
class
CatHomeModule
extends
AbstractModule
{
public
static
final
String
ID
=
"cat-home"
;
@Override
protected
void
execute
(
ModuleContext
ctx
)
throws
Exception
{
// warm up IP seeker
// IPSeekerManager.initailize(new File(serverConfigManager.getStorageLocalBaseDir()));
ServerConfigManager
serverConfigManager
=
ctx
.
lookup
(
ServerConfigManager
.
class
);
ctx
.
lookup
(
MessageConsumer
.
class
,
"realtime"
);
...
...
@@ -42,9 +41,17 @@ public class CatHomeModule extends AbstractModule {
Threads
.
forGroup
(
"Cat"
).
start
(
dailyTaskProducer
);
}
executeAbtestModule
(
ctx
);
executeAlarmModule
(
ctx
);
}
private
void
executeAbtestModule
(
ModuleContext
ctx
)
{
ABTestEntityServer
server
=
ctx
.
lookup
(
ABTestEntityServer
.
class
);
server
.
start
();
}
private
void
executeAlarmModule
(
ModuleContext
ctx
)
throws
Exception
{
ServerConfigManager
serverConfigManager
=
ctx
.
lookup
(
ServerConfigManager
.
class
);
...
...
cat-home/src/main/java/com/dianping/cat/build/CatDatabaseConfigurator.java
浏览文件 @
a2dc6adb
...
...
@@ -11,7 +11,7 @@ final class CatDatabaseConfigurator extends AbstractJdbcResourceConfigurator {
public
List
<
Component
>
defineComponents
()
{
List
<
Component
>
all
=
new
ArrayList
<
Component
>();
all
.
add
(
defineJdbcDataSourceComponent
(
"cat"
,
"com.mysql.jdbc.Driver"
,
"jdbc:mysql://1
27.0.0.1:3306/cat"
,
"root"
,
"
"
,
"<![CDATA[useUnicode=true&autoReconnect=true]]>"
));
all
.
add
(
defineJdbcDataSourceComponent
(
"cat"
,
"com.mysql.jdbc.Driver"
,
"jdbc:mysql://1
92.168.7.43:3306/cat"
,
"binlog"
,
"binlog
"
,
"<![CDATA[useUnicode=true&autoReconnect=true]]>"
));
defineSimpleTableProviderComponents
(
all
,
"cat"
,
com
.
dianping
.
cat
.
home
.
dal
.
report
.
_INDEX
.
getEntityClasses
());
defineDaoComponents
(
all
,
com
.
dianping
.
cat
.
home
.
dal
.
report
.
_INDEX
.
getDaoClasses
());
...
...
cat-home/src/main/java/com/dianping/cat/build/ServiceComponentConfigurator.java
浏览文件 @
a2dc6adb
...
...
@@ -8,6 +8,9 @@ import org.unidal.lookup.configuration.Component;
import
com.dianping.cat.configuration.ServerConfigManager
;
import
com.dianping.cat.hadoop.hdfs.HdfsMessageBucketManager
;
import
com.dianping.cat.home.dal.abtest.AbtestDao
;
import
com.dianping.cat.home.dal.abtest.AbtestRunDao
;
import
com.dianping.cat.home.dal.abtest.GroupStrategyDao
;
import
com.dianping.cat.message.spi.MessageCodec
;
import
com.dianping.cat.message.spi.MessageConsumer
;
import
com.dianping.cat.report.page.model.cross.CompositeCrossService
;
...
...
@@ -51,6 +54,8 @@ import com.dianping.cat.report.service.ReportService;
import
com.dianping.cat.storage.BucketManager
;
import
com.dianping.cat.storage.dump.LocalMessageBucketManager
;
import
com.dianping.cat.storage.dump.MessageBucketManager
;
import
com.dianping.cat.system.page.abtest.server.ABTestEntityServer
;
import
com.dianping.cat.system.page.abtest.server.DefaultABTestEntityServer
;
class
ServiceComponentConfigurator
extends
AbstractResourceConfigurator
{
@Override
...
...
@@ -169,6 +174,11 @@ class ServiceComponentConfigurator extends AbstractResourceConfigurator {
.
req
(
ServerConfigManager
.
class
)
//
.
req
(
ModelService
.
class
,
new
String
[]
{
"message-historical"
,
"logview-historical"
},
"m_services"
));
all
.
add
(
C
(
ABTestEntityServer
.
class
,
DefaultABTestEntityServer
.
class
)
//
.
req
(
AbtestRunDao
.
class
)
//
.
req
(
AbtestDao
.
class
)
//
.
req
(
GroupStrategyDao
.
class
));
return
all
;
}
}
cat-home/src/main/java/com/dianping/cat/system/page/abtest/Handler.java
浏览文件 @
a2dc6adb
...
...
@@ -35,6 +35,7 @@ import com.dianping.cat.home.dal.abtest.GroupStrategyDao;
import
com.dianping.cat.home.dal.abtest.GroupStrategyEntity
;
import
com.dianping.cat.system.SystemPage
;
import
com.dianping.cat.system.page.abtest.Model.AbtestDaoModel
;
import
com.dianping.cat.system.page.abtest.server.ABTestEntityServer
;
public
class
Handler
implements
PageHandler
<
Context
>,
LogEnabled
{
...
...
@@ -59,6 +60,9 @@ public class Handler implements PageHandler<Context>, LogEnabled {
@Inject
private
GroupStrategyDao
m_groupStrategyDao
;
@Inject
private
ABTestEntityServer
abTestEntityServer
;
@Override
@PayloadMeta
(
Payload
.
class
)
@InboundActionMeta
(
name
=
"abtest"
)
...
...
@@ -94,16 +98,22 @@ public class Handler implements PageHandler<Context>, LogEnabled {
AbtestRun
run
=
new
AbtestRun
();
run
.
setCreator
(
payload
.
getOwner
());
run
.
setStartDate
(
payload
.
getStartDate
());
run
.
setEndDate
(
payload
.
getEndDate
());
run
.
setDomains
(
StringUtils
.
join
(
payload
.
getDomains
(),
','
));
run
.
setStrategyConfiguration
(
payload
.
getStrategyConfig
());
run
.
setDisabled
(
false
);
Date
now
=
new
Date
();
run
.
setCreationDate
(
now
);
run
.
setModifiedDate
(
now
);
try
{
m_abtestDao
.
insert
(
abtest
);
run
.
setCaseId
(
abtest
.
getId
());
m_abtestRunDao
.
insert
(
run
);
abTestEntityServer
.
sendHeartbeat
();
}
catch
(
DalException
e
)
{
m_logger
.
error
(
"Error when saving abtest"
,
e
);
Cat
.
logError
(
e
);
...
...
@@ -117,12 +127,18 @@ public class Handler implements PageHandler<Context>, LogEnabled {
run
.
setId
(
payload
.
getId
());
run
.
setKeyId
(
payload
.
getId
());
run
.
setCreator
(
payload
.
getOwner
());
run
.
setStartDate
(
payload
.
getStartDate
());
run
.
setEndDate
(
payload
.
getEndDate
());
run
.
setDomains
(
StringUtils
.
join
(
payload
.
getDomains
(),
','
));
run
.
setStrategyConfiguration
(
payload
.
getStrategyConfig
());
Date
now
=
new
Date
();
run
.
setModifiedDate
(
now
);
// only update run info, do not update abtest meta-info
m_abtestRunDao
.
updateByPK
(
run
,
AbtestRunEntity
.
UPDATESET_ALLOWED_MODIFYPART
);
abTestEntityServer
.
sendHeartbeat
();
}
catch
(
DalException
e
)
{
m_logger
.
error
(
"Error when updating abtest"
,
e
);
Cat
.
logError
(
e
);
...
...
@@ -156,6 +172,8 @@ public class Handler implements PageHandler<Context>, LogEnabled {
error
.
addArgument
(
id
,
"Abtest "
+
id
+
" has been already active!"
);
}
}
abTestEntityServer
.
sendHeartbeat
();
}
catch
(
NumberFormatException
e
)
{
// do nothing
Cat
.
logError
(
e
);
...
...
cat-home/src/main/java/com/dianping/cat/system/page/abtest/server/ABTestEntityServer.java
0 → 100644
浏览文件 @
a2dc6adb
package
com.dianping.cat.system.page.abtest.server
;
public
interface
ABTestEntityServer
{
void
start
();
void
sendHeartbeat
();
}
cat-home/src/main/java/com/dianping/cat/system/page/abtest/server/DefaultABTestEntityServer.java
0 → 100644
浏览文件 @
a2dc6adb
package
com.dianping.cat.system.page.abtest.server
;
import
java.net.InetSocketAddress
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Timer
;
import
java.util.TimerTask
;
import
org.apache.commons.lang.StringUtils
;
import
org.codehaus.plexus.logging.LogEnabled
;
import
org.codehaus.plexus.logging.Logger
;
import
org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable
;
import
org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException
;
import
org.unidal.dal.jdbc.DalException
;
import
org.unidal.helper.Splitters
;
import
org.unidal.lookup.annotation.Inject
;
import
org.unidal.socket.MessageInboundHandler
;
import
org.unidal.socket.udp.UdpSocket
;
import
com.dianping.cat.Cat
;
import
com.dianping.cat.abtest.model.entity.AbtestModel
;
import
com.dianping.cat.abtest.model.entity.Case
;
import
com.dianping.cat.abtest.model.entity.Run
;
import
com.dianping.cat.abtest.model.transform.DefaultXmlBuilder
;
import
com.dianping.cat.abtest.repository.ProtocolMessage
;
import
com.dianping.cat.abtest.repository.ProtocolMessageCodec
;
import
com.dianping.cat.abtest.repository.ProtocolNames
;
import
com.dianping.cat.home.dal.abtest.Abtest
;
import
com.dianping.cat.home.dal.abtest.AbtestDao
;
import
com.dianping.cat.home.dal.abtest.AbtestEntity
;
import
com.dianping.cat.home.dal.abtest.AbtestRun
;
import
com.dianping.cat.home.dal.abtest.AbtestRunDao
;
import
com.dianping.cat.home.dal.abtest.AbtestRunEntity
;
import
com.dianping.cat.home.dal.abtest.GroupStrategy
;
import
com.dianping.cat.home.dal.abtest.GroupStrategyDao
;
import
com.dianping.cat.home.dal.abtest.GroupStrategyEntity
;
import
com.dianping.cat.system.page.abtest.AbtestStatus
;
/**
* send heartbeat(传输ABTestModel) every interval time.<br>
* receive hello from client, and reply heartbeat.<br>
* 一个case如果有多个run,只发当前最接近的一个run(不能多个run,cleint以caseId为key存储run的,所以client也只需一个run即可) server发送的run,是当前+最近即将生效的run(构建成ABTestModel来传输)。
*
* @author wukezhu
*/
public
class
DefaultABTestEntityServer
implements
ABTestEntityServer
,
Initializable
,
LogEnabled
{
private
static
final
String
MULTICAST_ADDRESS
=
"228.0.0.3"
;
private
static
final
int
MULTICAST_PORT
=
2283
;
private
static
final
int
MINUTE_PERIOD
=
60
*
1000
;
private
Logger
m_logger
;
@Inject
private
AbtestRunDao
m_abtestRunDao
;
@Inject
private
AbtestDao
abtestDao
;
@Inject
private
GroupStrategyDao
groupStrategyDao
;
@Inject
private
InetSocketAddress
m_address
=
new
InetSocketAddress
(
MULTICAST_ADDRESS
,
MULTICAST_PORT
);
private
UdpSocket
m_socket
;
private
Timer
m_timer
=
new
Timer
();
public
DefaultABTestEntityServer
()
{
super
();
}
@Override
public
void
initialize
()
throws
InitializationException
{
m_logger
.
info
(
"ABTest Server initing."
);
m_socket
=
new
UdpSocket
();
m_socket
.
setName
(
"ABTest"
);
m_socket
.
setCodec
(
new
ProtocolMessageCodec
());
m_socket
.
onMessage
(
new
ProtocolHandler
());
m_logger
.
info
(
"ABTest Server inited"
);
}
@Override
public
void
start
()
{
m_socket
.
listenOn
(
m_address
);
// TODO 参考 com.dianping.cat.status.StatusUpdateTask 使用Thread代替TimerTask
// 启动heartbeatTask任务
HeartbeatTask
heartbeatTask
=
new
HeartbeatTask
();
m_timer
.
schedule
(
heartbeatTask
,
0
,
MINUTE_PERIOD
);
}
public
void
setAddress
(
String
address
)
{
List
<
String
>
parts
=
Splitters
.
by
(
':'
).
trim
().
split
(
address
);
int
len
=
parts
.
size
();
int
index
=
0
;
String
host
=
len
>
index
?
parts
.
get
(
index
++)
:
MULTICAST_ADDRESS
;
int
port
=
len
>
index
?
Integer
.
parseInt
(
parts
.
get
(
index
++))
:
MULTICAST_PORT
;
m_address
=
new
InetSocketAddress
(
host
,
port
);
}
private
AbtestModel
fetchAbtestModel
()
{
try
{
AbtestModel
abtestModel
=
new
AbtestModel
();
List
<
AbtestRun
>
abtestRuns
=
m_abtestRunDao
.
findAll
(
AbtestRunEntity
.
READSET_FULL
);
if
(
abtestRuns
!=
null
)
{
Date
now
=
new
Date
();
for
(
AbtestRun
abtestRun
:
abtestRuns
)
{
AbtestStatus
status
=
AbtestStatus
.
calculateStatus
(
abtestRun
,
now
);
if
(
status
==
AbtestStatus
.
READY
||
status
==
AbtestStatus
.
RUNNING
)
{
// fetch Case and GroupStrategy
int
caseId
=
abtestRun
.
getCaseId
();
Abtest
entity
=
abtestDao
.
findByPK
(
caseId
,
AbtestEntity
.
READSET_FULL
);
int
gid
=
entity
.
getGroupStrategy
();
GroupStrategy
groupStrategy
=
groupStrategyDao
.
findByPK
(
gid
,
GroupStrategyEntity
.
READSET_FULL
);
Case
_case
=
transform
(
abtestRun
,
entity
,
groupStrategy
);
abtestModel
.
addCase
(
_case
);
}
}
}
return
abtestModel
;
}
catch
(
DalException
e
)
{
m_logger
.
error
(
"Error when find all AbtestRun"
,
e
);
Cat
.
logError
(
e
);
}
return
null
;
}
private
Case
transform
(
AbtestRun
abtestRun
,
Abtest
entity
,
GroupStrategy
groupStrategy
)
throws
DalException
{
Case
_case
=
new
Case
(
entity
.
getId
());
_case
.
setCreatedDate
(
entity
.
getCreationDate
());
_case
.
setDescription
(
entity
.
getDescription
());
_case
.
setGroupStrategy
(
groupStrategy
.
getName
());
_case
.
setName
(
entity
.
getName
());
_case
.
setOwner
(
entity
.
getOwner
());
_case
.
setLastModifiedDate
(
entity
.
getModifiedDate
());
for
(
String
domain
:
StringUtils
.
split
(
entity
.
getDomains
(),
','
))
{
_case
.
addDomain
(
domain
);
}
Run
run
=
new
Run
(
abtestRun
.
getId
());
for
(
String
domain
:
StringUtils
.
split
(
abtestRun
.
getDomains
(),
','
))
{
run
.
addDomain
(
domain
);
}
run
.
setCreator
(
abtestRun
.
getCreator
());
run
.
setDisabled
(
false
);
run
.
setEndDate
(
abtestRun
.
getEndDate
());
run
.
setGroupStrategyConfiguration
(
abtestRun
.
getStrategyConfiguration
());
run
.
setStartDate
(
abtestRun
.
getStartDate
());
_case
.
addRun
(
run
);
return
_case
;
}
class
HeartbeatTask
extends
TimerTask
{
@Override
public
void
run
()
{
sendHeartbeat
();
}
}
class
ProtocolHandler
implements
MessageInboundHandler
<
ProtocolMessage
>
{
@Override
public
void
handle
(
ProtocolMessage
message
)
{
String
name
=
message
.
getName
();
if
(
m_logger
.
isDebugEnabled
())
{
m_logger
.
debug
(
"Receive Message:"
+
message
);
}
if
(
ProtocolNames
.
HI
.
equals
(
name
))
{
sendHeartbeat
();
}
}
}
@Override
public
void
enableLogging
(
Logger
logger
)
{
m_logger
=
logger
;
}
@Override
public
void
sendHeartbeat
()
{
AbtestModel
abtestModel
=
fetchAbtestModel
();
if
(
abtestModel
!=
null
)
{
ProtocolMessage
message
=
new
ProtocolMessage
();
message
.
setName
(
ProtocolNames
.
HEARTBEAT
);
String
content
=
new
DefaultXmlBuilder
().
buildXml
(
abtestModel
);
message
.
setContent
(
content
);
m_socket
.
send
(
message
);
m_logger
.
info
(
"send heartbeat:"
+
message
);
}
else
{
m_logger
.
info
(
"send heartbeat: no abtest, so nothing to send."
);
}
}
}
cat-home/src/main/resources/META-INF/dal/jdbc/report-codegen.xml
浏览文件 @
a2dc6adb
...
...
@@ -4,7 +4,7 @@
<member
name=
"id"
field=
"id"
value-type=
"int"
length=
"10"
nullable=
"false"
key=
"true"
auto-increment=
"true"
/>
<member
name=
"name"
field=
"name"
value-type=
"String"
length=
"20"
nullable=
"false"
/>
<member
name=
"ip"
field=
"ip"
value-type=
"String"
length=
"20"
/>
<member
name=
"domain"
field=
"domain"
value-type=
"String"
length=
"
5
0"
nullable=
"false"
/>
<member
name=
"domain"
field=
"domain"
value-type=
"String"
length=
"
20
0"
nullable=
"false"
/>
<member
name=
"period"
field=
"period"
value-type=
"Date"
nullable=
"false"
/>
<member
name=
"type"
field=
"type"
value-type=
"int"
length=
"3"
nullable=
"false"
/>
<member
name=
"detail-content"
field=
"detail_content"
value-type=
"String"
length=
"16777215"
nullable=
"false"
/>
...
...
@@ -50,11 +50,12 @@
<member
name=
"domain"
field=
"domain"
value-type=
"String"
length=
"50"
nullable=
"false"
/>
<member
name=
"period"
field=
"period"
value-type=
"Date"
nullable=
"false"
/>
<member
name=
"type"
field=
"type"
value-type=
"int"
length=
"3"
nullable=
"false"
/>
<member
name=
"content"
field=
"content"
value-type=
"String"
length=
"
16777215
"
nullable=
"false"
/>
<member
name=
"content"
field=
"content"
value-type=
"String"
length=
"
2147483647
"
nullable=
"false"
/>
<member
name=
"creation-date"
field=
"creation_date"
value-type=
"Date"
nullable=
"false"
/>
<var
name=
"key-id"
value-type=
"int"
key-member=
"id"
/>
<primary-key
name=
"PRIMARY"
members=
"id"
/>
<index
name=
"period"
unique=
"true"
members=
"period ASC, domain ASC, name ASC"
/>
<index
name=
"period_column"
members=
"period ASC"
/>
<readsets>
<readset
name=
"FULL"
all=
"true"
/>
</readsets>
...
...
@@ -89,7 +90,7 @@
<member
name=
"id"
field=
"id"
value-type=
"int"
length=
"10"
nullable=
"false"
key=
"true"
auto-increment=
"true"
/>
<member
name=
"name"
field=
"name"
value-type=
"String"
length=
"20"
nullable=
"false"
/>
<member
name=
"ip"
field=
"ip"
value-type=
"String"
length=
"20"
/>
<member
name=
"domain"
field=
"domain"
value-type=
"String"
length=
"
5
0"
nullable=
"false"
/>
<member
name=
"domain"
field=
"domain"
value-type=
"String"
length=
"
20
0"
nullable=
"false"
/>
<member
name=
"period"
field=
"period"
value-type=
"Date"
nullable=
"false"
/>
<member
name=
"type"
field=
"type"
value-type=
"int"
length=
"3"
nullable=
"false"
/>
<member
name=
"detail-content"
field=
"detail_content"
value-type=
"String"
length=
"16777215"
nullable=
"false"
/>
...
...
@@ -172,10 +173,10 @@
<member
name=
"id"
field=
"id"
value-type=
"int"
length=
"10"
nullable=
"false"
key=
"true"
auto-increment=
"true"
/>
<member
name=
"name"
field=
"name"
value-type=
"String"
length=
"20"
nullable=
"false"
/>
<member
name=
"ip"
field=
"ip"
value-type=
"String"
length=
"20"
nullable=
"false"
/>
<member
name=
"domain"
field=
"domain"
value-type=
"String"
length=
"50"
nullable=
"false"
/>
<member
name=
"domain"
field=
"domain"
value-type=
"String"
length=
"50"
/>
<member
name=
"period"
field=
"period"
value-type=
"Date"
nullable=
"false"
/>
<member
name=
"type"
field=
"type"
value-type=
"int"
length=
"3"
nullable=
"false"
/>
<member
name=
"content"
field=
"content"
value-type=
"String"
length=
"
16777215"
nullable=
"false
"
/>
<member
name=
"content"
field=
"content"
value-type=
"String"
length=
"
2147483647
"
/>
<member
name=
"creation-date"
field=
"creation_date"
value-type=
"Date"
nullable=
"false"
/>
<var
name=
"key-id"
value-type=
"int"
key-member=
"id"
/>
<primary-key
name=
"PRIMARY"
members=
"id"
/>
...
...
@@ -214,7 +215,7 @@
<member
name=
"id"
field=
"id"
value-type=
"int"
length=
"10"
nullable=
"false"
key=
"true"
auto-increment=
"true"
/>
<member
name=
"name"
field=
"name"
value-type=
"String"
length=
"20"
nullable=
"false"
/>
<member
name=
"ip"
field=
"ip"
value-type=
"String"
length=
"20"
nullable=
"false"
/>
<member
name=
"domain"
field=
"domain"
value-type=
"String"
length=
"50"
nullable=
"false"
/>
<member
name=
"domain"
field=
"domain"
value-type=
"String"
length=
"50"
/>
<member
name=
"period"
field=
"period"
value-type=
"Date"
nullable=
"false"
/>
<member
name=
"type"
field=
"type"
value-type=
"int"
length=
"3"
nullable=
"false"
/>
<member
name=
"content"
field=
"content"
value-type=
"String"
length=
"16777215"
nullable=
"false"
/>
...
...
cat-home/src/main/resources/META-INF/plexus/components.xml
浏览文件 @
a2dc6adb
...
...
@@ -1141,6 +1141,21 @@
</requirement>
</requirements>
</component>
<component>
<role>
com.dianping.cat.system.page.abtest.server.ABTestEntityServer
</role>
<implementation>
com.dianping.cat.system.page.abtest.server.DefaultABTestEntityServer
</implementation>
<requirements>
<requirement>
<role>
com.dianping.cat.home.dal.abtest.AbtestRunDao
</role>
</requirement>
<requirement>
<role>
com.dianping.cat.home.dal.abtest.AbtestDao
</role>
</requirement>
<requirement>
<role>
com.dianping.cat.home.dal.abtest.GroupStrategyDao
</role>
</requirement>
</requirements>
</component>
<component>
<role>
org.unidal.dal.jdbc.datasource.JdbcDataSourceConfigurationManager
</role>
<implementation>
org.unidal.dal.jdbc.datasource.JdbcDataSourceConfigurationManager
</implementation>
...
...
@@ -1160,9 +1175,9 @@
<statement-cache-size>
1000
</statement-cache-size>
<properties>
<driver>
com.mysql.jdbc.Driver
</driver>
<URL>
jdbc:mysql://1
27.0.0.1
:3306/cat
</URL>
<user>
root
</user>
<password></password>
<URL>
jdbc:mysql://1
92.168.7.43
:3306/cat
</URL>
<user>
binlog
</user>
<password>
binlog
</password>
<connectionProperties>
<![CDATA[useUnicode=true&autoReconnect=true]]>
</connectionProperties>
</properties>
</configuration>
...
...
@@ -3171,6 +3186,9 @@
<requirement>
<role>
com.dianping.cat.home.dal.abtest.GroupStrategyDao
</role>
</requirement>
<requirement>
<role>
com.dianping.cat.system.page.abtest.server.ABTestEntityServer
</role>
</requirement>
</requirements>
</component>
<component>
...
...
cat-home/src/main/resources/META-INF/wizard/jdbc/wizard.xml
浏览文件 @
a2dc6adb
...
...
@@ -3,9 +3,9 @@
<jdbc
package=
"com.dianping.cat.home.dal"
name=
"cat"
>
<datasource>
<driver>
com.mysql.jdbc.Driver
</driver>
<url>
jdbc:mysql://1
27.0.0.1
:3306/cat
</url>
<user>
root
</user>
<password></password>
<url>
jdbc:mysql://1
92.168.7.43
:3306/cat
</url>
<user>
binlog
</user>
<password>
binlog
</password>
<properties>
useUnicode=true
&
autoReconnect=true
</properties>
</datasource>
<group
name=
"report"
package=
"com.dianping.cat.home.dal.report"
>
...
...
cat-home/src/main/webapp/jsp/system/abtestAllTest.jsp
浏览文件 @
a2dc6adb
...
...
@@ -158,11 +158,14 @@
<thead>
<tr
class=
"centerth"
>
<th
width=
"1%"
></th>
<th
width=
"6%"
>
ID
</th>
<th>
Name
</th>
<th>
PV
</th>
<th>
ConversionRate
</th>
<th
style=
"display: none;"
width=
"8%"
>
Case's ID
</th>
<th
width=
"8%"
>
Case's ID
</th>
<th>
Name
</th>
<th>
Domain
</th>
<th>
Start Time
</th>
<th>
End Time
</th>
<th>
Status
</th>
<th>
Creator
</th>
<th>
Created On
</th>
</tr>
</thead>
...
...
@@ -170,10 +173,12 @@
<c:forEach
var=
"item"
items=
"
${
model
.
reports
}
"
>
<tr
class=
"middle center rowlink"
>
<td
class=
"nolink"
style=
"padding-bottom: 8px"
><input
type=
"checkbox"
/></td>
<td><a
href=
"abtest?op=report&id=${item.run.id}"
>
${item.run.id}
</a></td>
<td
style=
"display: none;"
><a
href=
"abtest?op=report&id=${item.run.id}"
>
${item.run.id}
</a></td>
<td><span
class=
"badge badge-success"
><a
href=
"abtest?op=report&id=${item.run.id}"
>
${item.run.caseId}
</a></span></td>
<td>
${item.entity.name}
</td>
<td>
1000
</td>
<td>
10%
</td>
<td>
${item.run.domains}
</td>
<td><fmt:formatDate
pattern=
"yyyy-MM-dd hh:mm"
value=
"
${
item
.
run
.
startDate
}
"
/></td>
<td><fmt:formatDate
pattern=
"yyyy-MM-dd hh:mm"
value=
"
${
item
.
run
.
endDate
}
"
/></td>
<td>
<c:choose>
<c:when
test=
"
${
item
.
status
.
status
eq
'created'
}
"
>
...
...
@@ -203,7 +208,8 @@
</c:when>
</c:choose>
</td>
<td>
Apr 1, 2013
</td>
<td>
${item.run.creator}
</td>
<td><fmt:formatDate
pattern=
"yyyy-MM-dd hh:mm"
value=
"
${
item
.
run
.
startDate
}
"
/></td>
</tr>
</c:forEach>
</tbody>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录