Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nodetool over REST #121

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "scylla-jmx"]
path = scylla-jmx
url = [email protected]:scylladb/scylla-jmx.git
branch = master
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we avoid submodules + build?
The cassandra build.xml has support for fetching maven dependencies. We should use this with a local maven repo (easy to set up in jenkins).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had this talk with Pekka and all repos need to build (ideally) independently + we are not publishing maven artifacts from scylla-jmx and there is no plan for our own maven server
so I guess this could be solved by pushing all consumable artifacts from scylla-jmx to maven repos and having a proper scylla-jmx release cycle ... but since this doesn't make sense and is extra work we ended up deciding that submodule will be the easiest thing to do

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can easily have automatic maven repo generation in jenkins via the maven-repo plugin. Would literally be 5 minutes work to set up for our maven projects.

46 changes: 45 additions & 1 deletion build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
<property name="build.src.gen-java" value="${basedir}/src/gen-java"/>
<property name="build.lib" value="${basedir}/lib"/>
<property name="build.dir" value="${basedir}/build"/>
<property name="build.scylla-jmx-parent" value="${basedir}/scylla-jmx/scylla-jmx-parent/"/>
<property name="build.scylla-apiclient" value="${basedir}/scylla-jmx/scylla-apiclient/target"/>
<property name="build.dir.lib" value="${basedir}/build/lib"/>
<property name="build.test.dir" value="${build.dir}/test"/>
<property name="build.classes" value="${build.dir}/classes"/>
Expand Down Expand Up @@ -166,6 +168,11 @@
<exclude name="**/*-sources.jar"/>
<exclude name="**/ant-*.jar"/>
</fileset>
<fileset dir="${build.scylla-apiclient}">
<include name="**/scylla-apiclient*.jar" />
<exclude name="**/*-sources.jar"/>
<exclude name="**/ant-*.jar"/>
</fileset>
</path>

<macrodef name="create-javadoc">
Expand Down Expand Up @@ -453,6 +460,18 @@
<dependency groupId="com.github.ben-manes.caffeine" artifactId="caffeine" version="2.2.6" />
<dependency groupId="org.jctools" artifactId="jctools-core" version="1.2.1"/>
<dependency groupId="org.ow2.asm" artifactId="asm" version="5.0.4" />

<dependency groupId="org.glassfish.jersey.core" artifactId="jersey-common" version="2.22.1" />
<dependency groupId="javax.ws.rs" artifactId="javax.ws.rs-api" version="2.0.1" />
<dependency groupId="javax.ws.rs" artifactId="jsr311-api" version="1.1.1" />
<dependency groupId="org.glassfish.jersey.core" artifactId="jersey-client" version="2.22.1" />
<dependency groupId="org.glassfish" artifactId="javax.json" version="1.0.4" />
<dependency groupId="javax.activation" artifactId="activation" version="1.1" />
<dependency groupId="com.google.collections" artifactId="google-collections" version="1.0" />
<dependency groupId="javax.activation" artifactId="activation" version="1.1" />
<dependency groupId="javax.annotation" artifactId="javax.annotation-api" version="1.2" />
<dependency groupId="org.glassfish.jersey.bundles.repackaged" artifactId="jersey-guava" version="2.22.1" />

</dependencyManagement>
<developer id="adelapena" name="Andres de la Peña"/>
<developer id="alakshman" name="Avinash Lakshman"/>
Expand Down Expand Up @@ -641,6 +660,18 @@
<dependency groupId="com.github.ben-manes.caffeine" artifactId="caffeine" />
<dependency groupId="org.jctools" artifactId="jctools-core"/>
<dependency groupId="org.ow2.asm" artifactId="asm" />

<dependency groupId="org.glassfish.jersey.core" artifactId="jersey-common" version="2.22.1" />
<dependency groupId="javax.ws.rs" artifactId="javax.ws.rs-api" version="2.0.1" />
<dependency groupId="javax.ws.rs" artifactId="jsr311-api" version="1.1.1" />
<dependency groupId="org.glassfish.jersey.core" artifactId="jersey-client" version="2.22.1" />
<dependency groupId="org.glassfish" artifactId="javax.json" version="1.0.4" />
<dependency groupId="javax.activation" artifactId="activation" version="1.1" />
<dependency groupId="com.google.collections" artifactId="google-collections" version="1.0" />
<dependency groupId="javax.activation" artifactId="activation" version="1.1" />
<dependency groupId="javax.annotation" artifactId="javax.annotation-api" version="1.2" />
<dependency groupId="org.glassfish.jersey.bundles.repackaged" artifactId="jersey-guava" version="2.22.1" />

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good. Maven deps.
But why are some (also maven avail) files binaries below?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ant and local run, it still expects libraries to be copied to lib properly (so above code is only published to exported maven poms, not really used locally :-( )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be easy enough to use the maven fetch to add stuff to class path... Or simply add all maven deps to compile class path?

</artifact:pom>
<artifact:pom id="thrift-pom"
artifactId="cassandra-thrift"
Expand Down Expand Up @@ -816,7 +847,7 @@
depends="maven-ant-tasks-retrieve-build,build-project" description="Compile Cassandra classes"/>
<target name="codecoverage" depends="jacoco-run,jacoco-report" description="Create code coverage report"/>

<target depends="init,gen-cql3-grammar,generate-cql-html,generate-jflex-java"
<target depends="init,gen-cql3-grammar,generate-cql-html,generate-jflex-java,mvn-scylla-apiclient-jar"
name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<!-- Order matters! -->
Expand Down Expand Up @@ -1054,6 +1085,17 @@
</jar>
</target>

<target name="mvn-scylla-apiclient-jar">
<artifact:mvn mavenVersion="${maven.version}" pom="${build.scylla-jmx-parent}/pom.xml">
<arg value="-pl"/>
<arg value=":scylla-apiclient"/>
<arg value="package"/>
</artifact:mvn>
<copy todir="${build.lib}">
<fileset dir="${build.scylla-apiclient}" includes="*.jar"/>
</copy>
</target>

<!-- creates release tarballs -->
<target name="artifacts" depends="jar,javadoc,gen-doc"
description="Create Cassandra release artifacts">
Expand All @@ -1069,6 +1111,7 @@
<include name="${final.scylla-tools.name}.jar" />
<include name="${ant.project.name}-thrift-${version}.jar" />
</fileset>
<fileset dir="${build.scylla-apiclient}" includes="*.jar"/>
</copy>
<copy todir="${dist.dir}/javadoc">
<fileset dir="${javadoc.dir}"/>
Expand Down Expand Up @@ -1216,6 +1259,7 @@
<include name="commons*.jar"/>
</zipgroupfileset>
<zipgroupfileset dir="${build.lib}" includes="*.jar"/>
<zipgroupfileset dir="${build.scylla-apiclient}" includes="*.jar"/>
</jar>
<jar jarfile="${build.test.dir}/benchmarks.jar">
<manifest>
Expand Down
Binary file added lib/hk2-api-2.4.0-b31.jar
Binary file not shown.
Binary file added lib/hk2-locator-2.4.0-b31.jar
Binary file not shown.
Binary file added lib/hk2-utils-2.4.0-b31.jar
Binary file not shown.
Binary file added lib/jackson-annotations-2.9.9.jar
Binary file not shown.
Binary file added lib/jackson-core-2.9.9.jar
Binary file not shown.
Binary file added lib/jackson-databind-2.9.9.jar
Binary file not shown.
Binary file added lib/jackson-jaxrs-base-2.9.9.jar
Binary file not shown.
Binary file added lib/jackson-jaxrs-json-provider-2.9.9.jar
Binary file not shown.
Binary file added lib/jackson-module-jaxb-annotations-2.9.9.jar
Binary file not shown.
Binary file added lib/javax.annotation-api-1.2.jar
Binary file not shown.
Binary file added lib/javax.inject-2.4.0-b31.jar
Binary file not shown.
Binary file added lib/javax.json-1.0.4.jar
Binary file not shown.
Binary file added lib/javax.json-api-1.0.jar
Binary file not shown.
Binary file added lib/javax.ws.rs-api-2.0.1.jar
Binary file not shown.
Binary file added lib/jersey-client-2.22.1.jar
Binary file not shown.
Binary file added lib/jersey-common-2.22.1.jar
Binary file not shown.
Binary file added lib/jersey-guava-2.22.1.jar
Binary file not shown.
Binary file added lib/jsr305-2.0.2.jar
Binary file not shown.
Binary file added lib/jsr311-api-1.1.1.jar
Binary file not shown.
Binary file added lib/scylla-apiclient-1.0.jar
Binary file not shown.
1 change: 1 addition & 0 deletions scylla-jmx
Submodule scylla-jmx added at 04ea3a
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
*/
package org.apache.cassandra.db.compaction;

import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.management.openmbean.*;
import java.util.Map;
import java.util.UUID;
Expand Down Expand Up @@ -82,4 +84,35 @@ public static TabularData from(UntypedResultSet resultSet) throws OpenDataExcept
}
return result;
}

public static TabularData from(JsonArray resultSet) throws OpenDataException {
TabularDataSupport result = new TabularDataSupport(TABULAR_TYPE);
for (int i = 0; i < resultSet.size(); i++) {
JsonObject row = resultSet.getJsonObject(i);
String id = row.getString("id");
String ksName = row.getString("ks");
String cfName = row.getString("cf");
long compactedAt = row.getJsonNumber("compacted_at").longValue();
long bytesIn = row.getJsonNumber("bytes_in").longValue();
long bytesOut = row.getJsonNumber("bytes_out").longValue();

JsonArray merged = row.getJsonArray("rows_merged");
StringBuilder sb = new StringBuilder();
if (merged != null) {
sb.append('{');
for (int m = 0; m < merged.size(); m++) {
JsonObject entry = merged.getJsonObject(m);
if (m > 0) {
sb.append(',');
}
sb.append(entry.getString("key")).append(':').append(entry.getString("value"));

}
sb.append('}');
}
result.put(new CompositeDataSupport(COMPOSITE_TYPE, ITEM_NAMES,
new Object[] { id, ksName, cfName, compactedAt, bytesIn, bytesOut, sb.toString() }));
}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.db.compaction;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.TabularData;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;

import org.apache.cassandra.metrics.CompactionMetrics;

import com.scylladb.jmx.api.APIClient;

/**
* A singleton which manages a private executor of ongoing compactions.
* <p/>
* Scheduling for compaction is accomplished by swapping sstables to be
* compacted into a set via DataTracker. New scheduling attempts will ignore
* currently compacting sstables.
*/

/*
* Copyright 2015 Cloudius Systems
*
* Modified by Cloudius Systems
*/
public class ScyllaCompactionManager implements CompactionManagerMBean {
public static final String MBEAN_OBJECT_NAME = "org.apache.cassandra.db:type=CompactionManager";
private static final Logger logger = Logger.getLogger(CompactionManager.class.getName());
protected final APIClient client;

public void log(String str) {
logger.finest(str);
}

public ScyllaCompactionManager(APIClient client) {
this.client=client;
// super(MBEAN_OBJECT_NAME, client, new CompactionMetrics());
}

/** List of running compaction objects. */
@Override
public List<Map<String, String>> getCompactions() {
log(" getCompactions()");
List<Map<String, String>> results = new ArrayList<Map<String, String>>();
JsonArray compactions = client.getJsonArray("compaction_manager/compactions");
for (int i = 0; i < compactions.size(); i++) {
JsonObject compaction = compactions.getJsonObject(i);
Map<String, String> result = new HashMap<String, String>();
result.put("total", Long.toString(compaction.getJsonNumber("total").longValue()));
result.put("completed", Long.toString(compaction.getJsonNumber("completed").longValue()));
result.put("taskType", compaction.getString("task_type"));
result.put("keyspace", compaction.getString("ks"));
result.put("columnfamily", compaction.getString("cf"));
result.put("unit", compaction.getString("unit"));
result.put("compactionId", "<none>");
results.add(result);
}
return results;
}

/** List of running compaction summary strings. */
@Override
public List<String> getCompactionSummary() {
log(" getCompactionSummary()");
return client.getListStrValue("compaction_manager/compaction_summary");
}

/** compaction history **/
@Override
public TabularData getCompactionHistory() {
log(" getCompactionHistory()");
try {
return CompactionHistoryTabularData.from(client.getJsonArray("/compaction_manager/compaction_history"));
} catch (OpenDataException e) {
return null;
}
}

/**
* Triggers the compaction of user specified sstables. You can specify files
* from various keyspaces and columnfamilies. If you do so, user defined
* compaction is performed several times to the groups of files in the same
* keyspace/columnfamily.
*
* @param dataFiles
* a comma separated list of sstable file to compact. must
* contain keyspace and columnfamily name in path(for 2.1+) or
* file name itself.
*/
@Override
public void forceUserDefinedCompaction(String dataFiles) {
log(" forceUserDefinedCompaction(String dataFiles)");
MultivaluedMap<String, String> queryParams = new MultivaluedHashMap<String, String>();
queryParams.add("dataFiles", dataFiles);
client.post("compaction_manager/force_user_defined_compaction", queryParams);
}

@Override
public void forceUserDefinedCleanup(String dataFiles) {
//TODO fix add this
}

/**
* Stop all running compaction-like tasks having the provided {@code type}.
*
* @param type
* the type of compaction to stop. Can be one of: - COMPACTION -
* VALIDATION - CLEANUP - SCRUB - INDEX_BUILD
*/
@Override
public void stopCompaction(String type) {
log(" stopCompaction(String type)");
MultivaluedMap<String, String> queryParams = new MultivaluedHashMap<String, String>();
queryParams.add("type", type);
client.post("compaction_manager/stop_compaction", queryParams);
}

/**
* Returns core size of compaction thread pool
*/
@Override
public int getCoreCompactorThreads() {
log(" getCoreCompactorThreads()");
return client.getIntValue("");
}

/**
* Allows user to resize maximum size of the compaction thread pool.
*
* @param number
* New maximum of compaction threads
*/
@Override
public void setCoreCompactorThreads(int number) {
log(" setCoreCompactorThreads(int number)");
}

/**
* Returns maximum size of compaction thread pool
*/
@Override
public int getMaximumCompactorThreads() {
log(" getMaximumCompactorThreads()");
return client.getIntValue("");
}

/**
* Allows user to resize maximum size of the compaction thread pool.
*
* @param number
* New maximum of compaction threads
*/
@Override
public void setMaximumCompactorThreads(int number) {
log(" setMaximumCompactorThreads(int number)");
}

/**
* Returns core size of validation thread pool
*/
@Override
public int getCoreValidationThreads() {
log(" getCoreValidationThreads()");
return client.getIntValue("");
}

/**
* Allows user to resize maximum size of the compaction thread pool.
*
* @param number
* New maximum of compaction threads
*/
@Override
public void setCoreValidationThreads(int number) {
log(" setCoreValidationThreads(int number)");
}

/**
* Returns size of validator thread pool
*/
@Override
public int getMaximumValidatorThreads() {
log(" getMaximumValidatorThreads()");
return client.getIntValue("");
}

/**
* Allows user to resize maximum size of the validator thread pool.
*
* @param number
* New maximum of validator threads
*/
@Override
public void setMaximumValidatorThreads(int number) {
log(" setMaximumValidatorThreads(int number)");
}

@Override
public void stopCompactionById(String compactionId) {
// scylla does not have neither compaction ids nor the file described
// in:
// "Ids can be found in the transaction log files whose name starts with
// compaction_, located in the table transactions folder"
// (nodetool)
// TODO: throw?
log(" stopCompactionById");
}
}
Loading