package org.kairosdb.client;
import com.google.gson.stream.JsonReader;
import org.kairosdb.client.builder.MetricBuilder;
import org.kairosdb.client.builder.QueryBuilder;
import org.kairosdb.client.builder.QueryTagBuilder;
import org.kairosdb.client.response.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.kairosdb.client.util.Preconditions.checkNotNullOrEmpty;
/**
* Base code used to send metrics to Kairos or query Kairos.
*/
public abstract class AbstractClient implements Client
{
private String url;
private JsonMapper mapper;
private DataPointTypeRegistry typeRegistry;
/**
* Creates a client
*
* @param url url to the KairosDB server
* @throws MalformedURLException if url is malformed
*/
protected AbstractClient(String url) throws MalformedURLException
{
this.url = checkNotNullOrEmpty(url);
new URL(url); // validate url
typeRegistry = new DataPointTypeRegistry();
mapper = new JsonMapper(typeRegistry);
}
@Override
public GetResponse getMetricNames() throws IOException
{
return get(url + "/api/v1/metricnames");
}
@Override
public GetResponse getTagNames() throws IOException
{
return get(url + "/api/v1/tagnames");
}
@Override
public GetResponse getTagValues() throws IOException
{
return get(url + "/api/v1/tagvalues");
}
@Override
public QueryTagResponse queryTag(QueryTagBuilder builder) throws URISyntaxException, IOException
{
ClientResponse clientResponse = postData(builder.build(), url + "/api/v1/datapoints/query/tags");
int responseCode = clientResponse.getStatusCode();
InputStream stream = clientResponse.getContentStream();
return new QueryTagResponse(mapper, responseCode, stream);
}
@Override
public QueryResponse query(QueryBuilder builder) throws URISyntaxException, IOException
{
ClientResponse clientResponse = postData(builder.build(), url + "/api/v1/datapoints/query");
int responseCode = clientResponse.getStatusCode();
InputStream stream = clientResponse.getContentStream();
return new QueryResponse(mapper, responseCode, stream);
}
@Override
public Response pushMetrics(MetricBuilder builder) throws URISyntaxException, IOException
{
checkNotNull(builder);
ClientResponse clientResponse = postData(builder.build(), url + "/api/v1/datapoints");
return getResponse(clientResponse);
}
@Override
public Response deleteMetric(String name) throws IOException
{
checkNotNullOrEmpty(name);
ClientResponse response = delete(url + "/api/v1/metric/" + name);
return getResponse(response);
}
@Override
public Response delete(QueryBuilder builder) throws URISyntaxException, IOException
{
checkNotNull(builder);
ClientResponse clientResponse = postData(builder.build(), url + "/api/v1/datapoints/delete");
return getResponse(clientResponse);
}
@Override
public void registerCustomDataType(String groupType, Class dataPointClass)
{
typeRegistry.registerCustomDataType(groupType, dataPointClass);
}
@Override
public Class getDataPointValueClass(String groupType)
{
return typeRegistry.getDataPointValueClass(groupType);
}
private Response getResponse(ClientResponse clientResponse) throws IOException
{
Response response = new Response(clientResponse.getStatusCode());
InputStream stream = clientResponse.getContentStream();
if (stream != null)
{
InputStreamReader reader = new InputStreamReader(stream);
try
{
ErrorResponse errorResponse = mapper.fromJson(reader, ErrorResponse.class);
response.addErrors(errorResponse.getErrors());
}
finally
{
reader.close();
}
}
return response;
}
private GetResponse get(String url) throws IOException
{
ClientResponse clientResponse = queryData(url);
int responseCode = clientResponse.getStatusCode();
if (responseCode >= 400)
{
return new GetResponse(responseCode);
}
else
{
InputStream stream = clientResponse.getContentStream();
if (stream == null)
{
throw new IOException("Could not get content stream.");
}
return new GetResponse(responseCode, readNameQueryResponse(stream));
}
}
private List<String> readNameQueryResponse(InputStream stream) throws IOException
{
List<String> list = new ArrayList<String>();
JsonReader reader = new JsonReader(new InputStreamReader(stream, "UTF-8"));
try
{
reader.beginObject();
String container = reader.nextName();
if (container.equals("results"))
{
reader.beginArray();
while (reader.hasNext())
{
list.add(reader.nextString());
}
reader.endArray();
reader.endObject();
}
}
finally
{
reader.close();
}
return list;
}
protected abstract ClientResponse postData(String json, String url) throws IOException;
protected abstract ClientResponse queryData(String url) throws IOException;
protected abstract ClientResponse delete(String url) throws IOException;
}