NotificationScheduleController.java

/*
 * Copyright 2024 Global Crop Diversity Trust
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gringlobal.api.v2.impl;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

import org.gringlobal.api.model.NotificationScheduleDTO;
import org.gringlobal.api.v1.ApiBaseController;
import org.gringlobal.api.v2.FilteredCRUDController;
import org.gringlobal.api.v2.facade.NotificationScheduleApiService;
import org.gringlobal.model.notification.NotificationSchedule;
import org.gringlobal.service.filter.NotificationScheduleFilter;
import org.springframework.http.MediaType;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

@RestController("notificationScheduleApi2")
@RequestMapping(NotificationScheduleController.API_URL)
@PreAuthorize("hasAuthority('GROUP_ADMINS')")
@Tag(name = "NotificationScheduler")
@Validated
@Slf4j
public class NotificationScheduleController extends FilteredCRUDController<NotificationScheduleDTO, NotificationSchedule, NotificationScheduleApiService, NotificationScheduleFilter> {
	
	/** The Constant API_URL. */
	public static final String API_URL = ApiBaseController.APIv2_ADMIN_BASE + "/schedule";

	@GetMapping(value = "/generators", produces = { MediaType.APPLICATION_JSON_VALUE })
	@Operation(operationId = "listNotificationGenerators", description = "List all notification generators", summary = "List generators")
	public List<NotificationScheduleDTO> listNotificationGenerators() {
		return serviceFacade.listNotificationGenerators();
	}


	@PostMapping(value = "/cron-next", produces = { MediaType.APPLICATION_JSON_VALUE })
	@Operation(operationId = "generateNextCron", description = "Generate next ten times for the cron expression", summary = "List next ten instances")
	public List<ZonedDateTime> generateNextCron(@RequestBody String expression, @RequestParam(required = false, defaultValue = "UTC") String zone) {
		log.debug("Generating crons for {} at {}", expression, zone);
		var cron = CronExpression.parse(expression);
		List<ZonedDateTime> n = new ArrayList<>(10);
		ZonedDateTime t = ZonedDateTime.ofInstant(Instant.now(), TimeZone.getTimeZone(zone).toZoneId());
		for (var i = 0; i<10; i++) {
			t = cron.next(t);
			n.add(t);
		}
		return n;
	}

	@PostMapping(value = "/{id}/subscribe", produces = { MediaType.APPLICATION_JSON_VALUE })
	@Operation(operationId = "subscribe", description = "Add AclSid subscribers to the schedule notification", summary = "Subscribe")
	public NotificationScheduleDTO subscribe(@PathVariable Long id, @RequestBody(required = false) List<String> aclSids) {
		var notification = serviceFacade.get(id);
		return serviceFacade.subscribe(notification, aclSids);
	}

	@PostMapping(value = "/{id}/unsubscribe", produces = { MediaType.APPLICATION_JSON_VALUE })
	@Operation(operationId = "unsubscribe", description = "Remove AclSid subscribers from the schedule notification", summary = "Unsubscribe")
	public NotificationScheduleDTO unsubscribe(@PathVariable Long id, @RequestBody(required = false) List<String> aclSids) {
		var notification = serviceFacade.get(id);
		return serviceFacade.unsubscribe(notification, aclSids);
	}
}