Skip to content

Commit

Permalink
Merge pull request #1 from diegopacheco/dev
Browse files Browse the repository at this point in the history
Cluster Failover check and REST API
  • Loading branch information
diegopacheco committed Sep 15, 2016
2 parents 5371b96 + af8bd5e commit f462d6f
Show file tree
Hide file tree
Showing 12 changed files with 451 additions and 289 deletions.
412 changes: 174 additions & 238 deletions README.md

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions dynomite-cluster-checker/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-jedis/1.4.6/915579ab9b61eda22c25ff20a854dc38dd27555a/dyno-jedis-1.4.6-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-jedis/1.4.6/ccecef6c157bb98e472049ef6b705c36e15019de/dyno-jedis-1.4.6.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/javax.servlet/servlet-api/2.5/21599814ad9a605b86f3e6381571beccd861a32/servlet-api-2.5-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/javax.servlet/servlet-api/2.5/5959582d97d8b61f4d154ca9e495aafd16726e34/servlet-api-2.5.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-jedis/1.4.7/7a9b9fd04d7b2d59c59dae14fa9536463de3a2d1/dyno-jedis-1.4.7-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-jedis/1.4.7/57d8d80d76ead546b0570ee80108d5fdf4a3816c/dyno-jedis-1.4.7.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/joda-time/joda-time/2.3/ecd8588d8ce0963eb443de31d5fea29e3205f160/joda-time-2.3-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/joda-time/joda-time/2.3/56498efd17752898cfcc3868c1b6211a07b12b8f/joda-time-2.3.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/1.7.21/f285ac123f201fb4b028bac556928d7cf527ef48/slf4j-api-1.7.21-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/1.7.21/139535a69a4239db087de9bab0bee568bf8e0b70/slf4j-api-1.7.21.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-log4j12/1.7.21/16b1333786ea93d16bff6fb0f5e3b82716d1b008/slf4j-log4j12-1.7.21-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-log4j12/1.7.21/7238b064d1aba20da2ac03217d700d91e02460fa/slf4j-log4j12-1.7.21.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/com.googlecode.json-simple/json-simple/1.1/19c6d8dee6803c520d855ff7e8a8c3d97f1271ec/json-simple-1.1-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/com.googlecode.json-simple/json-simple/1.1/5e303a03d04e6788dddfa3655272580ae0fc13bb/json-simple-1.1.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/org.apache.httpcomponents/httpclient/4.2.1/6b27312b9c28b59aaeb6c21f3490045690c703d3/httpclient-4.2.1-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/org.apache.httpcomponents/httpclient/4.2.1/b69bd03af60bf487b3ae1209a644ecac587bf6fc/httpclient-4.2.1.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/com.sun.jersey/jersey-core/1.11/c5988ad1aa736b1d2754bfebe056d373baaf6aea/jersey-core-1.11-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/com.sun.jersey/jersey-core/1.11/2e39ffa15505559507888c439f720d3d38c06fd4/jersey-core-1.11.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-core/1.4.6/6ed3b48f0a50b648096e088a6a019e9a43454b80/dyno-core-1.4.6-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-core/1.4.6/8732fa47db1a17ca67ecd11a13df14c4941c88c7/dyno-core-1.4.6.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-contrib/1.4.6/85a868f0f0c515ab72ac70cfa69880fa625173e/dyno-contrib-1.4.6-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-contrib/1.4.6/a279de8937581a780fb9da2933df54aa4fd0e62d/dyno-contrib-1.4.6.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-core/1.4.7/953d1c9cf4081006d186d832130bcf2449c2be1f/dyno-core-1.4.7-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-core/1.4.7/2ea0e88fa3e5a5fa33e92c837a32eca8c60f5ee/dyno-core-1.4.7.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-contrib/1.4.7/95f27651d840912c0143072c227c6cd1a2bf959c/dyno-contrib-1.4.7-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/com.netflix.dyno/dyno-contrib/1.4.7/7107647fc1bf803f8ea9ac8287c874dbb71d0e6f/dyno-contrib-1.4.7.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/redis.clients/jedis/2.8.1/508eb6a4d5ed2e350a68b77b11487cb5e8048e9e/jedis-2.8.1-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/redis.clients/jedis/2.8.1/1fb5ad5e5d56c3998441dbc9054df4fd302e25bd/jedis-2.8.1.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/log4j/log4j/1.2.17/677abe279b68c5e7490d6d50c6951376238d7d3e/log4j-1.2.17-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/log4j/log4j/1.2.17/5af35056b4d257e4b64b9e8069c0746e8b08629f/log4j-1.2.17.jar" exported="true"/>
<classpathentry sourcepath="/home/diego/.gradle/caches/modules-2/files-2.1/org.apache.httpcomponents/httpcore/4.2.1/3f6caf5334fa83607b82e2f32dd128a9d8a0ea5e/httpcore-4.2.1-sources.jar" kind="lib" path="/home/diego/.gradle/caches/modules-2/files-2.1/org.apache.httpcomponents/httpcore/4.2.1/2d503272bf0a8b5f92d64db78b4ba9abbaccc6fd/httpcore-4.2.1.jar" exported="true"/>
Expand Down
14 changes: 12 additions & 2 deletions dynomite-cluster-checker/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'application'
apply plugin: 'eclipse'
apply plugin: 'jetty'

version = '1.0'
sourceCompatibility = 1.8
Expand Down Expand Up @@ -42,10 +43,19 @@ eclipse {

dependencies {
compile([
'com.netflix.dyno:dyno-jedis:1.4.6'
'javax.servlet:servlet-api:2.5',
'org.slf4j:slf4j-simple:1.7.21'
])

compile('com.netflix.dyno:dyno-jedis:1.4.7'){
exclude group: 'org.slf4j', module: 'slf4j-api'
}
}

httpPort = 7766
stopPort = 7765
stopKey = "stopKey"

jar {
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {
exclude "META-INF/*.SF"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void cleanUp(){
setGetTime(null);
setConsistency(false);
}

public String toJson(){
return "{" +
"\"server\":\"" + server + "\"," +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,25 @@
*/
public class DynomiteClusterCheckerMain {

private static final StringBuffer bufferdLogger = new StringBuffer();
private static final List<CheckerResponse> clusterResponses = new ArrayList<>();
private StringBuffer bufferdLogger = new StringBuffer();
private ResultReport resultReport = new ResultReport();

public static void main(String[] args) throws Throwable {
public static void main(String[] args){
DynomiteClusterCheckerMain dcc = new DynomiteClusterCheckerMain();
dcc.run(args[0]);
}

public String run(String seeds){

resultReport.setNodesReport(new ArrayList<>());
CheckerResponse checkerResponse = new CheckerResponse();

bufferedLogInfo("");
bufferedLogInfo("**** BEGIN DYNOMITE CLUSTER CHECKER ****");
bufferedLogInfo("1. Checking cluster connection... ");

List<DynomiteNodeInfo> nodes = DynomiteSeedsParser.parse(args[0]);
List<DynomiteNodeInfo> validNodes = checkAllNodes("dyn_o_mite", nodes);
List<DynomiteNodeInfo> nodes = DynomiteSeedsParser.parse(seeds);
List<DynomiteNodeInfo> validNodes = checkAllNodes(DynomiteConfig.CLUSTER_NAME, nodes);
List<DynomiteNodeInfo> badNodes = Lists.newArrayList(nodes);
badNodes.removeAll(validNodes);

Expand All @@ -48,65 +54,72 @@ public static void main(String[] args) throws Throwable {
if (validNodes==null || validNodes.size()<=0){
bufferedLogInfo("2. Cannot check data replication since there are no valid nodes");
}else{
cleanUp("dyn_o_mite",validNodes);
cleanUp(DynomiteConfig.CLUSTER_NAME,validNodes);

bufferedLogInfo("2. Checking cluster data replication... ");
bufferedLogInfo("SEEDS: " + validNodes.toString());
checkerResponse.setSeeds(validNodes.toString());

checkNode(true,validNodes.get(0),validNodes.get(0).getServer(),checkerResponse);
clusterResponses.add(checkerResponse);
resultReport.getNodesReport().add(checkerResponse);

List<DynomiteNodeInfo> otherSeeds = Lists.newArrayList(validNodes);
otherSeeds.remove(0);
if (otherSeeds.size() >= 1){
for(DynomiteNodeInfo node : otherSeeds){
checkerResponse = new CheckerResponse();
checkNode(false,node,node.getServer(),checkerResponse);
clusterResponses.add(checkerResponse);
resultReport.getNodesReport().add(checkerResponse);
}
}

bufferedLogInfo("3. Checking cluster failover... ");
String failoverStatus = checkClusterFailOver(DynomiteConfig.CLUSTER_NAME,nodes);
resultReport.setFailoverStatus(failoverStatus);
bufferedLogInfo("All Seeds Cluster Failover test: " + failoverStatus);

}

bufferedLogInfo("3. Shwoing Results as JSON... ");
bufferedLogInfo(ListJsonPrinter.print(clusterResponses));
bufferedLogInfo("4. Shwoing Results as JSON... ");
String jsonResult = ListJsonPrinter.print(resultReport);
bufferedLogInfo(jsonResult);
bufferedLogInfo("**** END DYNOMITE CLUSTER CHECKER ****");
bufferedLogPrint();

cleanUp("dyn_o_mite",validNodes);
System.exit(0);
cleanUp(DynomiteConfig.CLUSTER_NAME,validNodes);
return jsonResult;
}

private static void checkNode(boolean primary,DynomiteNodeInfo node ,String server,CheckerResponse checkerResponse) {
private void checkNode(boolean primary,DynomiteNodeInfo node ,String server,CheckerResponse checkerResponse) {
checkerResponse.setServer(node.getServer());
bufferedLogInfo("Checking Node: " + checkerResponse.getServer());

if(primary)
insert(KeysConfig.TEST_KEY, KeysConfig.TEST_VALUE, "dyn_o_mite",node,checkerResponse);
insert(DynomiteConfig.TEST_KEY, DynomiteConfig.TEST_VALUE, DynomiteConfig.CLUSTER_NAME,node,checkerResponse);

String result = get(KeysConfig.TEST_KEY, "dyn_o_mite",node,checkerResponse);
if(KeysConfig.TEST_VALUE.equals(result)){
String result = get(DynomiteConfig.TEST_KEY, DynomiteConfig.CLUSTER_NAME,node,checkerResponse);
if(DynomiteConfig.TEST_VALUE.equals(result)){
checkerResponse.setConsistency(true);
bufferedLogInfo(" 200 OK - set/get working fine!");
}else{
checkerResponse.setConsistency(false);
bufferedLogInfo(" ERROR - Inconsistency set/get! Set: " + KeysConfig.TEST_KEY + "Get: " + result);
bufferedLogInfo(" ERROR - Inconsistency set/get! Set: " + DynomiteConfig.TEST_KEY + "Get: " + result);
}
}

private static void bufferedLogInfo(String msg){
private void bufferedLogInfo(String msg){
bufferdLogger.append(msg + "\r\n");
}

private static void bufferedLogPrint(){
private void bufferedLogPrint(){
System.out.println(bufferdLogger.toString());
}

private static List<DynomiteNodeInfo> checkAllNodes(String clusterName,List<DynomiteNodeInfo> nodes){
private List<DynomiteNodeInfo> checkAllNodes(String clusterName,List<DynomiteNodeInfo> nodes){
List<DynomiteNodeInfo> validNodes = new ArrayList<>();
for(DynomiteNodeInfo node : nodes){
try{
DynoJedisClient cluster = DynomiteClusterConnectionManager.createCluster(clusterName,node);
DynoJedisClient cluster = DynomiteClusterConnectionManager.createSingleNodeCluster(clusterName,node);
cluster.get("awesomeSbrubles");
cluster.stopClient();
validNodes.add(node);
Expand All @@ -117,21 +130,38 @@ private static List<DynomiteNodeInfo> checkAllNodes(String clusterName,List<Dyno
return validNodes;
}

private static void cleanUp(String clusterName,List<DynomiteNodeInfo> seeds) throws Throwable {
private void cleanUp(String clusterName,List<DynomiteNodeInfo> seeds){
for(DynomiteNodeInfo node : seeds){
try{
DynoJedisClient cluster = DynomiteClusterConnectionManager.createCluster(clusterName,node);
cluster.del(KeysConfig.TEST_KEY);
DynoJedisClient cluster = DynomiteClusterConnectionManager.createSingleNodeCluster(clusterName,node);
cluster.del(DynomiteConfig.TEST_KEY);
cluster.stopClient();
}catch(Exception e){
System.out.println("Could not clean up cluster: " + clusterName + " Node: " + node);
}
}
}

private static void insert(String key,String value,String clusterName,DynomiteNodeInfo node,CheckerResponse checkerResponse) {
private String checkClusterFailOver(String clusterName,List<DynomiteNodeInfo> nodes){
try{
DynoJedisClient cluster = DynomiteClusterConnectionManager.createCluster(clusterName,nodes);
cluster.set(DynomiteConfig.TEST_FAILOVER_KEY, DynomiteConfig.TEST_FAILOVER_VALUE);
Thread.sleep(2000);
String result = cluster.get(DynomiteConfig.TEST_FAILOVER_KEY);
cluster.del(DynomiteConfig.TEST_FAILOVER_KEY);
cluster.stopClient();
if (result == null || ("".equals(result)) || (!DynomiteConfig.TEST_FAILOVER_VALUE.equals(result)) )
return "FAIL: get value missmatch! Expected: " + DynomiteConfig.TEST_FAILOVER_VALUE + " GOT: " + result;
}catch(Exception e){
System.out.println("Could not Connet on Cluster: " + nodes + " EX: " + e);
return "FAIL: " + e.getMessage();
}
return "OK";
}

private void insert(String key,String value,String clusterName,DynomiteNodeInfo node,CheckerResponse checkerResponse) {
try{
DynoJedisClient cluster = DynomiteClusterConnectionManager.createCluster(clusterName,node);
DynoJedisClient cluster = DynomiteClusterConnectionManager.createSingleNodeCluster(clusterName,node);
double init = System.currentTimeMillis();
cluster.set(key, value);
double end = System.currentTimeMillis();
Expand All @@ -144,9 +174,9 @@ private static void insert(String key,String value,String clusterName,DynomiteNo
}
}

private static String get(String key,String clusterName,DynomiteNodeInfo node,CheckerResponse checkerResponse) {
private String get(String key,String clusterName,DynomiteNodeInfo node,CheckerResponse checkerResponse) {
try{
DynoJedisClient cluster = DynomiteClusterConnectionManager.createCluster(clusterName,node);
DynoJedisClient cluster = DynomiteClusterConnectionManager.createSingleNodeCluster(clusterName,node);
double init = System.currentTimeMillis();
String result = cluster.get(key);
double end = System.currentTimeMillis();
Expand All @@ -161,7 +191,7 @@ private static String get(String key,String clusterName,DynomiteNodeInfo node,Ch
}
}

private static void printBench(String msg,double init, double end){
private void printBench(String msg,double init, double end){
int seconds = (int) ((end - init) / 1000) % 60 ;
bufferedLogInfo(" TIME to " + msg + ": " + (end - init) + " ms - " + seconds + " s" );
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.github.diegopacheco.dynomite.cluster.checker;

public class DynomiteConfig {

public static String CLUSTER_NAME = "dyn_o_mite";
public static String CLIENT_NAME = "DynomiteClusterChecker";

public static String TEST_KEY = "DCC_dynomite_123_kt";
public static String TEST_VALUE = "DCC_replication_works";

public static String TEST_FAILOVER_KEY = "DCC_dynomite_failoiverk";
public static String TEST_FAILOVER_VALUE = "DCC_dynomite_failoiver_works";
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.github.diegopacheco.dynomite.cluster.checker;

import java.util.List;

public class ResultReport {

private String failoverStatus;
private List<CheckerResponse> nodesReport;

public ResultReport() {}

public String getFailoverStatus() {
return failoverStatus;
}
public void setFailoverStatus(String failoverStatus) {
this.failoverStatus = failoverStatus;
}

public List<CheckerResponse> getNodesReport() {
return nodesReport;
}
public void setNodesReport(List<CheckerResponse> nodesReport) {
this.nodesReport = nodesReport;
}


@Override
public String toString() {
return "ResultReport [failoverStatus=" + failoverStatus + ", nodesReport=" + nodesReport + "]";
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((failoverStatus == null) ? 0 : failoverStatus.hashCode());
result = prime * result + ((nodesReport == null) ? 0 : nodesReport.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ResultReport other = (ResultReport) obj;
if (failoverStatus == null) {
if (other.failoverStatus != null)
return false;
} else if (!failoverStatus.equals(other.failoverStatus))
return false;
if (nodesReport == null) {
if (other.nodesReport != null)
return false;
} else if (!nodesReport.equals(other.nodesReport))
return false;
return true;
}

}
Loading

0 comments on commit f462d6f

Please sign in to comment.