package com.dalab.policyengine.model; import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; import jakarta.persistence.CascadeType; import jakarta.persistence.CollectionTable; import jakarta.persistence.Column; import jakarta.persistence.ElementCollection; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToMany; import jakarta.persistence.PrePersist; import jakarta.persistence.PreUpdate; import jakarta.persistence.Table; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; /** * Entity representing an event subscription configuration. * Users can subscribe to specific types of events and configure * notification preferences and action triggers. */ @Entity @Table(name = "event_subscriptions") public class EventSubscription { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(columnDefinition = "UUID") private UUID id; @NotBlank @Size(max = 255) @Column(nullable = false) private String name; @Size(max = 1000) private String description; @NotNull @Column(columnDefinition = "UUID", nullable = false) private UUID userId; @Enumerated(EnumType.STRING) @Column(nullable = false) private EventSubscriptionStatus status = EventSubscriptionStatus.ACTIVE; /** * Event types to subscribe to (e.g., POLICY_VIOLATION, ASSET_DISCOVERED, COMPLIANCE_ISSUE) */ @ElementCollection(fetch = FetchType.EAGER) @CollectionTable(name = "event_subscription_types", joinColumns = @JoinColumn(name = "subscription_id")) @Enumerated(EnumType.STRING) @Column(name = "event_type") private List eventTypes = new ArrayList<>(); /** * Event severity levels to include (e.g., HIGH, MEDIUM, LOW) */ @ElementCollection(fetch = FetchType.EAGER) @CollectionTable(name = "event_subscription_severities", joinColumns = @JoinColumn(name = "subscription_id")) @Enumerated(EnumType.STRING) @Column(name = "severity") private List severities = new ArrayList<>(); /** * Source services to monitor (e.g., da-catalog, da-discovery, da-compliance) */ @ElementCollection(fetch = FetchType.EAGER) @CollectionTable(name = "event_subscription_sources", joinColumns = @JoinColumn(name = "subscription_id")) @Column(name = "source_service") private List sourceServices = new ArrayList<>(); /** * Filter conditions for events (MVEL expressions) */ @OneToMany(mappedBy = "subscription", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER) private List rules = new ArrayList<>(); /** * Notification preferences and action configurations */ @JdbcTypeCode(SqlTypes.JSON) @Column(columnDefinition = "jsonb") private Map notificationConfig; // e.g., { "email": true, "slack": { "channel": "#alerts" } } /** * Action configurations to trigger when events match */ @JdbcTypeCode(SqlTypes.JSON) @Column(columnDefinition = "jsonb") private Map actionConfig; // e.g., { "autoQuarantine": true, "escalateTo": "admin" } @Column(nullable = false, updatable = false) private Instant createdAt; private Instant updatedAt; @Column(columnDefinition = "UUID") private UUID createdByUserId; @Column(columnDefinition = "UUID") private UUID updatedByUserId; // Constructors public EventSubscription() {} public EventSubscription(String name, UUID userId) { this.name = name; this.userId = userId; } // Getters and Setters public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public UUID getUserId() { return userId; } public void setUserId(UUID userId) { this.userId = userId; } public EventSubscriptionStatus getStatus() { return status; } public void setStatus(EventSubscriptionStatus status) { this.status = status; } public List getEventTypes() { return eventTypes; } public void setEventTypes(List eventTypes) { this.eventTypes = eventTypes != null ? eventTypes : new ArrayList<>(); } public void addEventType(EventType eventType) { if (this.eventTypes == null) { this.eventTypes = new ArrayList<>(); } this.eventTypes.add(eventType); } public void removeEventType(EventType eventType) { if (this.eventTypes != null) { this.eventTypes.remove(eventType); } } public List getSeverities() { return severities; } public void setSeverities(List severities) { this.severities = severities != null ? severities : new ArrayList<>(); } public void addSeverity(EventSeverity severity) { if (this.severities == null) { this.severities = new ArrayList<>(); } this.severities.add(severity); } public void removeSeverity(EventSeverity severity) { if (this.severities != null) { this.severities.remove(severity); } } public List getSourceServices() { return sourceServices; } public void setSourceServices(List sourceServices) { this.sourceServices = sourceServices != null ? sourceServices : new ArrayList<>(); } public void addSourceService(String sourceService) { if (this.sourceServices == null) { this.sourceServices = new ArrayList<>(); } this.sourceServices.add(sourceService); } public void removeSourceService(String sourceService) { if (this.sourceServices != null) { this.sourceServices.remove(sourceService); } } public List getRules() { return rules; } public void setRules(List rules) { this.rules = rules != null ? rules : new ArrayList<>(); this.rules.forEach(rule -> rule.setSubscription(this)); } public void addRule(EventRule rule) { if (this.rules == null) { this.rules = new ArrayList<>(); } this.rules.add(rule); rule.setSubscription(this); } public void removeRule(EventRule rule) { if (this.rules != null) { this.rules.remove(rule); rule.setSubscription(null); } } public Map getNotificationConfig() { return notificationConfig; } public void setNotificationConfig(Map notificationConfig) { this.notificationConfig = notificationConfig; } public Map getActionConfig() { return actionConfig; } public void setActionConfig(Map actionConfig) { this.actionConfig = actionConfig; } public Instant getCreatedAt() { return createdAt; } public void setCreatedAt(Instant createdAt) { this.createdAt = createdAt; } public Instant getUpdatedAt() { return updatedAt; } public void setUpdatedAt(Instant updatedAt) { this.updatedAt = updatedAt; } public UUID getCreatedByUserId() { return createdByUserId; } public void setCreatedByUserId(UUID createdByUserId) { this.createdByUserId = createdByUserId; } public UUID getUpdatedByUserId() { return updatedByUserId; } public void setUpdatedByUserId(UUID updatedByUserId) { this.updatedByUserId = updatedByUserId; } @PrePersist protected void onCreate() { createdAt = Instant.now(); updatedAt = Instant.now(); } @PreUpdate protected void onUpdate() { updatedAt = Instant.now(); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof EventSubscription)) return false; EventSubscription that = (EventSubscription) o; return id != null && id.equals(that.getId()); } @Override public int hashCode() { return getClass().hashCode(); } @Override public String toString() { return "EventSubscription{" + "id=" + id + ", name='" + name + '\'' + ", userId=" + userId + ", status=" + status + ", eventTypes=" + eventTypes + ", severities=" + severities + '}'; } }