@Test public void testAddComment() throws Exception { final User user = UserServiceFactory.getUserService().getCurrentUser(); String content = "Test comment"; Comment comment = commentController.insertComment(this.postEntity.getWebsafeId(), content, user); assertEquals(content, comment.getContent()); assertEquals(Key.create(user.getUserId()), comment.getParent()); assertEquals(owner.getUsername(), comment.getUsername()); assertEquals(owner.getAvatarUrl(), comment.getAvatarUrl()); assertEquals(Vote.Direction.DEFAULT, comment.getDir()); assertEquals(0, comment.getVoteCount()); assertEquals(false, comment.isAccepted()); PostEntity postEntity = Observable .just(ofy().load().group(PostEntity.ShardGroup.class).key(comment.getPostKey()).now()) .flatMap(postShardService::mergeShards) .blockingSingle(); assertEquals(1, postEntity.getCommentCount()); assertEquals(true, postEntity.isCommented()); Tracker tracker = ofy().load().key(Tracker.createKey(Key.create(user.getUserId()))).now(); assertNotNull(tracker); assertEquals(true, tracker.isFirstComment()); }
public Comment insertComment(String postId, String content, User user) { ImmutableSet.Builder<Key<?>> keyBuilder = ImmutableSet.builder(); final Key<Account> accountKey = Key.create(user.getUserId()); keyBuilder.add(accountKey); final Key<PostEntity> questionKey = Key.create(postId); keyBuilder.add(questionKey); final Key<PostShard> questionShardKey = postShardService.getRandomShardKey(questionKey); keyBuilder.add(questionShardKey); final Key<Tracker> trackerKey = Tracker.createKey(accountKey); keyBuilder.add(trackerKey); final Key<DeviceRecord> recordKey = DeviceRecord.createKey(questionKey.getParent()); keyBuilder.add(recordKey); ImmutableSet<Key<?>> batchKeys = keyBuilder.build(); Map<Key<Object>, Object> fetched = ofy().load().keys(batchKeys.toArray(new Key[batchKeys.size()])); Account account = (Account) fetched.get(accountKey); PostEntity postEntity = (PostEntity) fetched.get(questionKey); PostShard qqs = (PostShard) fetched.get(questionShardKey); Tracker tracker = (Tracker) fetched.get(trackerKey); DeviceRecord record = (DeviceRecord) fetched.get(recordKey); CommentEntity entity = commentService.createComment(account, questionKey, content); Comment comment = entity.getComment(); Collection<CommentShard> shards = entity.getShards().values(); postEntity = postEntity.withCommented(!postEntity.isCommented()); qqs.increaseComments(); List<Notifiable> notifiables = Lists.newArrayList(); gameService.addAnswerFirstQuestionBonus(record, tracker, notifiables::addAll); gameService.addFirstCommenterBonus(record, tracker, postEntity, notifiables::addAll); gameService.addAnswerToUnansweredQuestionBonus(record, tracker, postEntity, notifiables::addAll); ImmutableSet.Builder<Object> saveBuilder = ImmutableSet.builder() .add(comment) .addAll(shards) .add(qqs) .add(postEntity) .add(tracker); for (Notifiable bundle : notifiables) { saveBuilder.addAll(bundle.getNotifications()); } if (!questionKey.<Account>getParent().equivalent(accountKey)) { boolean sendCommentNotification = true; List<String> mentions = EXTRACTOR.extractMentionedScreennames(content); if (!mentions.isEmpty()) { Query<Account> query = ofy().load().type(Account.class); for (final String username : mentions) { query.filter(Account.FIELD_USERNAME + " =", username); } List<Key<Account>> accountKeys = query.keys().list(); Collection<DeviceRecord> records = ofy().load() .keys(DeviceUtil.createKeysFromAccount(accountKeys)).values(); MentionNotification mentionNotification = MentionNotification.create(postEntity, account, records, comment); notificationService.send(mentionNotification); sendCommentNotification = false; } CommentNotifiable commentNotifiable = CommentNotifiable.create(account, record, comment, postEntity); if (sendCommentNotification) { notificationService.send(commentNotifiable); } saveBuilder.addAll(commentNotifiable.getNotifications()); } return ofy().transact(() -> { Map<Key<Object>, Object> saved = ofy().save().entities(saveBuilder.build()).now(); for (Notifiable bundle : notifiables) { notificationService.send(bundle); } return (Comment) saved.get(comment.getKey()); }); }
CommentController extends Controller { public Comment insertComment(String postId, String content, User user) { ImmutableSet.Builder<Key<?>> keyBuilder = ImmutableSet.builder(); final Key<Account> accountKey = Key.create(user.getUserId()); keyBuilder.add(accountKey); final Key<PostEntity> questionKey = Key.create(postId); keyBuilder.add(questionKey); final Key<PostShard> questionShardKey = postShardService.getRandomShardKey(questionKey); keyBuilder.add(questionShardKey); final Key<Tracker> trackerKey = Tracker.createKey(accountKey); keyBuilder.add(trackerKey); final Key<DeviceRecord> recordKey = DeviceRecord.createKey(questionKey.getParent()); keyBuilder.add(recordKey); ImmutableSet<Key<?>> batchKeys = keyBuilder.build(); Map<Key<Object>, Object> fetched = ofy().load().keys(batchKeys.toArray(new Key[batchKeys.size()])); Account account = (Account) fetched.get(accountKey); PostEntity postEntity = (PostEntity) fetched.get(questionKey); PostShard qqs = (PostShard) fetched.get(questionShardKey); Tracker tracker = (Tracker) fetched.get(trackerKey); DeviceRecord record = (DeviceRecord) fetched.get(recordKey); CommentEntity entity = commentService.createComment(account, questionKey, content); Comment comment = entity.getComment(); Collection<CommentShard> shards = entity.getShards().values(); postEntity = postEntity.withCommented(!postEntity.isCommented()); qqs.increaseComments(); List<Notifiable> notifiables = Lists.newArrayList(); gameService.addAnswerFirstQuestionBonus(record, tracker, notifiables::addAll); gameService.addFirstCommenterBonus(record, tracker, postEntity, notifiables::addAll); gameService.addAnswerToUnansweredQuestionBonus(record, tracker, postEntity, notifiables::addAll); ImmutableSet.Builder<Object> saveBuilder = ImmutableSet.builder() .add(comment) .addAll(shards) .add(qqs) .add(postEntity) .add(tracker); for (Notifiable bundle : notifiables) { saveBuilder.addAll(bundle.getNotifications()); } if (!questionKey.<Account>getParent().equivalent(accountKey)) { boolean sendCommentNotification = true; List<String> mentions = EXTRACTOR.extractMentionedScreennames(content); if (!mentions.isEmpty()) { Query<Account> query = ofy().load().type(Account.class); for (final String username : mentions) { query.filter(Account.FIELD_USERNAME + " =", username); } List<Key<Account>> accountKeys = query.keys().list(); Collection<DeviceRecord> records = ofy().load() .keys(DeviceUtil.createKeysFromAccount(accountKeys)).values(); MentionNotification mentionNotification = MentionNotification.create(postEntity, account, records, comment); notificationService.send(mentionNotification); sendCommentNotification = false; } CommentNotifiable commentNotifiable = CommentNotifiable.create(account, record, comment, postEntity); if (sendCommentNotification) { notificationService.send(commentNotifiable); } saveBuilder.addAll(commentNotifiable.getNotifications()); } return ofy().transact(() -> { Map<Key<Object>, Object> saved = ofy().save().entities(saveBuilder.build()).now(); for (Notifiable bundle : notifiables) { notificationService.send(bundle); } return (Comment) saved.get(comment.getKey()); }); } }
CommentController extends Controller { public Comment insertComment(String postId, String content, User user) { ImmutableSet.Builder<Key<?>> keyBuilder = ImmutableSet.builder(); final Key<Account> accountKey = Key.create(user.getUserId()); keyBuilder.add(accountKey); final Key<PostEntity> questionKey = Key.create(postId); keyBuilder.add(questionKey); final Key<PostShard> questionShardKey = postShardService.getRandomShardKey(questionKey); keyBuilder.add(questionShardKey); final Key<Tracker> trackerKey = Tracker.createKey(accountKey); keyBuilder.add(trackerKey); final Key<DeviceRecord> recordKey = DeviceRecord.createKey(questionKey.getParent()); keyBuilder.add(recordKey); ImmutableSet<Key<?>> batchKeys = keyBuilder.build(); Map<Key<Object>, Object> fetched = ofy().load().keys(batchKeys.toArray(new Key[batchKeys.size()])); Account account = (Account) fetched.get(accountKey); PostEntity postEntity = (PostEntity) fetched.get(questionKey); PostShard qqs = (PostShard) fetched.get(questionShardKey); Tracker tracker = (Tracker) fetched.get(trackerKey); DeviceRecord record = (DeviceRecord) fetched.get(recordKey); CommentEntity entity = commentService.createComment(account, questionKey, content); Comment comment = entity.getComment(); Collection<CommentShard> shards = entity.getShards().values(); postEntity = postEntity.withCommented(!postEntity.isCommented()); qqs.increaseComments(); List<Notifiable> notifiables = Lists.newArrayList(); gameService.addAnswerFirstQuestionBonus(record, tracker, notifiables::addAll); gameService.addFirstCommenterBonus(record, tracker, postEntity, notifiables::addAll); gameService.addAnswerToUnansweredQuestionBonus(record, tracker, postEntity, notifiables::addAll); ImmutableSet.Builder<Object> saveBuilder = ImmutableSet.builder() .add(comment) .addAll(shards) .add(qqs) .add(postEntity) .add(tracker); for (Notifiable bundle : notifiables) { saveBuilder.addAll(bundle.getNotifications()); } if (!questionKey.<Account>getParent().equivalent(accountKey)) { boolean sendCommentNotification = true; List<String> mentions = EXTRACTOR.extractMentionedScreennames(content); if (!mentions.isEmpty()) { Query<Account> query = ofy().load().type(Account.class); for (final String username : mentions) { query.filter(Account.FIELD_USERNAME + " =", username); } List<Key<Account>> accountKeys = query.keys().list(); Collection<DeviceRecord> records = ofy().load() .keys(DeviceUtil.createKeysFromAccount(accountKeys)).values(); MentionNotification mentionNotification = MentionNotification.create(postEntity, account, records, comment); notificationService.send(mentionNotification); sendCommentNotification = false; } CommentNotifiable commentNotifiable = CommentNotifiable.create(account, record, comment, postEntity); if (sendCommentNotification) { notificationService.send(commentNotifiable); } saveBuilder.addAll(commentNotifiable.getNotifications()); } return ofy().transact(() -> { Map<Key<Object>, Object> saved = ofy().save().entities(saveBuilder.build()).now(); for (Notifiable bundle : notifiables) { notificationService.send(bundle); } return (Comment) saved.get(comment.getKey()); }); }  }
CommentController extends Controller { public Comment insertComment(String postId, String content, User user) { ImmutableSet.Builder<Key<?>> keyBuilder = ImmutableSet.builder(); final Key<Account> accountKey = Key.create(user.getUserId()); keyBuilder.add(accountKey); final Key<PostEntity> questionKey = Key.create(postId); keyBuilder.add(questionKey); final Key<PostShard> questionShardKey = postShardService.getRandomShardKey(questionKey); keyBuilder.add(questionShardKey); final Key<Tracker> trackerKey = Tracker.createKey(accountKey); keyBuilder.add(trackerKey); final Key<DeviceRecord> recordKey = DeviceRecord.createKey(questionKey.getParent()); keyBuilder.add(recordKey); ImmutableSet<Key<?>> batchKeys = keyBuilder.build(); Map<Key<Object>, Object> fetched = ofy().load().keys(batchKeys.toArray(new Key[batchKeys.size()])); Account account = (Account) fetched.get(accountKey); PostEntity postEntity = (PostEntity) fetched.get(questionKey); PostShard qqs = (PostShard) fetched.get(questionShardKey); Tracker tracker = (Tracker) fetched.get(trackerKey); DeviceRecord record = (DeviceRecord) fetched.get(recordKey); CommentEntity entity = commentService.createComment(account, questionKey, content); Comment comment = entity.getComment(); Collection<CommentShard> shards = entity.getShards().values(); postEntity = postEntity.withCommented(!postEntity.isCommented()); qqs.increaseComments(); List<Notifiable> notifiables = Lists.newArrayList(); gameService.addAnswerFirstQuestionBonus(record, tracker, notifiables::addAll); gameService.addFirstCommenterBonus(record, tracker, postEntity, notifiables::addAll); gameService.addAnswerToUnansweredQuestionBonus(record, tracker, postEntity, notifiables::addAll); ImmutableSet.Builder<Object> saveBuilder = ImmutableSet.builder() .add(comment) .addAll(shards) .add(qqs) .add(postEntity) .add(tracker); for (Notifiable bundle : notifiables) { saveBuilder.addAll(bundle.getNotifications()); } if (!questionKey.<Account>getParent().equivalent(accountKey)) { boolean sendCommentNotification = true; List<String> mentions = EXTRACTOR.extractMentionedScreennames(content); if (!mentions.isEmpty()) { Query<Account> query = ofy().load().type(Account.class); for (final String username : mentions) { query.filter(Account.FIELD_USERNAME + " =", username); } List<Key<Account>> accountKeys = query.keys().list(); Collection<DeviceRecord> records = ofy().load() .keys(DeviceUtil.createKeysFromAccount(accountKeys)).values(); MentionNotification mentionNotification = MentionNotification.create(postEntity, account, records, comment); notificationService.send(mentionNotification); sendCommentNotification = false; } CommentNotifiable commentNotifiable = CommentNotifiable.create(account, record, comment, postEntity); if (sendCommentNotification) { notificationService.send(commentNotifiable); } saveBuilder.addAll(commentNotifiable.getNotifications()); } return ofy().transact(() -> { Map<Key<Object>, Object> saved = ofy().save().entities(saveBuilder.build()).now(); for (Notifiable bundle : notifiables) { notificationService.send(bundle); } return (Comment) saved.get(comment.getKey()); }); }  Comment getComment(String commentId, User user); Comment insertComment(String postId, String content, User user); Comment updateComment(
      String postId,
      String commentId,
      Optional<String> content,
      Optional<Boolean> accepted,
      User user); void deleteComment(String postId, String commentId, User user); CollectionResponse<Comment> listComments(
      String questionId,
      Optional<String> cursor,
      Optional<Integer> limit,
      User user); }
CommentController extends Controller { public Comment insertComment(String postId, String content, User user) { ImmutableSet.Builder<Key<?>> keyBuilder = ImmutableSet.builder(); final Key<Account> accountKey = Key.create(user.getUserId()); keyBuilder.add(accountKey); final Key<PostEntity> questionKey = Key.create(postId); keyBuilder.add(questionKey); final Key<PostShard> questionShardKey = postShardService.getRandomShardKey(questionKey); keyBuilder.add(questionShardKey); final Key<Tracker> trackerKey = Tracker.createKey(accountKey); keyBuilder.add(trackerKey); final Key<DeviceRecord> recordKey = DeviceRecord.createKey(questionKey.getParent()); keyBuilder.add(recordKey); ImmutableSet<Key<?>> batchKeys = keyBuilder.build(); Map<Key<Object>, Object> fetched = ofy().load().keys(batchKeys.toArray(new Key[batchKeys.size()])); Account account = (Account) fetched.get(accountKey); PostEntity postEntity = (PostEntity) fetched.get(questionKey); PostShard qqs = (PostShard) fetched.get(questionShardKey); Tracker tracker = (Tracker) fetched.get(trackerKey); DeviceRecord record = (DeviceRecord) fetched.get(recordKey); CommentEntity entity = commentService.createComment(account, questionKey, content); Comment comment = entity.getComment(); Collection<CommentShard> shards = entity.getShards().values(); postEntity = postEntity.withCommented(!postEntity.isCommented()); qqs.increaseComments(); List<Notifiable> notifiables = Lists.newArrayList(); gameService.addAnswerFirstQuestionBonus(record, tracker, notifiables::addAll); gameService.addFirstCommenterBonus(record, tracker, postEntity, notifiables::addAll); gameService.addAnswerToUnansweredQuestionBonus(record, tracker, postEntity, notifiables::addAll); ImmutableSet.Builder<Object> saveBuilder = ImmutableSet.builder() .add(comment) .addAll(shards) .add(qqs) .add(postEntity) .add(tracker); for (Notifiable bundle : notifiables) { saveBuilder.addAll(bundle.getNotifications()); } if (!questionKey.<Account>getParent().equivalent(accountKey)) { boolean sendCommentNotification = true; List<String> mentions = EXTRACTOR.extractMentionedScreennames(content); if (!mentions.isEmpty()) { Query<Account> query = ofy().load().type(Account.class); for (final String username : mentions) { query.filter(Account.FIELD_USERNAME + " =", username); } List<Key<Account>> accountKeys = query.keys().list(); Collection<DeviceRecord> records = ofy().load() .keys(DeviceUtil.createKeysFromAccount(accountKeys)).values(); MentionNotification mentionNotification = MentionNotification.create(postEntity, account, records, comment); notificationService.send(mentionNotification); sendCommentNotification = false; } CommentNotifiable commentNotifiable = CommentNotifiable.create(account, record, comment, postEntity); if (sendCommentNotification) { notificationService.send(commentNotifiable); } saveBuilder.addAll(commentNotifiable.getNotifications()); } return ofy().transact(() -> { Map<Key<Object>, Object> saved = ofy().save().entities(saveBuilder.build()).now(); for (Notifiable bundle : notifiables) { notificationService.send(bundle); } return (Comment) saved.get(comment.getKey()); }); }  Comment getComment(String commentId, User user); Comment insertComment(String postId, String content, User user); Comment updateComment(
      String postId,
      String commentId,
      Optional<String> content,
      Optional<Boolean> accepted,
      User user); void deleteComment(String postId, String commentId, User user); CollectionResponse<Comment> listComments(
      String questionId,
      Optional<String> cursor,
      Optional<Integer> limit,
      User user);  }