Compare commits

...
23 Commits
Author SHA1 Message Date
Jim Klucar ce8e90b9e3 Merge branch 'ws_grafana' of github.com:NationalSecurityAgency/timely into ws_grafana 2016-08-25 10:49:43 -04:00
Jim Klucar ace99a2a50 websocket test working 2016-08-25 10:45:11 -04:00
Jim Klucar 860ec8ae3b rebuild of latest changes 2016-08-05 11:29:47 -04:00
Jim Klucar a8d68b73ec removed ssl options 2016-08-05 11:29:47 -04:00
Jim Klucar d4d43fd2eb fixed JAVA_HOME, removed ssl options 2016-08-05 11:29:47 -04:00
Jim Klucar 8ca9465739 removed obsolete redirect option 2016-08-05 11:29:47 -04:00
klucar 6af56d47b5 websocket demo skeleton 2016-08-05 11:29:47 -04:00
klucar e0334448d2 testing websocket from Grafana, getting cookie from document 2016-08-05 11:29:47 -04:00
Jim Klucar 019c5789ce fixed bug where timely.ssl.trust.store.file property is defined but is empty string 2016-08-05 11:27:43 -04:00
klucar 4336defc14 docker update version 2016-08-05 07:45:56 -04:00
klucar 712a2100bb added instances to metrics 2016-08-05 07:44:57 -04:00
klucar 6f5cd8c447 added instances to metrics 2016-08-05 07:43:49 -04:00
klucar 81e19fbe98 docker update version 2016-08-05 07:43:24 -04:00
klucar 1b1458ac6c websocket demo skeleton 2016-08-03 13:58:20 -04:00
klucar d2dd773268 testing websocket from Grafana, getting cookie from document 2016-08-03 13:58:20 -04:00
klucar bc46f54604 updated to 0.0.3-SNAPSHOT 2016-08-03 13:54:42 -04:00
Dave Marion 1b713e7874 re #56: fixed some scanner handling, log messages 2016-08-02 10:38:25 -04:00
Dave Marion 3f5dfd2219 fixes #56: Added a Netty handler in the web socket pipeline to get the TSESSIONID cookie value before the web socket upgrade and store it in the channel attribute map. Replaced sessionId property on subscription objects with subscriptionId, which will now allow multiple subscriptions per channel. Modified MetricResponse to contain the subscriptionId in the returned data. Updated tests and example. 2016-08-02 09:29:49 -04:00
Dave Marion ea707fda42 fixes #57, moved plugin/dependency versions to parent pom 2016-08-01 13:02:29 -04:00
klucar b245be476a fixed display name of dashboard 2016-07-28 09:25:24 -04:00
klucar 9619530814 making dashboards available for #59 2016-07-28 09:23:21 -04:00
klucar adf617e59f First cut at #59 2016-07-28 09:20:05 -04:00
Dave Marion 3f49855840 Set version to 0.0.3-SNAPSHOT 2016-07-27 08:23:50 -04:00
61 changed files with 17456 additions and 819 deletions

No files matched your search

+1 -36
View File
@@ -4,21 +4,17 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</version>
<version>0.0.3-SNAPSHOT</version>
</parent>
<artifactId>collectd-nsq-plugin</artifactId>
<dependencies>
<dependency>
<groupId>collectd</groupId>
<artifactId>collectd-api</artifactId>
<version>5.5.1</version>
<scope>system</scope>
<systemPath>${collectd-api-jar}</systemPath>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.1</version>
</dependency>
<dependency>
<groupId>timely</groupId>
@@ -56,7 +52,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<artifactSet>
<includes>
@@ -77,7 +72,6 @@
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>0.5.2</version>
<configuration>
<configFile>${project.parent.basedir}/eclipse/Eclipse-Formatter.xml</configFile>
<lineEnding>LF</lineEnding>
@@ -92,34 +86,5 @@
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<versionRange>[0.5.2,)</versionRange>
<goals>
<goal>format</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
+1 -37
View File
@@ -4,21 +4,17 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</version>
<version>0.0.3-SNAPSHOT</version>
</parent>
<artifactId>collectd-plugin-parent</artifactId>
<dependencies>
<dependency>
<groupId>collectd</groupId>
<artifactId>collectd-api</artifactId>
<version>5.5.1</version>
<scope>system</scope>
<systemPath>${collectd-api-jar}</systemPath>
</dependency>
<dependency>
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -29,7 +25,6 @@
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-easymock-release-full</artifactId>
<version>1.6.4</version>
<classifier>full</classifier>
<scope>test</scope>
</dependency>
@@ -64,7 +59,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<excludedGroups>timely.test.IntegrationTest</excludedGroups>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
@@ -73,7 +67,6 @@
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>0.5.2</version>
<configuration>
<configFile>${project.parent.basedir}/eclipse/Eclipse-Formatter.xml</configFile>
<lineEnding>LF</lineEnding>
@@ -88,34 +81,5 @@
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<versionRange>[0.5.2,)</versionRange>
<goals>
<goal>format</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
+1 -38
View File
@@ -4,21 +4,17 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</version>
<version>0.0.3-SNAPSHOT</version>
</parent>
<artifactId>collectd-timely-plugin</artifactId>
<dependencies>
<dependency>
<groupId>collectd</groupId>
<artifactId>collectd-api</artifactId>
<version>5.5.1</version>
<scope>system</scope>
<systemPath>${collectd-api-jar}</systemPath>
</dependency>
<dependency>
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -34,7 +30,6 @@
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-easymock-release-full</artifactId>
<version>1.6.4</version>
<classifier>full</classifier>
<scope>test</scope>
</dependency>
@@ -75,7 +70,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<artifactSet>
<includes>
@@ -96,7 +90,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<excludedGroups>timely.test.IntegrationTest</excludedGroups>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
@@ -105,7 +98,6 @@
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>0.5.2</version>
<configuration>
<configFile>${project.parent.basedir}/eclipse/Eclipse-Formatter.xml</configFile>
<lineEnding>LF</lineEnding>
@@ -120,34 +112,5 @@
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<versionRange>[0.5.2,)</versionRange>
<goals>
<goal>format</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
+1 -2
View File
@@ -4,14 +4,13 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</version>
<version>0.0.3-SNAPSHOT</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>assemble</id>
+8 -3
View File
@@ -108,9 +108,7 @@ System.register(['lodash'], function (_export, _context) {
switch (response.status) {
case 200:
var cookie = (document.cookie.match(/^(?:.*;)?TSESSIONID=([^;]+)(?:.*)?$/) || [, null])[1];
console.log(cookie);
console.log(document.cookie);
console.log(this.getCookie('TSESSIONID'));
this.fetching.status = 'success';
this.fetching.title = 'Login successful';
@@ -126,6 +124,13 @@ System.register(['lodash'], function (_export, _context) {
if (r.readyState != 4 || r.status != 200) return;
alert("Success: " + r.getResponseHeader('Set-Cookie'));
}
}, {
key: 'getCookie',
value: function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
}, {
key: '_getURI',
value: function _getURI(jsonData) {
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../../src/components/auths.js"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAO,O;;;;;;;;;;;;;;;;;;;;;2BAEM,S;AAEX,2BAAY,UAAZ,EAAwB,UAAxB,EAAoC,QAApC,EAA6C;AAAA;;AAC3C,eAAK,UAAL,GAAkB,UAAlB;AACA,eAAK,QAAL,GAAgB,QAAhB;AACA,eAAK,UAAL,GAAkB,UAAlB;AACD;;;;gCAEK,U,EAAW;AACf,iBAAK,QAAL,GAAgB,EAAhB;AACA,iBAAK,QAAL,CAAc,IAAd,GAAqB,KAArB;AACA,iBAAK,QAAL,CAAc,IAAd,GAAqB,IAArB;AACA,iBAAK,QAAL,CAAc,MAAd,GAAuB,SAAvB;AACA,iBAAK,QAAL,CAAc,KAAd,GAAsB,mBAAtB;;AAEA;AACA;AACA;;AAEA,gBAAI,MAAM,KAAK,OAAL,CAAa,WAAW,QAAxB,CAAV;;AAEA,gBAAG,WAAW,QAAX,CAAoB,UAAvB,EAAkC;AAChC,kBAAI,KAAK,aAAL,IAAsB,KAAK,iBAA/B,EAAiD;AAC/C,oBAAI,WAAW,EAAC,UAAU,KAAK,aAAhB,EAA+B,UAAU,KAAK,iBAA9C,EAAf;AACA,qBAAK,WAAL,CAAiB,GAAjB,EAAsB,QAAtB;AACD,eAHD,MAGO;AACL,qBAAK,UAAL,CAAgB,QAAhB,CAAyB,eAAzB,EAA0C,CAAC,WAAW,IAAZ,EAAkB,wBAAlB,CAA1C;AACA,qBAAK,QAAL,CAAc,MAAd,GAAuB,SAAvB;AACA,qBAAK,QAAL,CAAc,KAAd,GAAsB,wBAAtB;;AAEA;AACD;AACF,aAXD,MAWO;AACL,mBAAK,UAAL,CAAgB,GAAhB;AACD;AAEF;;;sCAEW,G,EAAK,Q,EAAS;AACxB,iBAAK,KAAL,CAAW,MAAX,EAAmB,GAAnB,EAAwB,QAAxB;AACD;;;qCAEU,G,EAAI;AACb,iBAAK,KAAL,CAAW,KAAX,EAAkB,GAAlB;AACD;;;gCAEK,I,EAAM,G,EAAK,I,EAAK;AACpB,gBAAI,CAAC,IAAL,EAAU;AACR,qBAAO,EAAP;AACD;AACD,gBAAI,IAAI,IAAI,cAAJ,EAAR;AACA,cAAE,IAAF,CAAO,IAAP,EAAa,GAAb,EAAkB,IAAlB;AACA,cAAE,eAAF,GAAoB,IAApB;AACA,cAAE,gBAAF,CAAmB,cAAnB,EAAmC,kBAAnC;AACA,cAAE,kBAAF,GAAuB,YAAY;AACjC,mBAAK,iBAAL,CAAuB,CAAvB;AACD,aAFsB,CAErB,IAFqB,CAEhB,IAFgB,CAAvB;AAGA,cAAE,IAAF,CAAO,KAAK,SAAL,CAAe,IAAf,CAAP;AACD;;;4CAEiB,Q,EAAS;AACzB;AACA,gBAAI,SAAS,UAAT,IAAuB,CAA3B,EAA8B;;AAE9B,iBAAK,QAAL,CAAc,IAAd,GAAqB,IAArB;;AAEA,oBAAO,SAAS,MAAhB;AACE,mBAAK,GAAL;AACE,oBAAI,SAAS,CAAC,SAAS,MAAT,CAAgB,KAAhB,CAAsB,qCAAtB,KAA8D,GAAE,IAAF,CAA/D,EAAwE,CAAxE,CAAb;AACA,wBAAQ,GAAR,CAAY,MAAZ;AACA,wBAAQ,GAAR,CAAY,SAAS,MAArB;;AAEA,qBAAK,QAAL,CAAc,MAAd,GAAuB,SAAvB;AACA,qBAAK,QAAL,CAAc,KAAd,GAAsB,kBAAtB;AACA,qBAAK,UAAL,CAAgB,QAAhB,CAAyB,eAAzB,EAA0C,CAAC,SAAD,EAAY,EAAZ,CAA1C;AACA;AACF;AACE,qBAAK,QAAL,CAAc,MAAd,GAAuB,SAAvB;AACA,qBAAK,QAAL,CAAc,KAAd,GAAsB,SAAS,UAA/B;AACA,qBAAK,UAAL,CAAgB,QAAhB,CAAyB,eAAzB,EAA0C,CAAC,SAAS,MAAT,GAAgB,IAAhB,GAAqB,SAAS,UAA/B,EAA0C,EAA1C,CAA1C;AACA;AAdJ;;AAiBA,gBAAI,EAAE,UAAF,IAAgB,CAAhB,IAAqB,EAAE,MAAF,IAAY,GAArC,EAA0C;AAC1C,kBAAM,cAAc,EAAE,iBAAF,CAAoB,YAApB,CAApB;AACD;;;kCAEO,Q,EAAS;AACf,mBAAO,aAAW,SAAS,UAApB,GAA+B,GAA/B,GAAmC,SAAS,SAA5C,GAAsD,QAA7D;AACD;;;yCAEa,CAEb","file":"auths.js","sourcesContent":["import _ from 'lodash';\n\nexport class AuthsCtrl {\n\n constructor(backendSrv, $rootScope, $timeout){\n this.$rootScope = $rootScope;\n this.$timeout = $timeout;\n this.backendSrv = backendSrv;\n }\n\n login(datasource){\n this.fetching = {};\n this.fetching.done = false;\n this.fetching.show = true;\n this.fetching.status = 'warning';\n this.fetching.title = 'Fetching auths...';\n\n //this.$rootScope.appEvent('alert-success', ['Authorization Cookie Received', '']);\n //this.$rootScope.appEvent('alert-error', ['Authorization Failed', '']);\n //this.$rootScope.appEvent('alert-warning', ['Fetching Authorizations', '']);\n\n var uri = this._getURI(datasource.jsonData);\n\n if(datasource.jsonData.basicAuths){\n if( this.basicAuthUser && this.basicAuthPassword){\n var authBlob = {username: this.basicAuthUser, password: this.basicAuthPassword};\n this.doPostLogin(uri, authBlob);\n } else {\n this.$rootScope.appEvent('alert-warning', [datasource.name, 'requires User/Password']);\n this.fetching.status = 'warning';\n this.fetching.title = 'User/Password required';\n\n return;\n }\n } else {\n this.doGetLogin(uri);\n }\n\n }\n\n doPostLogin(uri, authBlob){\n this.doXHR('POST', uri, authBlob);\n }\n\n doGetLogin(uri){\n this.doXHR('GET', uri)\n }\n\n doXHR(verb, uri, data){\n if( !data){\n data = \"\";\n }\n var r = new XMLHttpRequest();\n r.open(verb, uri, true);\n r.withCredentials = true;\n r.setRequestHeader('Content-Type', 'application/json');\n r.onreadystatechange = function () {\n this.handleLoginResult(r);\n }.bind(this);\n r.send(JSON.stringify(data));\n }\n\n handleLoginResult(response){\n // wait for readyState to be '4 => done'\n if (response.readyState != 4) return;\n\n this.fetching.done = true;\n\n switch(response.status){\n case 200:\n var cookie = (document.cookie.match(/^(?:.*;)?TSESSIONID=([^;]+)(?:.*)?$/)||[,null])[1]\n console.log(cookie);\n console.log(document.cookie);\n \n this.fetching.status = 'success';\n this.fetching.title = 'Login successful';\n this.$rootScope.appEvent('alert-success', ['Success', '']);\n break;\n default:\n this.fetching.status = 'warning';\n this.fetching.title = response.statusText;\n this.$rootScope.appEvent('alert-warning', [response.status+': '+response.statusText,'']);\n break;\n }\n\n if (r.readyState != 4 || r.status != 200) return;\n alert(\"Success: \" + r.Line truncated
{"version":3,"sources":["../../src/components/auths.js"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAO,O;;;;;;;;;;;;;;;;;;;;;2BAEM,S;AAEX,2BAAY,UAAZ,EAAwB,UAAxB,EAAoC,QAApC,EAA6C;AAAA;;AAC3C,eAAK,UAAL,GAAkB,UAAlB;AACA,eAAK,QAAL,GAAgB,QAAhB;AACA,eAAK,UAAL,GAAkB,UAAlB;AACD;;;;gCAEK,U,EAAW;AACf,iBAAK,QAAL,GAAgB,EAAhB;AACA,iBAAK,QAAL,CAAc,IAAd,GAAqB,KAArB;AACA,iBAAK,QAAL,CAAc,IAAd,GAAqB,IAArB;AACA,iBAAK,QAAL,CAAc,MAAd,GAAuB,SAAvB;AACA,iBAAK,QAAL,CAAc,KAAd,GAAsB,mBAAtB;;AAEA;AACA;AACA;;AAEA,gBAAI,MAAM,KAAK,OAAL,CAAa,WAAW,QAAxB,CAAV;;AAEA,gBAAG,WAAW,QAAX,CAAoB,UAAvB,EAAkC;AAChC,kBAAI,KAAK,aAAL,IAAsB,KAAK,iBAA/B,EAAiD;AAC/C,oBAAI,WAAW,EAAC,UAAU,KAAK,aAAhB,EAA+B,UAAU,KAAK,iBAA9C,EAAf;AACA,qBAAK,WAAL,CAAiB,GAAjB,EAAsB,QAAtB;AACD,eAHD,MAGO;AACL,qBAAK,UAAL,CAAgB,QAAhB,CAAyB,eAAzB,EAA0C,CAAC,WAAW,IAAZ,EAAkB,wBAAlB,CAA1C;AACA,qBAAK,QAAL,CAAc,MAAd,GAAuB,SAAvB;AACA,qBAAK,QAAL,CAAc,KAAd,GAAsB,wBAAtB;;AAEA;AACD;AACF,aAXD,MAWO;AACL,mBAAK,UAAL,CAAgB,GAAhB;AACD;AAEF;;;sCAEW,G,EAAK,Q,EAAS;AACxB,iBAAK,KAAL,CAAW,MAAX,EAAmB,GAAnB,EAAwB,QAAxB;AACD;;;qCAEU,G,EAAI;AACb,iBAAK,KAAL,CAAW,KAAX,EAAkB,GAAlB;AACD;;;gCAEK,I,EAAM,G,EAAK,I,EAAK;AACpB,gBAAI,CAAC,IAAL,EAAU;AACR,qBAAO,EAAP;AACD;AACD,gBAAI,IAAI,IAAI,cAAJ,EAAR;AACA,cAAE,IAAF,CAAO,IAAP,EAAa,GAAb,EAAkB,IAAlB;AACA,cAAE,eAAF,GAAoB,IAApB;AACA,cAAE,gBAAF,CAAmB,cAAnB,EAAmC,kBAAnC;AACA,cAAE,kBAAF,GAAuB,YAAY;AACjC,mBAAK,iBAAL,CAAuB,CAAvB;AACD,aAFsB,CAErB,IAFqB,CAEhB,IAFgB,CAAvB;AAGA,cAAE,IAAF,CAAO,KAAK,SAAL,CAAe,IAAf,CAAP;AACD;;;4CAEiB,Q,EAAS;AACzB;AACA,gBAAI,SAAS,UAAT,IAAuB,CAA3B,EAA8B;;AAE9B,iBAAK,QAAL,CAAc,IAAd,GAAqB,IAArB;;AAEA,oBAAO,SAAS,MAAhB;AACE,mBAAK,GAAL;AACE,wBAAQ,GAAR,CAAY,KAAK,SAAL,CAAe,YAAf,CAAZ;;AAEA,qBAAK,QAAL,CAAc,MAAd,GAAuB,SAAvB;AACA,qBAAK,QAAL,CAAc,KAAd,GAAsB,kBAAtB;AACA,qBAAK,UAAL,CAAgB,QAAhB,CAAyB,eAAzB,EAA0C,CAAC,SAAD,EAAY,EAAZ,CAA1C;AACA;AACF;AACE,qBAAK,QAAL,CAAc,MAAd,GAAuB,SAAvB;AACA,qBAAK,QAAL,CAAc,KAAd,GAAsB,SAAS,UAA/B;AACA,qBAAK,UAAL,CAAgB,QAAhB,CAAyB,eAAzB,EAA0C,CAAC,SAAS,MAAT,GAAgB,IAAhB,GAAqB,SAAS,UAA/B,EAA0C,EAA1C,CAA1C;AACA;AAZJ;;AAeA,gBAAI,EAAE,UAAF,IAAgB,CAAhB,IAAqB,EAAE,MAAF,IAAY,GAArC,EAA0C;AAC1C,kBAAM,cAAc,EAAE,iBAAF,CAAoB,YAApB,CAApB;AACD;;;oCAES,I,EAAM;AACd,gBAAI,QAAQ,OAAO,SAAS,MAA5B;AACA,gBAAI,QAAQ,MAAM,KAAN,CAAY,OAAO,IAAP,GAAc,GAA1B,CAAZ;AACA,gBAAI,MAAM,MAAN,IAAgB,CAApB,EAAuB,OAAO,MAAM,GAAN,GAAY,KAAZ,CAAkB,GAAlB,EAAuB,KAAvB,EAAP;AACxB;;;kCAEO,Q,EAAS;AACf,mBAAO,aAAW,SAAS,UAApB,GAA+B,GAA/B,GAAmC,SAAS,SAA5C,GAAsD,QAA7D;AACD;;;yCAEa,CAEb","file":"auths.js","sourcesContent":["import _ from 'lodash';\n\nexport class AuthsCtrl {\n\n constructor(backendSrv, $rootScope, $timeout){\n this.$rootScope = $rootScope;\n this.$timeout = $timeout;\n this.backendSrv = backendSrv;\n }\n\n login(datasource){\n this.fetching = {};\n this.fetching.done = false;\n this.fetching.show = true;\n this.fetching.status = 'warning';\n this.fetching.title = 'Fetching auths...';\n\n //this.$rootScope.appEvent('alert-success', ['Authorization Cookie Received', '']);\n //this.$rootScope.appEvent('alert-error', ['Authorization Failed', '']);\n //this.$rootScope.appEvent('alert-warning', ['Fetching Authorizations', '']);\n\n var uri = this._getURI(datasource.jsonData);\n\n if(datasource.jsonData.basicAuths){\n if( this.basicAuthUser && this.basicAuthPassword){\n var authBlob = {username: this.basicAuthUser, password: this.basicAuthPassword};\n this.doPostLogin(uri, authBlob);\n } else {\n this.$rootScope.appEvent('alert-warning', [datasource.name, 'requires User/Password']);\n this.fetching.status = 'warning';\n this.fetching.title = 'User/Password required';\n\n return;\n }\n } else {\n this.doGetLogin(uri);\n }\n\n }\n\n doPostLogin(uri, authBlob){\n this.doXHR('POST', uri, authBlob);\n }\n\n doGetLogin(uri){\n this.doXHR('GET', uri)\n }\n\n doXHR(verb, uri, data){\n if( !data){\n data = \"\";\n }\n var r = new XMLHttpRequest();\n r.open(verb, uri, true);\n r.withCredentials = true;\n r.setRequestHeader('Content-Type', 'application/json');\n r.onreadystatechange = function () {\n this.handleLoginResult(r);\n }.bind(this);\n r.send(JSON.stringify(data));\n }\n\n handleLoginResult(response){\n // wait for readyState to be '4 => done'\n if (response.readyState != 4) return;\n\n this.fetching.done = true;\n\n switch(response.status){\n case 200:\n console.log(this.getCookie('TSESSIONID'))\n\n this.fetching.status = 'success';\n this.fetching.title = 'Login successful';\n this.$rootScope.appEvent('alert-success', ['Success', '']);\n break;\n default:\n this.fetching.status = 'warning';\n this.fetching.title = response.statusText;\n this.$rootScope.appEvent('alert-warning', [response.status+': '+response.statusText,'']);\n break;\n }\n\n if (r.readyState != 4 || r.status != 200) return;\n alert(\"Success: \" + r.getResponseHeader('Set-CookiLine truncated
+67
View File
@@ -0,0 +1,67 @@
<div class="page-header">
<h1>Websocket Test</h1>
</div>
<div ng-hide="ctrl.websocketSupported" >
<h4>WebSockets are not suppported in this browser.</h4>
</div>
<div class="gf-box" ng-show="ctrl.websocketSupported">
<div class="gf-box-header">
<div class="gf-form-inline">
<div class="gf-form max-width-30">
<span class="gf-label width-7 p-y-1 p-x-1">Metric</span>
<div class="gf-form-select-wrapper gf-form-select-wrapper--has-help-icon max-width-24">
<input type="text" class="gf-form-input"
spellcheck='false'
data-min-length=0
data-items=100
ng-model="metricName"
placeholder="sys.">
<info-popover mode="right-absolute">
Type a Metric name<br>
</info-popover>
<div ng-hide="ctrl.fetching" class="gf-row">
<button type="submit" class="btn btn-success" ng-click="ctrl.start(metricName)">
Start
</button>
</div>
<div ng-show="ctrl.fetching" class="gf-row">
<button type="submit" class="btn btn-warning" ng-click="ctrl.stop(metricName)">
Stop
</button>
</div>
</div>
</div>
</div>
</div>
<div class="gf-box-body">
<div class="grafana-options-table">
<p>{{ctrl.metric_count}}</p>
<table>
<tr>
<th>Metric</th>
<th>Tags</th>
<th>Values</th>
</tr>
<tr>
<td>{{ctrl.metric['metric']}}</td>
<!--td class="p-x-1" ng-repeat="tag in ctrl.metric.tags">
{{tag.key}} = {{tag.value}}
</td -->
<td>{{ctrl.metric.timestamp}} -> {{ctrl.metric.value}}</td>
</tr>
</table>
</div>
</div>
</div>
+164
View File
@@ -0,0 +1,164 @@
'use strict';
System.register(['plugins/timely-app/components/authspage'], function (_export, _context) {
"use strict";
var AuthsPageCtrl, _createClass, WebsocketCtrl;
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
return {
setters: [function (_pluginsTimelyAppComponentsAuthspage) {
AuthsPageCtrl = _pluginsTimelyAppComponentsAuthspage.AuthsPageCtrl;
}],
execute: function () {
_createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
_export('WebsocketCtrl', WebsocketCtrl = function () {
function WebsocketCtrl($scope, $timeout, backendSrv, datasourceSrv) {
_classCallCheck(this, WebsocketCtrl);
this.$scope = $scope;
this.$timeout = $timeout;
var actrl = new AuthsPageCtrl(backendSrv, datasourceSrv);
var datasources = actrl.getTimelyDatasources();
this.datasource = datasources[0].jsonData;
this.websocketSupported = false;
if (window.WebSocket) {
this.websocketSupported = true;
}
this.metric_count = 0;
this.metric = { 'metric': 'empty',
'tags': [],
'timestamp': 0,
'value': 0.0
};
this.fetching = false;
}
_createClass(WebsocketCtrl, [{
key: 'start',
value: function start(metric) {
this.fetching = true;
var addr = this._getWebsocketAddress();
this.sock = new WebSocket(addr);
this.sock.onmessage = this._handleMessage.bind(this);
this.sock.onopen = this._handleOpen.bind(this);
this.sock.onclose = this._handleClose.bind(this);
}
}, {
key: 'stop',
value: function stop(metric) {
this.fetching = false;
this.sock.close();
}
}, {
key: '_handleMessage',
value: function _handleMessage(message) {
//console.log('handleMessage');
var metric = JSON.parse(message.data);
this.metric.metric = metric.metric;
this.metric.timestamp = metric.timestamp;
this.metric.value = metric.value;
this.metric.tags = metric.tags;
this.metric_count = this.metric_count + 1;
this.$scope.$digest();
//if( this.metrics.length >= 16){
// this.metrics.shift();
//}
//this.$scope.$apply( function(){
// this.metrics.push(metric);
// this.metric_count = this.metric_count + 1;
// }.bind(this));
}
}, {
key: '_handleOpen',
value: function _handleOpen() {
var create = {
"operation": "create",
"subscriptionId": "12345"
};
this.sock.send(JSON.stringify(create));
var m1 = {
"operation": "add",
"subscriptionId": "12345",
"metric": "sys.cpu.user"
};
this.sock.send(JSON.stringify(m1));
// var m2 = {
// "operation" : "add",
// "subscriptionId" : "12345",
// "metric" : "timely.keys.metric.inserted"
// }
// this.sock.send(JSON.stringify(m2));
}
}, {
key: '_handleClose',
value: function _handleClose() {
console.log("Websocket Closed");
}
}, {
key: '_getWebsocketAddress',
value: function _getWebsocketAddress() {
return "wss://" + this.datasource.timelyHost + ":" + this.datasource.wsPort + "/websocket";
}
}]);
return WebsocketCtrl;
}());
_export('WebsocketCtrl', WebsocketCtrl);
WebsocketCtrl.templateUrl = 'components/websocket.html';
// example metric message
//{
// "metric" : "sys.cpu.user",
// "timestamp":1469028728091,
// "value":1.0,
// "tags":
// [
// {
// "key":"rack",
// "value":"r1"
// },{
// "key":"tag3",
// "value":"value3"
// },{
// "key":"tag4",
// "value":"value4"
// }
// ],
// "subscriptionId":"<unique id>"
//}
}
};
});
//# sourceMappingURL=websocket.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../src/components/websocket.js"],"names":[],"mappings":";;;;;;;;;;;;;;;AACQ,mB,wCAAA,a;;;;;;;;;;;;;;;;;;;;;+BAGK,a;AAEX,+BAAY,MAAZ,EAAoB,QAApB,EAA8B,UAA9B,EAA0C,aAA1C,EAAyD;AAAA;;AACvD,eAAK,MAAL,GAAc,MAAd;AACA,eAAK,QAAL,GAAgB,QAAhB;;AAEA,cAAI,QAAQ,IAAI,aAAJ,CAAkB,UAAlB,EAA8B,aAA9B,CAAZ;;AAEA,cAAI,cAAc,MAAM,oBAAN,EAAlB;AACA,eAAK,UAAL,GAAkB,YAAY,CAAZ,EAAe,QAAjC;;AAEA,eAAK,kBAAL,GAA0B,KAA1B;AACA,cAAI,OAAO,SAAX,EAAsB;AAClB,iBAAK,kBAAL,GAA0B,IAA1B;AACH;AACD,eAAK,YAAL,GAAoB,CAApB;AACA,eAAK,MAAL,GAAc,EAAE,UAAU,OAAZ;AACE,oBAAO,EADT;AAEE,yBAAa,CAFf;AAGE,qBAAS;AAHX,WAAd;;AAMA,eAAK,QAAL,GAAgB,KAAhB;AACD;;;;gCAEK,M,EAAO;AACX,iBAAK,QAAL,GAAgB,IAAhB;AACA,gBAAI,OAAO,KAAK,oBAAL,EAAX;AACA,iBAAK,IAAL,GAAY,IAAI,SAAJ,CAAc,IAAd,CAAZ;AACA,iBAAK,IAAL,CAAU,SAAV,GAAsB,KAAK,cAAL,CAAoB,IAApB,CAAyB,IAAzB,CAAtB;AACA,iBAAK,IAAL,CAAU,MAAV,GAAmB,KAAK,WAAL,CAAiB,IAAjB,CAAsB,IAAtB,CAAnB;AACA,iBAAK,IAAL,CAAU,OAAV,GAAoB,KAAK,YAAL,CAAkB,IAAlB,CAAuB,IAAvB,CAApB;AACD;;;+BAEI,M,EAAQ;AACX,iBAAK,QAAL,GAAgB,KAAhB;AACA,iBAAK,IAAL,CAAU,KAAV;AACD;;;yCAEc,O,EAAQ;AACrB;AACA,gBAAI,SAAS,KAAK,KAAL,CAAW,QAAQ,IAAnB,CAAb;;AAEA,iBAAK,MAAL,CAAY,MAAZ,GAAqB,OAAO,MAA5B;AACA,iBAAK,MAAL,CAAY,SAAZ,GAAwB,OAAO,SAA/B;AACA,iBAAK,MAAL,CAAY,KAAZ,GAAoB,OAAO,KAA3B;AACA,iBAAK,MAAL,CAAY,IAAZ,GAAmB,OAAO,IAA1B;AACA,iBAAK,YAAL,GAAoB,KAAK,YAAL,GAAkB,CAAtC;AACA,iBAAK,MAAL,CAAY,OAAZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACD;;;wCAEY;AACX,gBAAI,SAAS;AACX,2BAAc,QADH;AAEX,gCAAmB;AAFR,aAAb;AAIA,iBAAK,IAAL,CAAU,IAAV,CAAe,KAAK,SAAL,CAAe,MAAf,CAAf;;AAEA,gBAAI,KAAK;AACP,2BAAc,KADP;AAEP,gCAAmB,OAFZ;AAGP,wBAAW;AAHJ,aAAT;AAKA,iBAAK,IAAL,CAAU,IAAV,CAAe,KAAK,SAAL,CAAe,EAAf,CAAf;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACG;;;yCAEa;AACZ,oBAAQ,GAAR,CAAY,kBAAZ;AACD;;;iDAEqB;AACpB,mBAAO,WAAW,KAAK,UAAL,CAAgB,UAA3B,GAAwC,GAAxC,GAA8C,KAAK,UAAL,CAAgB,MAA9D,GAAuE,YAA9E;AACD;;;;;;;;AAGH,oBAAc,WAAd,GAA4B,2BAA5B;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"websocket.js","sourcesContent":["\nimport {AuthsPageCtrl} from 'plugins/timely-app/components/authspage'\n\n\nexport class WebsocketCtrl {\n\n constructor($scope, $timeout, backendSrv, datasourceSrv) {\n this.$scope = $scope;\n this.$timeout = $timeout;\n\n var actrl = new AuthsPageCtrl(backendSrv, datasourceSrv);\n\n var datasources = actrl.getTimelyDatasources();\n this.datasource = datasources[0].jsonData;\n\n this.websocketSupported = false;\n if( window.WebSocket ){\n this.websocketSupported = true;\n }\n this.metric_count = 0;\n this.metric = { 'metric': 'empty',\n 'tags':[],\n 'timestamp': 0,\n 'value': 0.0\n };\n\n this.fetching = false;\n }\n\n start(metric){\n this.fetching = true;\n var addr = this._getWebsocketAddress();\n this.sock = new WebSocket(addr);\n this.sock.onmessage = this._handleMessage.bind(this);\n this.sock.onopen = this._handleOpen.bind(this);\n this.sock.onclose = this._handleClose.bind(this);\n }\n\n stop(metric) {\n this.fetching = false;\n this.sock.close();\n }\n\n _handleMessage(message){\n //console.log('handleMessage');\n var metric = JSON.parse(message.data);\n\n this.metric.metric = metric.metric;\n this.metric.timestamp = metric.timestamp;\n this.metric.value = metric.value;\n this.metric.tags = metric.tags;\n this.metric_count = this.metric_count+1;\n this.$scope.$digest();\n //if( this.metrics.length >= 16){\n // this.metrics.shift();\n //}\n //this.$scope.$apply( function(){\n // this.metrics.push(metric);\n // this.metric_count = this.metric_count + 1;\n // }.bind(this));\n }\n\n _handleOpen(){\n var create = {\n \"operation\" : \"create\",\n \"subscriptionId\" : \"12345\"\n }\n this.sock.send(JSON.stringify(create));\n\n var m1 = {\n \"operation\" : \"add\",\n \"subscriptionId\" : \"12345\",\n \"metric\" : \"sys.cpu.user\"\n }\n this.sock.send(JSON.stringify(m1));\n\n// var m2 = {\n// \"operation\" : \"add\",\n// \"subscriptionId\" : \"12345\",\n// \"metric\" : \"timely.keys.metric.inserted\"\n// }\n// this.sock.send(JSON.stringify(m2));\n }\n\n _handleClose(){\n console.log(\"Websocket Closed\")\n }\n\n _getWebsocketAddress(){\n return \"wss://\" + this.datasource.timelyHost + \":\" + this.datasource.wsPort + \"/websocket\";\n }\n\n}\nWebsocketCtrl.templateUrl = 'components/websocket.html';\n\n\n// example metric message\n//{\n// \"metric\" : \"sys.cpu.user\",\n// \"timestamp\":1469028728091,\n// \"value\":1.0,\n// \"tags\":\n// [\n// {\n// \"key\":\"rack\",\n// \"value\":\"r1\"\n// },{\n// \"key\":\"tag3\",\n// \"value\":\"value3\"\n// },{\n// \"key\":\"tag4\",\n// \"value\":\"value4\"\n// }\n// ],\n// \"subscriptionId\":\"<unique id>\"\n//}\n"]}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,786 @@
{
"__inputs": [
{
"name": "DS_TIMELY",
"label": "Timely",
"description": "",
"type": "datasource",
"pluginId": "timely-datasource",
"pluginName": "Timely"
}
],
"__requires": [
{
"type": "panel",
"id": "singlestat",
"name": "Singlestat",
"version": ""
},
{
"type": "panel",
"id": "graph",
"name": "Graph",
"version": ""
},
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "3.1.0"
},
{
"type": "datasource",
"id": "timely-datasource",
"name": "Timely",
"version": "1.0.0"
}
],
"id": null,
"title": "Timely Status",
"tags": [],
"style": "dark",
"timezone": "browser",
"editable": true,
"hideControls": false,
"sharedCrosshair": false,
"rows": [
{
"collapse": false,
"editable": true,
"height": "150",
"panels": [
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100000,
"minValue": 0,
"show": true,
"thresholdLabels": false,
"thresholdMarkers": false
},
"height": "150",
"hideTimeOverride": true,
"id": 8,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "count",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.metrics.received",
"refId": "A"
}
],
"thresholds": "",
"timeFrom": null,
"timeShift": "1m",
"title": "Metrics Received Last Minute",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
},
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"height": "150",
"hideTimeOverride": true,
"id": 9,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "count",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "count",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.queue_length",
"refId": "A",
"tags": {}
}
],
"thresholds": "",
"timeShift": "1m",
"title": "CollectD Instances Reporting",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
},
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"height": "150",
"hideTimeOverride": true,
"id": 10,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.derive.dropped",
"refId": "A",
"tags": {}
}
],
"thresholds": "",
"timeShift": "1m",
"title": "Metrics Dropped By CollectD",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
}
],
"title": "New row"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 3,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.keys.metric.inserted",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Metrics Inserted",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 4,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.keys.meta.inserted",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Meta Inserted",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 5,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.metrics.received",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Metrics Received",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"title": "New row"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 7,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"alias": "$tag_host",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.cache_size",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CollectD Cache Sizes",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 11,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"alias": "$tag_host",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.queue_length",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CollectD Queue Length",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"title": "New row"
}
],
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"now": true,
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"templating": {
"list": []
},
"annotations": {
"list": []
},
"refresh": "1m",
"schemaVersion": 12,
"version": 8,
"links": [],
"gnetId": null
}
@@ -1,15 +1,39 @@
{
"__inputs": [
{
"name": "DS_NAME",
"name": "DS_TIMELY",
"label": "Timely",
"description": "",
"type": "datasource",
"pluginId": "timely-datasource"
"pluginId": "timely-datasource",
"pluginName": "Timely"
}
],
"__requires": [
{
"type": "panel",
"id": "graph",
"name": "Graph",
"version": ""
},
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "3.1.1"
},
{
"type": "datasource",
"id": "timely-datasource",
"name": "Timely",
"version": "1.0.0"
}
],
"id": null,
"title": "${DS_NAME} - Status",
"originalTitle": "${DS_NAME} - Status",
"tags": ["imported"],
"title": "Timely Standalone Demo",
"tags": [
"imported"
],
"style": "dark",
"timezone": "browser",
"editable": true,
@@ -24,7 +48,7 @@
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_NAME}",
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 1,
@@ -99,6 +123,7 @@
"tooltip": {
"msResolution": true,
"shared": false,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
@@ -134,7 +159,7 @@
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_NAME}",
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 1,
@@ -146,6 +171,94 @@
},
"id": 2,
"isNew": true,
"legend": {
"alignAsTable": false,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "max",
"alias": "$tag_host $tag_instance",
"currentTagKey": "",
"currentTagValue": "",
"disableDownsampling": false,
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {
"host": ".*",
"instance": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CPU User by Instance",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 5,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": false,
@@ -179,7 +292,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {
"host": ".*"
@@ -190,8 +303,9 @@
"timeShift": null,
"title": "CPU User by Host",
"tooltip": {
"msResolution": false,
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
@@ -220,7 +334,7 @@
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_NAME}",
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 1,
@@ -265,7 +379,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {
"rack": ".*"
@@ -276,8 +390,9 @@
"timeShift": null,
"title": "CPU User by Rack",
"tooltip": {
"msResolution": false,
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
@@ -306,7 +421,7 @@
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_NAME}",
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 1,
@@ -351,7 +466,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {}
}
@@ -360,8 +475,9 @@
"timeShift": null,
"title": "Cumulative CPU",
"tooltip": {
"msResolution": false,
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
@@ -429,6 +545,7 @@
},
"refresh": "5s",
"schemaVersion": 12,
"version": 1,
"links": []
}
"version": 0,
"links": [],
"gnetId": null
}
+5 -1
View File
@@ -8,7 +8,11 @@
"annotations": true,
"includes": [
{"type": "dashboard", "name": "Timely Metrics", "path": "dashboards/standalone_test.json"}
{"type": "dashboard", "name": "Timely Standalone Test", "path": "dashboards/standalone_test.json"},
{"type": "dashboard", "name": "Accumulo Overview", "path": "dashboards/AccumuloOverview.json"},
{"type": "dashboard", "name": "Hadoop Overview", "path": "dashboards/HadoopOverview.json"},
{"type": "dashboard", "name": "System Overview", "path": "dashboards/SystemOverview.json"},
{"type": "dashboard", "name": "Timely Status", "path": "dashboards/TimelyStatus.json"}
],
"info": {
+6 -2
View File
@@ -1,9 +1,9 @@
'use strict';
System.register(['./components/config', './components/metrics', './components/authspage'], function (_export, _context) {
System.register(['./components/config', './components/metrics', './components/authspage', './components/websocket'], function (_export, _context) {
"use strict";
var TimelyAppConfigCtrl, MetricsPageCtrl, AuthsPageCtrl;
var TimelyAppConfigCtrl, MetricsPageCtrl, AuthsPageCtrl, WebsocketCtrl;
return {
setters: [function (_componentsConfig) {
TimelyAppConfigCtrl = _componentsConfig.TimelyAppConfigCtrl;
@@ -11,6 +11,8 @@ System.register(['./components/config', './components/metrics', './components/au
MetricsPageCtrl = _componentsMetrics.MetricsPageCtrl;
}, function (_componentsAuthspage) {
AuthsPageCtrl = _componentsAuthspage.AuthsPageCtrl;
}, function (_componentsWebsocket) {
WebsocketCtrl = _componentsWebsocket.WebsocketCtrl;
}],
execute: function () {
_export('ConfigCtrl', TimelyAppConfigCtrl);
@@ -18,6 +20,8 @@ System.register(['./components/config', './components/metrics', './components/au
_export('MetricsPageCtrl', MetricsPageCtrl);
_export('AuthsPageCtrl', AuthsPageCtrl);
_export('WebsocketPageCtrl', WebsocketCtrl);
}
};
});
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../src/module.js"],"names":[],"mappings":";;;;;;;;AAAQ,yB,qBAAA,mB;;AACA,qB,sBAAA,e;;AACA,mB,wBAAA,a;;;4BAGN,mB;;iCACA,e;;+BACA,a","file":"module.js","sourcesContent":["import {TimelyAppConfigCtrl} from './components/config';\nimport {MetricsPageCtrl} from './components/metrics';\nimport {AuthsPageCtrl} from './components/authspage';\n\nexport {\n TimelyAppConfigCtrl as ConfigCtrl,\n MetricsPageCtrl,\n AuthsPageCtrl\n};\n"]}
{"version":3,"sources":["../src/module.js"],"names":[],"mappings":";;;;;;;;AAAQ,yB,qBAAA,mB;;AACA,qB,sBAAA,e;;AACA,mB,wBAAA,a;;AACA,mB,wBAAA,a;;;4BAGN,mB;;iCACA,e;;+BACA,a;;mCACA,a","file":"module.js","sourcesContent":["import {TimelyAppConfigCtrl} from './components/config';\nimport {MetricsPageCtrl} from './components/metrics';\nimport {AuthsPageCtrl} from './components/authspage';\nimport {WebsocketCtrl} from './components/websocket';\n\nexport {\n TimelyAppConfigCtrl as ConfigCtrl,\n MetricsPageCtrl,\n AuthsPageCtrl,\n WebsocketCtrl as WebsocketPageCtrl\n};\n"]}
+3 -1
View File
@@ -30,7 +30,9 @@
"includes": [
{"type": "datasource", "name": "Timely"},
{ "type": "page", "name": "Login", "component": "AuthsPageCtrl", "role": "Viewer", "addToNav": true},
{ "type": "page", "name": "Metrics", "component": "MetricsPageCtrl", "role": "Viewer", "addToNav": true}
{ "type": "page", "name": "Metrics", "component": "MetricsPageCtrl", "role": "Viewer", "addToNav": true},
{ "type": "page", "name": "WebSocket", "component": "WebsocketPageCtrl", "role": "Viewer", "addToNav": true}
],
"dependencies": {
+3 -1
View File
@@ -30,7 +30,9 @@
"includes": [
{"type": "datasource", "name": "Timely"},
{ "type": "page", "name": "Login", "component": "AuthsPageCtrl", "role": "Viewer", "addToNav": true},
{ "type": "page", "name": "Metrics", "component": "MetricsPageCtrl", "role": "Viewer", "addToNav": true}
{ "type": "page", "name": "Metrics", "component": "MetricsPageCtrl", "role": "Viewer", "addToNav": true},
{ "type": "page", "name": "WebSocket", "component": "WebsocketPageCtrl", "role": "Viewer", "addToNav": true}
],
"dependencies": {
+8 -4
View File
@@ -68,10 +68,8 @@ export class AuthsCtrl {
switch(response.status){
case 200:
var cookie = (document.cookie.match(/^(?:.*;)?TSESSIONID=([^;]+)(?:.*)?$/)||[,null])[1]
console.log(cookie);
console.log(document.cookie);
console.log(this.getCookie('TSESSIONID'))
this.fetching.status = 'success';
this.fetching.title = 'Login successful';
this.$rootScope.appEvent('alert-success', ['Success', '']);
@@ -87,6 +85,12 @@ export class AuthsCtrl {
alert("Success: " + r.getResponseHeader('Set-Cookie'));
}
getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
_getURI(jsonData){
return 'https://'+jsonData.timelyHost+':'+jsonData.httpsPort+'/login'
}
@@ -0,0 +1,67 @@
<div class="page-header">
<h1>Websocket Test</h1>
</div>
<div ng-hide="ctrl.websocketSupported" >
<h4>WebSockets are not suppported in this browser.</h4>
</div>
<div class="gf-box" ng-show="ctrl.websocketSupported">
<div class="gf-box-header">
<div class="gf-form-inline">
<div class="gf-form max-width-30">
<span class="gf-label width-7 p-y-1 p-x-1">Metric</span>
<div class="gf-form-select-wrapper gf-form-select-wrapper--has-help-icon max-width-24">
<input type="text" class="gf-form-input"
spellcheck='false'
data-min-length=0
data-items=100
ng-model="metricName"
placeholder="sys.">
<info-popover mode="right-absolute">
Type a Metric name<br>
</info-popover>
<div ng-hide="ctrl.fetching" class="gf-row">
<button type="submit" class="btn btn-success" ng-click="ctrl.start(metricName)">
Start
</button>
</div>
<div ng-show="ctrl.fetching" class="gf-row">
<button type="submit" class="btn btn-warning" ng-click="ctrl.stop(metricName)">
Stop
</button>
</div>
</div>
</div>
</div>
</div>
<div class="gf-box-body">
<div class="grafana-options-table">
<p>{{ctrl.metric_count}}</p>
<table>
<tr>
<th>Metric</th>
<th>Tags</th>
<th>Values</th>
</tr>
<tr>
<td>{{ctrl.metric['metric']}}</td>
<!--td class="p-x-1" ng-repeat="tag in ctrl.metric.tags">
{{tag.key}} = {{tag.value}}
</td -->
<td>{{ctrl.metric.timestamp}} -> {{ctrl.metric.value}}</td>
</tr>
</table>
</div>
</div>
</div>
@@ -0,0 +1,116 @@
import {AuthsPageCtrl} from 'plugins/timely-app/components/authspage'
export class WebsocketCtrl {
constructor($scope, $timeout, backendSrv, datasourceSrv) {
this.$scope = $scope;
this.$timeout = $timeout;
var actrl = new AuthsPageCtrl(backendSrv, datasourceSrv);
var datasources = actrl.getTimelyDatasources();
this.datasource = datasources[0].jsonData;
this.websocketSupported = false;
if( window.WebSocket ){
this.websocketSupported = true;
}
this.metric_count = 0;
this.metric = { 'metric': 'empty',
'tags':[],
'timestamp': 0,
'value': 0.0
};
this.fetching = false;
}
start(metric){
this.fetching = true;
var addr = this._getWebsocketAddress();
this.sock = new WebSocket(addr);
this.sock.onmessage = this._handleMessage.bind(this);
this.sock.onopen = this._handleOpen.bind(this);
this.sock.onclose = this._handleClose.bind(this);
}
stop(metric) {
this.fetching = false;
this.sock.close();
}
_handleMessage(message){
//console.log('handleMessage');
var metric = JSON.parse(message.data);
this.metric.metric = metric.metric;
this.metric.timestamp = metric.timestamp;
this.metric.value = metric.value;
this.metric.tags = metric.tags;
this.metric_count = this.metric_count+1;
this.$scope.$digest();
//if( this.metrics.length >= 16){
// this.metrics.shift();
//}
//this.$scope.$apply( function(){
// this.metrics.push(metric);
// this.metric_count = this.metric_count + 1;
// }.bind(this));
}
_handleOpen(){
var create = {
"operation" : "create",
"subscriptionId" : "12345"
}
this.sock.send(JSON.stringify(create));
var m1 = {
"operation" : "add",
"subscriptionId" : "12345",
"metric" : "sys.cpu.user"
}
this.sock.send(JSON.stringify(m1));
// var m2 = {
// "operation" : "add",
// "subscriptionId" : "12345",
// "metric" : "timely.keys.metric.inserted"
// }
// this.sock.send(JSON.stringify(m2));
}
_handleClose(){
console.log("Websocket Closed")
}
_getWebsocketAddress(){
return "wss://" + this.datasource.timelyHost + ":" + this.datasource.wsPort + "/websocket";
}
}
WebsocketCtrl.templateUrl = 'components/websocket.html';
// example metric message
//{
// "metric" : "sys.cpu.user",
// "timestamp":1469028728091,
// "value":1.0,
// "tags":
// [
// {
// "key":"rack",
// "value":"r1"
// },{
// "key":"tag3",
// "value":"value3"
// },{
// "key":"tag4",
// "value":"value4"
// }
// ],
// "subscriptionId":"<unique id>"
//}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,786 @@
{
"__inputs": [
{
"name": "DS_TIMELY",
"label": "Timely",
"description": "",
"type": "datasource",
"pluginId": "timely-datasource",
"pluginName": "Timely"
}
],
"__requires": [
{
"type": "panel",
"id": "singlestat",
"name": "Singlestat",
"version": ""
},
{
"type": "panel",
"id": "graph",
"name": "Graph",
"version": ""
},
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "3.1.0"
},
{
"type": "datasource",
"id": "timely-datasource",
"name": "Timely",
"version": "1.0.0"
}
],
"id": null,
"title": "Timely Status",
"tags": [],
"style": "dark",
"timezone": "browser",
"editable": true,
"hideControls": false,
"sharedCrosshair": false,
"rows": [
{
"collapse": false,
"editable": true,
"height": "150",
"panels": [
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100000,
"minValue": 0,
"show": true,
"thresholdLabels": false,
"thresholdMarkers": false
},
"height": "150",
"hideTimeOverride": true,
"id": 8,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "count",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.metrics.received",
"refId": "A"
}
],
"thresholds": "",
"timeFrom": null,
"timeShift": "1m",
"title": "Metrics Received Last Minute",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
},
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"height": "150",
"hideTimeOverride": true,
"id": 9,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "count",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "count",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.queue_length",
"refId": "A",
"tags": {}
}
],
"thresholds": "",
"timeShift": "1m",
"title": "CollectD Instances Reporting",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
},
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"height": "150",
"hideTimeOverride": true,
"id": 10,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.derive.dropped",
"refId": "A",
"tags": {}
}
],
"thresholds": "",
"timeShift": "1m",
"title": "Metrics Dropped By CollectD",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
}
],
"title": "New row"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 3,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.keys.metric.inserted",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Metrics Inserted",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 4,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.keys.meta.inserted",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Meta Inserted",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 5,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.metrics.received",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Metrics Received",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"title": "New row"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 7,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"alias": "$tag_host",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.cache_size",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CollectD Cache Sizes",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 11,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"alias": "$tag_host",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.queue_length",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CollectD Queue Length",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"title": "New row"
}
],
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"now": true,
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"templating": {
"list": []
},
"annotations": {
"list": []
},
"refresh": "1m",
"schemaVersion": 12,
"version": 8,
"links": [],
"gnetId": null
}
@@ -1,15 +1,39 @@
{
"__inputs": [
{
"name": "DS_NAME",
"name": "DS_TIMELY",
"label": "Timely",
"description": "",
"type": "datasource",
"pluginId": "timely-datasource"
"pluginId": "timely-datasource",
"pluginName": "Timely"
}
],
"__requires": [
{
"type": "panel",
"id": "graph",
"name": "Graph",
"version": ""
},
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "3.1.1"
},
{
"type": "datasource",
"id": "timely-datasource",
"name": "Timely",
"version": "1.0.0"
}
],
"id": null,
"title": "${DS_NAME} - Status",
"originalTitle": "${DS_NAME} - Status",
"tags": ["imported"],
"title": "Timely Standalone Demo",
"tags": [
"imported"
],
"style": "dark",
"timezone": "browser",
"editable": true,
@@ -24,7 +48,7 @@
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_NAME}",
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 1,
@@ -99,6 +123,7 @@
"tooltip": {
"msResolution": true,
"shared": false,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
@@ -134,7 +159,7 @@
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_NAME}",
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 1,
@@ -146,6 +171,94 @@
},
"id": 2,
"isNew": true,
"legend": {
"alignAsTable": false,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "max",
"alias": "$tag_host $tag_instance",
"currentTagKey": "",
"currentTagValue": "",
"disableDownsampling": false,
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {
"host": ".*",
"instance": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CPU User by Instance",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 5,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": false,
@@ -179,7 +292,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {
"host": ".*"
@@ -190,8 +303,9 @@
"timeShift": null,
"title": "CPU User by Host",
"tooltip": {
"msResolution": false,
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
@@ -220,7 +334,7 @@
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_NAME}",
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 1,
@@ -265,7 +379,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {
"rack": ".*"
@@ -276,8 +390,9 @@
"timeShift": null,
"title": "CPU User by Rack",
"tooltip": {
"msResolution": false,
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
@@ -306,7 +421,7 @@
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_NAME}",
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 1,
@@ -351,7 +466,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {}
}
@@ -360,8 +475,9 @@
"timeShift": null,
"title": "Cumulative CPU",
"tooltip": {
"msResolution": false,
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
@@ -429,6 +545,7 @@
},
"refresh": "5s",
"schemaVersion": 12,
"version": 1,
"links": []
}
"version": 0,
"links": [],
"gnetId": null
}
@@ -8,7 +8,11 @@
"annotations": true,
"includes": [
{"type": "dashboard", "name": "Timely Metrics", "path": "dashboards/standalone_test.json"}
{"type": "dashboard", "name": "Timely Standalone Test", "path": "dashboards/standalone_test.json"},
{"type": "dashboard", "name": "Accumulo Overview", "path": "dashboards/AccumuloOverview.json"},
{"type": "dashboard", "name": "Hadoop Overview", "path": "dashboards/HadoopOverview.json"},
{"type": "dashboard", "name": "System Overview", "path": "dashboards/SystemOverview.json"},
{"type": "dashboard", "name": "Timely Status", "path": "dashboards/TimelyStatus.json"}
],
"info": {
+3 -1
View File
@@ -1,9 +1,11 @@
import {TimelyAppConfigCtrl} from './components/config';
import {MetricsPageCtrl} from './components/metrics';
import {AuthsPageCtrl} from './components/authspage';
import {WebsocketCtrl} from './components/websocket';
export {
TimelyAppConfigCtrl as ConfigCtrl,
MetricsPageCtrl,
AuthsPageCtrl
AuthsPageCtrl,
WebsocketCtrl as WebsocketPageCtrl
};
+156 -4
View File
@@ -3,8 +3,25 @@
<modelVersion>4.0.0</modelVersion>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</version>
<version>0.0.3-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Timely</name>
<description>A secure time series database based on Apache Accumulo</description>
<licenses>
<license>
<name>Apache License, Version 2.1</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<scm>
<connection>scm:git:https://github.com/NationalSecurityAgency/timely.git</connection>
<developerConnection>scm:git:[email protected]:NationalSecurityAgency/timely.git</developerConnection>
<url>https://github.com/NationalSecurityAgency/timely</url>
</scm>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/NationalSecurityAgency/timely/issues</url>
</issueManagement>
<modules>
<module>server</module>
<module>collectd-timely-plugin</module>
@@ -18,25 +35,53 @@
<os.detection.classifierWithLikes>fedora</os.detection.classifierWithLikes>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- dependency versions -->
<collectd-api-jar>/usr/share/collectd/java/collectd-api.jar</collectd-api-jar>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<version.accumulo>1.7.0</version.accumulo>
<version.caffeine>2.2.0</version.caffeine>
<version.collectd>5.5.1</version.collectd>
<version.commons-configuration>1.10</version.commons-configuration>
<version.commons-lang3>3.1</version.commons-lang3>
<version.disruptor>3.3.2</version.disruptor>
<version.fast-classpath-scanner>1.10.4</version.fast-classpath-scanner>
<version.hadoop>2.6.2</version.hadoop>
<version.httpcomponents>4.5.1</version.httpcomponents>
<version.jackson>2.6.1</version.jackson>
<version.javassist>3.20.0-GA</version.javassist>
<version.jcip-annotations>1.0</version.jcip-annotations>
<version.junit>4.11</version.junit>
<version.log4j>2.5</version.log4j>
<version.netty>4.0.38.Final</version.netty>
<version.netty-tcnative>1.1.33.Fork18</version.netty-tcnative>
<version.powermock>1.6.4</version.powermock>
<version.security>4.0.4.RELEASE</version.security>
<version.slf4j>1.7.12</version.slf4j>
<!-- plugin versions -->
<version.eclipse-lifecycle>1.0.0</version.eclipse-lifecycle>
<version.findbugs-maven>3.0.3</version.findbugs-maven>
<version.formatter>0.5.2</version.formatter>
<version.jacoco>0.7.6.201602180812</version.jacoco>
<version.maven-assembly>2.6</version.maven-assembly>
<version.maven-compiler>3.3</version.maven-compiler>
<version.maven-dependency>2.10</version.maven-dependency>
<version.maven-jar>3.0.1</version.maven-jar>
<version.os-maven>1.5.0.Final</version.os-maven>
<version.maven-pmd>3.6</version.maven-pmd>
<version.maven-rpm>2.1.4</version.maven-rpm>
<version.maven-shade>2.4.2</version.maven-shade>
<version.maven-surefire>2.19.1</version.maven-surefire>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>collectd</groupId>
<artifactId>collectd-api</artifactId>
<version>${version.collectd}</version>
<scope>system</scope>
<systemPath>${collectd-api-jar}</systemPath>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
@@ -62,6 +107,12 @@
<artifactId>caffeine</artifactId>
<version>${version.caffeine}</version>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>${version.disruptor}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
@@ -73,6 +124,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.github.lukehutch</groupId>
<artifactId>fast-classpath-scanner</artifactId>
<version>${version.fast-classpath-scanner}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
@@ -84,6 +140,12 @@
<version>${version.junit}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>${version.jcip-annotations}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
@@ -184,12 +246,24 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${version.httpcomponents}</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>${version.javassist}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-easymock-release-full</artifactId>
<version>${version.powermock}</version>
<classifier>full</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
@@ -210,24 +284,54 @@
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>${version.formatter}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>${version.maven-assembly}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<version>${version.maven-compiler}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${version.maven-dependency}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${version.maven-surefire}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<version>${version.maven-jar}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${version.maven-shade}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.maven-surefire}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.3</version>
<version>${version.findbugs-maven}</version>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
@@ -242,6 +346,54 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${version.jacoco}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<version>${version.maven-rpm}</version>
</plugin>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>${version.eclipse-lifecycle}</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<versionRange>[0.5.2,)</versionRange>
<goals>
<goal>format</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[2.10,)</versionRange>
<goals>
<goal>copy-dependencies</goal>
<goal>unpack</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
+4 -3
View File
@@ -3,15 +3,16 @@ FROM centos:centos7
MAINTAINER Jim Klucar "[email protected]"
VOLUME /timely-server-src
VOLUME /timely
RUN yum -y update && \
yum -y install java-1.8.0-openjdk-devel maven openssl apr && \
mkdir -p /timely/bin
ENV JAVA_HOME /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.91-1.b14.el7_2.x86_64
ENV JAVA_HOME /usr/lib/jvm/jre-1.8.0-openjdk
EXPOSE 9804 54321 54322
EXPOSE 9804 54321 54322 54323
ENV TIMELY_VERSION 0.0.2-SNAPSHOT
ENV TIMELY_VERSION 0.0.3-SNAPSHOT
#CMD /timely/bin/timely-standalone.sh
+6 -6
View File
@@ -6,14 +6,14 @@
/timely-server-src/bin/docker/wait-for-it.sh timely:54322 -t 45
# create datasource in grafana
curl -X POST -u admin:admin -H "Content-Type: application/json" -d \
'{"name":"Timely","type":"opentsdb","url":"https://timely:54322","access":"proxy","jsonData":{"tsdbVersion":1,"tsdbResolution":1}}' \
http://grafana:3000/api/datasources
#curl -X POST -u admin:admin -H "Content-Type: application/json" -d \
#'{"name":"Timely","type":"opentsdb","url":"https://timely:54322","access":"proxy","jsonData":{"tsdbVersion":1,"tsdbResolution":1}}' \
#http://grafana:3000/api/datasources
# insert the dashboard
curl -X POST -u admin:admin -H "Content-Type: application/json" \
-d @/timely-server-src/bin/docker/standalone_test.json \
http://grafana:3000/api/dashboards/db
#curl -X POST -u admin:admin -H "Content-Type: application/json" \
#-d @/timely-server-src/bin/docker/standalone_test.json \
#http://grafana:3000/api/dashboards/db
/timely/bin/insert-test-data.sh
+3 -3
View File
@@ -27,7 +27,7 @@
#################################### Server ####################################
[server]
# Protocol (http or https)
protocol = https
protocol = http
# The ip address to bind to, empty will bind to all interfaces
;http_addr =
@@ -55,8 +55,8 @@ http_port = 3000
;enable_gzip = false
# https certs & key file
cert_file = /etc/grafana/pki/timely-cert.pem
cert_key = /etc/grafana/pki/timely-key.pem
;cert_file = /etc/grafana/pki/timely-cert.pem
;cert_key = /etc/grafana/pki/timely-key.pem
#################################### Database ####################################
[database]
-429
View File
@@ -1,429 +0,0 @@
{"dashboard":
{
"id": null,
"title": "StandaloneTest",
"originalTitle": "StandaloneTest",
"tags": [],
"style": "dark",
"timezone": "browser",
"editable": true,
"hideControls": false,
"sharedCrosshair": false,
"rows": [
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "Timely",
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)",
"thresholdLine": false
},
"id": 1,
"legend": {
"alignAsTable": true,
"avg": false,
"current": true,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"total": true,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"disableDownsampling": false,
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"downsampleInterval": "",
"errors": {},
"isCounter": false,
"metric": "timely.metrics.received",
"refId": "A",
"shouldComputeRate": false
},
{
"aggregator": "sum",
"disableDownsampling": false,
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"downsampleInterval": "",
"errors": {},
"metric": "timely.keys.meta.inserted",
"refId": "B"
},
{
"aggregator": "sum",
"disableDownsampling": false,
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"downsampleInterval": "",
"errors": {},
"metric": "timely.keys.metric.inserted",
"refId": "C"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Status",
"tooltip": {
"msResolution": true,
"shared": false,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": "Keys",
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"logBase": 1,
"max": null,
"min": null,
"show": false
}
]
}
],
"title": "Row"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "Timely",
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 2,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "max",
"alias": "$tag_host",
"currentTagKey": "",
"currentTagValue": "",
"disableDownsampling": false,
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CPU User by Host",
"tooltip": {
"msResolution": false,
"shared": true,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "Timely",
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 3,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "max",
"alias": "$tag_rack",
"currentTagKey": "",
"currentTagValue": "",
"disableDownsampling": false,
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"refId": "A",
"tags": {
"rack": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CPU User by Rack",
"tooltip": {
"msResolution": false,
"shared": true,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "Timely",
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 4,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "max",
"alias": "",
"currentTagKey": "",
"currentTagValue": "",
"disableDownsampling": false,
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"refId": "A",
"tags": {}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Cumulative CPU",
"tooltip": {
"msResolution": false,
"shared": true,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"title": "New row"
}
],
"time": {
"from": "now-15m",
"to": "now"
},
"timepicker": {
"now": true,
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"templating": {
"list": []
},
"annotations": {
"list": []
},
"refresh": "5s",
"schemaVersion": 12,
"version": 1,
"links": []
}
}
+6 -7
View File
@@ -23,17 +23,16 @@ timely.metrics.report.tags.ignored=
timely.meta.cache.expiration.minutes=60
timely.meta.cache.initial.capacity=2000
timely.meta.cache.max.capacity=10000
timely.ssl.certificate.file=/timely-server-src/bin/docker/grafana/pki/timely-cert.pem
timely.ssl.key.file=/timely-server-src/bin/docker/grafana/pki/timely-pkcs8-key.pem
timely.ssl.key.pass=timely
timely.ssl.use.generated.keypair=false
timely.ssl.trust.store.file=/timely-server-src/bin/docker/grafana/pki/timely-ca.pem
#timely.ssl.certificate.file=/timely-server-src/bin/docker/grafana/pki/timely-cert.pem
#timely.ssl.key.file=/timely-server-src/bin/docker/grafana/pki/timely-pkcs8-key.pem
#timely.ssl.key.pass=timely
timely.ssl.use.generated.keypair=true
#timely.ssl.trust.store.file=/timely-server-src/bin/docker/grafana/pki/timely-ca.pem
timely.ssl.use.openssl=true
#timely.ssl.use.ciphers=
timely.session.max.age=86400
timely.http.host=localhost
timely.allow.anonymous.access=true
timely.web.socket.timeout=60
timely.ws.subscription.lag=120
timely.http.redirect.path=/secure-me
timely.ws.subscription.lag=1
timely.hsts.max.age=608400
-1
View File
@@ -35,5 +35,4 @@ timely.http.host=
timely.allow.anonymous.access=false
timely.web.socket.timeout=60
timely.ws.subscription.lag=120
timely.http.redirect.path=/secure-me
timely.hsts.max.age=608400
+3 -1
View File
@@ -7,11 +7,12 @@ services:
- "9804:9804" # standalone zookeeper
- "54321:54321" # timely put
- "54322:54322" # timely query
- "54323:54323" # timely ws
volumes:
- ${PWD}/:/timely-server-src
command: /timely-server-src/bin/docker/deploy-startup-standalone.sh
environment:
- TIMELY_VERSION=0.0.2-SNAPSHOT
- TIMELY_VERSION=0.0.3-SNAPSHOT
ingest:
image: timely
entrypoint: /timely-server-src/bin/docker/deploy-wait-and-insert.sh
@@ -22,6 +23,7 @@ services:
environment:
- TIMELY_HOST=timely
- TIMELY_PORT=54321
- TIMELY_VERSION=0.0.3-SNAPSHOT
grafana:
image: grafana/grafana
ports:
+5 -58
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</version>
<version>0.0.3-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -35,13 +35,11 @@
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.github.lukehutch</groupId>
<artifactId>fast-classpath-scanner</artifactId>
<version>1.10.4</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
@@ -134,14 +132,13 @@
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
<version>${version.os-maven}</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>assemble</id>
@@ -161,7 +158,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
@@ -200,7 +196,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19</version>
<configuration>
<argLine>${failsafeArgLine} -Djava.library.path=${project.build.dir}/native/META-INF/native/libnetty-tcnative.so -Dzookeeper.sasl.client=false</argLine>
<includes>
@@ -249,7 +244,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<argLine>${sureFireArgLine} -Djava.library.path=${project.build.dir}/native/META-INF/native/libnetty-tcnative.so -Dzookeeper.sasl.client=false</argLine>
<excludedGroups>timely.test.IntegrationTest</excludedGroups>
@@ -259,7 +253,6 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.6.201602180812</version>
<executions>
<execution>
<id>jacoco-prepare-ut</id>
@@ -288,7 +281,6 @@
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>0.5.2</version>
<configuration>
<configFile>${project.parent.basedir}/eclipse/Eclipse-Formatter.xml</configFile>
<lineEnding>LF</lineEnding>
@@ -303,50 +295,6 @@
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<versionRange>[0.5.2,)</versionRange>
<goals>
<goal>format</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[2.10,)</versionRange>
<goals>
<goal>copy-dependencies</goal>
<goal>unpack</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
@@ -356,7 +304,6 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<version>2.1.4</version>
<executions>
<execution>
<id>generate-rpm</id>
@@ -434,7 +381,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.3</version>
<version>${version.findbugs-maven}</version>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
@@ -443,7 +390,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.6</version>
<version>${version.maven-pmd}</version>
<configuration>
<targetJdk>1.8</targetJdk>
</configuration>
@@ -451,7 +398,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.6.201602180812</version>
<version>${version.jacoco}</version>
<reportSets>
<reportSet>
<id>JaCoCo Unit Test Coverage</id>
+5 -1
View File
@@ -69,6 +69,7 @@ import timely.netty.tcp.TcpPutHandler;
import timely.netty.tcp.TcpVersionHandler;
import timely.netty.websocket.WSMetricPutHandler;
import timely.netty.websocket.WSVersionRequestHandler;
import timely.netty.websocket.WebSocketHttpCookieHandler;
import timely.netty.websocket.WebSocketRequestDecoder;
import timely.netty.websocket.subscription.WSAddSubscriptionRequestHandler;
import timely.netty.websocket.subscription.WSCloseSubscriptionRequestHandler;
@@ -362,7 +363,9 @@ public class Server {
}
String trustStore = config.get(Configuration.SSL_TRUST_STORE_FILE);
if (null != trustStore) {
ssl.trustManager(new File(trustStore));
if (!trustStore.isEmpty()) {
ssl.trustManager(new File(trustStore));
}
}
return ssl.build();
}
@@ -447,6 +450,7 @@ public class Server {
ch.pipeline().addLast("ssl", sslCtx.newHandler(ch.alloc()));
ch.pipeline().addLast("httpServer", new HttpServerCodec());
ch.pipeline().addLast("aggregator", new HttpObjectAggregator(8192));
ch.pipeline().addLast("sessionExtractor", new WebSocketHttpCookieHandler(config));
ch.pipeline().addLast("idle-handler",
new IdleStateHandler(Integer.parseInt(conf.get(Configuration.WS_TIMEOUT_SECONDS)), 0, 0));
ch.pipeline().addLast("ws-protocol", new WebSocketServerProtocolHandler(WS_PATH, null, true));
@@ -219,12 +219,13 @@ public class Metric implements TcpRequest, HttpPostRequest, WebSocketRequest {
return JsonUtil.getObjectMapper().readValue(content.getBytes(StandardCharsets.UTF_8), Metric.class);
}
public MetricResponse toMetricResponse() {
public MetricResponse toMetricResponse(String subscriptionId) {
MetricResponse response = new MetricResponse();
response.setMetric(this.metric);
response.setTimestamp(this.timestamp);
response.setTags(this.tags);
response.setValue(this.value);
response.setSubscriptionId(subscriptionId);
return response;
}
@@ -4,10 +4,9 @@ import java.util.Map;
import java.util.Optional;
import timely.api.annotation.WebSocket;
import timely.api.request.AuthenticatedWebSocketRequest;
@WebSocket(operation = "add")
public class AddSubscription extends AuthenticatedWebSocketRequest {
public class AddSubscription extends SubscriptionRequest {
private String metric = null;
private Optional<Map<String, String>> tags = Optional.empty();
@@ -1,8 +1,7 @@
package timely.api.request.subscription;
import timely.api.annotation.WebSocket;
import timely.api.request.AuthenticatedWebSocketRequest;
@WebSocket(operation = "close")
public class CloseSubscription extends AuthenticatedWebSocketRequest {
public class CloseSubscription extends SubscriptionRequest {
}
@@ -1,8 +1,7 @@
package timely.api.request.subscription;
import timely.api.annotation.WebSocket;
import timely.api.request.AuthenticatedWebSocketRequest;
@WebSocket(operation = "create")
public class CreateSubscription extends AuthenticatedWebSocketRequest {
public class CreateSubscription extends SubscriptionRequest {
}
@@ -1,10 +1,9 @@
package timely.api.request.subscription;
import timely.api.annotation.WebSocket;
import timely.api.request.AuthenticatedWebSocketRequest;
@WebSocket(operation = "remove")
public class RemoveSubscription extends AuthenticatedWebSocketRequest {
public class RemoveSubscription extends SubscriptionRequest {
private String metric = null;
@@ -0,0 +1,24 @@
package timely.api.request.subscription;
import timely.api.request.AuthenticatedWebSocketRequest;
public class SubscriptionRequest extends AuthenticatedWebSocketRequest {
private String subscriptionId = null;
public String getSubscriptionId() {
return subscriptionId;
}
public void setSubscriptionId(String subscriptionId) {
this.subscriptionId = subscriptionId;
}
@Override
public void validate() {
if (null == subscriptionId) {
throw new IllegalArgumentException("Subscription ID is required.");
}
}
}
@@ -14,6 +14,7 @@ public class MetricResponse {
private long timestamp;
private double value;
private List<Tag> tags;
private String subscriptionId;
public String getMetric() {
return metric;
@@ -47,6 +48,14 @@ public class MetricResponse {
this.tags = tags;
}
public String getSubscriptionId() {
return subscriptionId;
}
public void setSubscriptionId(String subscriptionId) {
this.subscriptionId = subscriptionId;
}
@Override
public int hashCode() {
HashCodeBuilder hash = new HashCodeBuilder();
@@ -54,6 +63,7 @@ public class MetricResponse {
hash.append(this.timestamp);
hash.append(this.value);
hash.append(this.tags);
hash.append(this.subscriptionId);
return hash.hashCode();
}
@@ -74,6 +84,7 @@ public class MetricResponse {
equals.append(this.timestamp, other.timestamp);
equals.append(this.value, other.value);
equals.append(this.tags, other.tags);
equals.append(this.subscriptionId, other.subscriptionId);
return equals.isEquals();
}
@@ -84,6 +95,7 @@ public class MetricResponse {
tsb.append("timestamp", this.timestamp);
tsb.append("value", this.value);
tsb.append("tags", this.tags);
tsb.append("subscriptionId", this.subscriptionId);
return tsb.toString();
}
@@ -44,6 +44,26 @@ public class HttpRequestDecoder extends MessageToMessageDecoder<FullHttpRequest>
this.nonSecureRedirectAddress = conf.get(Configuration.NON_SECURE_REDIRECT_PATH);
}
public static String getSessionId(FullHttpRequest msg, boolean anonymousAccessAllowed) {
final StringBuilder buf = new StringBuilder();
msg.headers().getAll(Names.COOKIE).forEach(h -> {
ServerCookieDecoder.STRICT.decode(h).forEach(c -> {
if (c.name().equals(Constants.COOKIE_NAME)) {
if (buf.length() == 0) {
buf.append(c.value());
}
}
});
});
String sessionId = buf.toString();
if (sessionId.length() == 0 && anonymousAccessAllowed) {
sessionId = NO_AUTHORIZATIONS;
} else if (sessionId.length() == 0) {
sessionId = null;
}
return sessionId;
}
@Override
protected void decode(ChannelHandlerContext ctx, FullHttpRequest msg, List<Object> out) throws Exception {
@@ -56,24 +76,7 @@ public class HttpRequestDecoder extends MessageToMessageDecoder<FullHttpRequest>
return;
}
final StringBuilder buf = new StringBuilder();
msg.headers().getAll(Names.COOKIE).forEach(h -> {
ServerCookieDecoder.STRICT.decode(h).forEach(c -> {
if (c.name().equals(Constants.COOKIE_NAME)) {
if (buf.length() == 0) {
buf.append(c.value());
}
}
});
});
String sId = buf.toString();
if (sId.length() == 0 && this.anonymousAccessAllowed) {
sId = NO_AUTHORIZATIONS;
} else if (sId.length() == 0) {
sId = null;
}
final String sessionId = sId;
final String sessionId = getSessionId(msg, this.anonymousAccessAllowed);
LOG.trace("SessionID: " + sessionId);
Request request = null;
@@ -0,0 +1,42 @@
package timely.netty.websocket;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.handler.codec.http.FullHttpRequest;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.Configuration;
import timely.netty.http.HttpRequestDecoder;
import timely.subscription.SubscriptionRegistry;
public class WebSocketHttpCookieHandler extends MessageToMessageCodec<FullHttpRequest, FullHttpRequest> {
private static final Logger LOG = LoggerFactory.getLogger(WebSocketHttpCookieHandler.class);
private boolean anonymousAccessAllowed;
public WebSocketHttpCookieHandler(Configuration config) {
super();
this.anonymousAccessAllowed = config.getBoolean(Configuration.ALLOW_ANONYMOUS_ACCESS);
}
@Override
protected void decode(ChannelHandlerContext ctx, FullHttpRequest msg, List<Object> out) throws Exception {
msg.retain();
out.add(msg);
// If the session cookie exists, set its value on the ctx.
final String sessionId = HttpRequestDecoder.getSessionId(msg, this.anonymousAccessAllowed);
ctx.channel().attr(SubscriptionRegistry.SESSION_ID_ATTR).set(sessionId);
LOG.info("Found session id in WebSocket channel, setting sessionId {} on context", sessionId);
}
@Override
protected void encode(ChannelHandlerContext ctx, FullHttpRequest msg, List<Object> out) throws Exception {
msg.retain();
out.add(msg);
}
}
@@ -15,6 +15,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.Configuration;
import timely.api.request.AuthenticatedRequest;
import timely.api.request.WebSocketRequest;
import timely.api.response.TimelyException;
import timely.auth.AuthCache;
@@ -40,6 +41,13 @@ public class WebSocketRequestDecoder extends MessageToMessageDecoder<WebSocketFr
WebSocketRequest request = JsonUtil.getObjectMapper().readValue(content, WebSocketRequest.class);
LOG.trace("Received WS request {}", content);
String sessionId = ctx.channel().attr(SubscriptionRegistry.SESSION_ID_ATTR).get();
if (request instanceof AuthenticatedRequest && !StringUtils.isEmpty(sessionId)) {
LOG.info("Found session id in WebSocket channel, setting sessionId {} on request", sessionId);
AuthenticatedRequest ar = (AuthenticatedRequest) request;
ar.setSessionId(sessionId);
}
try {
request.validate();
} catch (IllegalArgumentException e) {
@@ -81,14 +89,14 @@ public class WebSocketRequestDecoder extends MessageToMessageDecoder<WebSocketFr
if (idle.state() == IdleState.READER_IDLE) {
// We have not read any data from client in a while, let's close
// the subscriptions for this context.
String sessionId = ctx.attr(SubscriptionRegistry.SESSION_ID_ATTR).get();
if (!StringUtils.isEmpty(sessionId)) {
if (SubscriptionRegistry.get().containsKey(sessionId)) {
LOG.info("Closing subscription with session id {} due to idle event", sessionId);
SubscriptionRegistry.get().get(sessionId).close();
String subscriptionId = ctx.channel().attr(SubscriptionRegistry.SUBSCRIPTION_ID_ATTR).get();
if (!StringUtils.isEmpty(subscriptionId)) {
if (SubscriptionRegistry.get().containsKey(subscriptionId)) {
LOG.info("Closing subscription with subscription id {} due to idle event", subscriptionId);
SubscriptionRegistry.get().get(subscriptionId).close();
}
} else {
LOG.warn("Channel idle, but no session id found on context. Unable to close subscriptions");
LOG.warn("Channel idle, but no subscription id found on context. Unable to close subscriptions");
}
}
} else {
@@ -19,7 +19,7 @@ public class WSAddSubscriptionRequestHandler extends SimpleChannelInboundHandler
@Override
protected void channelRead0(ChannelHandlerContext ctx, AddSubscription add) throws Exception {
Subscription s = SubscriptionRegistry.get().get(add.getSessionId());
Subscription s = SubscriptionRegistry.get().get(add.getSubscriptionId());
if (null != s) {
String metric = add.getMetric();
if (null == metric) {
@@ -40,8 +40,8 @@ public class WSAddSubscriptionRequestHandler extends SimpleChannelInboundHandler
}
s.addMetric(metric, tags, startTime, delayTime);
} else {
LOG.error("Unknown session id, create subscription first");
ctx.writeAndFlush(new CloseWebSocketFrame(1003, "Unknown session id, create subscription first"));
LOG.error("Unknown subscription id, create subscription first");
ctx.writeAndFlush(new CloseWebSocketFrame(1003, "Unknown subscription id, create subscription first"));
}
}
@@ -10,7 +10,7 @@ public class WSCloseSubscriptionRequestHandler extends SimpleChannelInboundHandl
@Override
protected void channelRead0(ChannelHandlerContext ctx, CloseSubscription close) throws Exception {
Subscription s = SubscriptionRegistry.get().remove(close.getSessionId());
Subscription s = SubscriptionRegistry.get().remove(close.getSubscriptionId());
if (null != s) {
s.close();
}
@@ -27,19 +27,21 @@ public class WSCreateSubscriptionRequestHandler extends SimpleChannelInboundHand
@Override
protected void channelRead0(ChannelHandlerContext ctx, CreateSubscription create) throws Exception {
SubscriptionRegistry.get().put(create.getSessionId(),
new Subscription(create.getSessionId(), store, ctx, this.conf));
final String subscriptionId = create.getSubscriptionId();
SubscriptionRegistry.get().put(subscriptionId,
new Subscription(subscriptionId, create.getSessionId(), store, ctx, this.conf));
// Store the session id as an attribute on the context.
ctx.attr(SubscriptionRegistry.SESSION_ID_ATTR).set(create.getSessionId());
ctx.channel().attr(SubscriptionRegistry.SUBSCRIPTION_ID_ATTR).set(subscriptionId);
LOG.info("Created subscription {} on channel {}", subscriptionId, ctx);
ctx.channel().closeFuture().addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
Subscription s = SubscriptionRegistry.get().remove(create.getSessionId());
Subscription s = SubscriptionRegistry.get().remove(subscriptionId);
if (null != s) {
LOG.info("Channel closed, closing subscriptions for sessionId: " + create.getSessionId());
LOG.info("Channel closed, closing subscriptions for subscriptionId: " + subscriptionId);
s.close();
}
}
@@ -10,7 +10,7 @@ public class WSRemoveSubscriptionRequestHandler extends SimpleChannelInboundHand
@Override
protected void channelRead0(ChannelHandlerContext ctx, RemoveSubscription remove) throws Exception {
Subscription s = SubscriptionRegistry.get().get(remove.getSessionId());
Subscription s = SubscriptionRegistry.get().get(remove.getSubscriptionId());
if (null != s) {
s.removeMetric(remove.getMetric());
}
@@ -36,16 +36,21 @@ public class MetricScanner extends Thread implements UncaughtExceptionHandler {
private final long delay;
private final String name;
private final int lag;
private final String subscriptionId;
private final String metric;
public MetricScanner(String sessionId, DataStore store, String metric, Map<String, String> tags, long startTime,
long delay, int lag, ChannelHandlerContext ctx) throws TimelyException {
public MetricScanner(String subscriptionId, String sessionId, DataStore store, String metric,
Map<String, String> tags, long startTime, long delay, int lag, ChannelHandlerContext ctx)
throws TimelyException {
this.setDaemon(true);
this.setUncaughtExceptionHandler(this);
this.ctx = ctx;
this.lag = lag;
this.metric = metric;
this.scanner = store.createScannerForMetric(sessionId, metric, tags, startTime, lag);
this.iter = scanner.iterator();
this.delay = delay;
this.subscriptionId = subscriptionId;
ToStringBuilder buf = new ToStringBuilder(this);
buf.append("sessionId", sessionId);
buf.append("metric", metric);
@@ -70,27 +75,32 @@ public class MetricScanner extends Thread implements UncaughtExceptionHandler {
Entry<Key, Value> e = this.iter.next();
m = Metric.parse(e.getKey(), e.getValue());
try {
String json = om.writeValueAsString(m.toMetricResponse());
String json = om.writeValueAsString(m.toMetricResponse(this.subscriptionId));
LOG.trace("Returning {} for subscription", json);
this.ctx.writeAndFlush(new TextWebSocketFrame(json));
} catch (JsonProcessingException e1) {
LOG.error("Error serializing metric: " + m, e1);
}
} else {
// Reset the starting range to the last key returned
LOG.debug("Exhausted scanner, waiting {}ms to retry.", delay);
UtilWaitThread.sleep(delay);
long endTime = (System.currentTimeMillis() - (lag * 1000));
byte[] end = Metric.encodeRowKey(this.metric, endTime);
Text endRow = new Text(end);
this.scanner.close();
Range prevRange = this.scanner.getRange();
if (null != m) {
long endTime = (System.currentTimeMillis() - (lag * 1000));
byte[] end = Metric.encodeRowKey(m.getMetric(), endTime);
Text endRow = new Text(end);
if (null == m) {
LOG.debug("No results found, waiting {}ms to retry.", delay);
UtilWaitThread.sleep(delay);
this.scanner.setRange(new Range(prevRange.getStartKey().getRow(), prevRange
.isStartKeyInclusive(), endRow, false));
this.iter = this.scanner.iterator();
} else {
// Reset the starting range to the last key returned
LOG.debug("Exhausted scanner, waiting {}ms to retry.", delay);
UtilWaitThread.sleep(delay);
this.scanner.setRange(new Range(new Text(Metric.encodeRowKey(m.getMetric(), m.getTimestamp())),
false, endRow, prevRange.isEndKeyInclusive()));
m = null;
this.iter = this.scanner.iterator();
}
this.iter = this.scanner.iterator();
}
}
} finally {
@@ -25,8 +25,11 @@ public class Subscription {
private final ChannelHandlerContext ctx;
private final ScheduledFuture<?> ping;
private final Integer lag;
private final String subscriptionId;
public Subscription(String sessionId, DataStore store, ChannelHandlerContext ctx, Configuration conf) {
public Subscription(String subscriptionId, String sessionId, DataStore store, ChannelHandlerContext ctx,
Configuration conf) {
this.subscriptionId = subscriptionId;
this.sessionId = sessionId;
this.store = store;
this.ctx = ctx;
@@ -44,8 +47,9 @@ public class Subscription {
}
public void addMetric(String metric, Map<String, String> tags, long startTime, long delay) throws TimelyException {
LOG.debug("Adding metric scanner for subscription {}", this.sessionId);
MetricScanner m = new MetricScanner(this.sessionId, store, metric, tags, startTime, delay, lag, ctx);
LOG.debug("Adding metric scanner for subscription {}", this.subscriptionId);
MetricScanner m = new MetricScanner(this.subscriptionId, this.sessionId, store, metric, tags, startTime, delay,
lag, ctx);
METRICS.put(metric, m);
m.start();
}
@@ -63,7 +67,7 @@ public class Subscription {
}
public void close() {
LOG.info("Closing subscriptions for session: " + this.sessionId);
LOG.info("Closing subscriptions for {}", this.subscriptionId);
this.ping.cancel(false);
METRICS.forEach((k, v) -> {
v.close();
@@ -7,6 +7,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class SubscriptionRegistry extends ConcurrentHashMap<String, Subscription> {
public static final AttributeKey<String> SESSION_ID_ATTR = AttributeKey.newInstance("sessionId");
public static final AttributeKey<String> SUBSCRIPTION_ID_ATTR = AttributeKey.newInstance("subscriptionId");
private static final long serialVersionUID = 1L;
private static final SubscriptionRegistry REGISTRY = new SubscriptionRegistry();
@@ -19,18 +19,18 @@ public class InsertTestData {
private static final List<String> METRICS = new ArrayList<>();
static {
METRICS.add("sys.cpu0.user");
METRICS.add("sys.cpu0.idle");
METRICS.add("sys.cpu0.system");
METRICS.add("sys.cpu0.wait");
METRICS.add("sys.cpu.user");
METRICS.add("sys.cpu.idle");
METRICS.add("sys.cpu.system");
METRICS.add("sys.cpu.wait");
METRICS.add("sys.memory.free");
METRICS.add("sys.memory.used");
METRICS.add("sys.eth0.rx-errors");
METRICS.add("sys.eth0.rx-dropped");
METRICS.add("sys.eth0.rx-packets");
METRICS.add("sys.eth0.tx-errors");
METRICS.add("sys.eth0.tx-dropped");
METRICS.add("sys.eth0.tx-packets");
METRICS.add("sys.eth.rx-errors");
METRICS.add("sys.eth.rx-dropped");
METRICS.add("sys.eth.rx-packets");
METRICS.add("sys.eth.tx-errors");
METRICS.add("sys.eth.tx-dropped");
METRICS.add("sys.eth.tx-packets");
METRICS.add("sys.swap.free");
METRICS.add("sys.swap.used");
}
@@ -49,17 +49,25 @@ public class InsertTestData {
RACKS.add("r02");
}
private static final Map<String, String> VISIBILITIES = new HashMap<>();
private static final List<String> INSTANCES = new ArrayList<>();
static {
VISIBILITIES.put("sys.eth0.rx-errors", "A");
VISIBILITIES.put("sys.eth0.rx-dropped", "B");
VISIBILITIES.put("sys.eth0.rx-packets", "C");
VISIBILITIES.put("sys.eth0.tx-errors", "D");
VISIBILITIES.put("sys.eth0.tx-dropped", "E");
VISIBILITIES.put("sys.eth0.tx-packets", "F");
INSTANCES.add("0");
INSTANCES.add("1");
INSTANCES.add("2");
INSTANCES.add("3");
}
private static final String FMT = "put {0} {1,number,#} {2,number} host={4}{3} rack={4}";
private static final Map<String, String> VISIBILITIES = new HashMap<>();
static {
VISIBILITIES.put("sys.eth.rx-errors", "A");
VISIBILITIES.put("sys.eth.rx-dropped", "B");
VISIBILITIES.put("sys.eth.rx-packets", "C");
VISIBILITIES.put("sys.eth.tx-errors", "D");
VISIBILITIES.put("sys.eth.tx-dropped", "E");
VISIBILITIES.put("sys.eth.tx-packets", "F");
}
private static final String FMT = "put {0} {1,number,#} {2,number} host={4}{3} rack={4} instance={5}";
private static String usage() {
return "InsertTestData <host> <port> [--fast]";
@@ -87,12 +95,17 @@ public class InsertTestData {
final String viz = VISIBILITIES.get(m);
RACKS.forEach(rack -> {
HOSTS.forEach(host -> {
String put = MessageFormat.format(FMT, m, time,
ThreadLocalRandom.current().nextDouble(0.0D, 100.0D), host, rack);
if (viz != null)
put += " viz=" + viz;
writer.println(put);
LOG.info(put);
INSTANCES.forEach(instance -> {
if (!m.startsWith("sys.cpu.") && !instance.equals("0")) {
return;
}
String put = MessageFormat.format(FMT, m, time,
ThreadLocalRandom.current().nextDouble(0.0D, 100.0D), host, rack, instance);
if (viz != null)
put += " viz=" + viz;
writer.println(put);
LOG.info(put);
});
});
});
});
+6 -6
View File
@@ -24,23 +24,23 @@
console.log("Web socket connection established.");
var create = {
"operation" : "create",
"sessionId" : "12345"
"subscriptionId" : "12345"
}
sock.send(JSON.stringify(create));
var m1 = {
"operation" : "add",
"sessionId" : "12345",
"subscriptionId" : "12345",
"metric" : "timely.metrics.received"
}
sock.send(JSON.stringify(m1));
var m1 = {
var m2 = {
"operation" : "add",
"sessionId" : "12345",
"subscriptionId" : "12345",
"metric" : "timely.keys.metric.inserted"
}
sock.send(JSON.stringify(m1));
sock.send(JSON.stringify(m2));
}
sock.onclose = function()
{
@@ -50,7 +50,7 @@
{
var close = {
"operation" : "close",
"sessionId" : "12345"
"subscriptionId" : "12345"
}
sock.send(JSON.stringify(close));
sock.close();
@@ -94,6 +94,7 @@ public class MetricTest {
@Test
public void testToMetricResponse() throws Exception {
String subscriptionId = "12345";
long ts = 1000L;
List<Tag> tags = new ArrayList<>();
tags.add(new Tag("tag1", "value1"));
@@ -103,8 +104,8 @@ public class MetricTest {
m.setValue(2.0D);
m.setTags(tags);
m.setVisibility(new ColumnVisibility("(a&b)|(c&d)"));
String json = JsonUtil.getObjectMapper().writeValueAsString(m.toMetricResponse());
String expected = "{\"metric\":\"sys.cpu.user\",\"timestamp\":1000,\"value\":2.0,\"tags\":[{\"key\":\"tag1\",\"value\":\"value1\"}]}";
String json = JsonUtil.getObjectMapper().writeValueAsString(m.toMetricResponse(subscriptionId));
String expected = "{\"metric\":\"sys.cpu.user\",\"timestamp\":1000,\"value\":2.0,\"tags\":[{\"key\":\"tag1\",\"value\":\"value1\"}],\"subscriptionId\":\"12345\"}";
Assert.assertEquals(expected, json);
}
}
@@ -1,5 +1,7 @@
package timely.netty.websocket;
import io.netty.channel.Channel;
import io.netty.channel.local.LocalChannel;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
@@ -32,11 +34,23 @@ import timely.api.request.timeseries.QueryRequest;
import timely.api.request.timeseries.SearchLookupRequest;
import timely.api.request.timeseries.SuggestRequest;
import timely.auth.AuthCache;
import timely.subscription.SubscriptionRegistry;
import timely.test.CaptureChannelHandlerContext;
import timely.test.TestConfiguration;
public class WebSocketRequestDecoderTest {
public static class WebSocketCaptureChannelHandlerContext extends CaptureChannelHandlerContext {
private Channel channel = new LocalChannel();
@Override
public Channel channel() {
return channel;
}
}
private static final Long TEST_TIME = System.currentTimeMillis();
@ClassRule
@@ -47,6 +61,7 @@ public class WebSocketRequestDecoderTest {
private WebSocketRequestDecoder decoder = null;
private List<Object> results = new ArrayList<>();
private static String cookie = null;
private CaptureChannelHandlerContext ctx = new WebSocketCaptureChannelHandlerContext();
@BeforeClass
public static void before() throws Exception {
@@ -74,15 +89,20 @@ public class WebSocketRequestDecoderTest {
@Before
public void setup() throws Exception {
results.clear();
ctx = new WebSocketCaptureChannelHandlerContext();
}
@Test
public void testVersion() throws Exception {
decoder = new WebSocketRequestDecoder(anonConfig);
String request = "{ \"operation\" : \"version\" }";
// @formatter:off
String request = "{ "+
"\"operation\" : \"version\"" +
" }";
// @formatter:on
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
decoder.decode(null, frame, results);
decoder.decode(ctx, frame, results);
Assert.assertEquals(1, results.size());
Assert.assertEquals(VersionRequest.class, results.get(0).getClass());
}
@@ -90,13 +110,24 @@ public class WebSocketRequestDecoderTest {
@Test
public void testPutMetric() throws Exception {
decoder = new WebSocketRequestDecoder(anonConfig);
String request = "{" + "\"operation\" : \"put\",\n" + "\"metric\" : \"sys.cpu.user\",\n" + "\"timestamp\":"
+ TEST_TIME + ",\n" + "\"value\":1.0,\n" + "\"tags\":[ {\n" + "\"key\":\"tag1\",\n"
+ "\"value\":\"value1\"\n" + "},{\n" + "\"key\":\"tag2\",\n" + "\"value\":\"value2\"\n" + "}]\n" + "}";
// @formatter:off
String request = "{" +
"\"operation\" : \"put\",\n" +
"\"metric\" : \"sys.cpu.user\",\n" +
"\"timestamp\":" + TEST_TIME + ",\n" +
"\"value\":1.0,\n" +
"\"tags\":[ {\n" +
"\"key\":\"tag1\",\n" +
"\"value\":\"value1\"\n" +
"},{\n" +
"\"key\":\"tag2\",\n" +
"\"value\":\"value2\"\n" +
"}]\n" +
"}";
// @formatter:on
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
decoder.decode(null, frame, results);
decoder.decode(ctx, frame, results);
Assert.assertEquals(1, results.size());
Assert.assertEquals(Metric.class, results.get(0).getClass());
Metric metric = (Metric) results.iterator().next();
@@ -107,10 +138,34 @@ public class WebSocketRequestDecoderTest {
}
@Test
public void testCreateSubscriptionWithSessionIdAndNonAnonymousAccess() throws Exception {
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
public void testCreateSubscriptionWithMissingSessionId() throws Exception {
decoder = new WebSocketRequestDecoder(config);
String request = "{ \"operation\" : \"create\", \"sessionId\" : \"1234\" }";
// @formatter:off
String request = "{ "+
"\"operation\" : \"create\", " +
"\"subscriptionId\" : \"1234\"" +
" }";
// @formatter:on
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
decoder.decode(ctx, frame, results);
Assert.assertNotNull(ctx.msg);
Assert.assertEquals(CloseWebSocketFrame.class, ctx.msg.getClass());
Assert.assertEquals(1008, ((CloseWebSocketFrame) ctx.msg).statusCode());
Assert.assertEquals("User must log in", ((CloseWebSocketFrame) ctx.msg).reasonText());
}
@Test
public void testCreateSubscriptionWithInvalidSessionIdAndNonAnonymousAccess() throws Exception {
ctx.channel().attr(SubscriptionRegistry.SESSION_ID_ATTR)
.set(URLEncoder.encode(UUID.randomUUID().toString(), StandardCharsets.UTF_8.name()));
decoder = new WebSocketRequestDecoder(config);
// @formatter:off
String request = "{ "+
"\"operation\" : \"create\", " +
"\"subscriptionId\" : \"1234\"" +
" }";
// @formatter:on
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
decoder.decode(ctx, frame, results);
@@ -122,9 +177,14 @@ public class WebSocketRequestDecoderTest {
@Test
public void testCreateSubscriptionWithValidSessionIdAndNonAnonymousAccess() throws Exception {
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
ctx.channel().attr(SubscriptionRegistry.SESSION_ID_ATTR).set(cookie);
decoder = new WebSocketRequestDecoder(config);
String request = "{ \"operation\" : \"create\", \"sessionId\" : \"" + cookie + "\" }";
// @formatter:off
String request = "{ " +
"\"operation\" : \"create\"," +
"\"subscriptionId\" : \"" + cookie + "\"" +
"}";
// @formatter:on
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
decoder.decode(ctx, frame, results);
@@ -133,8 +193,7 @@ public class WebSocketRequestDecoderTest {
}
@Test
public void testCreateSubscriptionWithoutSessionId() throws Exception {
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
public void testCreateSubscriptionWithoutSubscriptionId() throws Exception {
decoder = new WebSocketRequestDecoder(anonConfig);
String request = "{ \"operation\" : \"create\" }";
TextWebSocketFrame frame = new TextWebSocketFrame();
@@ -143,14 +202,13 @@ public class WebSocketRequestDecoderTest {
Assert.assertNotNull(ctx.msg);
Assert.assertEquals(CloseWebSocketFrame.class, ctx.msg.getClass());
Assert.assertEquals(1008, ((CloseWebSocketFrame) ctx.msg).statusCode());
Assert.assertEquals("SessionID is null, must log in first", ((CloseWebSocketFrame) ctx.msg).reasonText());
Assert.assertEquals("Subscription ID is required.", ((CloseWebSocketFrame) ctx.msg).reasonText());
}
@Test
public void testCreateSubscription() throws Exception {
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
decoder = new WebSocketRequestDecoder(anonConfig);
String request = "{ \"operation\" : \"create\", \"sessionId\" : \"1234\" }";
String request = "{ \"operation\" : \"create\", \"subscriptionId\" : \"1234\" }";
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
decoder.decode(ctx, frame, results);
@@ -162,9 +220,8 @@ public class WebSocketRequestDecoderTest {
@Test
public void testAddSubscription() throws Exception {
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
decoder = new WebSocketRequestDecoder(anonConfig);
String request = "{ \"operation\" : \"add\", \"sessionId\" : \"1234\" }";
String request = "{ \"operation\" : \"add\", \"subscriptionId\" : \"1234\" }";
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
decoder.decode(ctx, frame, results);
@@ -176,9 +233,8 @@ public class WebSocketRequestDecoderTest {
@Test
public void testRemoveSubscription() throws Exception {
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
decoder = new WebSocketRequestDecoder(anonConfig);
String request = "{ \"operation\" : \"remove\", \"sessionId\" : \"1234\" }";
String request = "{ \"operation\" : \"remove\", \"subscriptionId\" : \"1234\" }";
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
decoder.decode(ctx, frame, results);
@@ -190,9 +246,8 @@ public class WebSocketRequestDecoderTest {
@Test
public void testCloseSubscription() throws Exception {
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
decoder = new WebSocketRequestDecoder(anonConfig);
String request = "{ \"operation\" : \"close\", \"sessionId\" : \"1234\" }";
String request = "{ \"operation\" : \"close\", \"subscriptionId\" : \"1234\" }";
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
decoder.decode(ctx, frame, results);
@@ -204,7 +259,6 @@ public class WebSocketRequestDecoderTest {
@Test
public void testAggregrators() throws Exception {
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
decoder = new WebSocketRequestDecoder(anonConfig);
String request = "{ \"operation\" : \"aggregators\", \"sessionId\" : \"1234\" }";
TextWebSocketFrame frame = new TextWebSocketFrame();
@@ -218,7 +272,6 @@ public class WebSocketRequestDecoderTest {
@Test
public void testMetrics() throws Exception {
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
decoder = new WebSocketRequestDecoder(anonConfig);
String request = "{ \"operation\" : \"metrics\", \"sessionId\" : \"1234\" }";
TextWebSocketFrame frame = new TextWebSocketFrame();
@@ -275,7 +328,6 @@ public class WebSocketRequestDecoderTest {
" ]\n"+
"}";
// @formatter:on
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
decoder = new WebSocketRequestDecoder(anonConfig);
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
@@ -289,7 +341,6 @@ public class WebSocketRequestDecoderTest {
@Test
public void testLookup() throws Exception {
String request = "{ \"operation\" : \"lookup\", \"sessionId\" : \"1234\", \"metric\" : \"sys.cpu.user\" }";
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
decoder = new WebSocketRequestDecoder(anonConfig);
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
@@ -313,7 +364,6 @@ public class WebSocketRequestDecoderTest {
" \"max\": 30\n" +
"}";
// @formatter:on
CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext();
decoder = new WebSocketRequestDecoder(anonConfig);
TextWebSocketFrame frame = new TextWebSocketFrame();
frame.content().writeBytes(request.getBytes(StandardCharsets.UTF_8));
@@ -17,7 +17,9 @@ import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpHeaders.Names;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.cookie.ClientCookieEncoder;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
@@ -34,6 +36,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.util.UtilWaitThread;
@@ -63,6 +66,7 @@ import timely.api.response.timeseries.SearchLookupResponse;
import timely.api.response.timeseries.SearchLookupResponse.Result;
import timely.api.response.timeseries.SuggestResponse;
import timely.auth.AuthCache;
import timely.netty.Constants;
import timely.test.IntegrationTest;
import timely.test.integration.OneWaySSLBase;
import timely.util.JsonUtil;
@@ -176,15 +180,22 @@ public class WebSocketIT extends OneWaySSLBase {
private Channel ch = null;
private ClientHandler handler = null;
private Server s = null;
private String sessionId = null;
@Before
public void setup() throws Exception {
s = new Server(conf);
AuthCache.getCache().put("1234", new UsernamePasswordAuthenticationToken("test", "test1"));
this.sessionId = UUID.randomUUID().toString();
AuthCache.getCache().put(sessionId, new UsernamePasswordAuthenticationToken("test", "test1"));
group = new NioEventLoopGroup();
SslContext ssl = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
String cookieVal = ClientCookieEncoder.STRICT.encode(Constants.COOKIE_NAME, sessionId);
HttpHeaders headers = new DefaultHttpHeaders();
headers.add(Names.COOKIE, cookieVal);
WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker(LOCATION,
WebSocketVersion.V13, (String) null, false, (HttpHeaders) new DefaultHttpHeaders());
WebSocketVersion.V13, (String) null, false, headers);
handler = new ClientHandler(handshaker);
Bootstrap boot = new Bootstrap();
boot.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
@@ -201,15 +212,16 @@ public class WebSocketIT extends OneWaySSLBase {
// Wait until handshake is complete
while (!handshaker.isHandshakeComplete()) {
UtilWaitThread.sleep(500L);
LOG.debug("Waiting for Handshake to complete");
}
}
@Test
public void testClientDisappears() throws Exception {
try {
final String sessionId = "1235";
final String subscriptionId = "1235";
CreateSubscription c = new CreateSubscription();
c.setSessionId(sessionId);
c.setSubscriptionId(subscriptionId);
ch.writeAndFlush(new TextWebSocketFrame(JsonUtil.getObjectMapper().writeValueAsString(c)));
// Add some data
@@ -223,7 +235,7 @@ public class WebSocketIT extends OneWaySSLBase {
// Add subscription, confirm data
AddSubscription add = new AddSubscription();
add.setSessionId(sessionId);
add.setSubscriptionId(subscriptionId);
add.setMetric("sys.cpu.user");
add.setDelayTime(1000L);
ch.writeAndFlush(new TextWebSocketFrame(JsonUtil.getObjectMapper().writeValueAsString(add)));
@@ -254,7 +266,8 @@ public class WebSocketIT extends OneWaySSLBase {
second.setTags(secondTags);
for (String metrics : response) {
MetricResponse m = JsonUtil.getObjectMapper().readValue(metrics, MetricResponse.class);
Assert.assertTrue(m.equals(first.toMetricResponse()) || m.equals(second.toMetricResponse()));
Assert.assertTrue(m.equals(first.toMetricResponse(subscriptionId))
|| m.equals(second.toMetricResponse(subscriptionId)));
}
} finally {
ch.close().sync();
@@ -266,9 +279,9 @@ public class WebSocketIT extends OneWaySSLBase {
@Test
public void testSubscriptionWorkflow() throws Exception {
try {
final String sessionId = "1234";
final String subscriptionId = "1234";
CreateSubscription c = new CreateSubscription();
c.setSessionId(sessionId);
c.setSubscriptionId(subscriptionId);
ch.writeAndFlush(new TextWebSocketFrame(JsonUtil.getObjectMapper().writeValueAsString(c)));
// Add some data
@@ -282,7 +295,7 @@ public class WebSocketIT extends OneWaySSLBase {
// Add subscription, confirm data
AddSubscription add = new AddSubscription();
add.setSessionId(sessionId);
add.setSubscriptionId(subscriptionId);
add.setMetric("sys.cpu.user");
add.setDelayTime(1000L);
ch.writeAndFlush(new TextWebSocketFrame(JsonUtil.getObjectMapper().writeValueAsString(add)));
@@ -313,7 +326,8 @@ public class WebSocketIT extends OneWaySSLBase {
second.setTags(secondTags);
for (String metrics : response) {
MetricResponse m = JsonUtil.getObjectMapper().readValue(metrics, MetricResponse.class);
Assert.assertTrue(m.equals(first.toMetricResponse()) || m.equals(second.toMetricResponse()));
Assert.assertTrue(m.equals(first.toMetricResponse(subscriptionId))
|| m.equals(second.toMetricResponse(subscriptionId)));
}
// Add some more data
@@ -352,12 +366,13 @@ public class WebSocketIT extends OneWaySSLBase {
second.setTags(secondTags);
for (String metrics : response) {
MetricResponse m = JsonUtil.getObjectMapper().readValue(metrics, MetricResponse.class);
Assert.assertTrue(m.equals(first.toMetricResponse()) || m.equals(second.toMetricResponse()));
Assert.assertTrue(m.equals(first.toMetricResponse(subscriptionId))
|| m.equals(second.toMetricResponse(subscriptionId)));
}
// Add subscription
AddSubscription add2 = new AddSubscription();
add2.setSessionId(sessionId);
add2.setSubscriptionId(subscriptionId);
add2.setMetric("sys.cpu.idle");
add2.setDelayTime(1000L);
ch.writeAndFlush(new TextWebSocketFrame(JsonUtil.getObjectMapper().writeValueAsString(add2)));
@@ -410,23 +425,25 @@ public class WebSocketIT extends OneWaySSLBase {
fourth.setTags(fourthTags);
for (String metrics : response) {
MetricResponse m = JsonUtil.getObjectMapper().readValue(metrics, MetricResponse.class);
Assert.assertTrue(m.equals(first.toMetricResponse()) || m.equals(second.toMetricResponse())
|| m.equals(third.toMetricResponse()) || m.equals(fourth.toMetricResponse()));
Assert.assertTrue(m.equals(first.toMetricResponse(subscriptionId))
|| m.equals(second.toMetricResponse(subscriptionId))
|| m.equals(third.toMetricResponse(subscriptionId))
|| m.equals(fourth.toMetricResponse(subscriptionId)));
}
// Remove subscriptions to metric
RemoveSubscription remove1 = new RemoveSubscription();
remove1.setSessionId(sessionId);
remove1.setSubscriptionId(subscriptionId);
remove1.setMetric("sys.cpu.user");
ch.writeAndFlush(new TextWebSocketFrame(JsonUtil.getObjectMapper().writeValueAsString(remove1)));
RemoveSubscription remove2 = new RemoveSubscription();
remove2.setSessionId(sessionId);
remove2.setSubscriptionId(subscriptionId);
remove2.setMetric("sys.cpu.idle");
ch.writeAndFlush(new TextWebSocketFrame(JsonUtil.getObjectMapper().writeValueAsString(remove2)));
// Close subscription
CloseSubscription close = new CloseSubscription();
close.setSessionId(sessionId);
close.setSubscriptionId(subscriptionId);
ch.writeAndFlush(new TextWebSocketFrame(JsonUtil.getObjectMapper().writeValueAsString(close)));
} finally {
ch.close().sync();
@@ -439,7 +456,6 @@ public class WebSocketIT extends OneWaySSLBase {
public void testWSAggregators() throws Exception {
try {
AggregatorsRequest request = new AggregatorsRequest();
request.setSessionId("1234");
ch.writeAndFlush(new TextWebSocketFrame(JsonUtil.getObjectMapper().writeValueAsString(request)));
// Latency in TestConfiguration is 2s, wait for it
sleepUninterruptibly(4, TimeUnit.SECONDS);
@@ -464,7 +480,6 @@ public class WebSocketIT extends OneWaySSLBase {
public void testWSMetrics() throws Exception {
try {
MetricsRequest request = new MetricsRequest();
request.setSessionId("1234");
ch.writeAndFlush(new TextWebSocketFrame(JsonUtil.getObjectMapper().writeValueAsString(request)));
// Confirm receipt of all data sent to this point
@@ -496,7 +511,6 @@ public class WebSocketIT extends OneWaySSLBase {
String request =
"{"+
" \"operation\" : \"query\","+
" \"sessionId\" : \"1234\","+
" \"start\": "+TEST_TIME+","+
" \"end\": "+(TEST_TIME+6000)+","+
" \"queries\": ["+
@@ -557,7 +571,6 @@ public class WebSocketIT extends OneWaySSLBase {
String request =
"{"+
" \"operation\" : \"lookup\","+
" \"sessionId\" : \"1234\","+
" \"metric\" : \"sys.cpu.idle\","+
" \"tags\" : ["+
"\"tag3=*\""+
@@ -600,7 +613,6 @@ public class WebSocketIT extends OneWaySSLBase {
String request =
"{\n" +
" \"operation\" : \"suggest\",\n" +
" \"sessionId\" : \"1234\",\n" +
" \"type\": \"metrics\",\n" +
" \"q\": \"sys.cpu.user\",\n" +
" \"max\": 30\n" +