@@ -10,6 +10,7 @@ const {
10
10
GraphQLList,
11
11
GraphQLInt,
12
12
GraphQLNonNull,
13
+ GraphQLBoolean,
13
14
} = require ( 'graphql' ) ;
14
15
15
16
//---------------Internal Module Imports----------------
@@ -34,6 +35,15 @@ const RealTimeType = new GraphQLObjectType({
34
35
resolve : ( parent , args , context ) => parent [ 1 ]
35
36
}
36
37
} )
38
+ } ) ;
39
+
40
+ const ValidationType = new GraphQLObjectType ( {
41
+ name : 'inputValidation' ,
42
+ description : 'Object indicating input validity status and error message' ,
43
+ fields : ( ) => ( {
44
+ isValid : { type : GraphQLBoolean } ,
45
+ error : { type : GraphQLString }
46
+ } )
37
47
} )
38
48
39
49
//---------------Root Query Types----------------
@@ -48,13 +58,140 @@ const RootQueryType = new GraphQLObjectType({
48
58
metric : { type : GraphQLNonNull ( GraphQLString ) } ,
49
59
start : { type : GraphQLNonNull ( GraphQLInt ) } ,
50
60
end : { type : GraphQLNonNull ( GraphQLInt ) } ,
51
- resolution : { type : GraphQLNonNull ( GraphQLInt ) }
61
+ resolution : { type : GraphQLNonNull ( GraphQLInt ) } ,
62
+ prometheusURL : { type : GraphQLNonNull ( GraphQLString ) }
52
63
} ,
53
- resolve : ( parent , { start, end, resolution, metric} ) => {
54
- return axios . get ( `http://localhost:9090/api/v1/query_range?step=${ resolution } s&end=${ end } &start=${ start } &query=${ queryTypes [ metric ] } ` )
55
- . then ( res => res . data . data . result [ 0 ] . values )
64
+ resolve : ( parent , { start, end, resolution, metric, prometheusURL} ) => {
65
+ if ( prometheusURL [ prometheusURL . length - 1 ] === '/' ) prometheusURL = prometheusURL . slice ( 0 , prometheusURL . length - 1 ) ;
66
+
67
+ return axios . get ( `${ prometheusURL } /api/v1/query_range?step=${ resolution } s&end=${ end } &start=${ start } &query=${ queryTypes [ metric ] } ` )
68
+ . then ( res => {
69
+ return res . data . data . result [ 0 ] . values } )
56
70
. catch ( error => error ) ;
57
71
}
72
+ } ,
73
+ livenessIndicator : {
74
+ type : GraphQLBoolean ,
75
+ description : 'Boolean value representing whether the ksqlDB server up and emitting metrics.' ,
76
+ args : {
77
+ prometheusURL : { type : GraphQLNonNull ( GraphQLString ) }
78
+ } ,
79
+ resolve : async ( parent , { prometheusURL } ) => {
80
+ try {
81
+ return await axios . get ( `${ prometheusURL } /api/v1/query?query=ksql_ksql_engine_query_stats_liveness_indicator` )
82
+ . then ( res => res . data . data . result [ 0 ] . value [ 1 ] === "1" )
83
+ . catch ( error => { throw error } ) ;
84
+ } catch ( error ) {
85
+ return error ;
86
+ }
87
+ }
88
+ } ,
89
+ errorRate : {
90
+ type : GraphQLInt ,
91
+ description : 'The number of messages that were consumed but not processed.' ,
92
+ args : {
93
+ prometheusURL : { type : GraphQLNonNull ( GraphQLString ) }
94
+ } ,
95
+ resolve : async ( parent , { prometheusURL } ) => {
96
+ try {
97
+ return await axios . get ( `${ prometheusURL } /api/v1/query?query=ksql_ksql_engine_query_stats_error_rate` )
98
+ . then ( res => Number ( res . data . data . result [ 0 ] . value [ 1 ] ) )
99
+ . catch ( error => { throw error } ) ;
100
+ } catch ( error ) {
101
+ return error ;
102
+ }
103
+ }
104
+ } ,
105
+ errorQueries : {
106
+ type : GraphQLInt ,
107
+ description : 'The count of queries in ERROR state.' ,
108
+ args : {
109
+ prometheusURL : { type : GraphQLNonNull ( GraphQLString ) }
110
+ } ,
111
+ resolve : async ( parent , { prometheusURL } ) => {
112
+ try {
113
+ return await axios . get ( `${ prometheusURL } /api/v1/query?query=ksql_ksql_engine_query_stats_error_queries` )
114
+ . then ( res => Number ( res . data . data . result [ 0 ] . value [ 1 ] ) )
115
+ . catch ( error => { throw error } ) ;
116
+ } catch ( error ) {
117
+ return error ;
118
+ }
119
+ }
120
+ } ,
121
+ bytesConsumed : {
122
+ type : GraphQLInt ,
123
+ description : 'The total number of bytes consumed across all queries.' ,
124
+ args : {
125
+ prometheusURL : { type : GraphQLNonNull ( GraphQLString ) }
126
+ } ,
127
+ resolve : async ( parent , { prometheusURL } ) => {
128
+ try {
129
+ return await axios . get ( `${ prometheusURL } /api/v1/query?query=ksql_ksql_engine_query_stats_bytes_consumed_total` )
130
+ . then ( res => Number ( res . data . data . result [ 0 ] . value [ 1 ] ) )
131
+ . catch ( error => { throw error } ) ;
132
+ } catch ( error ) {
133
+ return error ;
134
+ }
135
+ }
136
+ } ,
137
+ isValidPrometheusURL : {
138
+ type : ValidationType ,
139
+ description : 'Object representing whether provided Prometheus URL points to valid Prometheus server and any errors' ,
140
+ args : {
141
+ prometheusURL : { type : GraphQLNonNull ( GraphQLString ) }
142
+ } ,
143
+ resolve : async ( parent , { prometheusURL } ) => {
144
+ if ( prometheusURL [ prometheusURL . length - 1 ] === '/' ) prometheusURL = prometheusURL . slice ( 0 , prometheusURL . length - 1 ) ;
145
+
146
+ return axios . get ( `${ prometheusURL } /api/v1/status/buildinfo` )
147
+ . then ( res => ( {
148
+ isValid : true ,
149
+ error : null
150
+ } ) )
151
+ . catch ( error => ( {
152
+ isValid : false ,
153
+ error : error . message
154
+ } ) ) ;
155
+ }
156
+ } ,
157
+ isValidKsqlDBURL : {
158
+ type : ValidationType ,
159
+ description : 'Object representing whether provided ksqlDB URL points to valid Prometheus server and any errors' ,
160
+ args : {
161
+ ksqlDBURL : { type : GraphQLNonNull ( GraphQLString ) }
162
+ } ,
163
+ resolve : ( parent , { ksqlDBURL } ) => {
164
+ if ( ksqlDBURL [ ksqlDBURL . length - 1 ] === '/' ) ksqlDBURL = ksqlDBURL . slice ( 0 , ksqlDBURL . length - 1 ) ;
165
+
166
+ return axios . get ( `${ ksqlDBURL } /clusterStatus` )
167
+ . then ( res => ( {
168
+ isValid : true ,
169
+ error : null
170
+ } ) )
171
+ . catch ( error => ( {
172
+ isValid : false ,
173
+ error : error . message
174
+ } ) ) ;
175
+ }
176
+ } ,
177
+ isValidDuration : {
178
+ type : GraphQLBoolean ,
179
+ description : 'Boolean representing whether Prometheus server accepts user duration.' ,
180
+ args : {
181
+ metric : { type : GraphQLNonNull ( GraphQLString ) } ,
182
+ start : { type : GraphQLNonNull ( GraphQLInt ) } ,
183
+ end : { type : GraphQLNonNull ( GraphQLInt ) } ,
184
+ resolution : { type : GraphQLNonNull ( GraphQLInt ) } ,
185
+ prometheusURL : { type : GraphQLNonNull ( GraphQLString ) }
186
+ } ,
187
+ resolve : ( parent , { start, end, resolution, metric, prometheusURL } ) => {
188
+ if ( prometheusURL [ prometheusURL . length - 1 ] === '/' ) prometheusURL = prometheusURL . slice ( 0 , prometheusURL . length - 1 ) ;
189
+
190
+
191
+ return axios . get ( `${ prometheusURL } /api/v1/query_range?step=${ resolution } s&end=${ end } &start=${ start } &query=${ queryTypes [ metric ] } ` )
192
+ . then ( res => true )
193
+ . catch ( error => false ) ;
194
+ }
58
195
}
59
196
} )
60
197
} ) ;
@@ -68,4 +205,4 @@ app.use('/graphql', graphqlHTTP({
68
205
graphiql : true
69
206
} ) ) ;
70
207
71
- app . listen ( 5000 , ( ) => console . log ( 'Server Running...' ) ) ;
208
+ app . listen ( 5001 , ( ) => console . log ( 'Server Running...' ) ) ;
0 commit comments