aboutsummaryrefslogtreecommitdiffstats
path: root/config-model-api/src/main/java/com/yahoo/config/application/api/Notifications.java
blob: 7955a11ce45329acdc2cfbdf59513fe8d8f13692 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.application.api;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static java.util.Collections.emptyList;

/**
 * Configuration of notifications for deployment jobs.
 *
 * Supports a list of email addresses, and a list of roles for which email addresses are known.
 * The currently supported roles are:
 * <ul>
 *     <li><strong>author</strong>: the author of the git commit of a given application package. </li>
 * </ul>
 *
 * @author jonmv
 */
public class Notifications {

    private static final Notifications none = new Notifications(Collections.emptyMap(), Collections.emptyMap());
    public static Notifications none() { return none; }

    private final Map<When, List<String>> emailAddresses;
    private final Map<When, List<Role>> emailRoles;

    private Notifications(Map<When, List<String>> emailAddresses, Map<When, List<Role>> emailRoles) {
        this.emailAddresses = emailAddresses;
        this.emailRoles = emailRoles;
    }

    /**
     * Returns a new Notifications as specified by the given String input.
     *
     * @param emailAddressesByWhen What email addresses to notify, indexed by when to notify them.
     * @param emailRolesByWhen What roles to infer email addresses for, and notify, indexed by when to notify them.
     * @return The Notifications as specified.
     */
    public static Notifications of(Map<When, List<String>> emailAddressesByWhen, Map<When, List<Role>> emailRolesByWhen) {
        if (   emailAddressesByWhen.values().stream().allMatch(List::isEmpty)
            && emailRolesByWhen.values().stream().allMatch(List::isEmpty))
            return none;

        ImmutableMap.Builder<When, List<String>> emailAddresses = ImmutableMap.builder();
        emailAddressesByWhen.forEach((when, addresses) -> emailAddresses.put(when, List.copyOf(addresses)));

        ImmutableMap.Builder<When, List<Role>> emailRoles = ImmutableMap.builder();
        emailRolesByWhen.forEach((when, roles) -> emailRoles.put(when, List.copyOf(roles)));

        return new Notifications(emailAddresses.build(), emailRoles.build());
    }

    /** Returns all email addresses to notify for the given condition. */
    public Set<String> emailAddressesFor(When when) {
        ImmutableSet.Builder<String> addresses = ImmutableSet.builder();
        addresses.addAll(emailAddresses.getOrDefault(when, emptyList()));
        for (When include : when.includes)
            addresses.addAll(emailAddressesFor(include));
        return addresses.build();
    }

    /** Returns all roles for which email notification is to be sent for the given condition. */
    public Set<Role> emailRolesFor(When when) {
        ImmutableSet.Builder<Role> roles = ImmutableSet.builder();
        roles.addAll(emailRoles.getOrDefault(when, emptyList()));
        for (When include : when.includes)
            roles.addAll(emailRolesFor(include));
        return roles.build();
    }


    public enum Role {

        /** Author of the last commit of an application package. */
        author;

        public static String toValue(Role role) {
            switch (role) {
                case author: return "author";
                default: throw new IllegalArgumentException("Unexpected constant '" + role.name() + "'.");
            }
        }

        public static Role fromValue(String value) {
            switch (value) {
                case "author": return author;
                default: throw new IllegalArgumentException("Unknown value '" + value + "'.");
            }
        }

    }


    public enum When {

        /** Send notifications whenever a job fails. */
        failing,

        /** Send notifications whenever a job fails while deploying a new commit. */
        failingCommit(failing);

        private final List<When> includes;

        When(When... includes) {
            this.includes = Arrays.asList(includes);
        }

        public static String toValue(When when) {
            switch (when) {
                case failing: return "failing";
                case failingCommit: return "failing-commit";
                default: throw new IllegalArgumentException("Unexpected constant '" + when.name() + "'.");
            }
        }

        public static When fromValue(String value) {
            return switch (value) {
                case "failing" -> failing;
                case "failing-commit" -> failingCommit;
                default -> throw new IllegalArgumentException("Unknown value '" + value + "'.");
            };
        }

    }

}