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 verifyTopic = Pattern.compile("^([a-zA-Z0-9._-]+(\\/[a-zA-Z0-9._-]+)+)|\\*$").asPredicate(); public static final Predicate 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 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 clearSubscriptions() { final Map 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 conditions; public InSubscription() {} public InSubscription(final String subscriber, final String topic, final NotificationFrequency frequency, final NotificationMode mode, final List 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 getConditions() { return conditions; } public void setConditions(final List 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); } }