summaryrefslogtreecommitdiff
path: root/src/com/p4square
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/p4square')
-rw-r--r--src/com/p4square/f1oauth/F1Access.java279
-rw-r--r--src/com/p4square/grow/GrowProcessComponent.java20
-rw-r--r--src/com/p4square/grow/backend/GrowBackend.java18
-rw-r--r--src/com/p4square/grow/frontend/GrowFrontend.java21
-rw-r--r--src/com/p4square/restlet/metrics/MetricRouter.java61
-rw-r--r--src/com/p4square/restlet/metrics/MetricsApplication.java43
-rw-r--r--src/com/p4square/restlet/metrics/MetricsResource.java32
7 files changed, 401 insertions, 73 deletions
diff --git a/src/com/p4square/f1oauth/F1Access.java b/src/com/p4square/f1oauth/F1Access.java
index 5b6f7ce..c3307f1 100644
--- a/src/com/p4square/f1oauth/F1Access.java
+++ b/src/com/p4square/f1oauth/F1Access.java
@@ -12,6 +12,10 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Timer;
+
import org.apache.log4j.Logger;
import org.restlet.Context;
@@ -60,6 +64,8 @@ public class F1Access {
private final Map<String, String> mAttributeIdByName;
+ private MetricRegistry mMetricRegistry;
+
/**
*/
public F1Access(Context context, String consumerKey, String consumerSecret,
@@ -108,19 +114,46 @@ public class F1Access {
}
/**
+ * Set the MetricRegistry to get metrics recorded.
+ */
+ public void setMetricRegistry(MetricRegistry metrics) {
+ mMetricRegistry = metrics;
+ }
+
+ /**
* Request an AccessToken for a particular username and password.
*
* This is an F1 extension to OAuth:
* http://developer.fellowshipone.com/docs/v1/Util/AuthDocs.help#2creds
*/
public OAuthUser getAccessToken(String username, String password) throws OAuthException {
- Request request = new Request(Method.POST, mBaseUrl + mMethod + TRUSTED_ACCESSTOKEN_URL);
- request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_OAUTH));
+ Timer.Context timer = getTimer("F1Access.getAccessToken.time");
+ boolean success = true;
+
+ try {
+ Request request = new Request(Method.POST,
+ mBaseUrl + mMethod + TRUSTED_ACCESSTOKEN_URL);
+ request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_OAUTH));
+
+ String base64String = Base64.encode((username + " " + password).getBytes(), false);
+ request.setEntity(new StringRepresentation(base64String));
- String base64String = Base64.encode((username + " " + password).getBytes(), false);
- request.setEntity(new StringRepresentation(base64String));
+ return mOAuthHelper.processAccessTokenRequest(request);
- return mOAuthHelper.processAccessTokenRequest(request);
+ } catch (Exception e) {
+ success = false;
+ throw e;
+
+ } finally {
+ if (timer != null) {
+ timer.stop();
+ }
+ if (success) {
+ incrementCounter("F1Access.getAccessToken.success");
+ } else {
+ incrementCounter("F1Access.getAccessToken.failure");
+ }
+ }
}
/**
@@ -135,26 +168,45 @@ public class F1Access {
*/
public boolean createAccount(String firstname, String lastname, String email, String redirect)
throws OAuthException {
- String req = String.format("{\n\"account\":{\n\"firstName\":\"%s\",\n"
- + "\"lastName\":\"%s\",\n\"email\":\"%s\",\n"
- + "\"urlRedirect\":\"%s\"\n}\n}",
- firstname, lastname, email, redirect);
+ Timer.Context timer = getTimer("F1Access.createAccount.time");
+ boolean success = true;
- Request request = new Request(Method.POST, mBaseUrl + "Accounts");
- request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_OAUTH));
- request.setEntity(new StringRepresentation(req, MediaType.APPLICATION_JSON));
+ try {
+ String req = String.format("{\n\"account\":{\n\"firstName\":\"%s\",\n"
+ + "\"lastName\":\"%s\",\n\"email\":\"%s\",\n"
+ + "\"urlRedirect\":\"%s\"\n}\n}",
+ firstname, lastname, email, redirect);
- Response response = mOAuthHelper.getResponse(request);
+ Request request = new Request(Method.POST, mBaseUrl + "Accounts");
+ request.setChallengeResponse(new ChallengeResponse(ChallengeScheme.HTTP_OAUTH));
+ request.setEntity(new StringRepresentation(req, MediaType.APPLICATION_JSON));
- Status status = response.getStatus();
- if (Status.SUCCESS_NO_CONTENT.equals(status)) {
- return true;
+ Response response = mOAuthHelper.getResponse(request);
- } else if (Status.CLIENT_ERROR_CONFLICT.equals(status)) {
- return false;
+ Status status = response.getStatus();
+ if (Status.SUCCESS_NO_CONTENT.equals(status)) {
+ return true;
- } else {
- throw new OAuthException(status);
+ } else if (Status.CLIENT_ERROR_CONFLICT.equals(status)) {
+ return false;
+
+ } else {
+ throw new OAuthException(status);
+ }
+
+ } catch (Exception e) {
+ success = false;
+ throw e;
+
+ } finally {
+ if (timer != null) {
+ timer.stop();
+ }
+ if (success) {
+ incrementCounter("F1Access.createAccount.success");
+ } else {
+ incrementCounter("F1Access.createAccount.failure");
+ }
}
}
@@ -180,24 +232,44 @@ public class F1Access {
*/
@Override
public F1User getF1User(OAuthUser user) throws OAuthException, IOException {
- Request request = new Request(Method.GET, user.getLocation() + ".json");
- request.setChallengeResponse(mUser.getChallengeResponse());
- Response response = mOAuthHelper.getResponse(request);
+ Timer.Context timer = getTimer("F1Access.getF1User.time");
+ boolean success = true;
try {
- Status status = response.getStatus();
- if (status.isSuccess()) {
- JacksonRepresentation<Map> entity =
- new JacksonRepresentation<Map>(response.getEntity(), Map.class);
- Map data = entity.getObject();
- return new F1User(user, data);
+ Request request = new Request(Method.GET, user.getLocation() + ".json");
+ request.setChallengeResponse(mUser.getChallengeResponse());
+ Response response = mOAuthHelper.getResponse(request);
- } else {
- throw new OAuthException(status);
+ try {
+ Status status = response.getStatus();
+ if (status.isSuccess()) {
+ JacksonRepresentation<Map> entity =
+ new JacksonRepresentation<Map>(response.getEntity(), Map.class);
+ Map data = entity.getObject();
+ return new F1User(user, data);
+
+ } else {
+ throw new OAuthException(status);
+ }
+
+ } finally {
+ if (response.getEntity() != null) {
+ response.release();
+ }
}
+
+ } catch (Exception e) {
+ success = false;
+ throw e;
+
} finally {
- if (response.getEntity() != null) {
- response.release();
+ if (timer != null) {
+ timer.stop();
+ }
+ if (success) {
+ incrementCounter("F1Access.getF1User.success");
+ } else {
+ incrementCounter("F1Access.getF1User.failure");
}
}
}
@@ -207,42 +279,61 @@ public class F1Access {
// Note: this list is shared by all F1 users.
synchronized (mAttributeIdByName) {
if (mAttributeIdByName.size() == 0) {
- // Reload attributes. Maybe it will be there now...
- Request request = new Request(Method.GET,
- mBaseUrl + "People/AttributeGroups.json");
- request.setChallengeResponse(mUser.getChallengeResponse());
- Response response = mOAuthHelper.getResponse(request);
+ Timer.Context timer = getTimer("F1Access.getAttributeList.time");
+ boolean success = true;
- Representation representation = response.getEntity();
try {
- Status status = response.getStatus();
- if (status.isSuccess()) {
- JacksonRepresentation<Map> entity =
- new JacksonRepresentation<Map>(response.getEntity(), Map.class);
-
- Map attributeGroups = (Map) entity.getObject().get("attributeGroups");
- List<Map> groups = (List<Map>) attributeGroups.get("attributeGroup");
-
- for (Map group : groups) {
- List<Map> attributes = (List<Map>) group.get("attribute");
- if (attributes != null) {
- for (Map attribute : attributes) {
- String id = (String) attribute.get("@id");
- String name = ((String) attribute.get("name"));
- mAttributeIdByName.put(name.toLowerCase(), id);
- LOG.debug("Caching attribute '" + name
- + "' with id '" + id + "'");
+ // Reload attributes. Maybe it will be there now...
+ Request request = new Request(Method.GET,
+ mBaseUrl + "People/AttributeGroups.json");
+ request.setChallengeResponse(mUser.getChallengeResponse());
+ Response response = mOAuthHelper.getResponse(request);
+
+ Representation representation = response.getEntity();
+ try {
+ Status status = response.getStatus();
+ if (status.isSuccess()) {
+ JacksonRepresentation<Map> entity =
+ new JacksonRepresentation<Map>(response.getEntity(), Map.class);
+
+ Map attributeGroups = (Map) entity.getObject().get("attributeGroups");
+ List<Map> groups = (List<Map>) attributeGroups.get("attributeGroup");
+
+ for (Map group : groups) {
+ List<Map> attributes = (List<Map>) group.get("attribute");
+ if (attributes != null) {
+ for (Map attribute : attributes) {
+ String id = (String) attribute.get("@id");
+ String name = ((String) attribute.get("name"));
+ mAttributeIdByName.put(name.toLowerCase(), id);
+ LOG.debug("Caching attribute '" + name
+ + "' with id '" + id + "'");
+ }
}
}
}
+
+ } catch (IOException e) {
+ throw new F1Exception("Could not parse AttributeGroups.", e);
+
+ } finally {
+ if (representation != null) {
+ representation.release();
+ }
}
- } catch (IOException e) {
- throw new F1Exception("Could not parse AttributeGroups.", e);
+ } catch (Exception e) {
+ success = false;
+ throw e;
} finally {
- if (representation != null) {
- representation.release();
+ if (timer != null) {
+ timer.stop();
+ }
+ if (success) {
+ incrementCounter("F1Access.getAttributeList.success");
+ } else {
+ incrementCounter("F1Access.getAttributeList.failure");
}
}
}
@@ -270,7 +361,10 @@ public class F1Access {
// Get Attribute Template
Map attributeTemplate = null;
- {
+ Timer.Context timer = getTimer("F1Access.addAttribute.GET.time");
+ boolean success = true;
+
+ try {
Request request = new Request(Method.GET,
mBaseUrl + "People/" + userId + "/Attributes/new.json");
request.setChallengeResponse(mUser.getChallengeResponse());
@@ -297,6 +391,19 @@ public class F1Access {
representation.release();
}
}
+ } catch (Exception e) {
+ success = false;
+ throw e;
+
+ } finally {
+ if (timer != null) {
+ timer.stop();
+ }
+ if (success) {
+ incrementCounter("F1Access.addAttribute.GET.success");
+ } else {
+ incrementCounter("F1Access.addAttribute.GET.failure");
+ }
}
if (attributeTemplate == null) {
@@ -323,7 +430,10 @@ public class F1Access {
// POST new attribute
Status status;
- {
+ timer = getTimer("F1Access.addAttribute.POST.time");
+ success = true;
+
+ try {
Request request = new Request(Method.POST,
mBaseUrl + "People/" + userId + "/Attributes.json");
request.setChallengeResponse(mUser.getChallengeResponse());
@@ -343,6 +453,19 @@ public class F1Access {
representation.release();
}
}
+ } catch (Exception e) {
+ success = false;
+ throw e;
+
+ } finally {
+ if (timer != null) {
+ timer.stop();
+ }
+ if (success) {
+ incrementCounter("F1Access.addAttribute.POST.success");
+ } else {
+ incrementCounter("F1Access.getAccessToken.POST.failure");
+ }
}
LOG.debug("addAttribute failed POST: " + status);
@@ -356,7 +479,10 @@ public class F1Access {
Map attributesResponse;
// Get Attributes
- {
+ Timer.Context timer = getTimer("F1Access.getAttribute.time");
+ boolean success = true;
+
+ try {
Request request = new Request(Method.GET,
mBaseUrl + "People/" + userId + "/Attributes.json");
request.setChallengeResponse(mUser.getChallengeResponse());
@@ -383,6 +509,19 @@ public class F1Access {
representation.release();
}
}
+ } catch (Exception e) {
+ success = false;
+ throw e;
+
+ } finally {
+ if (timer != null) {
+ timer.stop();
+ }
+ if (success) {
+ incrementCounter("F1Access.getAttribute.success");
+ } else {
+ incrementCounter("F1Access.getAttribute.failure");
+ }
}
// Parse Response
@@ -438,4 +577,18 @@ public class F1Access {
}
}
+
+ private Timer.Context getTimer(String name) {
+ if (mMetricRegistry != null) {
+ return mMetricRegistry.timer(name).time();
+ } else {
+ return null;
+ }
+ }
+
+ private void incrementCounter(String name) {
+ if (mMetricRegistry != null) {
+ mMetricRegistry.counter(name).inc();
+ }
+ }
}
diff --git a/src/com/p4square/grow/GrowProcessComponent.java b/src/com/p4square/grow/GrowProcessComponent.java
index 791f177..f63538c 100644
--- a/src/com/p4square/grow/GrowProcessComponent.java
+++ b/src/com/p4square/grow/GrowProcessComponent.java
@@ -6,6 +6,10 @@ package com.p4square.grow;
import java.io.File;
import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import com.codahale.metrics.ConsoleReporter;
+import com.codahale.metrics.MetricRegistry;
import org.apache.log4j.Logger;
@@ -21,6 +25,7 @@ import com.p4square.grow.backend.BackendVerifier;
import com.p4square.grow.backend.GrowBackend;
import com.p4square.grow.config.Config;
import com.p4square.grow.frontend.GrowFrontend;
+import com.p4square.restlet.metrics.MetricsApplication;
/**
*
@@ -32,6 +37,7 @@ public class GrowProcessComponent extends Component {
private static final String BACKEND_REALM = "Grow Backend";
private final Config mConfig;
+ private final MetricRegistry mMetricRegistry;
/**
* Create a new Grow Process website component combining a frontend and backend.
@@ -50,12 +56,15 @@ public class GrowProcessComponent extends Component {
mConfig = config;
mConfig.updateConfig(this.getClass().getResourceAsStream("/grow.properties"));
+ // Prepare Metrics
+ mMetricRegistry = new MetricRegistry();
+
// Frontend
- GrowFrontend frontend = new GrowFrontend(mConfig);
+ GrowFrontend frontend = new GrowFrontend(mConfig, mMetricRegistry);
getDefaultHost().attach(frontend);
// Backend
- GrowBackend backend = new GrowBackend(mConfig);
+ GrowBackend backend = new GrowBackend(mConfig, mMetricRegistry);
getInternalRouter().attach("/backend", backend);
// Authenticated access to the backend
@@ -64,6 +73,13 @@ public class GrowProcessComponent extends Component {
false, ChallengeScheme.HTTP_BASIC, BACKEND_REALM, verifier);
auth.setNext(backend);
getDefaultHost().attach("/backend", auth);
+
+ // Authenticated access to metrics
+ ChallengeAuthenticator metricAuth = new ChallengeAuthenticator(
+ getContext().createChildContext(), false,
+ ChallengeScheme.HTTP_BASIC, BACKEND_REALM, verifier);
+ metricAuth.setNext(new MetricsApplication(mMetricRegistry));
+ getDefaultHost().attach("/metrics", metricAuth);
}
diff --git a/src/com/p4square/grow/backend/GrowBackend.java b/src/com/p4square/grow/backend/GrowBackend.java
index e73ad38..4091138 100644
--- a/src/com/p4square/grow/backend/GrowBackend.java
+++ b/src/com/p4square/grow/backend/GrowBackend.java
@@ -6,6 +6,8 @@ package com.p4square.grow.backend;
import java.io.IOException;
+import com.codahale.metrics.MetricRegistry;
+
import org.apache.log4j.Logger;
import org.restlet.Application;
@@ -42,6 +44,8 @@ import com.p4square.grow.backend.feed.FeedDataProvider;
import com.p4square.grow.backend.feed.ThreadResource;
import com.p4square.grow.backend.feed.TopicResource;
+import com.p4square.restlet.metrics.MetricRouter;
+
/**
* Main class for the backend application.
*
@@ -51,22 +55,30 @@ public class GrowBackend extends Application implements GrowData {
private final static Logger LOG = Logger.getLogger(GrowBackend.class);
+ private final MetricRegistry mMetricRegistry;
+
private final Config mConfig;
private final GrowData mGrowData;
public GrowBackend() {
- this(new Config());
+ this(new Config(), new MetricRegistry());
}
- public GrowBackend(Config config) {
+ public GrowBackend(Config config, MetricRegistry metricRegistry) {
mConfig = config;
+ mMetricRegistry = metricRegistry;
+
mGrowData = new DynamoGrowData(config);
}
+ public MetricRegistry getMetrics() {
+ return mMetricRegistry;
+ }
+
@Override
public Restlet createInboundRoot() {
- Router router = new Router(getContext());
+ Router router = new MetricRouter(getContext(), mMetricRegistry);
// Account API
router.attach("/accounts/{userId}", AccountResource.class);
diff --git a/src/com/p4square/grow/frontend/GrowFrontend.java b/src/com/p4square/grow/frontend/GrowFrontend.java
index 926670b..37d4984 100644
--- a/src/com/p4square/grow/frontend/GrowFrontend.java
+++ b/src/com/p4square/grow/frontend/GrowFrontend.java
@@ -23,6 +23,8 @@ import org.restlet.routing.Redirector;
import org.restlet.routing.Router;
import org.restlet.security.Authenticator;
+import com.codahale.metrics.MetricRegistry;
+
import org.apache.log4j.Logger;
import com.p4square.fmfacade.FMFacade;
@@ -33,6 +35,8 @@ import com.p4square.grow.config.Config;
import com.p4square.f1oauth.F1Access;
import com.p4square.f1oauth.SecondPartyVerifier;
+import com.p4square.restlet.metrics.MetricRouter;
+
import com.p4square.session.SessionCheckingAuthenticator;
import com.p4square.session.SessionCreatingAuthenticator;
@@ -47,22 +51,28 @@ import com.p4square.session.SessionCreatingAuthenticator;
public class GrowFrontend extends FMFacade {
private static Logger LOG = Logger.getLogger(GrowFrontend.class);
- private Config mConfig;
+ private final Config mConfig;
+ private final MetricRegistry mMetricRegistry;
private F1Access mHelper;
public GrowFrontend() {
- this(new Config());
+ this(new Config(), new MetricRegistry());
}
- public GrowFrontend(Config config) {
+ public GrowFrontend(Config config, MetricRegistry metricRegistry) {
mConfig = config;
+ mMetricRegistry = metricRegistry;
}
public Config getConfig() {
return mConfig;
}
+ public MetricRegistry getMetrics() {
+ return mMetricRegistry;
+ }
+
@Override
public synchronized void start() throws Exception {
Template errorTemplate = getTemplate("templates/error.ftl");
@@ -80,6 +90,7 @@ public class GrowFrontend extends FMFacade {
mConfig.getString("f1BaseUrl", "staging.fellowshiponeapi.com"),
mConfig.getString("f1ChurchCode", "pfseawa"),
F1Access.UserType.WEBLINK);
+ mHelper.setMetricRegistry(mMetricRegistry);
}
return mHelper;
@@ -87,7 +98,7 @@ public class GrowFrontend extends FMFacade {
@Override
protected Router createRouter() {
- Router router = new Router(getContext());
+ Router router = new MetricRouter(getContext(), mMetricRegistry);
final Authenticator defaultGuard = new SessionCheckingAuthenticator(getContext(), true);
defaultGuard.setNext(FreeMarkerPageResource.class);
@@ -97,7 +108,7 @@ public class GrowFrontend extends FMFacade {
router.attach("/newaccount.html", NewAccountResource.class);
router.attach("/newbeliever", NewBelieverResource.class);
- final Router accountRouter = new Router(getContext());
+ final Router accountRouter = new MetricRouter(getContext(), mMetricRegistry);
accountRouter.attach("/authenticate", AuthenticatedResource.class);
accountRouter.attach("/logout", LogoutResource.class);
diff --git a/src/com/p4square/restlet/metrics/MetricRouter.java b/src/com/p4square/restlet/metrics/MetricRouter.java
new file mode 100644
index 0000000..d4da270
--- /dev/null
+++ b/src/com/p4square/restlet/metrics/MetricRouter.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014 Jesse Morgan
+ */
+
+package com.p4square.restlet.metrics;
+
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Timer;
+
+import org.restlet.Context;
+import org.restlet.Request;
+import org.restlet.Response;
+import org.restlet.Restlet;
+import org.restlet.routing.TemplateRoute;
+import org.restlet.routing.Router;
+
+/**
+ *
+ * @author Jesse Morgan <jesse@jesterpm.net>
+ */
+public class MetricRouter extends Router {
+
+ private final MetricRegistry mMetricRegistry;
+
+ public MetricRouter(Context context, MetricRegistry metrics) {
+ super(context);
+ mMetricRegistry = metrics;
+ }
+
+ @Override
+ protected void doHandle(Restlet next, Request request, Response response) {
+ String baseName;
+ if (next instanceof TemplateRoute) {
+ TemplateRoute temp = (TemplateRoute) next;
+ baseName = MetricRegistry.name("MetricRouter", temp.getTemplate().getPattern());
+ } else {
+ baseName = MetricRegistry.name("MetricRouter", "unknown");
+ }
+
+ final Timer.Context aggTimer = mMetricRegistry.timer("MetricRouter.time").time();
+ final Timer.Context timer = mMetricRegistry.timer(baseName + ".time").time();
+
+ try {
+ super.doHandle(next, request, response);
+ } finally {
+ timer.stop();
+ aggTimer.stop();
+
+ // Record status code
+ boolean success = !response.getStatus().isError();
+ if (success) {
+ mMetricRegistry.counter("MetricRouter.success").inc();
+ mMetricRegistry.counter(baseName + ".response.success").inc();
+ } else {
+ mMetricRegistry.counter("MetricRouter.failure").inc();
+ mMetricRegistry.counter(baseName + ".response.failure").inc();
+ }
+ }
+ }
+}
diff --git a/src/com/p4square/restlet/metrics/MetricsApplication.java b/src/com/p4square/restlet/metrics/MetricsApplication.java
new file mode 100644
index 0000000..6caf742
--- /dev/null
+++ b/src/com/p4square/restlet/metrics/MetricsApplication.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2014 Jesse Morgan
+ */
+
+package com.p4square.restlet.metrics;
+
+import java.util.concurrent.TimeUnit;
+
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.json.MetricsModule;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.restlet.Application;
+import org.restlet.Restlet;
+import org.restlet.resource.Finder;
+
+/**
+ *
+ * @author Jesse Morgan <jesse@jesterpm.net>
+ */
+public class MetricsApplication extends Application {
+ static final ObjectMapper MAPPER;
+ static {
+ MAPPER = new ObjectMapper();
+ MAPPER.registerModule(new MetricsModule(TimeUnit.SECONDS, TimeUnit.MILLISECONDS, true));
+ }
+
+ private final MetricRegistry mMetricRegistry;
+
+ public MetricsApplication(MetricRegistry metrics) {
+ mMetricRegistry = metrics;
+ }
+
+ public MetricRegistry getMetricRegistry() {
+ return mMetricRegistry;
+ }
+
+ @Override
+ public Restlet createInboundRoot() {
+ return new Finder(getContext(), MetricsResource.class);
+ }
+}
diff --git a/src/com/p4square/restlet/metrics/MetricsResource.java b/src/com/p4square/restlet/metrics/MetricsResource.java
new file mode 100644
index 0000000..e2ab14d
--- /dev/null
+++ b/src/com/p4square/restlet/metrics/MetricsResource.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014 Jesse Morgan
+ */
+
+package com.p4square.restlet.metrics;
+
+import com.codahale.metrics.MetricRegistry;
+
+import org.restlet.ext.jackson.JacksonRepresentation;
+import org.restlet.representation.Representation;
+import org.restlet.resource.ServerResource;
+
+/**
+ *
+ * @author Jesse Morgan <jesse@jesterpm.net>
+ */
+public class MetricsResource extends ServerResource {
+
+ private MetricRegistry mMetricRegistry;
+
+ @Override
+ public void doInit() {
+ mMetricRegistry = ((MetricsApplication) getApplication()).getMetricRegistry();
+ }
+
+ @Override
+ protected Representation get() {
+ JacksonRepresentation<MetricRegistry> rep = new JacksonRepresentation<>(mMetricRegistry);
+ rep.setObjectMapper(MetricsApplication.MAPPER);
+ return rep;
+ }
+}