dnet-applications/apps/dhp-broker-application/src/main/java/eu/dnetlib/broker/controllers/SubscriptionsController.java

182 lines
5.7 KiB
Java

package eu.dnetlib.broker.controllers;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.broker.LiteratureBrokerServiceApplication;
import eu.dnetlib.broker.common.elasticsearch.NotificationRepository;
import eu.dnetlib.broker.common.subscriptions.MapCondition;
import eu.dnetlib.broker.common.subscriptions.NotificationFrequency;
import eu.dnetlib.broker.common.subscriptions.NotificationMode;
import eu.dnetlib.broker.common.subscriptions.Subscription;
import eu.dnetlib.broker.common.subscriptions.SubscriptionRepository;
import eu.dnetlib.common.controller.AbstractDnetController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@RequestMapping("/api/subscriptions")
@Tag(name = LiteratureBrokerServiceApplication.TAG_SUBSCRIPTIONS)
public class SubscriptionsController extends AbstractDnetController {
@Autowired
private SubscriptionRepository subscriptionRepo;
@Autowired
private NotificationRepository notificationRepo;
public static final Predicate<String> verifyTopic = Pattern.compile("^([a-zA-Z0-9._-]+(\\/[a-zA-Z0-9._-]+)+)|\\*$").asPredicate();
public static final Predicate<String> verifyEmail = email -> {
try {
new InternetAddress(email).validate();
return true;
} catch (final AddressException e) {
return false;
}
};
@Operation(summary = "Return the list of subscriptions")
@GetMapping("")
public Iterable<Subscription> listSubscriptions() {
return subscriptionRepo.findAll();
}
@Operation(summary = "Return a subscription by ID")
@GetMapping("/{id}")
public Subscription getSubscription(@PathVariable final String id) {
return subscriptionRepo.findById(id).get();
}
@Operation(summary = "Delete a subscription by ID and its notifications")
@DeleteMapping("/{id}")
public void deleteSubscription(@PathVariable final String id) {
subscriptionRepo.deleteById(id);
notificationRepo.deleteBySubscriptionId(id);
}
@Operation(summary = "Perform a new subscription")
@PostMapping("")
public Subscription registerSubscription(@RequestBody final InSubscription inSub) {
final Subscription sub = inSub.asSubscription();
subscriptionRepo.save(sub);
return sub;
}
@Operation(summary = "Delete all subscriptions and notifications")
@DeleteMapping("")
public Map<String, Object> clearSubscriptions() {
final Map<String, Object> res = new HashMap<>();
subscriptionRepo.deleteAll();
notificationRepo.deleteAll();
res.put("deleted", "all");
return res;
}
@Operation(summary = "Reset the last notification date")
@DeleteMapping("/{id}/date")
public void deleteNotificationDate(@PathVariable final String id) {
final Subscription s = subscriptionRepo.findById(id).get();
s.setLastNotificationDate(null);
subscriptionRepo.save(s);
}
@Operation(summary = "Reset all the last notification dates")
@GetMapping("/resetLastNotificationDates")
public void deleteAllNotificationDates() {
for (final Subscription s : subscriptionRepo.findAll()) {
s.setLastNotificationDate(null);
subscriptionRepo.save(s);
}
}
}
class InSubscription {
private String subscriber;
private String topic;
private NotificationFrequency frequency;
private NotificationMode mode;
private List<MapCondition> conditions;
public InSubscription() {}
public InSubscription(final String subscriber, final String topic, final NotificationFrequency frequency, final NotificationMode mode,
final List<MapCondition> conditions) {
this.subscriber = subscriber;
this.topic = topic;
this.frequency = frequency;
this.mode = mode;
this.conditions = conditions;
}
public String getSubscriber() {
return subscriber;
}
public void setSubscriber(final String subscriber) {
this.subscriber = subscriber;
}
public String getTopic() {
return topic;
}
public void setTopic(final String topic) {
this.topic = topic;
}
public NotificationFrequency getFrequency() {
return frequency;
}
public void setFrequency(final NotificationFrequency frequency) {
this.frequency = frequency;
}
public NotificationMode getMode() {
return mode;
}
public void setMode(final NotificationMode mode) {
this.mode = mode;
}
public List<MapCondition> getConditions() {
return conditions;
}
public void setConditions(final List<MapCondition> conditions) {
this.conditions = conditions;
}
public Subscription asSubscription() {
if (StringUtils.isBlank(subscriber)) { throw new IllegalArgumentException("subscriber is empty"); }
if (StringUtils.isBlank(topic)) { throw new IllegalArgumentException("topic is empty"); }
if (!SubscriptionsController.verifyEmail.test(subscriber)) { throw new IllegalArgumentException("Invalid email: " + subscriber); }
if (!SubscriptionsController.verifyTopic.test(topic)) { throw new IllegalArgumentException("Invalid topic: " + topic); }
final String subscriptionId = "sub-" + UUID.randomUUID();
return new Subscription(subscriptionId, subscriber, topic, frequency, mode, null, new Date(), conditions);
}
}