aboutsummaryrefslogtreecommitdiffstats
path: root/config-provisioning/src/main/java/com/yahoo/config/provision/ApplicationId.java
blob: dd971ec510878e57cb8330099e54782ac523a571 (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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.provision;

import com.yahoo.cloud.config.ApplicationIdConfig;

import java.util.Comparator;
import java.util.Objects;
import java.util.logging.Logger;
import java.util.regex.Pattern;

import static java.util.logging.Level.SEVERE;

/**
 * A complete, immutable identification of an application instance.
 *
 * @author Ulf Lilleengen
 * @author vegard
 * @author bratseth
 */
public class ApplicationId implements Comparable<ApplicationId> {

    private static final Logger log = Logger.getLogger(ApplicationId.class.getName());

    static final Pattern namePattern = Pattern.compile("[a-zA-Z0-9_-]{1,256}");

    private static final ApplicationId global = new ApplicationId(TenantName.from("hosted-vespa"),
                                                                  ApplicationName.from("routing"),
                                                                  InstanceName.from("default")) { };

    private static final Comparator<ApplicationId> comparator = Comparator.comparing(ApplicationId::tenant)
                                                                          .thenComparing(ApplicationId::application)
                                                                          .thenComparing(ApplicationId::instance)
                                                                          .thenComparing(global::equals, Boolean::compare);

    private final TenantName tenant;
    private final ApplicationName application;
    private final InstanceName instance;
    private final String serializedForm;

    private ApplicationId(TenantName tenant, ApplicationName applicationName, InstanceName instanceName) {
        this.tenant = tenant;
        this.application = applicationName;
        this.instance = instanceName;
        this.serializedForm = toSerializedForm();
    }

    public static ApplicationId from(ApplicationIdConfig config) {
        return from(TenantName.from(config.tenant()),
                    ApplicationName.from(config.application()),
                    InstanceName.from(config.instance()));
    }

    public static ApplicationId from(TenantName tenant, ApplicationName application, InstanceName instance) {
        return new ApplicationId(tenant, application, instance);
    }

    public static ApplicationId from(String tenant, String application, String instance) {
        return new ApplicationId(TenantName.from(tenant), ApplicationName.from(application), InstanceName.from(instance));
    }

    public static ApplicationId fromSerializedForm(String idString) { return fromIdString(idString, ":"); }

    public static ApplicationId fromFullString(String idString) { return fromIdString(idString, "."); }

    private static ApplicationId fromIdString(String idString, String splitCharacter) {
        String[] parts = idString.split(Pattern.quote(splitCharacter));
        if (parts.length != 3)
            throw new IllegalArgumentException("Application ids must be on the form tenant" +
                                                       splitCharacter + "application" + splitCharacter + "instance, but was " + idString);
        return from(parts[0], parts[1], parts[2]);
    }

    @Override
    public int hashCode() { return Objects.hash(tenant, application, instance); }

    @Override
    public boolean equals(Object other) {
        if (this == other) return true;
        if (other == null || getClass() != other.getClass()) return false;

        ApplicationId rhs = (ApplicationId) other;
        return tenant.equals(rhs.tenant) &&
               application.equals(rhs.application) &&
               instance.equals(rhs.instance);
    }

    /** Returns a serialized form of the content of this: tenant:application:instance */
    public String serializedForm() { return serializedForm; }

    /** Returns "dotted" string (tenant.application.instance) with instance name omitted if it is "default" */
    public String toShortString() {
        return tenant().value() + "." + application().value() +
               ( instance().isDefault() ? "" : "." + instance().value() );
    }

    /** Returns "dotted" string (tenant.application.instance) with instance name always included */
    public String toFullString() {
        return tenant().value() + "." + application().value() + "." + instance().value();
    }

    private String toSerializedForm() {
        return tenant.value() + ":" + application.value() + ":" + instance.value();
    }

    public String toSerializedFormWithoutInstance() {
        return tenant.value() + ":" + application.value();
    }

    @Override
    public String toString() { return toShortString(); }

    public TenantName tenant() { return tenant; }
    public ApplicationName application() { return application; }
    public InstanceName instance() { return instance; }

    @Override
    public int compareTo(ApplicationId other) {
        return comparator.compare(this, other);
    }

    /** Returns an application id where all fields are "default" */
    public static ApplicationId defaultId() {
        return new ApplicationId(TenantName.defaultName(), ApplicationName.defaultName(), InstanceName.defaultName());
    }

    /** Returns a serialized form of tenant:application to be used with e.g Flags */
    public static String toSerializedForm(TenantName tenant, ApplicationName application) {
        return tenant.value() + ":" + application.value();
    }

    // TODO: kill this
    /** Returns a very special application id, which is not equal to any other id. */
    public static ApplicationId global() {
        return global;
    }

    public static class Builder {

        private TenantName tenant;
        private ApplicationName application;
        private InstanceName instance;

        public Builder() {
            this.tenant = TenantName.defaultName();
            this.application = null;
            this.instance = InstanceName.defaultName();
        }

        public Builder tenant(TenantName ten) { this.tenant = ten; return this; }
        public Builder tenant(String ten) { return tenant(TenantName.from(ten)); }

        public Builder applicationName(ApplicationName nam) { this.application = nam; return this; }
        public Builder applicationName(String nam) { return applicationName(ApplicationName.from(nam)); }

        public Builder instanceName(InstanceName ins) { this.instance = ins; return this; }
        public Builder instanceName(String ins) { return instanceName(InstanceName.from(ins)); }

        public ApplicationId build() {
            if (application == null) {
                throw new IllegalArgumentException("must set application name in builder");
            }
            return ApplicationId.from(tenant, application, instance);
        }

    }

}