Open-sourced generic, dynamic POC, RESTful alerting API
This commit is contained in:
1 parent
b2ed41c549
commit
0d1d154c7a
70 files changed
+3272
No files matched your search
+37
@@ -0,0 +1,37 @@
|
||||
HELP.md
|
||||
.gradle
|
||||
build/
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
bin/
|
||||
!**/src/main/**/bin/
|
||||
!**/src/test/**/bin/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
out/
|
||||
!**/src/main/**/out/
|
||||
!**/src/test/**/out/
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JpaPluginProjectSettings">
|
||||
<option name="lastSelectedLanguage" value="Kotlin" />
|
||||
</component>
|
||||
</project>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
@@ -0,0 +1,19 @@
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootJar
|
||||
|
||||
dependencies {
|
||||
implementation("org.springframework.amqp:spring-amqp")
|
||||
implementation("org.springframework.amqp:spring-rabbit")
|
||||
implementation("com.google.code.gson:gson")
|
||||
implementation("org.projectlombok:lombok")
|
||||
implementation("org.apache.commons:commons-lang3")
|
||||
|
||||
annotationProcessor("org.projectlombok:lombok")
|
||||
}
|
||||
|
||||
tasks.getByName<BootJar>("bootJar") {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
tasks.getByName<Jar>("jar") {
|
||||
enabled = true
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.poc.alerting.amqp;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface AmqpMessage extends Serializable {
|
||||
String correlationId = "correlation-id";
|
||||
|
||||
String getRoutingKey();
|
||||
|
||||
String getExchange();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.poc.alerting.amqp;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class AmqpResponse<T> implements Serializable {
|
||||
private T value;
|
||||
private ExceptionType exceptionType;
|
||||
private String exceptionMessage;
|
||||
private Integer errorCode;
|
||||
private String errorDescription;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.poc.alerting.amqp;
|
||||
|
||||
public enum ExceptionType {
|
||||
INVALID_REQUEST_EXCEPTION(400),
|
||||
INVALID_ACCOUNT_EXCEPTION(403),
|
||||
NOT_FOUND_EXCEPTION(404),
|
||||
REQUEST_TIMEOUT_EXCEPTION(408),
|
||||
CONFLICT_EXCEPTION(409),
|
||||
UNPROCESSABLE_ENTITY_EXCEPTION(422),
|
||||
INTERNAL_SERVER_EXCEPTION(500);
|
||||
|
||||
private final int status;
|
||||
|
||||
ExceptionType(final int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.poc.alerting.amqp;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.core.MessageProperties;
|
||||
import org.springframework.amqp.support.converter.MessageConversionException;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class GsonMessageConverter implements MessageConverter {
|
||||
private static final Gson GSON = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create();
|
||||
|
||||
@Override
|
||||
public Message toMessage(final Object object, final MessageProperties messageProperties) throws MessageConversionException {
|
||||
if (!(object instanceof Serializable)) {
|
||||
throw new MessageConversionException("Message object is not serializable");
|
||||
}
|
||||
|
||||
try {
|
||||
final String json = GSON.toJson(object);
|
||||
if (json == null) {
|
||||
throw new MessageConversionException("Unable to serialize the message to JSON");
|
||||
}
|
||||
|
||||
LOG.debug("json = {}", json);
|
||||
|
||||
final byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
|
||||
messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
|
||||
messageProperties.setContentEncoding("UTF-8");
|
||||
messageProperties.setContentLength(bytes.length);
|
||||
messageProperties.setTimestamp(new Date());
|
||||
messageProperties.setType(object.getClass().getName());
|
||||
if (messageProperties.getMessageId() == null) {
|
||||
messageProperties.setMessageId(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
return new Message(bytes, messageProperties);
|
||||
} catch (final Exception e) {
|
||||
throw new MessageConversionException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fromMessage(final Message message) throws MessageConversionException {
|
||||
final byte[] messageBody = message.getBody();
|
||||
if (messageBody == null) {
|
||||
LOG.warn("No message body found for message: {}", message);
|
||||
return null;
|
||||
}
|
||||
|
||||
final MessageProperties messageProperties = message.getMessageProperties();
|
||||
final String className = StringUtils.trimAllWhitespace(messageProperties.getType());
|
||||
if (StringUtils.isEmpty(className)) {
|
||||
LOG.error("Could not determine class from message: {}", message);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
final String json = new String(messageBody, StandardCharsets.UTF_8);
|
||||
LOG.debug("json = {}", json);
|
||||
return GSON.fromJson(json, Class.forName(className));
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Could not deserialize message: " + message, e);
|
||||
throw new MessageConversionException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.poc.alerting.amqp;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.amqp.core.Message;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class MessageDataTransferObject implements Serializable {
|
||||
private String routingKey;
|
||||
private String exchange;
|
||||
private Message message;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.poc.alerting.amqp;
|
||||
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class RabbitSender {
|
||||
private final RabbitTemplate rabbitTemplate;
|
||||
|
||||
public void send(final AmqpMessage amqpMessage) {
|
||||
try {
|
||||
LOG.info("Sending message: {}", amqpMessage.toString());
|
||||
rabbitTemplate.convertAndSend(amqpMessage.getExchange(), amqpMessage.getRoutingKey(), amqpMessage);
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Error sending message, serializing to disk", e);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T sendAndReceive(final AmqpMessage amqpMessage) {
|
||||
final AmqpResponse<T> amqpResponse = (AmqpResponse) rabbitTemplate.convertSendAndReceive(amqpMessage.getExchange(), amqpMessage.getRoutingKey(), amqpMessage);
|
||||
final String errorMessage = "Something went wrong";
|
||||
if (amqpResponse == null) {
|
||||
LOG.error(errorMessage);
|
||||
}
|
||||
final ExceptionType exceptionType = amqpResponse.getExceptionType();
|
||||
if (exceptionType != null) {
|
||||
final String exceptionMessage = amqpResponse.getExceptionMessage();
|
||||
final int statusCode = exceptionType.getStatus();
|
||||
if (amqpResponse.getErrorCode() != null) {
|
||||
final Integer errorCode = amqpResponse.getErrorCode();
|
||||
final String errorDescription = amqpResponse.getErrorDescription();
|
||||
LOG.error(errorMessage);
|
||||
} else {
|
||||
LOG.error(errorMessage);
|
||||
}
|
||||
}
|
||||
return amqpResponse.getValue();
|
||||
}
|
||||
|
||||
public void sendWithoutBackup(final AmqpMessage amqpMessage) {
|
||||
LOG.info("Sending message: {}", amqpMessage.toString());
|
||||
rabbitTemplate.convertAndSend(amqpMessage.getExchange(), amqpMessage.getRoutingKey(), amqpMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.poc.alerting.amqp
|
||||
|
||||
sealed class AlertingAmqpMessage(
|
||||
val alertId: String,
|
||||
val accountId: String
|
||||
): AmqpMessage {
|
||||
override fun getRoutingKey(): String {
|
||||
return "account_$accountId"
|
||||
}
|
||||
|
||||
override fun getExchange(): String {
|
||||
return "poc_alerting"
|
||||
}
|
||||
|
||||
class Add(val frequency: String, alertId: String, accountId: String): AlertingAmqpMessage(alertId, accountId)
|
||||
class Update(val frequency: String, alertId: String, accountId: String): AlertingAmqpMessage(alertId, accountId)
|
||||
class Delete(alertId: String, accountId: String): AlertingAmqpMessage(alertId, accountId)
|
||||
class Pause(alertId: String, accountId: String): AlertingAmqpMessage(alertId, accountId)
|
||||
class Resume(alertId: String, accountId: String): AlertingAmqpMessage(alertId, accountId)
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.poc.alerting.amqp
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils.MILLIS_PER_MINUTE
|
||||
import org.springframework.amqp.core.Binding
|
||||
import org.springframework.amqp.core.BindingBuilder
|
||||
import org.springframework.amqp.core.DirectExchange
|
||||
import org.springframework.amqp.core.Exchange
|
||||
import org.springframework.amqp.core.ExchangeBuilder
|
||||
import org.springframework.amqp.core.FanoutExchange
|
||||
import org.springframework.amqp.core.Queue
|
||||
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.ComponentScan
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = ["com.poc.alerting.amqp"])
|
||||
open class AmqpConfiguration {
|
||||
companion object {
|
||||
const val AMQP_NAME = "poc_alerting"
|
||||
const val NEW_ACCOUNT = "new_account"
|
||||
const val FANOUT_NAME = "${AMQP_NAME}_fanout"
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun connectionFactory(): ConnectionFactory {
|
||||
return CachingConnectionFactory().apply {
|
||||
virtualHost = "poc"
|
||||
username = "poc_user"
|
||||
setPassword("s!mpleP@ssw0rd")
|
||||
setAddresses("localhost")
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun newAccountQueue(): Queue {
|
||||
return Queue(NEW_ACCOUNT, true)
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun newAccountExchange(): FanoutExchange {
|
||||
return FanoutExchange(NEW_ACCOUNT)
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun newAccountBinding(newAccountQueue: Queue, newAccountExchange: FanoutExchange): Binding {
|
||||
return BindingBuilder.bind(newAccountQueue).to(newAccountExchange)
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun pocAlertingExchange(): FanoutExchange {
|
||||
return FanoutExchange(FANOUT_NAME)
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun directExchange(): DirectExchange {
|
||||
return ExchangeBuilder.directExchange(AMQP_NAME)
|
||||
.durable(false)
|
||||
.withArgument("alternate-exchange", NEW_ACCOUNT)
|
||||
.build()
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun exchangeBinding(directExchange: Exchange, pocAlertingExchange: FanoutExchange): Binding {
|
||||
return BindingBuilder.bind(directExchange).to(pocAlertingExchange)
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun rabbitTemplate(connectionFactory: ConnectionFactory, gsonMessageConverter: GsonMessageConverter): RabbitTemplate {
|
||||
return RabbitTemplate(connectionFactory).apply {
|
||||
setExchange(FANOUT_NAME)
|
||||
messageConverter = gsonMessageConverter
|
||||
setReplyTimeout(MILLIS_PER_MINUTE)
|
||||
setMandatory(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootJar
|
||||
|
||||
plugins {
|
||||
id("io.swagger.core.v3.swagger-gradle-plugin") version "2.1.9"
|
||||
kotlin("plugin.jpa") version "1.5.10"
|
||||
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
sourceCompatibility = "1.8"
|
||||
targetCompatibility = "1.8"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"implementation"(project(":persistence"))
|
||||
"implementation"(project(":amqp"))
|
||||
|
||||
implementation("org.springframework.boot:spring-boot-starter-aop")
|
||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||
implementation("org.springframework.boot:spring-boot-starter-tomcat")
|
||||
implementation("javax.validation:validation-api")
|
||||
}
|
||||
|
||||
tasks.getByName<BootJar>("bootJar") {
|
||||
enabled = true
|
||||
mainClass.set("com.poc.alerting.api.AlertingApi")
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.poc.alerting.api;
|
||||
|
||||
import java.beans.FeatureDescriptor;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
|
||||
public final class PropertyCopier {
|
||||
private PropertyCopier() {
|
||||
}
|
||||
|
||||
public static void copyNonNullProperties(final Object source, final Object target, final List<String> ignoredProperties) {
|
||||
BeanUtils.copyProperties(source, target, getNullPropertyNames(source, ignoredProperties));
|
||||
}
|
||||
|
||||
private static String[] getNullPropertyNames(final Object source, final List<String> ignoredProperties) {
|
||||
final BeanWrapper wrappedSource = new BeanWrapperImpl(source);
|
||||
return Stream.of(wrappedSource.getPropertyDescriptors())
|
||||
.map(FeatureDescriptor::getName)
|
||||
.filter(propertyName -> wrappedSource.getPropertyValue(propertyName) == null || (ignoredProperties != null && ignoredProperties.contains(propertyName)))
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.poc.alerting.api
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
|
||||
@SpringBootApplication(scanBasePackages = ["com.poc.alerting"])
|
||||
open class AlertingApi
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
runApplication<AlertingApi>(*args)
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.poc.alerting.api.controller
|
||||
|
||||
import com.poc.alerting.amqp.AlertingAmqpMessage.Add
|
||||
import com.poc.alerting.amqp.AlertingAmqpMessage.Delete
|
||||
import com.poc.alerting.amqp.AlertingAmqpMessage.Pause
|
||||
import com.poc.alerting.amqp.AlertingAmqpMessage.Resume
|
||||
import com.poc.alerting.amqp.AlertingAmqpMessage.Update
|
||||
import com.poc.alerting.amqp.RabbitSender
|
||||
import com.poc.alerting.api.PropertyCopier
|
||||
import com.poc.alerting.persistence.dto.Alert
|
||||
import com.poc.alerting.persistence.repositories.AccountRepository
|
||||
import com.poc.alerting.persistence.repositories.AlertRepository
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.validation.annotation.Validated
|
||||
import org.springframework.web.bind.annotation.DeleteMapping
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PatchMapping
|
||||
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.RequestParam
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import javax.validation.Valid
|
||||
|
||||
@RestController
|
||||
@Validated
|
||||
open class AlertController @Autowired constructor(
|
||||
private val accountRepository: AccountRepository,
|
||||
private val alertRepository: AlertRepository,
|
||||
private val rabbitSender: RabbitSender
|
||||
) {
|
||||
@PostMapping("/accounts/{account_id}/alerts")
|
||||
open fun addAlert(@PathVariable("account_id") accountId: String,
|
||||
@RequestBody body: @Valid Alert
|
||||
): ResponseEntity<Alert> {
|
||||
val account = accountRepository.findByExtId(accountId)
|
||||
body.account = account
|
||||
val alert = alertRepository.save(body).also {
|
||||
rabbitSender.send(Add(body.frequency, body.extId, accountId))
|
||||
}
|
||||
|
||||
return ResponseEntity(alert, HttpStatus.CREATED)
|
||||
}
|
||||
|
||||
@DeleteMapping("/accounts/{account_id}/alerts/{alert_id}")
|
||||
open fun deleteAlert(@PathVariable("account_id") accountId: String,
|
||||
@PathVariable("alert_id") alertId: String
|
||||
): ResponseEntity<Void> {
|
||||
rabbitSender.send(Delete(alertId, accountId))
|
||||
return ResponseEntity(HttpStatus.OK)
|
||||
}
|
||||
|
||||
@GetMapping("/accounts/{account_id}/alerts/{alert_id}")
|
||||
open fun getAlertById(
|
||||
@PathVariable("account_id") accountId: String,
|
||||
@PathVariable("alert_id") alertId: String,
|
||||
@RequestParam(value = "include_recipients", required = false, defaultValue = "false") includeRecipients: @Valid Boolean?
|
||||
): ResponseEntity<Alert> {
|
||||
return ResponseEntity.ok(alertRepository.findByExtIdAndAccount_ExtId(alertId, accountId))
|
||||
}
|
||||
|
||||
@GetMapping("/accounts/{account_id}/alerts")
|
||||
open fun getListOfAlerts(
|
||||
@PathVariable("account_id") accountId: String,
|
||||
@RequestParam(value = "include_recipients", required = false, defaultValue = "false") includeRecipients: @Valid Boolean?
|
||||
): ResponseEntity<List<Alert>> {
|
||||
return ResponseEntity.ok(alertRepository.findAllByAccount_ExtId(accountId))
|
||||
}
|
||||
|
||||
@PatchMapping("/accounts/{account_id}/alerts/{alert_id}")
|
||||
open fun updateAlert(
|
||||
@PathVariable("account_id") accountId: String,
|
||||
@PathVariable("alert_id") alertId: String,
|
||||
@RequestBody body: @Valid Alert
|
||||
): ResponseEntity<Alert> {
|
||||
val existingAlert = alertRepository.findByExtIdAndAccount_ExtId(alertId, accountId)
|
||||
|
||||
rabbitSender.send(Update(body.frequency, alertId, accountId))
|
||||
|
||||
body.enabled.let {
|
||||
if (body.enabled.isNotBlank() && body.enabled.toBoolean() != existingAlert.enabled.toBoolean()) {
|
||||
if (body.enabled.toBoolean()) {
|
||||
rabbitSender.send(Resume(alertId, accountId))
|
||||
} else {
|
||||
rabbitSender.send(Pause(alertId, accountId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PropertyCopier.copyNonNullProperties(body, existingAlert, null)
|
||||
return ResponseEntity.ok(alertRepository.save(existingAlert))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.poc.alerting.api.controller
|
||||
|
||||
import com.poc.alerting.api.PropertyCopier
|
||||
import com.poc.alerting.persistence.dto.Recipient
|
||||
import com.poc.alerting.persistence.repositories.RecipientRepository
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.validation.annotation.Validated
|
||||
import org.springframework.web.bind.annotation.DeleteMapping
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PatchMapping
|
||||
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.RestController
|
||||
import javax.validation.Valid
|
||||
|
||||
@RestController
|
||||
@Validated
|
||||
open class RecipientController @Autowired constructor(
|
||||
private val recipientRepository: RecipientRepository
|
||||
) {
|
||||
@PostMapping("/accounts/{account_id}/alerts/{alert_id}/recipients")
|
||||
open fun addRecipient(@PathVariable("account_id") accountId: String,
|
||||
@PathVariable("alert_id") alertId: String,
|
||||
@RequestBody body: @Valid MutableList<Recipient>
|
||||
): ResponseEntity<Iterable<Recipient>> {
|
||||
return ResponseEntity(recipientRepository.saveAll(body), HttpStatus.CREATED)
|
||||
}
|
||||
|
||||
@DeleteMapping("/accounts/{account_id}/alerts/{alert_id}/recipients/{recipient_id}")
|
||||
open fun deleteRecipient(
|
||||
@PathVariable("account_id") accountId: String,
|
||||
@PathVariable("alert_id") alertId: String,
|
||||
@PathVariable("recipient_id") recipientId: String
|
||||
): ResponseEntity<Void> {
|
||||
recipientRepository.delete(recipientRepository.findByExtIdAndAlert_ExtIdAndAccount_ExtId(recipientId, alertId, accountId))
|
||||
return ResponseEntity(HttpStatus.OK)
|
||||
}
|
||||
|
||||
@GetMapping("/accounts/{account_id}/recipients")
|
||||
open fun getAllRecipients(
|
||||
@PathVariable("account_id") accountId: String
|
||||
): ResponseEntity<List<Recipient>> {
|
||||
return ResponseEntity.ok(recipientRepository.findAllByAccount_ExtId(accountId))
|
||||
}
|
||||
|
||||
@GetMapping("/accounts/{account_id}/alerts/{alert_id}/recipients/{recipient_id}")
|
||||
open fun getRecipient(
|
||||
@PathVariable("account_id") accountId: String,
|
||||
@PathVariable("alert_id") alertId: String,
|
||||
@PathVariable("recipient_id") recipientId: String
|
||||
): ResponseEntity<Recipient> {
|
||||
return ResponseEntity.ok(recipientRepository.findByExtIdAndAlert_ExtIdAndAccount_ExtId(recipientId, alertId, accountId))
|
||||
}
|
||||
|
||||
@GetMapping("/accounts/{account_id}/alerts/{alert_id}/recipients")
|
||||
open fun getRecipientList(
|
||||
@PathVariable("account_id") accountId: String,
|
||||
@PathVariable("alert_id") alertId: String
|
||||
): ResponseEntity<List<Recipient>> {
|
||||
return ResponseEntity.ok(recipientRepository.findAllByAlert_ExtIdAndAccount_ExtId(alertId, accountId))
|
||||
}
|
||||
|
||||
@PatchMapping("/accounts/{account_id}/alerts/{alert_id}/recipients/{recipient_id}")
|
||||
open fun updateRecipient(
|
||||
@PathVariable("account_id") accountId: String,
|
||||
@PathVariable("alert_id") alertId: String,
|
||||
@PathVariable("recipient_id") recipientId: String,
|
||||
@RequestBody body: @Valid Recipient
|
||||
): ResponseEntity<Recipient> {
|
||||
val existingRecipient = recipientRepository.findByExtIdAndAlert_ExtIdAndAccount_ExtId(recipientId, alertId, accountId)
|
||||
PropertyCopier.copyNonNullProperties(body, existingRecipient, null)
|
||||
return ResponseEntity.ok(recipientRepository.save(existingRecipient))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
server:
|
||||
servlet:
|
||||
contextPath: "/poc/alerting/v1"
|
||||
port: 8080
|
||||
spring:
|
||||
jackson:
|
||||
time-zone: UTC
|
||||
default-property-inclusion: non_null
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: update
|
||||
show-sql: true
|
||||
datasource:
|
||||
url: "jdbc:h2:tcp://localhost:9091/mem:alerting"
|
||||
username: "defaultUser"
|
||||
password: "secret"
|
||||
application:
|
||||
name: AlertingApi
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
profiles:
|
||||
active: "api"
|
||||
@@ -0,0 +1,29 @@
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootJar
|
||||
|
||||
dependencies {
|
||||
"implementation"(project(":persistence"))
|
||||
"implementation"(project(":amqp"))
|
||||
|
||||
implementation("org.slf4j:slf4j-api")
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||
implementation("org.springframework.amqp:spring-amqp")
|
||||
implementation("org.springframework.amqp:spring-rabbit")
|
||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||
implementation("org.springframework.boot:spring-boot-starter-quartz")
|
||||
implementation("org.springframework:spring-jdbc")
|
||||
implementation("org.projectlombok:lombok")
|
||||
implementation("org.apache.commons:commons-lang3")
|
||||
implementation("org.apache.httpcomponents:fluent-hc")
|
||||
implementation("com.google.code.gson:gson")
|
||||
|
||||
annotationProcessor("org.projectlombok:lombok")
|
||||
}
|
||||
|
||||
tasks.getByName<BootJar>("bootJar") {
|
||||
enabled = true
|
||||
mainClass.set("com.poc.alerting.batch.BatchWorkerKt")
|
||||
}
|
||||
|
||||
springBoot {
|
||||
mainClass.set("com.poc.alerting.batch.BatchWorkerKt")
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.poc.alerting.batch;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AccountConsumerManager {
|
||||
private volatile boolean shuttingDown = false;
|
||||
@Getter private final Map<String, SimpleMessageListenerContainer> consumers = new ConcurrentHashMap<>();
|
||||
private final Object lifecycleMonitor = new Object();
|
||||
|
||||
void registerAndStart(final String queueName, final SimpleMessageListenerContainer newListenerContainer) {
|
||||
synchronized (this.lifecycleMonitor) {
|
||||
if (shuttingDown) {
|
||||
LOG.warn("Shutdown process is underway. Not registering consumer for queue {}", queueName);
|
||||
return;
|
||||
}
|
||||
|
||||
final SimpleMessageListenerContainer oldListenerContainer = consumers.get(queueName);
|
||||
if (oldListenerContainer != null) {
|
||||
oldListenerContainer.stop();
|
||||
}
|
||||
newListenerContainer.start();
|
||||
consumers.put(queueName, newListenerContainer);
|
||||
LOG.info("Registered a new consumer on queue {}", queueName);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopConsumers() {
|
||||
synchronized (this.lifecycleMonitor) {
|
||||
shuttingDown = true;
|
||||
LOG.info("Shutting down consumers on queues {}", consumers.keySet());
|
||||
consumers.entrySet().parallelStream().forEach(entry -> {
|
||||
LOG.info("Shutting down consumer on queue {}", entry.getKey());
|
||||
try {
|
||||
entry.getValue().stop();
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Encountered error while stopping consumer on queue " + entry.getKey(), e);
|
||||
}
|
||||
});
|
||||
|
||||
LOG.info("Finished shutting down all consumers");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.poc.alerting.batch;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.apache.http.client.fluent.Request;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {
|
||||
ConnectionFactory connectionFactory;
|
||||
MessageListenerAdapter accountWorkerListenerAdapter;
|
||||
MessageConverter gsonMessageConverter;
|
||||
ApplicationEventPublisher applicationEventPublisher;
|
||||
ConsumerCreator consumerCreator;
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ApplicationStartup.class);
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(@NotNull final ApplicationReadyEvent event) {
|
||||
LOG.info("Creating consumers for existing queues");
|
||||
try {
|
||||
|
||||
final String rabbitMqUrl = String.format("http://%s:15672/api/exchanges/poc/alerting/bindings/source", "localhost");
|
||||
|
||||
//auth is kind of a kluge here. Apparently the HttpClient Fluent API doesn't support
|
||||
//it except by explicitly setting the auth header.
|
||||
final String json = Request.Get(rabbitMqUrl)
|
||||
.connectTimeout(1000)
|
||||
.socketTimeout(1000)
|
||||
.addHeader("Authorization", "Basic " + getAuthToken())
|
||||
.execute().returnContent().asString();
|
||||
|
||||
final JsonParser parser = new JsonParser();
|
||||
final JsonArray array = parser.parse(json).getAsJsonArray();
|
||||
|
||||
StreamSupport.stream(array.spliterator(), false)
|
||||
.map(jsonElement -> jsonElement.getAsJsonObject().get("destination").getAsString())
|
||||
.forEach(queueName -> consumerCreator.createConsumer(queueName));
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Error create consumers for existing queues", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getAuthToken() {
|
||||
final String basicPlaintext = "poc" + ":" + "s!mpleP@ssw0rd";
|
||||
|
||||
final Base64.Encoder encoder = Base64.getEncoder();
|
||||
return encoder.encodeToString(basicPlaintext.getBytes());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.poc.alerting.batch;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.springframework.amqp.support.ConditionalExceptionLogger;
|
||||
|
||||
public class ExclusiveConsumerExceptionLogger implements ConditionalExceptionLogger {
|
||||
@Override
|
||||
public void log(final Log logger, final String message, final Throwable t) {
|
||||
//do not log exclusive consumer warnings
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.poc.alerting.batch;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.springframework.amqp.core.BindingBuilder;
|
||||
import org.springframework.amqp.core.DirectExchange;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.amqp.core.QueueBuilder;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.poc.alerting.amqp.AmqpMessage;
|
||||
import com.poc.alerting.amqp.AmqpResponse;
|
||||
import com.poc.alerting.amqp.ExceptionType;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static com.poc.alerting.amqp.AmqpConfiguration.AMQP_NAME;
|
||||
import static com.poc.alerting.batch.WorkerConfiguration.NEW_CONSUMER;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class QueueCreator {
|
||||
private final RabbitAdmin rabbitAdmin;
|
||||
private final RabbitTemplate rabbitTemplate;
|
||||
private final DirectExchange directExchange;
|
||||
|
||||
public <T> AmqpResponse<T> createQueue(final AmqpMessage amqpMessage) throws IOException, ClassNotFoundException {
|
||||
final String routingKey = amqpMessage.getRoutingKey();
|
||||
LOG.info("Attempting to create new queue {}", routingKey);
|
||||
setupQueueForAccount(routingKey);
|
||||
final AmqpResponse response = (AmqpResponse) rabbitTemplate.convertSendAndReceive(AMQP_NAME, routingKey, amqpMessage);
|
||||
if (response != null && ExceptionType.INVALID_ACCOUNT_EXCEPTION.equals(response.getExceptionType())) {
|
||||
LOG.info("Invalid account, removing queue {}", routingKey);
|
||||
CompletableFuture.runAsync(() -> rabbitAdmin.deleteQueue(routingKey, false, true));
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
private void setupQueueForAccount(final String routingKey) {
|
||||
final Properties properties = rabbitAdmin.getQueueProperties(routingKey);
|
||||
if (properties == null) {
|
||||
final Queue queue = QueueBuilder.nonDurable(routingKey)
|
||||
.withArgument("x-expires", DateUtils.MILLIS_PER_DAY)
|
||||
.build();
|
||||
|
||||
rabbitAdmin.declareQueue(queue);
|
||||
rabbitAdmin.declareBinding(BindingBuilder.bind(queue).to(directExchange).with(routingKey));
|
||||
sendCreateConsumerMessage(routingKey);
|
||||
} else if ((Integer) properties.get(RabbitAdmin.QUEUE_CONSUMER_COUNT) < 1) {
|
||||
LOG.info("{} queue already exists. Adding consumer.", routingKey);
|
||||
sendCreateConsumerMessage(routingKey);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendCreateConsumerMessage(final String queueName) {
|
||||
rabbitTemplate.convertAndSend(NEW_CONSUMER, "", queueName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.poc.alerting.batch
|
||||
|
||||
import com.poc.alerting.amqp.AlertingAmqpMessage
|
||||
import com.poc.alerting.amqp.AlertingAmqpMessage.Add
|
||||
import com.poc.alerting.amqp.AlertingAmqpMessage.Delete
|
||||
import com.poc.alerting.amqp.AlertingAmqpMessage.Pause
|
||||
import com.poc.alerting.amqp.AlertingAmqpMessage.Resume
|
||||
import com.poc.alerting.amqp.AlertingAmqpMessage.Update
|
||||
import com.poc.alerting.batch.jobs.AlertQueryJob
|
||||
import com.poc.alerting.batch.jobs.AlertQueryJob.Companion.ACCOUNT_ID
|
||||
import com.poc.alerting.batch.jobs.AlertQueryJob.Companion.ALERT_ID
|
||||
import com.poc.alerting.batch.jobs.AlertQueryJob.Companion.CRON
|
||||
import com.poc.alerting.persistence.dto.Alert
|
||||
import com.poc.alerting.persistence.repositories.AlertRepository
|
||||
import org.quartz.CronScheduleBuilder
|
||||
import org.quartz.JobBuilder
|
||||
import org.quartz.JobDataMap
|
||||
import org.quartz.JobDetail
|
||||
import org.quartz.JobKey
|
||||
import org.quartz.Scheduler
|
||||
import org.quartz.Trigger
|
||||
import org.quartz.TriggerBuilder
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.stereotype.Service
|
||||
import java.time.ZoneId
|
||||
import java.util.TimeZone
|
||||
|
||||
@Service
|
||||
open class AccountWorker @Autowired constructor(
|
||||
private val alertRepository: AlertRepository,
|
||||
private val scheduler: Scheduler
|
||||
){
|
||||
fun processMessage(message: AlertingAmqpMessage) {
|
||||
when (message) {
|
||||
is Add -> createJob(message.alertId, message.accountId, message.frequency)
|
||||
is Update -> updateJob(message.alertId, message.accountId, message.frequency)
|
||||
is Delete -> deleteJob(message.alertId, message.accountId)
|
||||
is Pause -> pauseJob(message.alertId, message.accountId)
|
||||
is Resume -> resumeJob(message.alertId, message.accountId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createJob(alertId: String, accountId: String, cron: String): Alert {
|
||||
val jobDetail = buildJob(alertId, accountId, cron)
|
||||
val trigger = createTrigger(alertId, jobDetail, cron)
|
||||
|
||||
with (scheduler) {
|
||||
scheduleJob(jobDetail, trigger)
|
||||
start()
|
||||
}
|
||||
|
||||
return alertRepository.findByExtIdAndAccount_Id(alertId, accountId)
|
||||
}
|
||||
|
||||
private fun updateJob(alertId: String, accountId: String, cron: String): Alert {
|
||||
scheduler.deleteJob(JobKey.jobKey(alertId, accountId))
|
||||
return createJob(alertId, accountId, cron)
|
||||
}
|
||||
|
||||
private fun deleteJob(alertId: String, accountId: String): Alert {
|
||||
val alert = alertRepository.findByExtIdAndAccount_Id(alertId, accountId)
|
||||
scheduler.deleteJob(JobKey.jobKey(alertId, accountId))
|
||||
alertRepository.delete(alert)
|
||||
return alert
|
||||
}
|
||||
|
||||
private fun pauseJob(alertId: String, accountId: String): Alert {
|
||||
scheduler.pauseJob(JobKey.jobKey(alertId, accountId))
|
||||
return alertRepository.findByExtIdAndAccount_Id(alertId, accountId)
|
||||
}
|
||||
|
||||
private fun resumeJob(alertId: String, accountId: String): Alert {
|
||||
scheduler.resumeJob(JobKey.jobKey(alertId, accountId))
|
||||
return alertRepository.findByExtIdAndAccount_Id(alertId, accountId)
|
||||
}
|
||||
|
||||
private fun buildJob(alertId: String, accountId: String, cron: String): JobDetail {
|
||||
val jobDataMap = JobDataMap()
|
||||
jobDataMap[ALERT_ID] = alertId
|
||||
jobDataMap[ACCOUNT_ID] = accountId
|
||||
jobDataMap[CRON] = cron
|
||||
return JobBuilder.newJob().ofType(AlertQueryJob::class.java)
|
||||
.storeDurably()
|
||||
.withIdentity(alertId, accountId)
|
||||
.usingJobData(jobDataMap)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun createTrigger(alertId: String, jobDetail: JobDetail, cron: String): Trigger {
|
||||
return TriggerBuilder.newTrigger()
|
||||
.forJob(jobDetail)
|
||||
.withIdentity("${alertId}_trigger")
|
||||
.withSchedule(
|
||||
CronScheduleBuilder.cronSchedule(cron)
|
||||
.withMisfireHandlingInstructionFireAndProceed()
|
||||
.inTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault()))
|
||||
)
|
||||
.usingJobData("cron", cron)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.poc.alerting.batch
|
||||
|
||||
import org.quartz.Job
|
||||
import org.quartz.SchedulerContext
|
||||
import org.quartz.spi.TriggerFiredBundle
|
||||
import org.springframework.beans.MutablePropertyValues
|
||||
import org.springframework.beans.PropertyAccessorFactory
|
||||
import org.springframework.context.ApplicationContext
|
||||
import org.springframework.context.ApplicationContextAware
|
||||
import org.springframework.scheduling.quartz.SpringBeanJobFactory
|
||||
|
||||
|
||||
class AutowiringSpringBeanJobFactory : SpringBeanJobFactory(), ApplicationContextAware {
|
||||
private var ctx: ApplicationContext? = null
|
||||
private var schedulerContext: SchedulerContext? = null
|
||||
override fun setApplicationContext(context: ApplicationContext) {
|
||||
ctx = context
|
||||
}
|
||||
|
||||
override fun createJobInstance(bundle: TriggerFiredBundle): Any {
|
||||
val job: Job = ctx!!.getBean(bundle.jobDetail.jobClass)
|
||||
val bw = PropertyAccessorFactory.forBeanPropertyAccess(job)
|
||||
val pvs = MutablePropertyValues()
|
||||
pvs.addPropertyValues(bundle.jobDetail.jobDataMap)
|
||||
pvs.addPropertyValues(bundle.trigger.jobDataMap)
|
||||
if (this.schedulerContext != null) {
|
||||
pvs.addPropertyValues(this.schedulerContext)
|
||||
}
|
||||
bw.setPropertyValues(pvs, true)
|
||||
return job
|
||||
}
|
||||
|
||||
override fun setSchedulerContext(schedulerContext: SchedulerContext) {
|
||||
this.schedulerContext = schedulerContext
|
||||
super.setSchedulerContext(schedulerContext)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.poc.alerting.batch
|
||||
|
||||
import org.springframework.boot.Banner
|
||||
import org.springframework.boot.WebApplicationType
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder
|
||||
|
||||
@SpringBootApplication(scanBasePackages = ["com.poc.alerting"])
|
||||
open class BatchWorker
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
SpringApplicationBuilder().sources(BatchWorker::class.java)
|
||||
.bannerMode(Banner.Mode.OFF)
|
||||
.web(WebApplicationType.NONE)
|
||||
.run(*args)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.poc.alerting.batch
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory
|
||||
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer
|
||||
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.context.ApplicationEventPublisher
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
open class ConsumerCreator @Autowired constructor(
|
||||
private val connectionFactory: ConnectionFactory,
|
||||
private val accountWorkerListenerAdapter: MessageListenerAdapter,
|
||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
||||
private val accountConsumerManager: AccountConsumerManager
|
||||
){
|
||||
fun createConsumer(queueName: String) {
|
||||
val consumer = SimpleMessageListenerContainer(connectionFactory)
|
||||
consumer.setExclusive(true)
|
||||
consumer.setExclusiveConsumerExceptionLogger(ExclusiveConsumerExceptionLogger())
|
||||
consumer.setQueueNames(queueName)
|
||||
consumer.setMessageListener(accountWorkerListenerAdapter)
|
||||
consumer.setIdleEventInterval(DateUtils.MILLIS_PER_HOUR)
|
||||
consumer.setApplicationEventPublisher(applicationEventPublisher)
|
||||
consumer.setDefaultRequeueRejected(false)
|
||||
consumer.setAutoDeclare(false)
|
||||
consumer.setShutdownTimeout(DateUtils.MILLIS_PER_SECOND * 10)
|
||||
accountConsumerManager.registerAndStart(queueName, consumer)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.poc.alerting.batch
|
||||
|
||||
import com.poc.alerting.amqp.AmqpConfiguration.Companion.NEW_ACCOUNT
|
||||
import com.poc.alerting.amqp.GsonMessageConverter
|
||||
import org.springframework.amqp.core.Binding
|
||||
import org.springframework.amqp.core.BindingBuilder
|
||||
import org.springframework.amqp.core.FanoutExchange
|
||||
import org.springframework.amqp.core.Queue
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin
|
||||
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer
|
||||
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.scheduling.annotation.AsyncConfigurer
|
||||
import org.springframework.scheduling.annotation.EnableAsync
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
|
||||
import java.net.InetAddress
|
||||
import java.util.concurrent.Executor
|
||||
|
||||
@Configuration
|
||||
@EnableAsync
|
||||
open class WorkerConfiguration: AsyncConfigurer {
|
||||
companion object {
|
||||
const val NEW_CONSUMER = "new_consumer"
|
||||
}
|
||||
|
||||
@Bean("asyncExecutor")
|
||||
override fun getAsyncExecutor(): Executor {
|
||||
return ThreadPoolTaskExecutor()
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun rabbitAdmin(connectionFactory: ConnectionFactory): RabbitAdmin {
|
||||
return RabbitAdmin(connectionFactory)
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun queueCreatorListenerAdapter(queueCreator: QueueCreator, gsonMessageConverter: GsonMessageConverter): MessageListenerAdapter {
|
||||
return MessageListenerAdapter(queueCreator, "createQueue").apply {
|
||||
setMessageConverter(gsonMessageConverter)
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun queueCreatorContainer(connectionFactory: ConnectionFactory, queueCreatorListenerAdapter: MessageListenerAdapter,
|
||||
gsonMessageConverter: GsonMessageConverter): SimpleMessageListenerContainer {
|
||||
return SimpleMessageListenerContainer(connectionFactory).apply {
|
||||
setExclusive(true)
|
||||
setExclusiveConsumerExceptionLogger(ExclusiveConsumerExceptionLogger())
|
||||
setQueueNames(NEW_ACCOUNT)
|
||||
setMessageListener(queueCreatorListenerAdapter)
|
||||
setDefaultRequeueRejected(false)
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun newConsumerExchange(): FanoutExchange {
|
||||
return FanoutExchange(NEW_CONSUMER)
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun newConsumerQueue(): Queue {
|
||||
return Queue("${NEW_CONSUMER}_${InetAddress.getLocalHost().hostName}", true)
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun newConsumerBinding(newConsumerQueue: Queue, newConsumerExchange: FanoutExchange): Binding {
|
||||
return BindingBuilder.bind(newConsumerQueue).to(newConsumerExchange)
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun consumerCreatorListenerAdapter(consumerCreator: ConsumerCreator, gsonMessageConverter: GsonMessageConverter): MessageListenerAdapter {
|
||||
return MessageListenerAdapter(consumerCreator, "createConsumer").apply {
|
||||
setMessageConverter(gsonMessageConverter)
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun consumerCreatorContainer(connectionFactory: ConnectionFactory, consumerCreatorListenerAdapter: MessageListenerAdapter,
|
||||
newConsumerQueue: Queue): SimpleMessageListenerContainer {
|
||||
return SimpleMessageListenerContainer(connectionFactory).apply {
|
||||
setExclusive(true)
|
||||
setExclusiveConsumerExceptionLogger(ExclusiveConsumerExceptionLogger())
|
||||
setQueues(newConsumerQueue)
|
||||
setMessageListener(consumerCreatorListenerAdapter)
|
||||
setDefaultRequeueRejected(false)
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun accountWorkerListenerAdapter(accountWorker: AccountWorker, gsonMessageConverter: GsonMessageConverter): MessageListenerAdapter {
|
||||
return MessageListenerAdapter(accountWorker, "processMessage").apply {
|
||||
setMessageConverter(gsonMessageConverter)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.poc.alerting.batch.jobs
|
||||
|
||||
import com.poc.alerting.persistence.repositories.AlertRepository
|
||||
import org.quartz.Job
|
||||
import org.quartz.JobExecutionContext
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.stereotype.Component
|
||||
import java.time.Duration
|
||||
import java.util.Date
|
||||
|
||||
@Component
|
||||
open class AlertQueryJob @Autowired constructor(
|
||||
private val alertRepository: AlertRepository
|
||||
): Job {
|
||||
companion object {
|
||||
const val ALERT_ID = "alertId"
|
||||
const val CRON = "cron"
|
||||
const val ACCOUNT_ID = "accountId"
|
||||
}
|
||||
|
||||
override fun execute(context: JobExecutionContext) {
|
||||
val data = context.jobDetail.jobDataMap
|
||||
val alertId = data.getString(ALERT_ID)
|
||||
val cron = data.getString(CRON)
|
||||
val accountId = data.getString(ACCOUNT_ID)
|
||||
|
||||
val alert = alertRepository.findByExtIdAndAccount_Id(alertId, accountId)
|
||||
|
||||
with(alert) {
|
||||
val queryResult = type.query()
|
||||
println("PERFORMING QUERY for $alertId-$accountId. Running with the following CRON expression: $cron")
|
||||
if (queryResult >= threshold.toInt()) {
|
||||
val currentTime = Date()
|
||||
if (!isTriggered) {
|
||||
isTriggered = true
|
||||
}
|
||||
|
||||
notificationSentTimestamp.let {
|
||||
if (Duration.between(notificationSentTimestamp.toInstant(), currentTime.toInstant()).toSeconds() >= 15) {
|
||||
println("Alert Triggered!!!!!!!!!!!!!")
|
||||
notificationSentTimestamp = currentTime
|
||||
}
|
||||
}
|
||||
|
||||
lastTriggerTimestamp = currentTime
|
||||
alertRepository.save(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.poc.alerting.batch.jobs
|
||||
|
||||
import com.poc.alerting.batch.AutowiringSpringBeanJobFactory
|
||||
import org.quartz.spi.JobFactory
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.context.ApplicationContext
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.ComponentScan
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.scheduling.quartz.SchedulerFactoryBean
|
||||
import javax.sql.DataSource
|
||||
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
@EnableAutoConfiguration
|
||||
open class ScheduleAlertQueryConfiguration {
|
||||
@Bean
|
||||
open fun jobFactory(applicationContext: ApplicationContext): JobFactory {
|
||||
return AutowiringSpringBeanJobFactory().apply {
|
||||
setApplicationContext(applicationContext)
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun schedulerFactory(applicationContext: ApplicationContext, dataSource: DataSource, jobFactory: JobFactory): SchedulerFactoryBean {
|
||||
return SchedulerFactoryBean().apply {
|
||||
setOverwriteExistingJobs(true)
|
||||
isAutoStartup = true
|
||||
setDataSource(dataSource)
|
||||
setJobFactory(jobFactory)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
server:
|
||||
port: 0
|
||||
servlet:
|
||||
encoding:
|
||||
charset: UTF-8
|
||||
enabled: true
|
||||
spring:
|
||||
profiles:
|
||||
active: "batch"
|
||||
datasource:
|
||||
url: "jdbc:h2:tcp://localhost:9091/mem:alerting;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE;"
|
||||
username: "defaultUser"
|
||||
password: "secret"
|
||||
application:
|
||||
name: BatchWorker
|
||||
jackson:
|
||||
time-zone: UTC
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
@@ -0,0 +1,75 @@
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
id("org.springframework.boot") version "2.5.0"
|
||||
id("io.spring.dependency-management") version "1.0.11.RELEASE"
|
||||
kotlin("jvm") version "1.5.10"
|
||||
kotlin("plugin.spring") version "1.5.10"
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
allprojects {
|
||||
group = "com.poc.alerting"
|
||||
version = "0.0.1-SNAPSHOT"
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
sourceCompatibility = "11"
|
||||
targetCompatibility = "11"
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = listOf("-Xjsr305=strict", "-Xextended-compiler-checks")
|
||||
jvmTarget = "11"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
apply(plugin = "org.jetbrains.kotlin.jvm")
|
||||
apply(plugin = "org.springframework.boot")
|
||||
apply(plugin = "io.spring.dependency-management")
|
||||
apply(plugin = "java")
|
||||
apply(plugin = "java-library")
|
||||
|
||||
dependencies {
|
||||
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
failOnVersionConflict()
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java.srcDir("src/main/kotlin")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
springBoot {
|
||||
mainClass.set("com.poc.alerting.persistence.Persistence")
|
||||
}
|
||||
@@ -0,0 +1,938 @@
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Alerting API
|
||||
description: 'This is a POC API for a dynamic, reactive alerting system.'
|
||||
version: 0.0.1
|
||||
servers:
|
||||
- url: http://localhost:8080/poc/alerting/v1
|
||||
tags:
|
||||
- name: Alerts
|
||||
- name: Recipients
|
||||
security:
|
||||
- alerting_auth:
|
||||
- read
|
||||
- write
|
||||
paths:
|
||||
/accounts/{account_id}/alerts:
|
||||
get:
|
||||
tags:
|
||||
- Alerts
|
||||
description: Get the list of alerts for an account
|
||||
summary: Get the list of alerts for an account
|
||||
operationId: getListOfAlerts
|
||||
parameters:
|
||||
- name: account_id
|
||||
in: path
|
||||
description: ID of the account to get alerts from.
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1234567
|
||||
- name: include_recipients
|
||||
in: query
|
||||
description: >
|
||||
If set to true, then the list of all recipients belonging to each alert will be included in the response.
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
example: true
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Alert'
|
||||
example:
|
||||
- id: "percentageOfDeliveryFailures"
|
||||
name: "Percentage of Delivery Failures"
|
||||
threshold: "90"
|
||||
type: "PERCENTAGE_OF_DELIVERY_FAILURES"
|
||||
frequency: "15m"
|
||||
enabled: true
|
||||
last_triggered: "2021-04-22T16:33:21.959Z"
|
||||
notification_sent: "2021-04-22T16:33:21.959Z"
|
||||
is_triggered: true,
|
||||
reference_time_period: "1 Week"
|
||||
created: "2021-04-22T16:33:21.959Z"
|
||||
updated: "2021-04-22T16:33:21.959Z"
|
||||
updated_by: "someOtherUser"
|
||||
recipients:
|
||||
- id: "someUsersEmail"
|
||||
recipient: "someUser@somedomain.com"
|
||||
type: "EMAIL"
|
||||
created: "2021-02-22T16:09:28.139Z"
|
||||
updated: "2021-04-26T04:01:13.448Z"
|
||||
updated_by: "someUser"
|
||||
- id: "someOtherUsersEmail"
|
||||
recipient: "someOtherUser@somedomain.com"
|
||||
type: "EMAIL"
|
||||
created: "2021-03-04T07:17:33.244Z"
|
||||
updated: "2021-03-04T08:00:54.562Z"
|
||||
updated_by: "someOtherUser"
|
||||
- id: "failureThresholdAlert"
|
||||
name: "Too Many Errors"
|
||||
threshold: "1820"
|
||||
type: "FAILURE_THRESHOLD_ALERT"
|
||||
frequency: "5m"
|
||||
enabled: false
|
||||
last_triggered: "2021-04-22T16:33:21.959Z"
|
||||
notification_sent: "2021-04-22T16:33:21.959Z"
|
||||
is_triggered: true
|
||||
reference_time_period: "1 Month"
|
||||
created: "2021-04-22T16:33:21.959Z"
|
||||
updated: "2021-04-26T04:01:13.448Z"
|
||||
updated_by: "someOtherUser"
|
||||
recipients:
|
||||
- id: "someUserHttpRecipient"
|
||||
recipient: "https://some.test.callback.com/callback"
|
||||
type: "HTTP"
|
||||
username: "mikeRoweSoft"
|
||||
password: "iSuPpOrTwInDoWs"
|
||||
created: "2021-05-19T02:39:12.922Z"
|
||||
updated: "2021-05-19T02:39:12.922Z"
|
||||
updated_by: "someUser"
|
||||
403:
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
security:
|
||||
- alerting_auth:
|
||||
- write:alert
|
||||
- read:alert
|
||||
|
||||
post:
|
||||
tags:
|
||||
- Alerts
|
||||
description: Add an alert to the specified account.
|
||||
summary: Add an alert to the specified account
|
||||
operationId: addAlert
|
||||
parameters:
|
||||
- name: account_id
|
||||
in: path
|
||||
description: ID of an account to add an alert to.
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1234567
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: >
|
||||
External ID used by users to refer to alert.
|
||||
If an ID is specified, the ID must be account-unique.
|
||||
If not provided, it will be automatically generated.
|
||||
name:
|
||||
type: string
|
||||
description: The name of this alert
|
||||
default: "Default value differs by the alert type"
|
||||
threshold:
|
||||
type: string
|
||||
description: A threshold must be given for a custom alert.
|
||||
default: "Default value differs by the alert type"
|
||||
type:
|
||||
type: string
|
||||
description: The type of alert being added to the account
|
||||
enum:
|
||||
- PERCENTAGE_OF_DELIVERY_FAILURES
|
||||
- FAILURE_THRESHOLD_ALERT
|
||||
- HARD_CODED_ALERT_1
|
||||
- HARD_CODED_ALERT_2
|
||||
frequency:
|
||||
type: string
|
||||
description: The frequency of how often the alerting condition is checked.
|
||||
default: "15m"
|
||||
enabled:
|
||||
type: boolean
|
||||
description: Boolean value denoting whether the alert is enabled or not.
|
||||
default: true
|
||||
reference_time_period:
|
||||
type: string
|
||||
description: Time period to run the alerting condition against (lags in time series data).
|
||||
default: "1 Month"
|
||||
example:
|
||||
id: "testAlert1"
|
||||
name: "Too Many Messages Are Being Sent"
|
||||
threshold: "666"
|
||||
type: "FAILURE_THRESHOLD_ALERT"
|
||||
frequency: "5m"
|
||||
enabled: false
|
||||
reference_time_period: "1 Week"
|
||||
required:
|
||||
- type
|
||||
responses:
|
||||
201:
|
||||
description: Successfully created new alert
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Alert'
|
||||
example:
|
||||
id: "testAlert1"
|
||||
name: "Too Many Messages Are Being Sent"
|
||||
threshold: "666"
|
||||
type: "FAILURE_THRESHOLD_ALERT"
|
||||
frequency: "15m"
|
||||
enabled: false
|
||||
reference_time_period: "1 Week"
|
||||
created: "2021-04-22T16:33:21.959Z"
|
||||
updated: "2021-04-22T16:33:21.959Z"
|
||||
updated_by: "someUser"
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
409:
|
||||
description: An alert with the specified ID already exists on the given account
|
||||
422:
|
||||
description: >
|
||||
* Invalid alert request
|
||||
|
||||
* The type was unspecified, or does not exist
|
||||
security:
|
||||
- alerting_auth:
|
||||
- write:alert
|
||||
- read:alert
|
||||
|
||||
/accounts/{account_id}/alerts/{alert_id}:
|
||||
get:
|
||||
tags:
|
||||
- Alerts
|
||||
description: Get an alert given an alert ID and account ID.
|
||||
summary: Get an alert given an alert ID and account ID
|
||||
operationId: getAlertById
|
||||
parameters:
|
||||
- name: account_id
|
||||
in: path
|
||||
description: ID of the account to get alerts from.
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1234567
|
||||
- name: alert_id
|
||||
in: path
|
||||
description: External ID used by users to refer to an alert.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "someHardcodedAlert"
|
||||
- name: include_recipients
|
||||
in: query
|
||||
description: >
|
||||
If set to true, then the list of all recipients belonging to the alert will be included in the response.
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
example: true
|
||||
responses:
|
||||
200:
|
||||
description: Found alert
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Alert'
|
||||
example:
|
||||
id: "someHardcodedAlert"
|
||||
name: "Percentage of Delivery Failures"
|
||||
threshold: "90"
|
||||
type: "PERCENTAGE_OF_DELIVERY_FAILURES"
|
||||
frequency: "15m"
|
||||
enabled: true
|
||||
last_triggered: "2021-04-22T16:33:21.959Z"
|
||||
notification_sent: "2021-04-22T16:33:21.959Z"
|
||||
is_triggered: true
|
||||
reference_time_period: "1 Week"
|
||||
created: "2021-04-22T16:33:21.959Z"
|
||||
updated: "2021-04-22T16:33:21.959Z"
|
||||
updated_by: "someOtherUser"
|
||||
403:
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFoundAlert'
|
||||
security:
|
||||
- alerting_auth:
|
||||
- write:alerts
|
||||
- read:alerts
|
||||
|
||||
patch:
|
||||
tags:
|
||||
- Alerts
|
||||
description: >
|
||||
Update the attributes of an existing alert. Note that if a user attempts to update the type of an alert, the value will be ignored.
|
||||
summary: Update the attributes of an existing alert
|
||||
operationId: updateAlert
|
||||
parameters:
|
||||
- name: account_id
|
||||
in: path
|
||||
description: >
|
||||
ID of the account that the alert belongs to. This cannot be updated and will be ignored if placed in the payload
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1234567
|
||||
- name: alert_id
|
||||
in: path
|
||||
description: External ID used by users to refer to an alert. This cannot be updated and will be ignored if placed in the payload
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "testAlert1"
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: A new name for the specified alert
|
||||
threshold:
|
||||
type: string
|
||||
description: A new threshold for the alert
|
||||
frequency:
|
||||
type: string
|
||||
description: The frequency of how often the alerting condition is checked
|
||||
enabled:
|
||||
type: boolean
|
||||
description: Boolean value denoting whether the alert is enabled or not
|
||||
reference_time_period:
|
||||
type: string
|
||||
description: Time period to run the alerting condition against (lags in time series data)
|
||||
example:
|
||||
name: "Too Many Messages Are Being Sent"
|
||||
threshold: "955"
|
||||
frequency: "15m"
|
||||
enabled: true
|
||||
reference_time_period: "1 Month"
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Alert'
|
||||
example:
|
||||
id: "testAlert1"
|
||||
name: "Too Many Messages Are Being Sent"
|
||||
threshold: "955"
|
||||
type: "FAILURE_THRESHOLD_ALERT"
|
||||
frequency: "15m"
|
||||
enabled: true
|
||||
last_triggered: "2021-04-22T16:33:21.959Z"
|
||||
notification_sent: "2021-04-22T16:33:21.959Z"
|
||||
is_triggered: false
|
||||
reference_time_period: "1 Month"
|
||||
created: "2021-04-22T16:33:21.959Z"
|
||||
updated: "2021-05-19T12:45:09.127Z"
|
||||
updated_by: "someUser"
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFoundAlert'
|
||||
422:
|
||||
description: >
|
||||
* Invalid update request
|
||||
|
||||
* User was attempting to update alert type
|
||||
|
||||
* User attempted to update name value to an empty value
|
||||
|
||||
* User attempted to update threshold value to empty value
|
||||
security:
|
||||
- alerting_auth:
|
||||
- write:alerts
|
||||
- read:alerts
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- Alerts
|
||||
description: >
|
||||
Remove the specified alert from the account. When an alert is deleted, all recipients belonging to the alert are also removed.
|
||||
summary: Remove the specified alert from the account
|
||||
operationId: deleteAlert
|
||||
parameters:
|
||||
- name: account_id
|
||||
in: path
|
||||
description: ID of the account that the alert exists on.
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1234567
|
||||
- name: alert_id
|
||||
in: path
|
||||
description: External ID used by users to refer to an alert.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "testAlert1"
|
||||
responses:
|
||||
204:
|
||||
description: Successfully deleted alert
|
||||
403:
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFoundAlert'
|
||||
security:
|
||||
- alerting_auth:
|
||||
- write:alert
|
||||
- read:alert
|
||||
|
||||
/accounts/{account_id}/recipients:
|
||||
get:
|
||||
tags:
|
||||
- Recipients
|
||||
description: Get the list of all recipients on the specified account
|
||||
summary: Get the list of all recipients on the specified account
|
||||
operationId: getAllRecipients
|
||||
parameters:
|
||||
- name: account_id
|
||||
in: path
|
||||
description: ID of the account to get recipients from
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1234567
|
||||
responses:
|
||||
200:
|
||||
description: Successfully returned the list of recipients
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Recipient'
|
||||
example:
|
||||
- id: "someUsersEmail"
|
||||
recipient: "someUser@somedomain.com"
|
||||
type: "EMAIL"
|
||||
created: "2021-02-22T16:09:28.139Z"
|
||||
updated: "2021-04-26T04:01:13.448Z"
|
||||
updated_by: "someUser"
|
||||
- id: "someOtherUsersEmail"
|
||||
recipient: "someOtherUser@somedomain.com"
|
||||
type: "EMAIL"
|
||||
created: "2021-03-04T07:17:33.244Z"
|
||||
updated: "2021-03-04T08:00:54.562Z"
|
||||
updated_by: "someOtherUser"
|
||||
- id: "someUserHttpRecipient"
|
||||
recipient: "https://some.test.callback.com/callback"
|
||||
type: "HTTP"
|
||||
username: "mikeRoweSoft"
|
||||
password: "iSuPpOrTwInDoWs"
|
||||
created: "2021-05-19T02:39:12.922Z"
|
||||
updated: "2021-05-19T02:39:12.922Z"
|
||||
updated_by: "someUser"
|
||||
403:
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
security:
|
||||
- alerting_auth:
|
||||
- write:alerts
|
||||
- read:alerts
|
||||
|
||||
/accounts/{account_id}/alerts/{alert_id}/recipients:
|
||||
get:
|
||||
tags:
|
||||
- Recipients
|
||||
description: Get the list of recipients for an alert
|
||||
summary: Get the list of recipients for an alert
|
||||
operationId: getRecipientList
|
||||
parameters:
|
||||
- name: account_id
|
||||
in: path
|
||||
description: ID of the account to get recipients from
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1234567
|
||||
- name: alert_id
|
||||
in: path
|
||||
description: The alert that the recipients belong to
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "percentageOfDeliveryFailures"
|
||||
responses:
|
||||
200:
|
||||
description: Successfully returned list of recipients
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Recipient'
|
||||
example:
|
||||
- id: "someUsersEmail"
|
||||
recipient: "someUser@somedomain.com"
|
||||
type: "EMAIL"
|
||||
created: "2021-02-22T16:09:28.139Z"
|
||||
updated: "2021-04-26T04:01:13.448Z"
|
||||
updated_by: "someUser"
|
||||
- id: "someOtherUsersEmail"
|
||||
recipient: "someOtherUser@somedomain.com"
|
||||
type: "EMAIL"
|
||||
created: "2021-03-04T07:17:33.244Z"
|
||||
updated: "2021-03-04T08:00:54.562Z"
|
||||
updated_by: "someOtherUser"
|
||||
403:
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFoundAlert'
|
||||
security:
|
||||
- alerting_auth:
|
||||
- write:alerts
|
||||
- read:alerts
|
||||
|
||||
post:
|
||||
tags:
|
||||
- Recipients
|
||||
description: Add one or more recipients to an alert. Note that no more than 25 recipients can be added to an alert.
|
||||
summary: Add one or more recipients to an alert
|
||||
operationId: addRecipient
|
||||
parameters:
|
||||
- name: account_id
|
||||
in: path
|
||||
description: ID of the account that the recipient exists on.
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1234567
|
||||
- name: alert_id
|
||||
in: path
|
||||
description: The alert that the recipient(s) will belong to
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "percentageOfDeliveryFailures"
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: >
|
||||
External ID used by users to refer to a recipient.
|
||||
This must be unique among all recipient IDs given for the specified account. If this field is not provided, an ID is generated.
|
||||
recipient:
|
||||
type: string
|
||||
description: >
|
||||
Identifier that indicates who is receiving the notification.
|
||||
|
||||
* When the type is SMS, the recipient value must conform to the E.164 format recommendation
|
||||
|
||||
* When the type is EMAIL, the recipient value must conform to RFC-5322
|
||||
|
||||
* When the type is HTTP, as of RFC 3986, URIs should no longer support credentials.
|
||||
As a result, all URIs must conform to “http[s]://host[:port]/path?querystring” format.
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- EMAIL
|
||||
- SMS
|
||||
- HTTP
|
||||
description: The type of the recipient.
|
||||
username:
|
||||
type: string
|
||||
description: >
|
||||
Username for recipient HTTP webhook authentication. Only applicable to HTTP recipient types.
|
||||
password:
|
||||
type: string
|
||||
description: >
|
||||
Password for recipient HTTP webhook authentication. Only applicable to HTTP recipient types.
|
||||
required:
|
||||
- recipient
|
||||
- type
|
||||
example:
|
||||
- id: "someUserHttpRecipient"
|
||||
recipient: "https://some.test.callback.com/callback"
|
||||
type: "HTTP"
|
||||
username: "mikeRoweSoft"
|
||||
password: "iSuPpOrTwInDoWs"
|
||||
- id: "someUsersEmail"
|
||||
recipient: "someUser@somedomain.com"
|
||||
type: "EMAIL"
|
||||
responses:
|
||||
201:
|
||||
description: Successfully created new recipient(s)
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Recipient'
|
||||
example:
|
||||
- id: "someUserHttpRecipient"
|
||||
recipient: "https://some.test.callback.com/callback"
|
||||
type: "HTTP"
|
||||
username: "mikeRoweSoft"
|
||||
password: "iSuPpOrTwInDoWs"
|
||||
created: "2021-05-19T02:39:12.922Z"
|
||||
updated: "2021-05-19T02:39:12.922Z"
|
||||
updated_by: "someUser"
|
||||
- id: "someUsersEmail"
|
||||
recipient: "someUser@somedomain.com"
|
||||
type: "EMAIL"
|
||||
created: "2021-02-22T16:09:28.139Z"
|
||||
updated: "2021-02-22T16:09:28.139Z"
|
||||
updated_by: "someUser"
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFoundAlert'
|
||||
409:
|
||||
description: A recipient with the specified ID already exists on the given account
|
||||
422:
|
||||
description: >
|
||||
* Invalid recipient request
|
||||
|
||||
* User provided an unsupported type for one or more of the recipients
|
||||
|
||||
* User attempted to add more than 25 recipients to the alert
|
||||
|
||||
* Alert already has the maximum number of recipients
|
||||
security:
|
||||
- alerting_auth:
|
||||
- write:alerts
|
||||
- read:alerts
|
||||
|
||||
/accounts/{account_id}/alerts/{alert_id}/recipients/{recipient_id}:
|
||||
get:
|
||||
tags:
|
||||
- Recipients
|
||||
description: Get a recipient given the account ID, alert ID, and recipient ID.
|
||||
summary: Get a recipient given the account ID, alert ID, and recipient ID
|
||||
operationId: getRecipient
|
||||
parameters:
|
||||
- name: account_id
|
||||
in: path
|
||||
description: ID of the account to get recipients from
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1234567
|
||||
- name: alert_id
|
||||
in: path
|
||||
description: The alert that the recipient belongs to
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "someHardCodedAlert"
|
||||
- name: recipient_id
|
||||
in: path
|
||||
description: External ID used by users to refer to a recipient
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "someUsersEmail"
|
||||
responses:
|
||||
200:
|
||||
description: Found Recipient
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Recipient'
|
||||
example:
|
||||
id: "someUsersEmail"
|
||||
recipient: "someUser@somedomain.com"
|
||||
type: "EMAIL"
|
||||
created: "2021-02-22T16:09:28.139Z"
|
||||
updated: "2021-04-26T04:01:13.448Z"
|
||||
updated_by: "someUser"
|
||||
403:
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
404:
|
||||
description: >
|
||||
* Recipient ID is unknown
|
||||
|
||||
* Alert ID is unknown
|
||||
security:
|
||||
- alerting_auth:
|
||||
- write:alerts
|
||||
- read:alerts
|
||||
|
||||
patch:
|
||||
tags:
|
||||
- Recipients
|
||||
description: Update the attributes of a recipient.
|
||||
summary: Update the attributes of a recipient
|
||||
operationId: updateRecipient
|
||||
parameters:
|
||||
- name: account_id
|
||||
in: path
|
||||
description: ID of the account that the recipient exists on.
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1234567
|
||||
- name: alert_id
|
||||
in: path
|
||||
description: The alert that the recipient belongs to
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "someHardCodedAlert"
|
||||
- name: recipient_id
|
||||
in: path
|
||||
description: External ID used by users to refer to a recipient
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "someUserHttpRecipient"
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
recipient:
|
||||
type: string
|
||||
description: >
|
||||
Identifier that indicates who is receiving the notification.
|
||||
|
||||
* When the type is SMS, the recipient value must conform to the E.164 format recommendation
|
||||
|
||||
* When the type is EMAIL, the recipient value must conform to RFC-5322
|
||||
|
||||
* When the type is HTTP, as of RFC 3986, URIs should no longer support credentials.
|
||||
As a result, all URIs must conform to “http[s]://host[:port]/path?querystring” format.
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- EMAIL
|
||||
- SMS
|
||||
- HTTP
|
||||
description: The type of the recipient
|
||||
username:
|
||||
type: string
|
||||
description: >
|
||||
Username for recipient HTTP webhook authentication. Only applicable to HTTP recipient types.
|
||||
password:
|
||||
type: string
|
||||
description: >
|
||||
Password for recipient HTTP webhook authentication. Only applicable to HTTP recipient types.
|
||||
example:
|
||||
password: "AppleHQLooksLikeAHalo.Suspicious!"
|
||||
responses:
|
||||
200:
|
||||
description: Successfully updated recipient
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Recipient'
|
||||
example:
|
||||
id: "someUserHttpRecipient"
|
||||
recipient: "https://some.test.callback.com/callback"
|
||||
type: "HTTP"
|
||||
username: "mikeRoweSoft"
|
||||
password: "AppleHQLooksLikeAHalo.Suspicious!"
|
||||
created: "2021-05-19T02:39:12.922Z"
|
||||
updated: "2021-05-19T03:13:59.164Z"
|
||||
updated_by: "someUser"
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
404:
|
||||
description: >
|
||||
* Recipient ID is unknown
|
||||
|
||||
* Alert ID is unknown
|
||||
422:
|
||||
description: >
|
||||
* Invalid update recipient request
|
||||
|
||||
* Invalid type provided
|
||||
|
||||
* Invalid or unsupported recipient URI given
|
||||
security:
|
||||
- alerting_auth:
|
||||
- write:alerts
|
||||
- read:alerts
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- Recipients
|
||||
description: Delete a recipient.
|
||||
summary: Delete a recipient
|
||||
operationId: deleteRecipient
|
||||
parameters:
|
||||
- name: account_id
|
||||
in: path
|
||||
description: ID of the account that the recipient exists on
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1234567
|
||||
- name: alert_id
|
||||
in: path
|
||||
description: The alert that the recipient(s) belong to
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "someHardCodedAlert"
|
||||
- name: recipient_id
|
||||
in: path
|
||||
description: >
|
||||
External ID used by users to refer to a recipient.
|
||||
Multiple recipients can be deleted by specify a comma-separated list of recipient ID's.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "someUserHttpRecipient,someUsersEmail"
|
||||
responses:
|
||||
204:
|
||||
description: Successfully removed recipient(s)
|
||||
403:
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
404:
|
||||
description: >
|
||||
* One or more recipient IDs are unknown
|
||||
|
||||
* Alert ID is unknown
|
||||
security:
|
||||
- alerting_auth:
|
||||
- write:alerts
|
||||
- read:alerts
|
||||
|
||||
components:
|
||||
responses:
|
||||
Forbidden:
|
||||
description: >
|
||||
* Unknown Account
|
||||
|
||||
* User is not allowed to represent the given account
|
||||
|
||||
BadRequest:
|
||||
description: Request is invalid
|
||||
|
||||
NotFoundAlert:
|
||||
description: Alert ID is unknown
|
||||
|
||||
schemas:
|
||||
Alert:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Hardcoded or account-unique identifier for the alert
|
||||
name:
|
||||
type: string
|
||||
description: The name of this alert
|
||||
threshold:
|
||||
type: string
|
||||
description: The threshold value associated with this alert
|
||||
type:
|
||||
type: string
|
||||
description: The type of alert. The type will be an enum value matching one of the hard coded alerts.
|
||||
enum:
|
||||
- PERCENTAGE_OF_DELIVERY_FAILURES
|
||||
- FAILURE_THRESHOLD_ALERT
|
||||
- HARD_CODED_ALERT_1
|
||||
- HARD_CODED_ALERT_2
|
||||
frequency:
|
||||
type: string
|
||||
description: The frequency of how often the alerting condition is checked
|
||||
enabled:
|
||||
type: boolean
|
||||
description: Boolean value denoting whether the alert is enabled or not
|
||||
last_triggered:
|
||||
type: string
|
||||
description: >
|
||||
Timestamp of when the alert was last triggered, conforming to RFC 3339 format. The time zone is always UTC
|
||||
notification_sent:
|
||||
type: string
|
||||
description: >
|
||||
Timestamp of when the last notification was sent, conforming to RFC 3339 format. The time zone is always UTC
|
||||
is_triggered:
|
||||
type: boolean
|
||||
description: Boolean value denoting whether the alert is still currently being triggered
|
||||
reference_time_period:
|
||||
type: string
|
||||
description: Time period to run the alerting condition against (lags in time series data)
|
||||
created:
|
||||
type: string
|
||||
description: >
|
||||
Timestamp of when the alert was created, conforming to RFC 3339 format.
|
||||
The time zone is always UTC. For the create operation, the updated time will be the same as the created time.
|
||||
updated:
|
||||
type: string
|
||||
description: >
|
||||
Timestamp of when the alert was last updated, conforming to RFC 3339 format. The time zone is always UTC
|
||||
updated_by:
|
||||
type: string
|
||||
description: The last user to update the alert
|
||||
recipients:
|
||||
type: array
|
||||
description: >
|
||||
The list of full recipient objects is only returned when the include_recipients parameter is set to true
|
||||
items:
|
||||
$ref: '#/components/schemas/Recipient'
|
||||
|
||||
Recipient:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Account-unique identifier for the recipient
|
||||
recipient:
|
||||
type: string
|
||||
description: Identifier that indicates who is receiving the notification
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- EMAIL
|
||||
- SMS
|
||||
- HTTP
|
||||
description: Type of recipient.
|
||||
username:
|
||||
type: string
|
||||
description: >
|
||||
Username for recipient HTTP webhook authentication. Only applicable to HTTP recipient types.
|
||||
password:
|
||||
type: string
|
||||
description: >
|
||||
Password for recipient HTTP webhook authentication. Only applicable to HTTP recipient types.
|
||||
created:
|
||||
type: string
|
||||
description: >
|
||||
Timestamp of when the recipient was created, conforming to RFC 3339 format. The time zone is always UTC.
|
||||
updated:
|
||||
type: string
|
||||
description: >
|
||||
Timestamp of when the recipient was last updated, conforming to RFC 3339 format. The time zone is always UTC.
|
||||
For the create operation, the updated time will be the same as the created time.
|
||||
updated_by:
|
||||
type: string
|
||||
description: The last user to update the recipient.
|
||||
|
||||
securitySchemes:
|
||||
alerting_auth:
|
||||
type: oauth2
|
||||
flows:
|
||||
authorizationCode:
|
||||
authorizationUrl: https://login.alexjclarke.com/oauth/authorize
|
||||
tokenUrl: https://login.alexjclarke.com/oauth/token
|
||||
scopes:
|
||||
read:alerts: read your alerts
|
||||
write:alerts: modify alerts in your account
|
||||
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 665 B |
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 628 B |
Vendored
+75
@@ -0,0 +1,75 @@
|
||||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Swagger UI: OAuth2 Redirect</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1);
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&");
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value);
|
||||
}
|
||||
) : {};
|
||||
|
||||
isValid = qp.state === sentState;
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorization_code"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg;
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
run();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(function(){try{return require("esprima")}catch(e){}}()):"function"==typeof define&&define.amd?define(["esprima"],t):"object"==typeof exports?exports.SwaggerUIBundle=t(function(){try{return require("esprima")}catch(e){}}()):e.SwaggerUIBundle=t(e.esprima)}(this,(function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist",n(n.s=555)}([function(e,t,n){"use strict";e.exports=n(131)},function(e,t,n){e.exports=function(){"use strict";var e=Array.prototype.slice;function t(e,t){t&&(e.prototype=Object.create(t.prototype)),e.prototype.constructor=e}function n(e){return i(e)?e:J(e)}function r(e){return s(e)?e:K(e)}function o(e){return u(e)?e:Y(e)}function a(e){return i(e)&&!c(e)?e:G(e)}function i(e){return!(!e||!e[p])}function s(e){return!(!e||!e[f])}function u(e){return!(!e||!e[h])}function c(e){return s(e)||u(e)}function l(e){return!(!e||!e[d])}t(r,n),t(o,n),t(a,n),n.isIterable=i,n.isKeyed=s,n.isIndexed=u,n.isAssociative=c,n.isOrdered=l,n.Keyed=r,n.Indexed=o,n.Set=a;var p="@@__IMMUTABLE_ITERABLE__@@",f="@@__IMMUTABLE_KEYED__@@",h="@@__IMMUTABLE_INDEXED__@@",d="@@__IMMUTABLE_ORDERED__@@",m="delete",v=5,g=1<<v,y=g-1,b={},_={value:!1},x={value:!1};function w(e){return e.value=!1,e}function E(e){e&&(e.value=!0)}function S(){}function C(e,t){t=t||0;for(var n=Math.max(0,e.length-t),r=new Array(n),o=0;o<n;o++)r[o]=e[o+t];return r}function A(e){return void 0===e.size&&(e.size=e.__iterate(k)),e.size}function O(e,t){if("number"!=typeof t){var n=t>>>0;if(""+n!==t||4294967295===n)return NaN;t=n}return t<0?A(e)+t:t}function k(){return!0}function j(e,t,n){return(0===e||void 0!==n&&e<=-n)&&(void 0===t||void 0!==n&&t>=n)}function T(e,t){return P(e,t,0)}function I(e,t){return P(e,t,t)}function P(e,t,n){return void 0===e?n:e<0?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}var N=0,M=1,R=2,D="function"==typeof Symbol&&Symbol.iterator,L="@@iterator",B=D||L;function F(e){this.next=e}function U(e,t,n,r){var o=0===e?t:1===e?n:[t,n];return r?r.value=o:r={value:o,done:!1},r}function q(){return{value:void 0,done:!0}}function z(e){return!!H(e)}function V(e){return e&&"function"==typeof e.next}function W(e){var t=H(e);return t&&t.call(e)}function H(e){var t=e&&(D&&e[D]||e[L]);if("function"==typeof t)return t}function $(e){return e&&"number"==typeof e.length}function J(e){return null==e?ie():i(e)?e.toSeq():ce(e)}function K(e){return null==e?ie().toKeyedSeq():i(e)?s(e)?e.toSeq():e.fromEntrySeq():se(e)}function Y(e){return null==e?ie():i(e)?s(e)?e.entrySeq():e.toIndexedSeq():ue(e)}function G(e){return(null==e?ie():i(e)?s(e)?e.entrySeq():e:ue(e)).toSetSeq()}F.prototype.toString=function(){return"[Iterator]"},F.KEYS=N,F.VALUES=M,F.ENTRIES=R,F.prototype.inspect=F.prototype.toSource=function(){return this.toString()},F.prototype[B]=function(){return this},t(J,n),J.of=function(){return J(arguments)},J.prototype.toSeq=function(){return this},J.prototype.toString=function(){return this.__toString("Seq {","}")},J.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},J.prototype.__iterate=function(e,t){return pe(this,e,t,!0)},J.prototype.__iterator=function(e,t){return fe(this,e,t,!0)},t(K,J),K.prototype.toKeyedSeq=function(){return this},t(Y,J),Y.of=function(){return Y(arguments)},Y.prototype.toIndexedSeq=function(){return this},Y.prototype.toString=function(){return this.__toString("Seq [","]")},Y.prototype.__iterate=function(e,t){return pe(this,e,t,!1)},Y.prototype.__iterator=function(e,t){return fe(this,e,t,!1)},t(G,J),G.of=function(){return G(arguments)},G.prototype.toSetSeq=function(){return this},J.isSeq=ae,J.Keyed=K,J.Set=G,J.Indexed=Y;var Z,X,Q,ee="@@__IMMUTABLE_SEQ__@@";function te(e){this._array=e,this.size=e.length}function ne(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function re(e){this._iterable=e,this.size=e.length||e.size}function oe(e){this._iterator=e,this._iteratorCache=[]}function ae(e){return!(!e||!e[ee])}function ie(){return Z||(Z=new te([]))}function se(e){var t=Array.isArray(Line truncated
|
||||
//# sourceMappingURL=swagger-ui-bundle.js.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["webpack://SwaggerUIBundle/webpack/universalModuleDefinition","webpack://SwaggerUIBundle/webpack/bootstrap","webpack://SwaggerUIBundle/./node_modules/react/react.js","webpack://SwaggerUIBundle/./node_modules/immutable/dist/immutable.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/concat.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/defineProperty.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/map.js","webpack://SwaggerUIBundle/./src/core/utils.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/classCallCheck.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/createClass.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/inherits.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/createSuper.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/assertThisInitialized.js","webpack://SwaggerUIBundle/./node_modules/prop-types/index.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/filter.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/slicedToArray.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/toConsumableArray.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/object/keys.js","webpack://SwaggerUIBundle/./node_modules/reselect/es/index.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/index-of.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/typeof.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/reduce.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/slice.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/object/assign.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/export.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/array/is-array.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/for-each.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/objectSpread2.js","webpack://SwaggerUIBundle/./node_modules/fbjs/lib/invariant.js","webpack://SwaggerUIBundle/./src/core/window.js","webpack://SwaggerUIBundle/./node_modules/react-immutable-proptypes/dist/ImmutablePropTypes.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/extends.js","webpack://SwaggerUIBundle/./node_modules/react-dom/lib/reactProdInvariant.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/includes.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/json/stringify.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/path.js","webpack://SwaggerUIBundle/./node_modules/fbjs/lib/warning.js","webpack://SwaggerUIBundle/./src/core/plugins/oas3/helpers.jsx","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/bind.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/fails.js","webpack://SwaggerUIBundle/./node_modules/object-assign/index.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/regenerator/index.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/global.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/well-known-symbol.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/entry-virtual.js","webpack://SwaggerUIBundle/./node_modules/lodash/get.js","webpack://SwaggerUIBundle/./node_modules/react-dom/lib/ReactDOMComponentTree.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/is-object.js","webpack://SwaggerUIBundle/./src/core/plugins/spec/actions.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/define-well-known-symbol.js","webpack://SwaggerUIBundle/./node_modules/js-yaml/lib/js-yaml/type.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/descriptors.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/createForOfIteratorHelper.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/an-object.js","webpack://SwaggerUIBundle/./node_modules/lodash/isArray.js","webpack://SwaggerUIBundle/(webpack)/buildin/global.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/has.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/objectWithoutProperties.js","webpack://SwaggerUIBundle/./src/core/plugins/oas3/actions.js","webpack://SwaggerUIBundle/./node_modules/fbjs/lib/ExecutionEnvironment.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/find.js","Line truncated
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
/*! For license information please see swagger-ui-es-bundle-core.js.LICENSE.txt */
|
||||
module.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist",n(n.s=417)}([function(e,t){e.exports=require("react")},function(e,t){e.exports=require("immutable")},function(e,t,n){e.exports=n(449)},function(e,t,n){var r=n(199);e.exports=function(e,t,n){return t in e?r(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){e.exports=n(478)},function(e,t,n){"use strict";(function(e){n.d(t,"z",(function(){return be})),n.d(t,"i",(function(){return Ee})),n.d(t,"v",(function(){return xe})),n.d(t,"r",(function(){return Se})),n.d(t,"t",(function(){return we})),n.d(t,"s",(function(){return je})),n.d(t,"p",(function(){return Oe})),n.d(t,"u",(function(){return Ce})),n.d(t,"x",(function(){return _e})),n.d(t,"y",(function(){return Ae})),n.d(t,"J",(function(){return ke})),n.d(t,"f",(function(){return Ie})),n.d(t,"n",(function(){return Pe})),n.d(t,"h",(function(){return Te})),n.d(t,"D",(function(){return Re})),n.d(t,"K",(function(){return Me})),n.d(t,"o",(function(){return Ve})),n.d(t,"C",(function(){return ze})),n.d(t,"a",(function(){return Fe})),n.d(t,"H",(function(){return Je})),n.d(t,"b",(function(){return We})),n.d(t,"G",(function(){return He})),n.d(t,"F",(function(){return $e})),n.d(t,"E",(function(){return Ye})),n.d(t,"k",(function(){return Ke})),n.d(t,"d",(function(){return Ge})),n.d(t,"g",(function(){return Ze})),n.d(t,"m",(function(){return Xe})),n.d(t,"l",(function(){return Qe})),n.d(t,"e",(function(){return et})),n.d(t,"I",(function(){return tt})),n.d(t,"w",(function(){return nt})),n.d(t,"A",(function(){return rt})),n.d(t,"B",(function(){return at})),n.d(t,"j",(function(){return ot})),n.d(t,"c",(function(){return it})),n.d(t,"q",(function(){return ct}));var r=n(14),a=n.n(r),o=(n(13),n(18)),i=n.n(o),s=n(44),c=n.n(s),u=n(23),l=n.n(u),p=n(4),f=n.n(p),d=n(70),h=n.n(d),m=n(2),v=n.n(m),g=n(24),y=n.n(g),b=n(11),E=n.n(b),x=n(15),S=n.n(x),w=(n(33),n(19)),j=n.n(w),O=n(21),C=n.n(O),_=n(165),A=n.n(_),k=n(20),I=n.n(k),P=n(64),T=n.n(P),R=(n(29),n(30)),N=n.n(R),M=n(17),q=n.n(M),D=n(50),B=n.n(D),L=n(137),U=n.n(L),V=n(85),z=n.n(V),F=n(1),J=n.n(F),W=n(383),H=n(384),$=n.n(H),Y=n(217),K=n.n(Y),G=n(218),Z=n.n(G),X=n(166),Q=n.n(X),ee=n(278),te=n.n(ee),ne=n(101),re=n.n(ne),ae=n(56),oe=n.n(ae),ie=n(113),se=n(26),ce=n(386),ue=n.n(ce),le=n(116),pe=n(387),fe=n.n(pe),de=n(388),he=n.n(de),me=n(63),ve=n.n(me),ge="default",ye=function(e){return J.a.Iterable.isIterable(e)};function be(e){return we(e)?ye(e)?e.toJS():e:{}}function Ee(e){var t,n;if(ye(e))return e;if(e instanceof se.a.File)return e;if(!we(e))return e;if(l()(e))return f()(n=J.a.Seq(e)).call(n,Ee).toList();if(oe()(h()(e))){var r,a=function(e){if(!oe()(h()(e)))return e;var t,n={},r="_**[]",a={},o=c()(h()(e).call(e));try{for(o.s();!(t=o.n()).done;){var i=t.value;if(n[i[0]]||a[i[0]]&&a[i[0]].containsMultiple){var s,u,l,p;if(!a[i[0]])a[i[0]]={containsMultiple:!0,length:1},n[v()(l=v()(p="".concat(i[0])).call(p,r)).call(l,a[i[0]].length)]=n[i[0]],delete n[i[0]];a[i[0]].length+=1,n[v()(s=v()(u="".concat(i[0])).call(u,r)).call(s,a[i[0]].length)]=i[1]}else n[i[0]]=i[1]}}catch(e){o.e(e)}finally{o.f()}return n}(e);return f()(r=J.a.OrderedMap(a)).call(r,Ee)}return f()(t=J.a.OrderedMap(e)).call(t,Ee)}function xe(e){return l()(e)?e:[e]}function Se(e){return"function"==typeof e}function we(e){return!!e&&"object"===i()(e)}function je(e){return"function"==typeof e}function Oe(e){return l()(e)}var Ce=Z.a;function _e(e,t){var n;return j()(n=S()(e)).call(n,(function(n,r){return n[r]=t(e[r],r),n}),{})}function Ae(e,t){var n;return j()(n=S()(e)).call(n,(function(n,r){var a=t(e[r],r);return a&&"object"===i()(a)&&C()(n,a),n}),{})}function ke(e){return function(t){t.dispatch,t.getState;return function(t){return function(n){return"function"==typeof n?n(e()):t(n)}}}}function Ie(e){var t,n=e.keySeq();return n.contains(ge)?ge:A()(t=E()(n).call(n,(function(e){return"2"===(e+"")[0]}))).call(t).first()}function Pe(e,t){if(!J.a.Iterable.isIterable(e))return J.a.List();var n=e.getIn(l()(t)?t:[t]);return J.a.List.isList(n)?n:J.a.List()}function Te(e){var t,n=[/filename\*=[^']+'\w*'"([^"]Line truncated
|
||||
//# sourceMappingURL=swagger-ui-es-bundle-core.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["webpack://SwaggerUIBundle/webpack/bootstrap","webpack://SwaggerUIBundle/external \"react\"","webpack://SwaggerUIBundle/external \"immutable\"","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/concat.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/defineProperty.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/map.js","webpack://SwaggerUIBundle/./src/core/utils.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/classCallCheck.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/createClass.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/inherits.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/createSuper.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/assertThisInitialized.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/filter.js","webpack://SwaggerUIBundle/external \"prop-types\"","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/slicedToArray.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/toConsumableArray.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/object/keys.js","webpack://SwaggerUIBundle/external \"reselect\"","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/index-of.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/typeof.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/reduce.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/slice.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/object/assign.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/export.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/array/is-array.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/for-each.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/objectSpread2.js","webpack://SwaggerUIBundle/./src/core/window.js","webpack://SwaggerUIBundle/external \"react-immutable-proptypes\"","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/extends.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/includes.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/json/stringify.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/path.js","webpack://SwaggerUIBundle/./src/core/plugins/oas3/helpers.jsx","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/bind.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/fails.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/regenerator/index.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/global.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/well-known-symbol.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/entry-virtual.js","webpack://SwaggerUIBundle/./node_modules/lodash/get.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/is-object.js","webpack://SwaggerUIBundle/./src/core/plugins/spec/actions.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/define-well-known-symbol.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/descriptors.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/createForOfIteratorHelper.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/an-object.js","webpack://SwaggerUIBundle/./node_modules/lodash/isArray.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/has.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/objectWithoutProperties.js","webpack://SwaggerUIBundle/./src/core/plugins/oas3/actions.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/find.js","webpack://SwaggerUIBundle/./node_modules/lodash/isObject.js","webpack://SwaggerUIBundle/./node_modules/swagger-client/es/helpers.js","webpack://SwaggerUIBundle/./src/core/plugins/err/actions.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/to-object.js","webpack://SwaggerUIBundle/external \"classnames\"","webpack://SwaggerUIBundle/./node_modules/lodash/isFunction.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/promise.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/to-indexed-object.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/create-non-enumerable-property.js","webpack://SwaggerUIBundle/./node_moLine truncated
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
/*! For license information please see swagger-ui-es-bundle.js.LICENSE.txt */
|
||||
module.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist",n(n.s=555)}([function(e,t,n){"use strict";e.exports=n(131)},function(e,t,n){e.exports=function(){"use strict";var e=Array.prototype.slice;function t(e,t){t&&(e.prototype=Object.create(t.prototype)),e.prototype.constructor=e}function n(e){return i(e)?e:J(e)}function r(e){return s(e)?e:K(e)}function o(e){return u(e)?e:Y(e)}function a(e){return i(e)&&!c(e)?e:G(e)}function i(e){return!(!e||!e[p])}function s(e){return!(!e||!e[f])}function u(e){return!(!e||!e[h])}function c(e){return s(e)||u(e)}function l(e){return!(!e||!e[d])}t(r,n),t(o,n),t(a,n),n.isIterable=i,n.isKeyed=s,n.isIndexed=u,n.isAssociative=c,n.isOrdered=l,n.Keyed=r,n.Indexed=o,n.Set=a;var p="@@__IMMUTABLE_ITERABLE__@@",f="@@__IMMUTABLE_KEYED__@@",h="@@__IMMUTABLE_INDEXED__@@",d="@@__IMMUTABLE_ORDERED__@@",m="delete",v=5,g=1<<v,y=g-1,b={},_={value:!1},x={value:!1};function w(e){return e.value=!1,e}function E(e){e&&(e.value=!0)}function S(){}function C(e,t){t=t||0;for(var n=Math.max(0,e.length-t),r=new Array(n),o=0;o<n;o++)r[o]=e[o+t];return r}function A(e){return void 0===e.size&&(e.size=e.__iterate(k)),e.size}function O(e,t){if("number"!=typeof t){var n=t>>>0;if(""+n!==t||4294967295===n)return NaN;t=n}return t<0?A(e)+t:t}function k(){return!0}function j(e,t,n){return(0===e||void 0!==n&&e<=-n)&&(void 0===t||void 0!==n&&t>=n)}function T(e,t){return P(e,t,0)}function I(e,t){return P(e,t,t)}function P(e,t,n){return void 0===e?n:e<0?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}var N=0,M=1,R=2,D="function"==typeof Symbol&&Symbol.iterator,L="@@iterator",B=D||L;function F(e){this.next=e}function U(e,t,n,r){var o=0===e?t:1===e?n:[t,n];return r?r.value=o:r={value:o,done:!1},r}function q(){return{value:void 0,done:!0}}function z(e){return!!H(e)}function V(e){return e&&"function"==typeof e.next}function W(e){var t=H(e);return t&&t.call(e)}function H(e){var t=e&&(D&&e[D]||e[L]);if("function"==typeof t)return t}function $(e){return e&&"number"==typeof e.length}function J(e){return null==e?ie():i(e)?e.toSeq():ce(e)}function K(e){return null==e?ie().toKeyedSeq():i(e)?s(e)?e.toSeq():e.fromEntrySeq():se(e)}function Y(e){return null==e?ie():i(e)?s(e)?e.entrySeq():e.toIndexedSeq():ue(e)}function G(e){return(null==e?ie():i(e)?s(e)?e.entrySeq():e:ue(e)).toSetSeq()}F.prototype.toString=function(){return"[Iterator]"},F.KEYS=N,F.VALUES=M,F.ENTRIES=R,F.prototype.inspect=F.prototype.toSource=function(){return this.toString()},F.prototype[B]=function(){return this},t(J,n),J.of=function(){return J(arguments)},J.prototype.toSeq=function(){return this},J.prototype.toString=function(){return this.__toString("Seq {","}")},J.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},J.prototype.__iterate=function(e,t){return pe(this,e,t,!0)},J.prototype.__iterator=function(e,t){return fe(this,e,t,!0)},t(K,J),K.prototype.toKeyedSeq=function(){return this},t(Y,J),Y.of=function(){return Y(arguments)},Y.prototype.toIndexedSeq=function(){return this},Y.prototype.toString=function(){return this.__toString("Seq [","]")},Y.prototype.__iterate=function(e,t){return pe(this,e,t,!1)},Y.prototype.__iterator=function(e,t){return fe(this,e,t,!1)},t(G,J),G.of=function(){return G(arguments)},G.prototype.toSetSeq=function(){return this},J.isSeq=ae,J.Keyed=K,J.Set=G,J.Indexed=Y;var Z,X,Q,ee="@@__IMMUTABLE_SEQ__@@";function te(e){this._array=e,this.size=e.length}function ne(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function re(e){this._iterable=e,this.size=e.length||e.size}function oe(e){this._iterator=e,this._iteratorCache=[]}function ae(e){return!(!e||!e[ee])}function ie(){return Z||(Z=new te([]))}function se(e){var t=Array.isArray(e)?new te(e).fromEntrySeq():V(e)?new oe(e).fromEntrySeq():z(e)?new re(e).fromEntrySeq():"object"==typeof e?new ne(e):void 0;if(!t)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+e);return t}function ue(e){var t=le(e);if(!t)throw new TypeError("Expected Array or iterable object of values: "+e);return tLine truncated
|
||||
//# sourceMappingURL=swagger-ui-es-bundle.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["webpack://SwaggerUIBundle/webpack/bootstrap","webpack://SwaggerUIBundle/./node_modules/react/react.js","webpack://SwaggerUIBundle/./node_modules/immutable/dist/immutable.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/concat.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/defineProperty.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/map.js","webpack://SwaggerUIBundle/./src/core/utils.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/classCallCheck.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/createClass.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/inherits.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/createSuper.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/assertThisInitialized.js","webpack://SwaggerUIBundle/./node_modules/prop-types/index.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/filter.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/slicedToArray.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/toConsumableArray.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/object/keys.js","webpack://SwaggerUIBundle/./node_modules/reselect/es/index.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/index-of.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/typeof.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/reduce.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/slice.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/object/assign.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/export.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/array/is-array.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/for-each.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/objectSpread2.js","webpack://SwaggerUIBundle/./node_modules/fbjs/lib/invariant.js","webpack://SwaggerUIBundle/./src/core/window.js","webpack://SwaggerUIBundle/./node_modules/react-immutable-proptypes/dist/ImmutablePropTypes.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/extends.js","webpack://SwaggerUIBundle/./node_modules/react-dom/lib/reactProdInvariant.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/includes.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/json/stringify.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/path.js","webpack://SwaggerUIBundle/./node_modules/fbjs/lib/warning.js","webpack://SwaggerUIBundle/./src/core/plugins/oas3/helpers.jsx","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/bind.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/fails.js","webpack://SwaggerUIBundle/./node_modules/object-assign/index.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/regenerator/index.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/global.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/well-known-symbol.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/entry-virtual.js","webpack://SwaggerUIBundle/./node_modules/lodash/get.js","webpack://SwaggerUIBundle/./node_modules/react-dom/lib/ReactDOMComponentTree.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/is-object.js","webpack://SwaggerUIBundle/./src/core/plugins/spec/actions.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/define-well-known-symbol.js","webpack://SwaggerUIBundle/./node_modules/js-yaml/lib/js-yaml/type.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/descriptors.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/createForOfIteratorHelper.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/an-object.js","webpack://SwaggerUIBundle/./node_modules/lodash/isArray.js","webpack://SwaggerUIBundle/(webpack)/buildin/global.js","webpack://SwaggerUIBundle/./node_modules/core-js-pure/internals/has.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/helpers/objectWithoutProperties.js","webpack://SwaggerUIBundle/./src/core/plugins/oas3/actions.js","webpack://SwaggerUIBundle/./node_modules/fbjs/lib/ExecutionEnvironment.js","webpack://SwaggerUIBundle/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/find.js","webpack://SwaggerUIBundle/./node_modules/lodash/isObject.js","Line truncated
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
/*! For license information please see swagger-ui-standalone-preset.js.LICENSE.txt */
|
||||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(function(){try{return require("esprima")}catch(t){}}()):"function"==typeof define&&define.amd?define(["esprima"],e):"object"==typeof exports?exports.SwaggerUIStandalonePreset=e(function(){try{return require("esprima")}catch(t){}}()):t.SwaggerUIStandalonePreset=e(t.esprima)}(this,(function(t){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/dist",n(n.s=242)}([function(t,e,n){t.exports=function(){"use strict";var t=Array.prototype.slice;function e(t,e){e&&(t.prototype=Object.create(e.prototype)),t.prototype.constructor=t}function n(t){return u(t)?t:J(t)}function r(t){return s(t)?t:Z(t)}function i(t){return a(t)?t:V(t)}function o(t){return u(t)&&!c(t)?t:X(t)}function u(t){return!(!t||!t[l])}function s(t){return!(!t||!t[p])}function a(t){return!(!t||!t[h])}function c(t){return s(t)||a(t)}function f(t){return!(!t||!t[d])}e(r,n),e(i,n),e(o,n),n.isIterable=u,n.isKeyed=s,n.isIndexed=a,n.isAssociative=c,n.isOrdered=f,n.Keyed=r,n.Indexed=i,n.Set=o;var l="@@__IMMUTABLE_ITERABLE__@@",p="@@__IMMUTABLE_KEYED__@@",h="@@__IMMUTABLE_INDEXED__@@",d="@@__IMMUTABLE_ORDERED__@@",y="delete",v=5,g=1<<v,w=g-1,M={},m={value:!1},_={value:!1};function L(t){return t.value=!1,t}function x(t){t&&(t.value=!0)}function b(){}function j(t,e){e=e||0;for(var n=Math.max(0,t.length-e),r=new Array(n),i=0;i<n;i++)r[i]=t[i+e];return r}function N(t){return void 0===t.size&&(t.size=t.__iterate(D)),t.size}function S(t,e){if("number"!=typeof e){var n=e>>>0;if(""+n!==e||4294967295===n)return NaN;e=n}return e<0?N(t)+e:e}function D(){return!0}function I(t,e,n){return(0===t||void 0!==n&&t<=-n)&&(void 0===e||void 0!==n&&e>=n)}function A(t,e){return E(t,e,0)}function O(t,e){return E(t,e,e)}function E(t,e,n){return void 0===t?n:t<0?Math.max(0,e+t):void 0===e?t:Math.min(e,t)}var C=0,T=1,z=2,k="function"==typeof Symbol&&Symbol.iterator,U="@@iterator",Y=k||U;function P(t){this.next=t}function R(t,e,n,r){var i=0===t?e:1===t?n:[e,n];return r?r.value=i:r={value:i,done:!1},r}function Q(){return{value:void 0,done:!0}}function F(t){return!!W(t)}function B(t){return t&&"function"==typeof t.next}function G(t){var e=W(t);return e&&e.call(t)}function W(t){var e=t&&(k&&t[k]||t[U]);if("function"==typeof e)return e}function q(t){return t&&"number"==typeof t.length}function J(t){return null==t?ut():u(t)?t.toSeq():ct(t)}function Z(t){return null==t?ut().toKeyedSeq():u(t)?s(t)?t.toSeq():t.fromEntrySeq():st(t)}function V(t){return null==t?ut():u(t)?s(t)?t.entrySeq():t.toIndexedSeq():at(t)}function X(t){return(null==t?ut():u(t)?s(t)?t.entrySeq():t:at(t)).toSetSeq()}P.prototype.toString=function(){return"[Iterator]"},P.KEYS=C,P.VALUES=T,P.ENTRIES=z,P.prototype.inspect=P.prototype.toSource=function(){return this.toString()},P.prototype[Y]=function(){return this},e(J,n),J.of=function(){return J(arguments)},J.prototype.toSeq=function(){return this},J.prototype.toString=function(){return this.__toString("Seq {","}")},J.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},J.prototype.__iterate=function(t,e){return lt(this,t,e,!0)},J.prototype.__iterator=function(t,e){return pt(this,t,e,!0)},e(Z,J),Z.prototype.toKeyedSeq=function(){return this},e(V,J),V.of=function(){return V(arguments)},V.prototype.toIndexedSeq=function(){return this},V.prototype.toString=function(){return this.__toString("Seq [","]")},V.prototype.__iterate=function(t,e){return lt(this,t,e,!1)},V.prototype.__iterator=function(t,e){return pt(this,t,e,!1)},e(X,J),X.of=function(){return X(arguments)},X.prototype.toSetSeq=function(){return this},J.isSeq=ot,J.Keyed=Z,J.Set=X,J.Indexed=V;var H,K,$,tt="@@__IMMUTABLE_SEQ__@@";function et(t){this._array=t,this.size=t.length}function nt(t){var e=Object.keys(t);this._object=t,this._keys=e,this.size=e.length}function rt(t){this._iterable=t,this.size=t.length||t.size}function it(t){this._iterator=t,this._iteratorCache=[]}function ot(t){return!(!t||!t[tt])}function ut(){return H||(H=new et([]))}function st(t){var e=Array.isArray(t)?new et(t).fromEntrySeq()Line truncated
|
||||
//# sourceMappingURL=swagger-ui-standalone-preset.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["webpack://SwaggerUIStandalonePreset/webpack/universalModuleDefinition","webpack://SwaggerUIStandalonePreset/webpack/bootstrap","webpack://SwaggerUIStandalonePreset/./node_modules/immutable/dist/immutable.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/export.js","webpack://SwaggerUIStandalonePreset/./node_modules/react/react.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/concat.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/core-js-stable/array/is-array.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/define-well-known-symbol.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/fails.js","webpack://SwaggerUIStandalonePreset/./node_modules/js-yaml/lib/js-yaml/type.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/well-known-symbol.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/entry-virtual.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/for-each.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/path.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/map.js","webpack://SwaggerUIStandalonePreset/./src/core/utils.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/global.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/helpers/defineProperty.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/is-object.js","webpack://SwaggerUIStandalonePreset/./node_modules/inherits/inherits_browser.js","webpack://SwaggerUIStandalonePreset/./node_modules/safe-buffer/index.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/helpers/typeof.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/to-object.js","webpack://SwaggerUIStandalonePreset/(webpack)/buildin/global.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/has.js","webpack://SwaggerUIStandalonePreset/./node_modules/lodash/isArray.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/descriptors.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/create-non-enumerable-property.js","webpack://SwaggerUIStandalonePreset/./node_modules/lodash/_root.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/helpers/assertThisInitialized.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/filter.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/core-js-stable/object/keys.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/an-object.js","webpack://SwaggerUIStandalonePreset/./node_modules/es5-ext/object/valid-callable.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/to-indexed-object.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/object-define-property.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/to-length.js","webpack://SwaggerUIStandalonePreset/./node_modules/process/browser.js","webpack://SwaggerUIStandalonePreset/./node_modules/readable-stream/lib/_stream_duplex.js","webpack://SwaggerUIStandalonePreset/./node_modules/es5-ext/object/is-value.js","webpack://SwaggerUIStandalonePreset/./node_modules/es5-ext/number/to-pos-integer.js","webpack://SwaggerUIStandalonePreset/./node_modules/d/index.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/includes.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/index-of.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/require-object-coercible.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/array-iteration.js","webpack://SwaggerUIStandalonePreset/./node_modules/core-js-pure/internals/iterators.js","webpack://SwaggerUIStandalonePreset/./node_modules/react/lib/ReactElement.js","webpack://SwaggerUIStandalonePreset/./node_modules/lodash/_getNative.js","webpack://SwaggerUIStandalonePreset/./node_modules/es5-ext/object/valid-value.js","webpack://SwaggerUIStandalonePreset/./node_modules/sha.js/hash.js","webpack://SwaggerUIStandalonePreset/./node_modules/js-yaml/lib/js-yaml/common.js","webpack://SwaggerUIStandalonePreset/./node_modules/js-yaml/lib/js-yaml/schema.js","webpack://SwaggerUIStandalonePreset/./node_modules/lodash/eq.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/slice.js","webpack://SwaggerUIStandalonePreset/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/some.js","webpack://SwaggerUILine truncated
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
.swagger-ui{color:#3b4151;
|
||||
/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */font-family:sans-serif}.swagger-ui html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}.swagger-ui body{margin:0}.swagger-ui article,.swagger-ui aside,.swagger-ui footer,.swagger-ui header,.swagger-ui nav,.swagger-ui section{display:block}.swagger-ui h1{font-size:2em;margin:.67em 0}.swagger-ui figcaption,.swagger-ui figure,.swagger-ui main{display:block}.swagger-ui figure{margin:1em 40px}.swagger-ui hr{box-sizing:content-box;height:0;overflow:visible}.swagger-ui pre{font-family:monospace,monospace;font-size:1em}.swagger-ui a{background-color:transparent;-webkit-text-decoration-skip:objects}.swagger-ui abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.swagger-ui b,.swagger-ui strong{font-weight:inherit;font-weight:bolder}.swagger-ui code,.swagger-ui kbd,.swagger-ui samp{font-family:monospace,monospace;font-size:1em}.swagger-ui dfn{font-style:italic}.swagger-ui mark{background-color:#ff0;color:#000}.swagger-ui small{font-size:80%}.swagger-ui sub,.swagger-ui sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.swagger-ui sub{bottom:-.25em}.swagger-ui sup{top:-.5em}.swagger-ui audio,.swagger-ui video{display:inline-block}.swagger-ui audio:not([controls]){display:none;height:0}.swagger-ui img{border-style:none}.swagger-ui svg:not(:root){overflow:hidden}.swagger-ui button,.swagger-ui input,.swagger-ui optgroup,.swagger-ui select,.swagger-ui textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}.swagger-ui button,.swagger-ui input{overflow:visible}.swagger-ui button,.swagger-ui select{text-transform:none}.swagger-ui [type=reset],.swagger-ui [type=submit],.swagger-ui button,.swagger-ui html [type=button]{-webkit-appearance:button}.swagger-ui [type=button]::-moz-focus-inner,.swagger-ui [type=reset]::-moz-focus-inner,.swagger-ui [type=submit]::-moz-focus-inner,.swagger-ui button::-moz-focus-inner{border-style:none;padding:0}.swagger-ui [type=button]:-moz-focusring,.swagger-ui [type=reset]:-moz-focusring,.swagger-ui [type=submit]:-moz-focusring,.swagger-ui button:-moz-focusring{outline:1px dotted ButtonText}.swagger-ui fieldset{padding:.35em .75em .625em}.swagger-ui legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}.swagger-ui progress{display:inline-block;vertical-align:baseline}.swagger-ui textarea{overflow:auto}.swagger-ui [type=checkbox],.swagger-ui [type=radio]{box-sizing:border-box;padding:0}.swagger-ui [type=number]::-webkit-inner-spin-button,.swagger-ui [type=number]::-webkit-outer-spin-button{height:auto}.swagger-ui [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.swagger-ui [type=search]::-webkit-search-cancel-button,.swagger-ui [type=search]::-webkit-search-decoration{-webkit-appearance:none}.swagger-ui ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.swagger-ui details,.swagger-ui menu{display:block}.swagger-ui summary{display:list-item}.swagger-ui canvas{display:inline-block}.swagger-ui template{display:none}.swagger-ui [hidden]{display:none}.swagger-ui .debug *{outline:1px solid gold}.swagger-ui .debug-white *{outline:1px solid #fff}.swagger-ui .debug-black *{outline:1px solid #000}.swagger-ui .debug-grid{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTRDOTY4N0U2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTRDOTY4N0Q2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3NjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3NzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsBS+GMAAAAjSURBVHjaYvz//z8DLsD4gcGXiYEAGBIKGBne//fFpwAgwAB98AaF2pjlUQAAAABJRU5ErkJggg==) repeat 0 0}.swagger-ui .debug-grid-16{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1lLine truncated
|
||||
|
||||
/*# sourceMappingURL=swagger-ui.css.map*/
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["webpack:///./src/style/main.scss","webpack:///./src/style/_type.scss","webpack:///./src/style/_variables.scss","webpack:///./node_modules/tachyons-sass/scss/_normalize.scss","webpack:///./node_modules/tachyons-sass/scss/_debug-children.scss","webpack:///./node_modules/tachyons-sass/scss/_debug-grid.scss","webpack:///./node_modules/tachyons-sass/scss/_box-sizing.scss","webpack:///./node_modules/tachyons-sass/scss/_aspect-ratios.scss","webpack:///./node_modules/tachyons-sass/scss/_images.scss","webpack:///./node_modules/tachyons-sass/scss/_background-size.scss","webpack:///./node_modules/tachyons-sass/scss/_background-position.scss","webpack:///./node_modules/tachyons-sass/scss/_outlines.scss","webpack:///./node_modules/tachyons-sass/scss/_borders.scss","webpack:///./node_modules/tachyons-sass/scss/_border-colors.scss","webpack:///./node_modules/tachyons-sass/scss/_border-radius.scss","webpack:///./node_modules/tachyons-sass/scss/_border-style.scss","webpack:///./node_modules/tachyons-sass/scss/_border-widths.scss","webpack:///./node_modules/tachyons-sass/scss/_box-shadow.scss","webpack:///./node_modules/tachyons-sass/scss/_code.scss","webpack:///./node_modules/tachyons-sass/scss/_coordinates.scss","webpack:///./node_modules/tachyons-sass/scss/_clears.scss","webpack:///./node_modules/tachyons-sass/scss/_flexbox.scss","webpack:///./node_modules/tachyons-sass/scss/_display.scss","webpack:///./node_modules/tachyons-sass/scss/_floats.scss","webpack:///./node_modules/tachyons-sass/scss/_font-family.scss","webpack:///./node_modules/tachyons-sass/scss/_font-style.scss","webpack:///./node_modules/tachyons-sass/scss/_font-weight.scss","webpack:///./node_modules/tachyons-sass/scss/_forms.scss","webpack:///./node_modules/tachyons-sass/scss/_heights.scss","webpack:///./node_modules/tachyons-sass/scss/_letter-spacing.scss","webpack:///./node_modules/tachyons-sass/scss/_line-height.scss","webpack:///./node_modules/tachyons-sass/scss/_links.scss","webpack:///./node_modules/tachyons-sass/scss/_lists.scss","webpack:///./node_modules/tachyons-sass/scss/_max-widths.scss","webpack:///./node_modules/tachyons-sass/scss/_widths.scss","webpack:///./node_modules/tachyons-sass/scss/_overflow.scss","webpack:///./node_modules/tachyons-sass/scss/_position.scss","webpack:///./node_modules/tachyons-sass/scss/_opacity.scss","webpack:///./node_modules/tachyons-sass/scss/_rotations.scss","webpack:///./node_modules/tachyons-sass/scss/_skins.scss","webpack:///./node_modules/tachyons-sass/scss/_skins-pseudo.scss","webpack:///./node_modules/tachyons-sass/scss/_spacing.scss","webpack:///./node_modules/tachyons-sass/scss/_variables.scss","webpack:///./node_modules/tachyons-sass/scss/_negative-margins.scss","webpack:///./node_modules/tachyons-sass/scss/_tables.scss","webpack:///./node_modules/tachyons-sass/scss/_text-decoration.scss","webpack:///./node_modules/tachyons-sass/scss/_text-align.scss","webpack:///./node_modules/tachyons-sass/scss/_text-transform.scss","webpack:///./node_modules/tachyons-sass/scss/_type-scale.scss","webpack:///./node_modules/tachyons-sass/scss/_typography.scss","webpack:///./node_modules/tachyons-sass/scss/_utilities.scss","webpack:///./node_modules/tachyons-sass/scss/_visibility.scss","webpack:///./node_modules/tachyons-sass/scss/_white-space.scss","webpack:///./node_modules/tachyons-sass/scss/_vertical-align.scss","webpack:///./node_modules/tachyons-sass/scss/_hovers.scss","webpack:///./node_modules/tachyons-sass/scss/_z-index.scss","webpack:///./node_modules/tachyons-sass/scss/_nested.scss","webpack:///./src/style/_layout.scss","webpack:///./src/style/_buttons.scss","webpack:///./src/style/_mixins.scss","webpack:///./src/style/_form.scss","webpack:///./src/style/_modal.scss","webpack:///./src/style/_models.scss","webpack:///./src/style/_servers.scss","webpack:///./src/style/_table.scss","webpack:///./src/style/_topbar.scss","webpack:///./src/style/_information.scss","webpack:///./src/style/_authorize.scss","webpack:///./src/style/_errors.scss","webpack:///./src/style/_split-pane-mode.scss","webpack:///./src/style/_markdown.scss"],"names":[],"mappings":"AAAA,YCII,aCYiB;ECTrB,4EFLI,sBDqhCJ,CAvhCA,iBGmBE,gBAAiB,CACjB,yBAA0B,CAC1B,6BH2gCF,CAhiCA,iBGgCE,QHogCF,CApiCA,gHG6CE,aHggCF,CA7iCA,eGsDE,aAAc,CACd,cH2/BF,CAljCA,2DGqEE,aHo/BF,CAzjCA,mBG6EE,eHg/BF,CA7jCA,eGsFE,sBAAuB,CACvB,QAAS,CACT,gBH8+BF,CAtkCA,gBGiGE,+BAAiC,CACjC,aH2+BF,CA7kCA,cG8GE,4BAA6B,CAC7B,oCHq+BF,CAplCA,wBGwHE,kBAAmB,CACnB,yBAA0B,CAC1B,wCAAiC,CAAjC,gCHm+BF,CA7lCA,iCGmIE,mBAAoB,CASpB,kBHs9BF,CAlmCA,kDGuJE,+BAAiC,CACjC,aHw9BF,CAhnCA,gBGgKE,iBHo9BF,CApnCA,iBGwKE,qBAAsB,CACtB,UHg9BF,CAznCA,kBGiLE,aH48BF,CA7nCA,gCG2LE,aAAc,CACd,aAAc,CACd,iBAAkB,CAClB,uBHu8BF,CAroCA,gBGkME,aHu8BF,CAzoCA,gBGsME,SHu8BF,CA7oCA,oCGkNE,oBHg8BF,CAlpCA,kCG0NE,YAAa,CACb,QH47BF,CAvpCA,gBGmOE,iBHw7BF,CA3pCA,2BG2OE,eHo7BF,CA/pCA,kGG2PE,sBAAuB,CACvB,cAAe,CACf,gBAAiB,CACjB,QHg7BF,CA9qCA,qCGwQE,gBH46BF,CAprCA,sCGkRE,mBHw6BF,CA1rCA,qGG+RE,yBHm6BF,CAlsCA,wKG0SE,iBAAkB,CACLine truncated
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
/*! For license information please see swagger-ui.js.LICENSE.txt */
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SwaggerUICore=t():e.SwaggerUICore=t()}(this,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist",n(n.s=417)}([function(e,t){e.exports=require("react")},function(e,t){e.exports=require("immutable")},function(e,t,n){e.exports=n(449)},function(e,t,n){var r=n(199);e.exports=function(e,t,n){return t in e?r(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){e.exports=n(478)},function(e,t,n){"use strict";(function(e){n.d(t,"z",(function(){return be})),n.d(t,"i",(function(){return Ee})),n.d(t,"v",(function(){return xe})),n.d(t,"r",(function(){return Se})),n.d(t,"t",(function(){return we})),n.d(t,"s",(function(){return je})),n.d(t,"p",(function(){return Oe})),n.d(t,"u",(function(){return Ce})),n.d(t,"x",(function(){return _e})),n.d(t,"y",(function(){return Ae})),n.d(t,"J",(function(){return ke})),n.d(t,"f",(function(){return Ie})),n.d(t,"n",(function(){return Pe})),n.d(t,"h",(function(){return Te})),n.d(t,"D",(function(){return Re})),n.d(t,"K",(function(){return Me})),n.d(t,"o",(function(){return Ve})),n.d(t,"C",(function(){return ze})),n.d(t,"a",(function(){return Fe})),n.d(t,"H",(function(){return Je})),n.d(t,"b",(function(){return We})),n.d(t,"G",(function(){return He})),n.d(t,"F",(function(){return $e})),n.d(t,"E",(function(){return Ye})),n.d(t,"k",(function(){return Ke})),n.d(t,"d",(function(){return Ge})),n.d(t,"g",(function(){return Ze})),n.d(t,"m",(function(){return Xe})),n.d(t,"l",(function(){return Qe})),n.d(t,"e",(function(){return et})),n.d(t,"I",(function(){return tt})),n.d(t,"w",(function(){return nt})),n.d(t,"A",(function(){return rt})),n.d(t,"B",(function(){return at})),n.d(t,"j",(function(){return ot})),n.d(t,"c",(function(){return it})),n.d(t,"q",(function(){return ct}));var r=n(14),a=n.n(r),o=(n(13),n(18)),i=n.n(o),s=n(44),c=n.n(s),u=n(23),l=n.n(u),p=n(4),f=n.n(p),d=n(70),h=n.n(d),m=n(2),v=n.n(m),g=n(24),y=n.n(g),b=n(11),E=n.n(b),x=n(15),S=n.n(x),w=(n(33),n(19)),j=n.n(w),O=n(21),C=n.n(O),_=n(165),A=n.n(_),k=n(20),I=n.n(k),P=n(64),T=n.n(P),R=(n(29),n(30)),N=n.n(R),M=n(17),q=n.n(M),D=n(50),B=n.n(D),L=n(137),U=n.n(L),V=n(85),z=n.n(V),F=n(1),J=n.n(F),W=n(383),H=n(384),$=n.n(H),Y=n(217),K=n.n(Y),G=n(218),Z=n.n(G),X=n(166),Q=n.n(X),ee=n(278),te=n.n(ee),ne=n(101),re=n.n(ne),ae=n(56),oe=n.n(ae),ie=n(113),se=n(26),ce=n(386),ue=n.n(ce),le=n(116),pe=n(387),fe=n.n(pe),de=n(388),he=n.n(de),me=n(63),ve=n.n(me),ge="default",ye=function(e){return J.a.Iterable.isIterable(e)};function be(e){return we(e)?ye(e)?e.toJS():e:{}}function Ee(e){var t,n;if(ye(e))return e;if(e instanceof se.a.File)return e;if(!we(e))return e;if(l()(e))return f()(n=J.a.Seq(e)).call(n,Ee).toList();if(oe()(h()(e))){var r,a=function(e){if(!oe()(h()(e)))return e;var t,n={},r="_**[]",a={},o=c()(h()(e).call(e));try{for(o.s();!(t=o.n()).done;){var i=t.value;if(n[i[0]]||a[i[0]]&&a[i[0]].containsMultiple){var s,u,l,p;if(!a[i[0]])a[i[0]]={containsMultiple:!0,length:1},n[v()(l=v()(p="".concat(i[0])).call(p,r)).call(l,a[i[0]].length)]=n[i[0]],delete n[i[0]];a[i[0]].length+=1,n[v()(s=v()(u="".concat(i[0])).call(u,r)).call(s,a[i[0]].length)]=i[1]}else n[i[0]]=i[1]}}catch(e){o.e(e)}finally{o.f()}return n}(e);return f()(r=J.a.OrderedMap(a)).call(r,Ee)}return f()(t=J.a.OrderedMap(e)).call(t,Ee)}function xe(e){return l()(e)?e:[e]}function Se(e){return"function"==typeof e}function we(e){return!!e&&"object"===i()(e)}function je(e){return"function"==typeof e}function Oe(e){return l()(e)}var Ce=Z.a;function _e(e,t){var n;return j()(n=S()(e)).call(n,(function(n,r){return n[r]=t(e[r],r),n}),{})}function Ae(e,t){var n;return j()(n=S()(e)).call(n,(function(n,r){var a=t(e[r],r);return a&&"object"===i()(a)&&C()(n,a),n}),{})}function ke(e){return function(t){t.dispatch,t.getState;return function(t){return function(n){return"function"==typeof n?n(e()):t(n)}}}}function Ie(e){var t,n=e.keySeq();return n.contains(ge)?ge:A()(t=E()(n).call(n,(function(e){return"2"==Line truncated
|
||||
//# sourceMappingURL=swagger-ui.js.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["webpack://SwaggerUICore/webpack/universalModuleDefinition","webpack://SwaggerUICore/webpack/bootstrap","webpack://SwaggerUICore/external \"react\"","webpack://SwaggerUICore/external \"immutable\"","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/concat.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/defineProperty.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/map.js","webpack://SwaggerUICore/./src/core/utils.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/classCallCheck.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/createClass.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/inherits.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/createSuper.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/assertThisInitialized.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/filter.js","webpack://SwaggerUICore/external \"prop-types\"","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/slicedToArray.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/toConsumableArray.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/object/keys.js","webpack://SwaggerUICore/external \"reselect\"","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/index-of.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/typeof.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/reduce.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/slice.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/object/assign.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/export.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/array/is-array.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/for-each.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/objectSpread2.js","webpack://SwaggerUICore/./src/core/window.js","webpack://SwaggerUICore/external \"react-immutable-proptypes\"","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/extends.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/includes.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/json/stringify.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/path.js","webpack://SwaggerUICore/./src/core/plugins/oas3/helpers.jsx","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/bind.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/fails.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/regenerator/index.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/global.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/well-known-symbol.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/entry-virtual.js","webpack://SwaggerUICore/./node_modules/lodash/get.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/is-object.js","webpack://SwaggerUICore/./src/core/plugins/spec/actions.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/define-well-known-symbol.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/descriptors.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/createForOfIteratorHelper.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/an-object.js","webpack://SwaggerUICore/./node_modules/lodash/isArray.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/has.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/helpers/objectWithoutProperties.js","webpack://SwaggerUICore/./src/core/plugins/oas3/actions.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/instance/find.js","webpack://SwaggerUICore/./node_modules/lodash/isObject.js","webpack://SwaggerUICore/./node_modules/swagger-client/es/helpers.js","webpack://SwaggerUICore/./src/core/plugins/err/actions.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/to-object.js","webpack://SwaggerUICore/external \"classnames\"","webpack://SwaggerUICore/./node_modules/lodash/isFunction.js","webpack://SwaggerUICore/./node_modules/@babel/runtime-corejs3/core-js-stable/promise.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/to-indexed-object.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/create-non-enumerable-property.js","webpack://SwaggerUICore/./node_modules/core-js-pure/internals/object-define-property.js","webpackLine truncated
|
||||
@@ -0,0 +1,60 @@
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="dist/swagger-ui.css" />
|
||||
<link rel="icon" type="image/png" href="dist/favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="dist/favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="dist/swagger-ui-bundle.js" charset="UTF-8"> </script>
|
||||
<script src="dist/swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "AlertingApi.yaml",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
});
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui;
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Vendored
BIN
Binary file not shown.
+5
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# https://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.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
Vendored
+89
@@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,6 @@
|
||||
config.stopBubbling = true
|
||||
lombok.accessors.chain = true
|
||||
lombok.accessors.fluent = false
|
||||
lombok.addLombokGeneratedAnnotation = true
|
||||
lombok.data.flagUsage = error
|
||||
lombok.LOG.fieldName = LOG
|
||||
@@ -0,0 +1,27 @@
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootJar
|
||||
|
||||
plugins {
|
||||
id("org.flywaydb.flyway") version "7.9.1"
|
||||
kotlin("plugin.jpa") version "1.5.10"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"implementation"("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||
implementation("org.springframework.boot:spring-boot-starter-validation")
|
||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||
implementation("org.flywaydb:flyway-core")
|
||||
implementation("org.apache.tomcat:tomcat-jdbc")
|
||||
implementation("com.h2database:h2:1.4.200")
|
||||
}
|
||||
|
||||
flyway {
|
||||
url = "jdbc:h2:mem:alerting"
|
||||
user = "defaultUser"
|
||||
password = "secret"
|
||||
locations = arrayOf("classpath:resources/db/migration")
|
||||
}
|
||||
|
||||
tasks.getByName<BootJar>("bootJar") {
|
||||
enabled = true
|
||||
mainClass.set("com.poc.alerting.persistence.Persistence")
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.poc.alerting.persistence
|
||||
|
||||
import org.h2.tools.Server
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
|
||||
|
||||
@Configuration
|
||||
@EnableJpaRepositories("com.poc.alerting.persistence.repositories")
|
||||
@EntityScan("com.poc.alerting.persistence.dto")
|
||||
@EnableAutoConfiguration
|
||||
open class H2Config {
|
||||
@Bean(initMethod = "start", destroyMethod = "stop")
|
||||
@Profile("persistence")
|
||||
open fun inMemoryH2DatabaseServer(): Server {
|
||||
return Server.createTcpServer(
|
||||
"-tcp", "-tcpAllowOthers", "-tcpPort", "9091"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.poc.alerting.persistence
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
|
||||
|
||||
@SpringBootApplication(scanBasePackages = ["com.poc.alerting.persistence"])
|
||||
open class Persistence
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
runApplication<Persistence>(*args)
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.poc.alerting.persistence.dto
|
||||
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.GeneratedValue
|
||||
import javax.persistence.Id
|
||||
import javax.validation.constraints.NotBlank
|
||||
import javax.validation.constraints.Size
|
||||
|
||||
@Entity
|
||||
data class Account(
|
||||
@Id
|
||||
@GeneratedValue
|
||||
val id: Long,
|
||||
|
||||
@NotBlank
|
||||
@Size(max = 255)
|
||||
val name: String,
|
||||
|
||||
@NotBlank
|
||||
@Size(max = 255)
|
||||
val extId: String
|
||||
)
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.poc.alerting.persistence.dto
|
||||
|
||||
import org.hibernate.annotations.CreationTimestamp
|
||||
import org.hibernate.annotations.UpdateTimestamp
|
||||
import java.util.Date
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.EnumType
|
||||
import javax.persistence.Enumerated
|
||||
import javax.persistence.GeneratedValue
|
||||
import javax.persistence.GenerationType
|
||||
import javax.persistence.Id
|
||||
import javax.persistence.ManyToOne
|
||||
import javax.persistence.Temporal
|
||||
import javax.persistence.TemporalType
|
||||
import javax.validation.constraints.NotBlank
|
||||
import javax.validation.constraints.NotNull
|
||||
import javax.validation.constraints.Size
|
||||
|
||||
@Entity
|
||||
data class Alert(
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
val id: Long,
|
||||
|
||||
@NotBlank
|
||||
@Size(max = 255)
|
||||
val extId: String,
|
||||
|
||||
@Size(max = 255)
|
||||
var threshold: String,
|
||||
|
||||
@NotNull
|
||||
@Enumerated(EnumType.STRING)
|
||||
val type: AlertTypeEnum,
|
||||
|
||||
@Size(max = 255)
|
||||
var frequency: String = "",
|
||||
|
||||
var enabled: String = "",
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
var lastTriggerTimestamp: Date,
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
var notificationSentTimestamp: Date,
|
||||
|
||||
var isTriggered: Boolean,
|
||||
|
||||
@Size(max = 255)
|
||||
var referenceTimePeriod: String,
|
||||
|
||||
@CreationTimestamp
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
val created: Date,
|
||||
|
||||
@UpdateTimestamp
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
var updated: Date,
|
||||
|
||||
@Size(max = 255)
|
||||
var updatedBy: String,
|
||||
|
||||
@ManyToOne
|
||||
var account: Account
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.poc.alerting.persistence.dto
|
||||
|
||||
import kotlin.random.Random
|
||||
|
||||
enum class AlertTypeEnum(val query: () -> Int) {
|
||||
HARDCODED_ALERT_1({ Random.nextInt(0,1000) }),
|
||||
HARDCODED_ALERT_2({ Random.nextInt(0,1000) })
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.poc.alerting.persistence.dto
|
||||
|
||||
import org.hibernate.annotations.CreationTimestamp
|
||||
import org.hibernate.annotations.UpdateTimestamp
|
||||
import java.util.Date
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.EnumType
|
||||
import javax.persistence.Enumerated
|
||||
import javax.persistence.GeneratedValue
|
||||
import javax.persistence.Id
|
||||
import javax.persistence.ManyToOne
|
||||
import javax.persistence.Temporal
|
||||
import javax.persistence.TemporalType
|
||||
import javax.validation.constraints.NotBlank
|
||||
import javax.validation.constraints.NotNull
|
||||
import javax.validation.constraints.Size
|
||||
|
||||
@Entity
|
||||
data class Recipient(
|
||||
@Id
|
||||
@GeneratedValue
|
||||
val id: Long,
|
||||
|
||||
@NotBlank
|
||||
@Size(max = 255)
|
||||
val extId: String,
|
||||
|
||||
@NotBlank
|
||||
@Size(max = 255)
|
||||
val recipient: String,
|
||||
|
||||
@NotNull
|
||||
@Enumerated(EnumType.STRING)
|
||||
val type: RecipientTypeEnum,
|
||||
|
||||
@Size(max = 255)
|
||||
val username: String,
|
||||
|
||||
@Size(max = 255)
|
||||
val password: String,
|
||||
|
||||
@CreationTimestamp
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
val created: Date,
|
||||
|
||||
@UpdateTimestamp
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
val updated: Date,
|
||||
|
||||
@Size(max = 255)
|
||||
val updatedBy: String,
|
||||
|
||||
@ManyToOne
|
||||
val alert: Alert,
|
||||
|
||||
@ManyToOne
|
||||
val account: Account
|
||||
)
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.poc.alerting.persistence.dto
|
||||
|
||||
enum class RecipientTypeEnum {
|
||||
EMAIL,
|
||||
SMS,
|
||||
HTTP
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.poc.alerting.persistence.repositories
|
||||
|
||||
import com.poc.alerting.persistence.dto.Account
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
interface AccountRepository : JpaRepository<Account, Long> {
|
||||
fun findByExtId(accountExtId: String): Account
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.poc.alerting.persistence.repositories
|
||||
|
||||
import com.poc.alerting.persistence.dto.Alert
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
import org.springframework.data.repository.PagingAndSortingRepository
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
interface AlertRepository : CrudRepository<Alert, Long>, PagingAndSortingRepository<Alert, Long> {
|
||||
fun findByExtIdAndAccount_ExtId(alertId: String, accountExtId: String): Alert
|
||||
|
||||
fun findAllByAccount_ExtId(accountExtId: String): List<Alert>
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.poc.alerting.persistence.repositories
|
||||
|
||||
import com.poc.alerting.persistence.dto.Recipient
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
interface RecipientRepository : CrudRepository<Recipient, Long> {
|
||||
fun findByExtIdAndAlert_ExtIdAndAccount_ExtId(recipientId: String, alertId: String, accountExtId: String): Recipient
|
||||
|
||||
fun findAllByAccount_ExtId(accountExtId: String): List<Recipient>
|
||||
|
||||
fun findAllByAlert_ExtIdAndAccount_ExtId(alertId: String, accountExtId: String): List<Recipient>
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: "persistence"
|
||||
datasource:
|
||||
url: "jdbc:h2:mem:alerting;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE;"
|
||||
driver-class-name: org.h2.Driver
|
||||
username: defaultUser
|
||||
password: secret
|
||||
jpa:
|
||||
database-platform: org.hibernate.dialect.H2Dialect
|
||||
hibernate:
|
||||
ddl-auto: update
|
||||
naming:
|
||||
implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
|
||||
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
|
||||
h2:
|
||||
console:
|
||||
enabled: true
|
||||
path: /h2-console
|
||||
server:
|
||||
port: 8081
|
||||
@@ -0,0 +1,11 @@
|
||||
DROP TABLE qrtz_calendars IF EXISTS;
|
||||
DROP TABLE qrtz_cron_triggers IF EXISTS;
|
||||
DROP TABLE qrtz_fired_triggeres IF EXISTS;
|
||||
DROP TABLE qrtz_paused_trigger_grps IF EXISTS;
|
||||
DROP TABLE qrtz_scheduler_state IF EXISTS;
|
||||
DROP TABLE qrtz_locks IF EXISTS;
|
||||
DROP TABLE qrtz_job_details IF EXISTS;
|
||||
DROP TABLE qrtz_simple_triggers IF EXISTS;
|
||||
DROP TABLE qrtz_simprop_triggers IF EXISTS;
|
||||
DROP TABLE qrtz_blob_triggers IF EXISTS;
|
||||
DROP TABLE qrtz_triggers IF EXISTS;
|
||||
@@ -0,0 +1,238 @@
|
||||
CREATE TABLE QRTZ_CALENDARS (
|
||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
||||
CALENDAR_NAME VARCHAR (200) NOT NULL ,
|
||||
CALENDAR IMAGE NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE QRTZ_CRON_TRIGGERS (
|
||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
||||
TRIGGER_NAME VARCHAR (200) NOT NULL ,
|
||||
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
|
||||
CRON_EXPRESSION VARCHAR (120) NOT NULL ,
|
||||
TIME_ZONE_ID VARCHAR (80)
|
||||
);
|
||||
|
||||
CREATE TABLE QRTZ_FIRED_TRIGGERS (
|
||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
||||
ENTRY_ID VARCHAR (95) NOT NULL ,
|
||||
TRIGGER_NAME VARCHAR (200) NOT NULL ,
|
||||
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
|
||||
INSTANCE_NAME VARCHAR (200) NOT NULL ,
|
||||
FIRED_TIME BIGINT NOT NULL ,
|
||||
SCHED_TIME BIGINT NOT NULL ,
|
||||
PRIORITY INTEGER NOT NULL ,
|
||||
STATE VARCHAR (16) NOT NULL,
|
||||
JOB_NAME VARCHAR (200) NULL ,
|
||||
JOB_GROUP VARCHAR (200) NULL ,
|
||||
IS_NONCONCURRENT BOOLEAN NULL ,
|
||||
REQUESTS_RECOVERY BOOLEAN NULL
|
||||
);
|
||||
|
||||
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
|
||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
||||
TRIGGER_GROUP VARCHAR (200) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE QRTZ_SCHEDULER_STATE (
|
||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
||||
INSTANCE_NAME VARCHAR (200) NOT NULL ,
|
||||
LAST_CHECKIN_TIME BIGINT NOT NULL ,
|
||||
CHECKIN_INTERVAL BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE QRTZ_LOCKS (
|
||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
||||
LOCK_NAME VARCHAR (40) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE QRTZ_JOB_DETAILS (
|
||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
||||
JOB_NAME VARCHAR (200) NOT NULL ,
|
||||
JOB_GROUP VARCHAR (200) NOT NULL ,
|
||||
DESCRIPTION VARCHAR (250) NULL ,
|
||||
JOB_CLASS_NAME VARCHAR (250) NOT NULL ,
|
||||
IS_DURABLE BOOLEAN NOT NULL ,
|
||||
IS_NONCONCURRENT BOOLEAN NOT NULL ,
|
||||
IS_UPDATE_DATA BOOLEAN NOT NULL ,
|
||||
REQUESTS_RECOVERY BOOLEAN NOT NULL ,
|
||||
JOB_DATA IMAGE NULL
|
||||
);
|
||||
|
||||
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
|
||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
||||
TRIGGER_NAME VARCHAR (200) NOT NULL ,
|
||||
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
|
||||
REPEAT_COUNT BIGINT NOT NULL ,
|
||||
REPEAT_INTERVAL BIGINT NOT NULL ,
|
||||
TIMES_TRIGGERED BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE QRTZ_SIMPROP_TRIGGERS (
|
||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
||||
TRIGGER_NAME VARCHAR(200) NOT NULL,
|
||||
TRIGGER_GROUP VARCHAR(200) NOT NULL,
|
||||
STR_PROP_1 VARCHAR(512) NULL,
|
||||
STR_PROP_2 VARCHAR(512) NULL,
|
||||
STR_PROP_3 VARCHAR(512) NULL,
|
||||
INT_PROP_1 INTEGER NULL,
|
||||
INT_PROP_2 INTEGER NULL,
|
||||
LONG_PROP_1 BIGINT NULL,
|
||||
LONG_PROP_2 BIGINT NULL,
|
||||
DEC_PROP_1 NUMERIC(13,4) NULL,
|
||||
DEC_PROP_2 NUMERIC(13,4) NULL,
|
||||
BOOL_PROP_1 BOOLEAN NULL,
|
||||
BOOL_PROP_2 BOOLEAN NULL
|
||||
);
|
||||
|
||||
CREATE TABLE QRTZ_BLOB_TRIGGERS (
|
||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
||||
TRIGGER_NAME VARCHAR (200) NOT NULL ,
|
||||
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
|
||||
BLOB_DATA IMAGE NULL
|
||||
);
|
||||
|
||||
CREATE TABLE QRTZ_TRIGGERS (
|
||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
||||
TRIGGER_NAME VARCHAR (200) NOT NULL ,
|
||||
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
|
||||
JOB_NAME VARCHAR (200) NOT NULL ,
|
||||
JOB_GROUP VARCHAR (200) NOT NULL ,
|
||||
DESCRIPTION VARCHAR (250) NULL ,
|
||||
NEXT_FIRE_TIME BIGINT NULL ,
|
||||
PREV_FIRE_TIME BIGINT NULL ,
|
||||
PRIORITY INTEGER NULL ,
|
||||
TRIGGER_STATE VARCHAR (16) NOT NULL ,
|
||||
TRIGGER_TYPE VARCHAR (8) NOT NULL ,
|
||||
START_TIME BIGINT NOT NULL ,
|
||||
END_TIME BIGINT NULL ,
|
||||
CALENDAR_NAME VARCHAR (200) NULL ,
|
||||
MISFIRE_INSTR SMALLINT NULL ,
|
||||
JOB_DATA IMAGE NULL
|
||||
);
|
||||
|
||||
ALTER TABLE QRTZ_CALENDARS ADD
|
||||
CONSTRAINT PK_QRTZ_CALENDARS PRIMARY KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
CALENDAR_NAME
|
||||
);
|
||||
|
||||
ALTER TABLE QRTZ_CRON_TRIGGERS ADD
|
||||
CONSTRAINT PK_QRTZ_CRON_TRIGGERS PRIMARY KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
TRIGGER_NAME,
|
||||
TRIGGER_GROUP
|
||||
);
|
||||
|
||||
ALTER TABLE QRTZ_FIRED_TRIGGERS ADD
|
||||
CONSTRAINT PK_QRTZ_FIRED_TRIGGERS PRIMARY KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
ENTRY_ID
|
||||
);
|
||||
|
||||
ALTER TABLE QRTZ_PAUSED_TRIGGER_GRPS ADD
|
||||
CONSTRAINT PK_QRTZ_PAUSED_TRIGGER_GRPS PRIMARY KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
TRIGGER_GROUP
|
||||
);
|
||||
|
||||
ALTER TABLE QRTZ_SCHEDULER_STATE ADD
|
||||
CONSTRAINT PK_QRTZ_SCHEDULER_STATE PRIMARY KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
INSTANCE_NAME
|
||||
);
|
||||
|
||||
ALTER TABLE QRTZ_LOCKS ADD
|
||||
CONSTRAINT PK_QRTZ_LOCKS PRIMARY KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
LOCK_NAME
|
||||
);
|
||||
|
||||
ALTER TABLE QRTZ_JOB_DETAILS ADD
|
||||
CONSTRAINT PK_QRTZ_JOB_DETAILS PRIMARY KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
JOB_NAME,
|
||||
JOB_GROUP
|
||||
);
|
||||
|
||||
ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD
|
||||
CONSTRAINT PK_QRTZ_SIMPLE_TRIGGERS PRIMARY KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
TRIGGER_NAME,
|
||||
TRIGGER_GROUP
|
||||
);
|
||||
|
||||
ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD
|
||||
CONSTRAINT PK_QRTZ_SIMPROP_TRIGGERS PRIMARY KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
TRIGGER_NAME,
|
||||
TRIGGER_GROUP
|
||||
);
|
||||
|
||||
ALTER TABLE QRTZ_TRIGGERS ADD
|
||||
CONSTRAINT PK_QRTZ_TRIGGERS PRIMARY KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
TRIGGER_NAME,
|
||||
TRIGGER_GROUP
|
||||
);
|
||||
|
||||
ALTER TABLE QRTZ_CRON_TRIGGERS ADD
|
||||
CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
TRIGGER_NAME,
|
||||
TRIGGER_GROUP
|
||||
) REFERENCES QRTZ_TRIGGERS (
|
||||
SCHED_NAME,
|
||||
TRIGGER_NAME,
|
||||
TRIGGER_GROUP
|
||||
) ON DELETE CASCADE;
|
||||
|
||||
|
||||
ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD
|
||||
CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
TRIGGER_NAME,
|
||||
TRIGGER_GROUP
|
||||
) REFERENCES QRTZ_TRIGGERS (
|
||||
SCHED_NAME,
|
||||
TRIGGER_NAME,
|
||||
TRIGGER_GROUP
|
||||
) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD
|
||||
CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
TRIGGER_NAME,
|
||||
TRIGGER_GROUP
|
||||
) REFERENCES QRTZ_TRIGGERS (
|
||||
SCHED_NAME,
|
||||
TRIGGER_NAME,
|
||||
TRIGGER_GROUP
|
||||
) ON DELETE CASCADE;
|
||||
|
||||
|
||||
ALTER TABLE QRTZ_TRIGGERS ADD
|
||||
CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS FOREIGN KEY
|
||||
(
|
||||
SCHED_NAME,
|
||||
JOB_NAME,
|
||||
JOB_GROUP
|
||||
) REFERENCES QRTZ_JOB_DETAILS (
|
||||
SCHED_NAME,
|
||||
JOB_NAME,
|
||||
JOB_GROUP
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,63 @@
|
||||
CREATE TABLE `account` (
|
||||
`id` long PRIMARY KEY,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`ext_id` varchar(255) NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO `account`
|
||||
VALUES (1, 'Test Account 1', '1111'),
|
||||
(2, 'Test Account 2', '2222');
|
||||
|
||||
CREATE TABLE `alert` (
|
||||
`id` long PRIMARY KEY AUTO_INCREMENT,
|
||||
`ext_id` varchar(255) UNIQUE NOT NULL,
|
||||
`name` varchar(255),
|
||||
`threshold` varchar(255),
|
||||
`type` ENUM ('HARDCODED_ALERT_1', 'HARDCODED_ALERT_2'),
|
||||
`frequency` varchar(255),
|
||||
`enabled` boolean default false,
|
||||
`last_trigger_timestamp` timestamp,
|
||||
`notification_sent_timestamp` timestamp,
|
||||
`is_triggered` boolean default false,
|
||||
`reference_time_period` varchar(255),
|
||||
`created` timestamp,
|
||||
`updated` timestamp,
|
||||
`updated_by` varchar(255),
|
||||
`account_id` long NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO `alert`
|
||||
VALUES (1, '1111-alert-1', 'Some Test Alert for Account 1111', '90', 'HARDCODED_ALERT_1', '15m', true, '2021-04-22 16:33:21.959', '2021-04-22 16:33:21.959', false, '1 Month', '2021-04-22 16:33:21.959', '2021-04-22 16:33:21.959', 'someUser1', 1),
|
||||
(2, '1111-alert-2', 'Some Other Test Alert for Account 1111', '666', 'HARDCODED_ALERT_2', '5m', true, null, null, false, '1 Week', '2021-04-22 16:33:21.959', '2021-04-26 04:01:13.448', 'someUser1', 1),
|
||||
(3, '2222-alert-1', 'Some Test Alert for Account 2222', '90', 'HARDCODED_ALERT_1', '15m', true, '2021-04-22 16:33:21.959', '2021-04-22 16:33:21.959', false, '1 Month', '2021-04-22 16:33:21.959', '2021-04-22 16:33:21.959', 'someOtherUser2', 2),
|
||||
(4, '2222-alert-2', 'Some Other Test Alert for Account 2222', '666', 'HARDCODED_ALERT_2', '5m', true, null, null, false, '1 Week', '2021-04-22 16:33:21.959', '2021-04-26 04:01:13.448', 'someOtherUser2', 2);
|
||||
|
||||
ALTER TABLE `alert` ADD FOREIGN KEY (`account_id`) REFERENCES `account` (`id`);
|
||||
|
||||
CREATE TABLE `recipient` (
|
||||
`id` long PRIMARY KEY AUTO_INCREMENT,
|
||||
`ext_id` varchar(255) UNIQUE NOT NULL,
|
||||
`recipient` varchar(255) NOT NULL,
|
||||
`type` ENUM ('EMAIL', 'SMS', 'HTTP'),
|
||||
`username` varchar(255),
|
||||
`password` varchar(255),
|
||||
`created` timestamp NOT NULL,
|
||||
`updated` timestamp NOT NULL,
|
||||
`updated_by` varchar(255) NOT NULL,
|
||||
`alert_id` long,
|
||||
`account_id` long
|
||||
);
|
||||
|
||||
INSERT INTO `recipient`
|
||||
VALUES (1, 'someUsersEmail-account-1111', 'someUser1@somedomain.com', 'EMAIL', null, null, '2021-02-22 16:09:28.139', '2021-02-22 16:09:28.139', 'someUser1', 1, 1),
|
||||
(2, 'someOtherUsersEmail-account-1111', 'someOtherUser1@somedomain.com', 'EMAIL', null, null, '2021-03-04 07:17:33.244', '2021-03-04 08:00:54.562', 'someOtherUser1', 1, 1),
|
||||
(3, 'someUserHttpRecipient-account-1111', 'https://some.test.callback.com/callback1', 'HTTP', 'mikeRoweSoft', 'iSuPpOrTwInDoWs', '2021-05-19 02:39:12.922', '2021-05-19 02:39:12.922', 'someUser1', 2, 1),
|
||||
(4, 'someUserHttpRecipient-account-2222', 'https://some.test.callback.com/callback2', 'HTTP', 'teriDactyl', 'L1f3F1nd$AWay', '2021-05-19 02:39:12.922', '2021-05-19 02:39:12.922', 'someUser2', 2, 2),
|
||||
(5, 'someUsersEmail-account-2222', 'someUser2@somedomain.com', 'EMAIL', null, null, '2021-02-22 16:09:28.139', '2021-02-22 16:09:28.139', 'someUser2', 1, 2),
|
||||
(6, 'someOtherUsersSms-account-2222', '13035552222', 'SMS', null, null, '2021-02-22 16:09:28.139', '2021-02-22 16:09:28.139', 'someOtherUser2', 1, 2);
|
||||
|
||||
ALTER TABLE `recipient` ADD FOREIGN KEY (`alert_id`) REFERENCES `alert` (`id`);
|
||||
|
||||
ALTER TABLE `recipient` ADD FOREIGN KEY (`account_id`) REFERENCES `account` (`id`);
|
||||
|
||||
CREATE SEQUENCE `hibernate_sequence` START WITH 5 INCREMENT BY 1;
|
||||
@@ -0,0 +1,2 @@
|
||||
rootProject.name = "alerting-poc"
|
||||
include(":persistence", ":amqp", ":api", ":batch")
|
||||
Reference in new issue
Block a user