mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
additional timer metrics
This commit is contained in:
@@ -360,3 +360,14 @@ module.directive('metricGauge', function() {
|
||||
templateUrl : 'templates/_metrics.gauge.html'
|
||||
};
|
||||
});
|
||||
|
||||
module.directive('metricTimer', function() {
|
||||
return {
|
||||
scope : {
|
||||
metric : '=',
|
||||
label : '='
|
||||
},
|
||||
restrict : 'E',
|
||||
templateUrl : 'templates/_metrics.timer.html'
|
||||
};
|
||||
});
|
||||
|
||||
@@ -4,14 +4,8 @@
|
||||
<dt>Mean</dt>
|
||||
<dd>{{metric.meanRate | number:2}}</dd>
|
||||
|
||||
<dt>1 min</dt>
|
||||
<dd>{{metric.oneMinuteRate | number:2}}</dd>
|
||||
|
||||
<dt>5 min</dt>
|
||||
<dd>{{metric.fiveMinuteRate | number:2}}</dd>
|
||||
|
||||
<dt>15 min</dt>
|
||||
<dd>{{metric.fifteenMinuteRate | number:2}}</dd>
|
||||
<dt>1/5/15 min</dt>
|
||||
<dd>{{metric.oneMinuteRate | number:2}} {{metric.fiveMinuteRate | number:2}} {{metric.fifteenMinuteRate | number:2}}</dd>
|
||||
|
||||
<dt>Total</dt>
|
||||
<dd>{{metric.count}}</dd>
|
||||
|
||||
17
src/main/app/templates/_metrics.timer.html
Normal file
17
src/main/app/templates/_metrics.timer.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<div>
|
||||
<span>{{label}}</span>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Mean</dt>
|
||||
<dd>{{metric.meanRate | number:2}}</dd>
|
||||
|
||||
<dt>1/5/15 min</dt>
|
||||
<dd>{{metric.oneMinuteRate | number:2}} {{metric.fiveMinuteRate | number:2}} {{metric.fifteenMinuteRate | number:2}}</dd>
|
||||
|
||||
<dt>Total</dt>
|
||||
<dd>{{metric.count}}</dd>
|
||||
|
||||
<dt>min/max/mean (ms)</dt>
|
||||
<dd>{{metric.snapshot.min/1000000 | number:0}} {{metric.snapshot.max/1000000 | number:0}} {{metric.snapshot.mean/1000000 | number:0}}</dd>
|
||||
|
||||
</dl>
|
||||
</div>
|
||||
@@ -1,21 +1,28 @@
|
||||
<div>
|
||||
<metric-meter metric="metrics.meters['com.commafeed.backend.feed.FeedQueues.refill']" label="'Refresh queue refill rate (/sec)'"></metric-meter>
|
||||
<metric-meter metric="metrics.meters['com.commafeed.backend.feed.FeedRefreshTaskGiver.feedRefreshed']" label="'Feed refreshed (/sec)'"></metric-meter>
|
||||
<metric-meter metric="metrics.meters['com.commafeed.backend.feed.FeedRefreshUpdater.feedUpdated']" label="'Feed updated (/sec)'"></metric-meter>
|
||||
<metric-meter metric="metrics.meters['com.commafeed.backend.feed.FeedRefreshUpdater.entryCacheHit']" label="'Entry cache hit (/sec)'"></metric-meter>
|
||||
<metric-meter metric="metrics.meters['com.commafeed.backend.feed.FeedRefreshUpdater.entryCacheMiss']" label="'Entry cache miss (/sec)'"></metric-meter>
|
||||
<div class="col-md-6">
|
||||
<metric-meter metric="metrics.meters['com.commafeed.backend.feed.FeedQueues.refill']" label="'Refresh queue refill rate (/sec)'"></metric-meter>
|
||||
<metric-meter metric="metrics.meters['com.commafeed.backend.feed.FeedRefreshTaskGiver.feedRefreshed']" label="'Feed refreshed (/sec)'"></metric-meter>
|
||||
<metric-meter metric="metrics.meters['com.commafeed.backend.feed.FeedRefreshUpdater.feedUpdated']" label="'Feed updated (/sec)'"></metric-meter>
|
||||
<metric-meter metric="metrics.meters['com.commafeed.backend.feed.FeedRefreshUpdater.entryCacheHit']" label="'Entry cache hit (/sec)'"></metric-meter>
|
||||
<metric-meter metric="metrics.meters['com.commafeed.backend.feed.FeedRefreshUpdater.entryCacheMiss']" label="'Entry cache miss (/sec)'"></metric-meter>
|
||||
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedRefreshExecutor.feed-refresh-updater.active']"
|
||||
label="'Feed Updater active'"></metric-gauge>
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedRefreshExecutor.feed-refresh-updater.pending']"
|
||||
label="'Feed Updater queued'"></metric-gauge>
|
||||
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedRefreshExecutor.feed-refresh-updater.active']"
|
||||
label="'Feed Updater active'"></metric-gauge>
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedRefreshExecutor.feed-refresh-updater.pending']"
|
||||
label="'Feed Updater queued'"></metric-gauge>
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedRefreshExecutor.feed-refresh-worker.active']"
|
||||
label="'Feed Worker active'"></metric-gauge>
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedRefreshExecutor.feed-refresh-worker.pending']"
|
||||
label="'Feed Worker queued'"></metric-gauge>
|
||||
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedRefreshExecutor.feed-refresh-worker.active']"
|
||||
label="'Feed Worker active'"></metric-gauge>
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedRefreshExecutor.feed-refresh-worker.pending']"
|
||||
label="'Feed Worker queued'"></metric-gauge>
|
||||
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedQueues.addQueue']" label="'Task Giver Add Queue'"></metric-gauge>
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedQueues.takeQueue']" label="'Task Giver Take Queue'"></metric-gauge>
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedQueues.giveBackQueue']" label="'Task Giver Give Back Queue'"></metric-gauge>
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedQueues.addQueue']" label="'Task Giver Add Queue'"></metric-gauge>
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedQueues.takeQueue']" label="'Task Giver Take Queue'"></metric-gauge>
|
||||
<metric-gauge metric="metrics.gauges['com.commafeed.backend.feed.FeedQueues.giveBackQueue']" label="'Task Giver Give Back Queue'"></metric-gauge>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div ng-repeat="(name, timer) in metrics.timers">
|
||||
<metric-timer metric="timer" label="name"></metric-gauge>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -19,6 +19,7 @@ import javax.ws.rs.core.Response.Status;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
import com.codahale.metrics.annotation.Timed;
|
||||
import com.commafeed.CommaFeedApplication;
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.CommaFeedConfiguration.ApplicationSettings;
|
||||
@@ -42,10 +43,10 @@ import io.swagger.annotations.ApiParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Path("/admin")
|
||||
@Api(value = "/admin", description = "Operations about application administration")
|
||||
@Api(value = "/admin")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@Singleton
|
||||
public class AdminREST {
|
||||
|
||||
@@ -60,6 +61,7 @@ public class AdminREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Save or update a user", notes = "Save or update a user. If the id is not specified, a new user will be created")
|
||||
@Timed
|
||||
public Response save(@SecurityCheck(Role.ADMIN) User user, @ApiParam(required = true) UserModel userModel) {
|
||||
Preconditions.checkNotNull(userModel);
|
||||
Preconditions.checkNotNull(userModel.getName());
|
||||
@@ -114,6 +116,7 @@ public class AdminREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Get user information", notes = "Get user information", response = UserModel.class)
|
||||
@Timed
|
||||
public Response getUser(@SecurityCheck(Role.ADMIN) User user, @ApiParam(value = "user id", required = true) @PathParam("id") Long id) {
|
||||
Preconditions.checkNotNull(id);
|
||||
User u = userDAO.findById(id);
|
||||
@@ -130,6 +133,7 @@ public class AdminREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Get all users", notes = "Get all users", response = UserModel.class, responseContainer = "List")
|
||||
@Timed
|
||||
public Response getUsers(@SecurityCheck(Role.ADMIN) User user) {
|
||||
Map<Long, UserModel> users = new HashMap<>();
|
||||
for (UserRole role : userRoleDAO.findAll()) {
|
||||
@@ -157,6 +161,7 @@ public class AdminREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Delete a user", notes = "Delete a user, and all his subscriptions")
|
||||
@Timed
|
||||
public Response delete(@SecurityCheck(Role.ADMIN) User user, @ApiParam(required = true) IDRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getId());
|
||||
@@ -176,6 +181,7 @@ public class AdminREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Retrieve application settings", notes = "Retrieve application settings", response = ApplicationSettings.class)
|
||||
@Timed
|
||||
public Response getSettings(@SecurityCheck(Role.ADMIN) User user) {
|
||||
return Response.ok(config.getApplicationSettings()).build();
|
||||
}
|
||||
@@ -184,6 +190,7 @@ public class AdminREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Retrieve server metrics")
|
||||
@Timed
|
||||
public Response getMetrics(@SecurityCheck(Role.ADMIN) User user) {
|
||||
return Response.ok(metrics).build();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.codahale.metrics.annotation.Timed;
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.backend.cache.CacheService;
|
||||
import com.commafeed.backend.dao.FeedCategoryDAO;
|
||||
@@ -69,11 +70,11 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Path("/category")
|
||||
@Api(value = "/category", description = "Operations about user categories")
|
||||
@Api(value = "/category")
|
||||
@Slf4j
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@Singleton
|
||||
public class CategoryREST {
|
||||
|
||||
@@ -92,10 +93,13 @@ public class CategoryREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Get category entries", notes = "Get a list of category entries", response = Entries.class)
|
||||
public Response getCategoryEntries(
|
||||
@SecurityCheck User user,
|
||||
@Timed
|
||||
public Response getCategoryEntries(@SecurityCheck User user,
|
||||
@ApiParam(value = "id of the category, 'all' or 'starred'", required = true) @QueryParam("id") String id,
|
||||
@ApiParam(value = "all entries or only unread ones", allowableValues = "all,unread", required = true) @DefaultValue("unread") @QueryParam("readType") ReadingMode readType,
|
||||
@ApiParam(
|
||||
value = "all entries or only unread ones",
|
||||
allowableValues = "all,unread",
|
||||
required = true) @DefaultValue("unread") @QueryParam("readType") ReadingMode readType,
|
||||
@ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan,
|
||||
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset,
|
||||
@ApiParam(value = "limit for paging, default 20, maximum 1000") @DefaultValue("20") @QueryParam("limit") int limit,
|
||||
@@ -103,7 +107,8 @@ public class CategoryREST {
|
||||
@ApiParam(
|
||||
value = "search for keywords in either the title or the content of the entries, separated by spaces, 3 characters minimum") @QueryParam("keywords") String keywords,
|
||||
@ApiParam(value = "return only entry ids") @DefaultValue("false") @QueryParam("onlyIds") boolean onlyIds,
|
||||
@ApiParam(value = "comma-separated list of excluded subscription ids") @QueryParam("excludedSubscriptionIds") String excludedSubscriptionIds,
|
||||
@ApiParam(
|
||||
value = "comma-separated list of excluded subscription ids") @QueryParam("excludedSubscriptionIds") String excludedSubscriptionIds,
|
||||
@ApiParam(value = "keep only entries tagged with this tag") @QueryParam("tag") String tag) {
|
||||
|
||||
Preconditions.checkNotNull(readType);
|
||||
@@ -138,18 +143,16 @@ public class CategoryREST {
|
||||
offset, limit + 1, order, true, onlyIds, tag);
|
||||
|
||||
for (FeedEntryStatus status : list) {
|
||||
entries.getEntries().add(
|
||||
Entry.build(status, config.getApplicationSettings().getPublicUrl(), config.getApplicationSettings()
|
||||
.getImageProxyEnabled()));
|
||||
entries.getEntries().add(Entry.build(status, config.getApplicationSettings().getPublicUrl(),
|
||||
config.getApplicationSettings().getImageProxyEnabled()));
|
||||
}
|
||||
|
||||
} else if (STARRED.equals(id)) {
|
||||
entries.setName("Starred");
|
||||
List<FeedEntryStatus> starred = feedEntryStatusDAO.findStarred(user, newerThanDate, offset, limit + 1, order, !onlyIds);
|
||||
for (FeedEntryStatus status : starred) {
|
||||
entries.getEntries().add(
|
||||
Entry.build(status, config.getApplicationSettings().getPublicUrl(), config.getApplicationSettings()
|
||||
.getImageProxyEnabled()));
|
||||
entries.getEntries().add(Entry.build(status, config.getApplicationSettings().getPublicUrl(),
|
||||
config.getApplicationSettings().getImageProxyEnabled()));
|
||||
}
|
||||
} else {
|
||||
FeedCategory parent = feedCategoryDAO.findById(user, Long.valueOf(id));
|
||||
@@ -161,9 +164,8 @@ public class CategoryREST {
|
||||
offset, limit + 1, order, true, onlyIds, tag);
|
||||
|
||||
for (FeedEntryStatus status : list) {
|
||||
entries.getEntries().add(
|
||||
Entry.build(status, config.getApplicationSettings().getPublicUrl(), config.getApplicationSettings()
|
||||
.getImageProxyEnabled()));
|
||||
entries.getEntries().add(Entry.build(status, config.getApplicationSettings().getPublicUrl(),
|
||||
config.getApplicationSettings().getImageProxyEnabled()));
|
||||
}
|
||||
entries.setName(parent.getName());
|
||||
} else {
|
||||
@@ -188,10 +190,13 @@ public class CategoryREST {
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Get category entries as feed", notes = "Get a feed of category entries")
|
||||
@Produces(MediaType.APPLICATION_XML)
|
||||
public Response getCategoryEntriesAsFeed(
|
||||
@SecurityCheck(apiKeyAllowed = true) User user,
|
||||
@Timed
|
||||
public Response getCategoryEntriesAsFeed(@SecurityCheck(apiKeyAllowed = true) User user,
|
||||
@ApiParam(value = "id of the category, 'all' or 'starred'", required = true) @QueryParam("id") String id,
|
||||
@ApiParam(value = "all entries or only unread ones", allowableValues = "all,unread", required = true) @DefaultValue("all") @QueryParam("readType") ReadingMode readType,
|
||||
@ApiParam(
|
||||
value = "all entries or only unread ones",
|
||||
allowableValues = "all,unread",
|
||||
required = true) @DefaultValue("all") @QueryParam("readType") ReadingMode readType,
|
||||
@ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan,
|
||||
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset,
|
||||
@ApiParam(value = "limit for paging, default 20, maximum 1000") @DefaultValue("20") @QueryParam("limit") int limit,
|
||||
@@ -199,7 +204,8 @@ public class CategoryREST {
|
||||
@ApiParam(
|
||||
value = "search for keywords in either the title or the content of the entries, separated by spaces, 3 characters minimum") @QueryParam("keywords") String keywords,
|
||||
@ApiParam(value = "return only entry ids") @DefaultValue("false") @QueryParam("onlyIds") boolean onlyIds,
|
||||
@ApiParam(value = "comma-separated list of excluded subscription ids") @QueryParam("excludedSubscriptionIds") String excludedSubscriptionIds,
|
||||
@ApiParam(
|
||||
value = "comma-separated list of excluded subscription ids") @QueryParam("excludedSubscriptionIds") String excludedSubscriptionIds,
|
||||
@ApiParam(value = "keep only entries tagged with this tag") @QueryParam("tag") String tag) {
|
||||
|
||||
Response response = getCategoryEntries(user, id, readType, newerThan, offset, limit, order, keywords, onlyIds,
|
||||
@@ -231,6 +237,7 @@ public class CategoryREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Mark category entries", notes = "Mark feed entries of this category as read")
|
||||
@Timed
|
||||
public Response markCategoryEntries(@SecurityCheck User user,
|
||||
@ApiParam(value = "category id, or 'all'", required = true) MarkRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
@@ -272,6 +279,7 @@ public class CategoryREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Add a category", notes = "Add a new feed category", response = Long.class)
|
||||
@Timed
|
||||
public Response addCategory(@SecurityCheck User user, @ApiParam(required = true) AddCategoryRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getName());
|
||||
@@ -295,6 +303,7 @@ public class CategoryREST {
|
||||
@Path("/delete")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Delete a category", notes = "Delete an existing feed category")
|
||||
@Timed
|
||||
public Response deleteCategory(@SecurityCheck User user, @ApiParam(required = true) IDRequest req) {
|
||||
|
||||
Preconditions.checkNotNull(req);
|
||||
@@ -327,6 +336,7 @@ public class CategoryREST {
|
||||
@Path("/modify")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Rename a category", notes = "Rename an existing feed category")
|
||||
@Timed
|
||||
public Response modifyCategory(@SecurityCheck User user, @ApiParam(required = true) CategoryModificationRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getId());
|
||||
@@ -381,6 +391,7 @@ public class CategoryREST {
|
||||
@Path("/collapse")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Collapse a category", notes = "Save collapsed or expanded status for a category")
|
||||
@Timed
|
||||
public Response collapse(@SecurityCheck User user, @ApiParam(required = true) CollapseRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getId());
|
||||
@@ -399,6 +410,7 @@ public class CategoryREST {
|
||||
@Path("/unreadCount")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Get unread count for feed subscriptions", response = UnreadCount.class, responseContainer = "List")
|
||||
@Timed
|
||||
public Response getUnreadCount(@SecurityCheck User user) {
|
||||
Map<Long, UnreadCount> unreadCount = feedSubscriptionService.getUnreadCount(user);
|
||||
return Response.ok(Lists.newArrayList(unreadCount.values())).build();
|
||||
@@ -408,6 +420,7 @@ public class CategoryREST {
|
||||
@Path("/get")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Get feed categories", notes = "Get all categories and subscriptions of the user", response = Category.class)
|
||||
@Timed
|
||||
public Response getSubscriptions(@SecurityCheck User user) {
|
||||
Category root = cache.getUserRootCategory(user);
|
||||
if (root == null) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import com.codahale.metrics.annotation.Timed;
|
||||
import com.commafeed.backend.dao.FeedEntryTagDAO;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.service.FeedEntryService;
|
||||
@@ -30,10 +31,10 @@ import io.swagger.annotations.ApiParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Path("/entry")
|
||||
@Api(value = "/entry", description = "Operations about feed entries")
|
||||
@Api(value = "/entry")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@Singleton
|
||||
public class EntryREST {
|
||||
|
||||
@@ -45,6 +46,7 @@ public class EntryREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Mark a feed entry", notes = "Mark a feed entry as read/unread")
|
||||
@Timed
|
||||
public Response markFeedEntry(@SecurityCheck User user, @ApiParam(value = "Mark Request", required = true) MarkRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getId());
|
||||
@@ -57,6 +59,7 @@ public class EntryREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Mark multiple feed entries", notes = "Mark feed entries as read/unread")
|
||||
@Timed
|
||||
public Response markFeedEntries(@SecurityCheck User user,
|
||||
@ApiParam(value = "Multiple Mark Request", required = true) MultipleMarkRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
@@ -73,6 +76,7 @@ public class EntryREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Mark a feed entry", notes = "Mark a feed entry as read/unread")
|
||||
@Timed
|
||||
public Response starFeedEntry(@SecurityCheck User user, @ApiParam(value = "Star Request", required = true) StarRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getId());
|
||||
@@ -87,6 +91,7 @@ public class EntryREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Get list of tags for the user", notes = "Get list of tags for the user")
|
||||
@Timed
|
||||
public Response getTags(@SecurityCheck User user) {
|
||||
List<String> tags = feedEntryTagDAO.findByUser(user);
|
||||
return Response.ok(tags).build();
|
||||
@@ -96,6 +101,7 @@ public class EntryREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Mark a feed entry", notes = "Mark a feed entry as read/unread")
|
||||
@Timed
|
||||
public Response tagFeedEntry(@SecurityCheck User user, @ApiParam(value = "Tag Request", required = true) TagRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getEntryId());
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||
|
||||
import com.codahale.metrics.annotation.Timed;
|
||||
import com.commafeed.CommaFeedApplication;
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.backend.cache.CacheService;
|
||||
@@ -90,11 +91,11 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Path("/feed")
|
||||
@Api(value = "/feed", description = "Operations about feeds")
|
||||
@Api(value = "/feed")
|
||||
@Slf4j
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@Singleton
|
||||
public class FeedREST {
|
||||
|
||||
@@ -130,10 +131,13 @@ public class FeedREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Get feed entries", notes = "Get a list of feed entries", response = Entries.class)
|
||||
public Response getFeedEntries(
|
||||
@SecurityCheck User user,
|
||||
@Timed
|
||||
public Response getFeedEntries(@SecurityCheck User user,
|
||||
@ApiParam(value = "id of the feed", required = true) @QueryParam("id") String id,
|
||||
@ApiParam(value = "all entries or only unread ones", allowableValues = "all,unread", required = true) @DefaultValue("unread") @QueryParam("readType") ReadingMode readType,
|
||||
@ApiParam(
|
||||
value = "all entries or only unread ones",
|
||||
allowableValues = "all,unread",
|
||||
required = true) @DefaultValue("unread") @QueryParam("readType") ReadingMode readType,
|
||||
@ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan,
|
||||
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset,
|
||||
@ApiParam(value = "limit for paging, default 20, maximum 1000") @DefaultValue("20") @QueryParam("limit") int limit,
|
||||
@@ -171,9 +175,8 @@ public class FeedREST {
|
||||
entryKeywords, newerThanDate, offset, limit + 1, order, true, onlyIds, null);
|
||||
|
||||
for (FeedEntryStatus status : list) {
|
||||
entries.getEntries().add(
|
||||
Entry.build(status, config.getApplicationSettings().getPublicUrl(), config.getApplicationSettings()
|
||||
.getImageProxyEnabled()));
|
||||
entries.getEntries().add(Entry.build(status, config.getApplicationSettings().getPublicUrl(),
|
||||
config.getApplicationSettings().getImageProxyEnabled()));
|
||||
}
|
||||
|
||||
boolean hasMore = entries.getEntries().size() > limit;
|
||||
@@ -196,10 +199,13 @@ public class FeedREST {
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Get feed entries as a feed", notes = "Get a feed of feed entries")
|
||||
@Produces(MediaType.APPLICATION_XML)
|
||||
public Response getFeedEntriesAsFeed(
|
||||
@SecurityCheck(apiKeyAllowed = true) User user,
|
||||
@Timed
|
||||
public Response getFeedEntriesAsFeed(@SecurityCheck(apiKeyAllowed = true) User user,
|
||||
@ApiParam(value = "id of the feed", required = true) @QueryParam("id") String id,
|
||||
@ApiParam(value = "all entries or only unread ones", allowableValues = "all,unread", required = true) @DefaultValue("all") @QueryParam("readType") ReadingMode readType,
|
||||
@ApiParam(
|
||||
value = "all entries or only unread ones",
|
||||
allowableValues = "all,unread",
|
||||
required = true) @DefaultValue("all") @QueryParam("readType") ReadingMode readType,
|
||||
@ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan,
|
||||
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset,
|
||||
@ApiParam(value = "limit for paging, default 20, maximum 1000") @DefaultValue("20") @QueryParam("limit") int limit,
|
||||
@@ -253,6 +259,7 @@ public class FeedREST {
|
||||
@Path("/fetch")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Fetch a feed", notes = "Fetch a feed by its url", response = FeedInfo.class)
|
||||
@Timed
|
||||
public Response fetchFeed(@SecurityCheck User user, @ApiParam(value = "feed url", required = true) FeedInfoRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getUrl());
|
||||
@@ -271,6 +278,7 @@ public class FeedREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Queue all feeds of the user for refresh", notes = "Manually add all feeds of the user to the refresh queue")
|
||||
@Timed
|
||||
public Response queueAllForRefresh(@SecurityCheck User user) {
|
||||
feedSubscriptionService.refreshAll(user);
|
||||
return Response.ok().build();
|
||||
@@ -280,6 +288,7 @@ public class FeedREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Queue a feed for refresh", notes = "Manually add a feed to the refresh queue")
|
||||
@Timed
|
||||
public Response queueForRefresh(@SecurityCheck User user, @ApiParam(value = "Feed id") IDRequest req) {
|
||||
|
||||
Preconditions.checkNotNull(req);
|
||||
@@ -298,6 +307,7 @@ public class FeedREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Mark feed entries", notes = "Mark feed entries as read (unread is not supported)")
|
||||
@Timed
|
||||
public Response markFeedEntries(@SecurityCheck User user, @ApiParam(value = "Mark request") MarkRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getId());
|
||||
@@ -317,6 +327,7 @@ public class FeedREST {
|
||||
@Path("/get/{id}")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "", notes = "")
|
||||
@Timed
|
||||
public Response get(@SecurityCheck User user, @ApiParam(value = "user id", required = true) @PathParam("id") Long id) {
|
||||
|
||||
Preconditions.checkNotNull(id);
|
||||
@@ -332,6 +343,7 @@ public class FeedREST {
|
||||
@Path("/favicon/{id}")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Fetch a feed's icon", notes = "Fetch a feed's icon")
|
||||
@Timed
|
||||
public Response getFavicon(@SecurityCheck User user, @ApiParam(value = "subscription id") @PathParam("id") Long id) {
|
||||
|
||||
Preconditions.checkNotNull(id);
|
||||
@@ -361,6 +373,7 @@ public class FeedREST {
|
||||
@Path("/subscribe")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Subscribe to a feed", notes = "Subscribe to a feed")
|
||||
@Timed
|
||||
public Response subscribe(@SecurityCheck User user, @ApiParam(value = "subscription request", required = true) SubscribeRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getTitle());
|
||||
@@ -387,6 +400,7 @@ public class FeedREST {
|
||||
@Path("/subscribe")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Subscribe to a feed", notes = "Subscribe to a feed")
|
||||
@Timed
|
||||
public Response subscribe(@SecurityCheck User user, @ApiParam(value = "feed url", required = true) @QueryParam("url") String url) {
|
||||
|
||||
try {
|
||||
@@ -414,6 +428,7 @@ public class FeedREST {
|
||||
@Path("/unsubscribe")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Unsubscribe from a feed", notes = "Unsubscribe from a feed")
|
||||
@Timed
|
||||
public Response unsubscribe(@SecurityCheck User user, @ApiParam(required = true) IDRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getId());
|
||||
@@ -430,6 +445,7 @@ public class FeedREST {
|
||||
@Path("/modify")
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Modify a subscription", notes = "Modify a feed subscription")
|
||||
@Timed
|
||||
public Response modify(@SecurityCheck User user, @ApiParam(value = "subscription id", required = true) FeedModificationRequest req) {
|
||||
Preconditions.checkNotNull(req);
|
||||
Preconditions.checkNotNull(req.getId());
|
||||
@@ -489,12 +505,13 @@ public class FeedREST {
|
||||
@UnitOfWork
|
||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||
@ApiOperation(value = "OPML import", notes = "Import an OPML file, posted as a FORM with the 'file' name")
|
||||
@Timed
|
||||
public Response importOpml(@SecurityCheck User user, @FormDataParam("file") InputStream input) {
|
||||
|
||||
String publicUrl = config.getApplicationSettings().getPublicUrl();
|
||||
if (StringUtils.isBlank(publicUrl)) {
|
||||
throw new WebApplicationException(Response.status(Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Set the public URL in the admin section.").build());
|
||||
throw new WebApplicationException(
|
||||
Response.status(Status.INTERNAL_SERVER_ERROR).entity("Set the public URL in the admin section.").build());
|
||||
}
|
||||
|
||||
if (CommaFeedApplication.USERNAME_DEMO.equals(user.getName())) {
|
||||
@@ -515,6 +532,7 @@ public class FeedREST {
|
||||
@UnitOfWork
|
||||
@Produces(MediaType.APPLICATION_XML)
|
||||
@ApiOperation(value = "OPML export", notes = "Export an OPML file of the user's subscriptions")
|
||||
@Timed
|
||||
public Response exportOpml(@SecurityCheck User user) {
|
||||
Opml opml = opmlExporter.export(user);
|
||||
WireFeedOutput output = new WireFeedOutput();
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
import com.codahale.metrics.annotation.Timed;
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.backend.dao.FeedDAO;
|
||||
import com.commafeed.backend.feed.FeedParser;
|
||||
@@ -36,7 +37,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Path("/push")
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@Singleton
|
||||
public class PubSubHubbubCallbackREST {
|
||||
|
||||
@@ -53,6 +54,7 @@ public class PubSubHubbubCallbackREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@Produces(MediaType.TEXT_PLAIN)
|
||||
@Timed
|
||||
public Response verify(@QueryParam("hub.mode") String mode, @QueryParam("hub.topic") String topic,
|
||||
@QueryParam("hub.challenge") String challenge, @QueryParam("hub.lease_seconds") String leaseSeconds,
|
||||
@QueryParam("hub.verify_token") String verifyToken) {
|
||||
@@ -84,6 +86,7 @@ public class PubSubHubbubCallbackREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@Consumes({ MediaType.APPLICATION_ATOM_XML, "application/rss+xml" })
|
||||
@Timed
|
||||
public Response callback() {
|
||||
|
||||
if (!config.getApplicationSettings().getPubsubhubbub()) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import javax.ws.rs.core.Response.Status;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.codahale.metrics.annotation.Timed;
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.backend.HttpGetter;
|
||||
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||
@@ -27,10 +28,10 @@ import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Path("/server")
|
||||
@Api(value = "/server", description = "Operations about server infos")
|
||||
@Api(value = "/server")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@Singleton
|
||||
public class ServerREST {
|
||||
|
||||
@@ -41,6 +42,7 @@ public class ServerREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Get server infos", notes = "Get server infos", response = ServerInfo.class)
|
||||
@Timed
|
||||
public Response get() {
|
||||
ServerInfo infos = new ServerInfo();
|
||||
infos.setAnnouncement(config.getApplicationSettings().getAnnouncement());
|
||||
@@ -57,6 +59,7 @@ public class ServerREST {
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "proxy image")
|
||||
@Produces("image/png")
|
||||
@Timed
|
||||
public Response get(@SecurityCheck User user, @QueryParam("u") String url) {
|
||||
if (!config.getApplicationSettings().getImageProxyEnabled()) {
|
||||
return Response.status(Status.FORBIDDEN).build();
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
|
||||
import com.codahale.metrics.annotation.Timed;
|
||||
import com.commafeed.CommaFeedApplication;
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.backend.dao.UserDAO;
|
||||
@@ -61,11 +62,11 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Path("/user")
|
||||
@Api(value = "/user", description = "Operations about the user")
|
||||
@Api(value = "/user")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@Singleton
|
||||
public class UserREST {
|
||||
|
||||
@@ -81,6 +82,7 @@ public class UserREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Retrieve user settings", notes = "Retrieve user settings", response = Settings.class)
|
||||
@Timed
|
||||
public Response getSettings(@SecurityCheck User user) {
|
||||
Settings s = new Settings();
|
||||
UserSettings settings = userSettingsDAO.findByUser(user);
|
||||
@@ -135,6 +137,7 @@ public class UserREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Save user settings", notes = "Save user settings")
|
||||
@Timed
|
||||
public Response saveSettings(@SecurityCheck User user, @ApiParam(required = true) Settings settings) {
|
||||
Preconditions.checkNotNull(settings);
|
||||
|
||||
@@ -173,6 +176,7 @@ public class UserREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Retrieve user's profile", response = UserModel.class)
|
||||
@Timed
|
||||
public Response get(@SecurityCheck User user) {
|
||||
UserModel userModel = new UserModel();
|
||||
userModel.setId(user.getId());
|
||||
@@ -192,6 +196,7 @@ public class UserREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Save user's profile")
|
||||
@Timed
|
||||
public Response save(@SecurityCheck User user, @ApiParam(required = true) ProfileModificationRequest request) {
|
||||
Preconditions.checkArgument(StringUtils.isBlank(request.getPassword()) || request.getPassword().length() >= 6);
|
||||
if (StringUtils.isNotBlank(request.getEmail())) {
|
||||
@@ -220,6 +225,7 @@ public class UserREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Register a new account")
|
||||
@Timed
|
||||
public Response register(@Valid @ApiParam(required = true) RegistrationRequest req, @Context SessionHelper sessionHelper) {
|
||||
try {
|
||||
User registeredUser = userService.register(req.getName(), req.getPassword(), req.getEmail(), Arrays.asList(Role.USER));
|
||||
@@ -236,6 +242,7 @@ public class UserREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Login and create a session")
|
||||
@Timed
|
||||
public Response login(@ApiParam(required = true) LoginRequest req, @Context SessionHelper sessionHelper) {
|
||||
Optional<User> user = userService.login(req.getName(), req.getPassword());
|
||||
if (user.isPresent()) {
|
||||
@@ -250,6 +257,7 @@ public class UserREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "send a password reset email")
|
||||
@Timed
|
||||
public Response sendPasswordReset(@Valid PasswordResetRequest req) {
|
||||
User user = userDAO.findByEmail(req.getEmail());
|
||||
if (user == null) {
|
||||
@@ -271,9 +279,9 @@ public class UserREST {
|
||||
private String buildEmailContent(User user) throws Exception {
|
||||
String publicUrl = FeedUtils.removeTrailingSlash(config.getApplicationSettings().getPublicUrl());
|
||||
publicUrl += "/rest/user/passwordResetCallback";
|
||||
return String
|
||||
.format("You asked for password recovery for account '%s', <a href='%s'>follow this link</a> to change your password. Ignore this if you didn't request a password recovery.",
|
||||
user.getName(), callbackUrl(user, publicUrl));
|
||||
return String.format(
|
||||
"You asked for password recovery for account '%s', <a href='%s'>follow this link</a> to change your password. Ignore this if you didn't request a password recovery.",
|
||||
user.getName(), callbackUrl(user, publicUrl));
|
||||
}
|
||||
|
||||
private String callbackUrl(User user, String publicUrl) throws Exception {
|
||||
@@ -285,6 +293,7 @@ public class UserREST {
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
@Timed
|
||||
public Response passwordRecoveryCallback(@QueryParam("email") String email, @QueryParam("token") String token) {
|
||||
Preconditions.checkNotNull(email);
|
||||
Preconditions.checkNotNull(token);
|
||||
@@ -320,6 +329,7 @@ public class UserREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Delete the user account")
|
||||
@Timed
|
||||
public Response delete(@SecurityCheck User user) {
|
||||
if (CommaFeedApplication.USERNAME_ADMIN.equals(user.getName()) || CommaFeedApplication.USERNAME_DEMO.equals(user.getName())) {
|
||||
return Response.status(Status.FORBIDDEN).build();
|
||||
|
||||
Reference in New Issue
Block a user