Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: NotificationService #63

Open
wants to merge 30 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
fef17d9
feat: `notify:list` ResponseTransformer
JeremyTubongbanua Oct 12, 2022
f751af9
feat: AtNotification class
JeremyTubongbanua Oct 20, 2022
1a1a783
feat: NotificationParams class
JeremyTubongbanua Oct 20, 2022
58abfcc
feat: NotificationEnums class
JeremyTubongbanua Oct 20, 2022
1784ac9
feat: AtNotification class
JeremyTubongbanua Oct 24, 2022
fd658d7
feat: NotificationParams getters
JeremyTubongbanua Oct 24, 2022
aac17bb
feat: NotificationResult class
JeremyTubongbanua Oct 24, 2022
54339e3
feat: NotificationService interface
JeremyTubongbanua Oct 24, 2022
095f428
feat: NotifyListVerbBuilder
JeremyTubongbanua Oct 24, 2022
b19a575
feat: NotificationServiceImpl init
JeremyTubongbanua Oct 24, 2022
67d8cd2
feat: AtClientValidation.validateNotificationRequest
JeremyTubongbanua Nov 1, 2022
80261be
chore: add unadded import
JeremyTubongbanua Nov 1, 2022
c248ed2
feat: add NotificationServiceImpl instance to AtClientImpl
JeremyTubongbanua Nov 1, 2022
75ea8e2
feat: notify() and notifyList()
JeremyTubongbanua Nov 2, 2022
5a6a24c
Merge remote-tracking branch 'upstream/trunk' into notification
JeremyTubongbanua Dec 15, 2022
fc311da
fix: invalid class name `NotifyStatusVerbBuilder`
JeremyTubongbanua Dec 15, 2022
558bfde
feat: protect NotificationParams to force use of static factory methods
JeremyTubongbanua Dec 15, 2022
fcc57a3
feat: move `NotificationServiceImpl.java`, implement overloaded `noti…
JeremyTubongbanua Dec 16, 2022
b816688
chore: `NotifyListVerbBuilder` Str>Date objects arg
JeremyTubongbanua Dec 16, 2022
c8126ca
chore: use primitive boolean to omit null case
JeremyTubongbanua Dec 16, 2022
f750f45
feat: invalid from > to check
JeremyTubongbanua Dec 16, 2022
6ff72e5
test: notifyList and notifyDelete verb builder tests
JeremyTubongbanua Dec 16, 2022
36370e1
chore: use `this` keyword
JeremyTubongbanua Dec 16, 2022
d743cac
refactor: use "remove" wording instead of "delete"
JeremyTubongbanua Dec 16, 2022
8422eea
refactor: use notifyRemove instead of notifyDelete
JeremyTubongbanua Dec 16, 2022
d70cff6
feat: Notify examples
JeremyTubongbanua Dec 16, 2022
2a376e6
test: notify list response transformer tests
JeremyTubongbanua Dec 20, 2022
bb3bcf4
feat: conceptual notification validation
JeremyTubongbanua Dec 20, 2022
4e56197
fix: failing test
JeremyTubongbanua Dec 20, 2022
838e9c1
Merge branch 'trunk' into notification
gkc Dec 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions at_client/src/examples/NotifyListExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

import java.util.List;
import java.util.concurrent.ExecutionException;

import org.atsign.client.api.AtClient;
import org.atsign.client.api.notification.AtNotification;
import org.atsign.client.api.notification.NotificationService;
import org.atsign.common.AtException;
import org.atsign.common.AtSign;

public class NotifyListExample {
public static void main(String[] args) throws AtException, InterruptedException, ExecutionException {
final String ROOT_URL = "root.atsign.org:64";
final String ATSIGN_STR = "@smoothalligator";
final AtSign atSign = new AtSign(ATSIGN_STR);
final AtClient atClient = AtClient.withRemoteSecondary(ROOT_URL, atSign);

final NotificationService ns = atClient.getNotificationService();
final List<AtNotification> notifications = ns.notifyList().get();

final int numNotifications = notifications.size();
System.out.println("Notifications Listed: (" + numNotifications + ")");
for(int i = 0; i < numNotifications; i++) {
AtNotification notification = notifications.get(i);
String id = notification.id;
String from = notification.from;
String key = notification.key;
System.out.println("[" + i + "]: " + id + " | from: " + from + " | key: " + key);
}
}
}
30 changes: 30 additions & 0 deletions at_client/src/examples/NotifyRemoveExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

import java.util.Scanner;
import java.util.concurrent.ExecutionException;


import org.atsign.client.api.AtClient;
import org.atsign.client.api.notification.NotificationResult;
import org.atsign.client.api.notification.NotificationService;
import org.atsign.common.AtException;
import org.atsign.common.AtSign;

public class NotifyRemoveExample {

public static void main(String[] args) throws AtException, InterruptedException, ExecutionException {
final String ROOT_URL = "root.atsign.org:64";
final String ATSIGN_STR = "@smoothalligator";
final AtSign atSign = new AtSign(ATSIGN_STR);
final AtClient atClient = AtClient.withRemoteSecondary(ROOT_URL, atSign);

final NotificationService ns = atClient.getNotificationService();

Scanner scanner = new Scanner(System.in);
System.out.println("Enter notification id to delete: ");
String notificationId = scanner.nextLine();
scanner.close();
NotificationResult result = ns.notifyRemove(notificationId).get();
System.out.println(result.toString());
}

}
35 changes: 35 additions & 0 deletions at_client/src/examples/NotifySendExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

import java.util.concurrent.ExecutionException;

import org.atsign.client.api.AtClient;
import org.atsign.client.api.notification.NotificationParams;
import org.atsign.client.api.notification.NotificationResult;
import org.atsign.client.api.notification.NotificationService;
import org.atsign.client.api.notification.NotificationServiceImpl;
import org.atsign.common.AtException;
import org.atsign.common.AtSign;

public class NotifySendExample {

public static void main(String[] args) throws AtException, InterruptedException, ExecutionException {

// initialize AtClient instance
final String ROOT_URL = "root.atsign.org:64";
final String ATSIGN_STR = "@soccer0";
final AtSign atSign = new AtSign(ATSIGN_STR);
final AtClient atClient = AtClient.withRemoteSecondary(ROOT_URL, atSign);

// get notification service
final NotificationService ns = (NotificationServiceImpl) atClient.getNotificationService();

final String RECIPIENT_ATSIGN_STR = "@smoothalligator";
final AtSign recipient = new AtSign(RECIPIENT_ATSIGN_STR);
final NotificationResult result = ns.notify(NotificationParams.forText("12345", atSign, recipient, false)).get();

System.out.println(result.toString());



}

}
3 changes: 3 additions & 0 deletions at_client/src/main/java/org/atsign/client/api/AtClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.atsign.client.api.impl.connections.DefaultAtConnectionFactory;
import org.atsign.client.api.impl.events.SimpleAtEventBus;
import org.atsign.client.api.impl.secondaries.RemoteSecondary;
import org.atsign.client.api.notification.NotificationService;
import org.atsign.common.AtSign;
import org.atsign.common.AtException;
import org.atsign.client.util.KeysUtil;
Expand Down Expand Up @@ -161,4 +162,6 @@ static AtClient withRemoteSecondary(Secondary.Address remoteSecondaryAddress, At
CompletableFuture<String> put(PublicKey publicKey, byte[] value);

CompletableFuture<List<AtKey>> getAtKeys(String regex);

NotificationService getNotificationService();
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.atsign.client.api.AtEvents.AtEventBus;
import org.atsign.client.api.AtEvents.AtEventListener;
import org.atsign.client.api.AtEvents.AtEventType;
import org.atsign.client.api.notification.NotificationService;
import org.atsign.client.api.Secondary;
import org.atsign.client.util.EncryptionUtil;
import org.atsign.client.util.KeysUtil;
Expand Down Expand Up @@ -57,16 +58,20 @@ public class AtClientImpl implements AtClient {

private final Map<String, String> keys;
@Override public Map<String, String> getEncryptionKeys() {return keys;}

private final Secondary secondary;
@Override public Secondary getSecondary() {return secondary;}

private final NotificationService notificationService;
@Override public NotificationService getNotificationService() {return notificationService;}

private final AtEventBus eventBus;
public AtClientImpl(AtEventBus eventBus, AtSign atSign, Map<String, String> keys, Secondary secondary) {
this.eventBus = eventBus;
this.atSign = atSign;
this.keys = keys;
this.secondary = secondary;

this.notificationService = NotificationService.create(this);
eventBus.addEventListener(this, EnumSet.allOf(AtEventType.class));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.atsign.client.api.notification;

import java.util.ArrayList;
import java.util.List;

import org.atsign.client.api.Secondary;
import org.atsign.common.ResponseTransformers.NotifyListResponseTransformer;
import org.atsign.common.response_models.NotifyListResponse;

/**
* Class represents a notification in the atProtocol.
*/
public class AtNotification {

public String id; // id of the notification
public String key; // notification data
public String from; // the atSign the notification is sent by
public String to; // the atSign the notification is being sent to
public Long epochMillis; // when the notification was sent in epoch millis
public String value; // notification value, [OPTIONAL]
public String operation; // "update", "delete", [OPTIONAL]
public String messageType; // MessageType.Text or MessageType.Key
public Boolean isEncrypted; // notification

@Override
public String toString() {
return "{\"id\": \"" + id + "\", \"key\": \"" + key + "\", \"from\": \"" + from + "\", \"to\": \"" + to + "\", \"epochMillis\": " + epochMillis.toString() + ", \"value\": \"" + value + "\", \"operation\": \"" + operation + "\", \"messageType\": \"" + messageType + "\", \"isEncrypted\": " + isEncrypted.toString() + "}";
}

/**
* Convert the Secondary.Response into a List<AtNotification> object
* @param response The response data from `data:<response data>` after running
* `notify:list`
* @return a List<AtNotification> where each AtNotification
*/
public static List<AtNotification> fromResponse(Secondary.Response response) {
NotifyListResponseTransformer transformer = new NotifyListResponseTransformer();
NotifyListResponse model = transformer.transform(response);
List<AtNotification> notifications = new ArrayList<AtNotification>();
model.notifications.stream().forEach((n) -> {
AtNotification notification = new AtNotification();
notification.id = n.id;
notification.key = n.key;
notification.from = n.from;
notification.to = n.to;
notification.epochMillis = n.epochMillis;
notification.value = n.value;
notification.operation = n.operation;
notification.messageType = n.messageType;
notification.isEncrypted = n.isEncrypted;
notifications.add(notification);
});
return notifications;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package org.atsign.client.api.notification;

import java.util.UUID;

import org.atsign.common.AtSign;
import org.atsign.common.KeyBuilders;
import org.atsign.common.Keys;
import org.atsign.common.NotificationEnums;
import org.atsign.common.Keys.AtKey;
import org.atsign.common.Keys.SharedKey;
import org.atsign.common.NotificationEnums.Operation;


public class NotificationParams {

private String id;
private AtKey atKey;
private String value; // nullable (optional)
private NotificationEnums.Operation operation;
private NotificationEnums.MessageType messageType;
private NotificationEnums.Priority priority;
private NotificationEnums.Strategy strategy;
// private Integer latestN = 1;
// private String notifier = SYSTEM;

// only this class, children, and other classes in this package can create instances
// use static factory methods to create instances of NotificationParams.
protected NotificationParams() {}

public String getNotificationId() {
return id;
}

public AtKey getAtKey() {
return atKey;
}

public String getValue() {
return value;
}

public NotificationEnums.Operation getOperation() {
return operation;
}

public NotificationEnums.MessageType getMessageType() {
return messageType;
}

public NotificationEnums.Priority getPriority() {
return priority;
}

public NotificationEnums.Strategy getStrategy() {
return strategy;
}

/**
*
* @param atKey AtKey object which contains the sharedBy and sharedWith atSign.
* @param value nullable (optional)
* @return NotificationParams object
*/
public static NotificationParams forUpdate(AtKey atKey, String value) {
NotificationParams params = new NotificationParams();
params.id = UUID.randomUUID().toString();
params.atKey = atKey;
params.value = value;
params.operation = Operation.UPDATE;
params.messageType = NotificationEnums.MessageType.KEY;
params.priority = NotificationEnums.Priority.LOW;
params.strategy = NotificationEnums.Strategy.ALL;
return params;
}

public static NotificationParams forDelete(AtKey atKey) {
NotificationParams params = new NotificationParams();
params.id = UUID.randomUUID().toString();
params.atKey = atKey;
params.operation = Operation.DELETE;
params.messageType = NotificationEnums.MessageType.KEY;
params.priority = NotificationEnums.Priority.LOW;
params.strategy = NotificationEnums.Strategy.ALL;
return params;
}

public static NotificationParams forText(String text, AtSign sharedBy, AtSign sharedWith, boolean shouldEncrypt) {

SharedKey sharedKey = new KeyBuilders.SharedKeyBuilder(sharedBy, sharedWith).key(text).build();
sharedKey.metadata.isEncrypted = shouldEncrypt;


NotificationParams params = new NotificationParams();
params.id = UUID.randomUUID().toString();
params.atKey = sharedKey;
params.operation = Operation.UPDATE;
params.messageType = NotificationEnums.MessageType.TEXT;
params.priority = NotificationEnums.Priority.LOW;
params.strategy = NotificationEnums.Strategy.ALL;
return params;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.atsign.client.api.notification;

import org.atsign.common.NotificationStatus;
import org.atsign.common.Keys.AtKey;

public class NotificationResult {
private String notificationId;
private AtKey atKey;
private NotificationStatus notificationStatus;

public NotificationResult(String notificationId, AtKey atKey, NotificationStatus notificationStatus) {
this.notificationId = notificationId;
this.atKey = atKey;
this.notificationStatus = notificationStatus;
}

public void setAtKey(AtKey atKey) {
this.atKey = atKey;
}

public void setNotificationId(String notificationId) {
this.notificationId = notificationId;
}

public void setNotificationStatus(NotificationStatus notificationStatus) {
this.notificationStatus = notificationStatus;
}

public AtKey getAtKey() {
return this.atKey;
}

public String getNotificationId() {
return this.notificationId;
}

public NotificationStatus getNotificationStatus() {
return this.notificationStatus;
}

@Override
public String toString() {
return "id: " + this.notificationId + " | status: " + this.notificationStatus.name();
}

}
Loading