summaryrefslogtreecommitdiffstats
path: root/controller-api
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2019-02-25 09:26:21 +0100
committerGitHub <noreply@github.com>2019-02-25 09:26:21 +0100
commit1f5547e1401fda44fa491e93a31c1da15078db42 (patch)
treef7f03d988e9ecf05585a4e1c1609f3c17d5073fa /controller-api
parentefe78d724c0d0eb7e49ef6f4ed42d4efbc61a3ac (diff)
parent187e5420d09ac7fc95cebb224ffa1fd06314029d (diff)
Merge pull request #8552 from vespa-engine/mpolden/remove-record-id
Remove RecordId
Diffstat (limited to 'controller-api')
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MemoryNameService.java69
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/NameService.java27
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/Record.java39
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordData.java9
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordId.java40
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordName.java23
6 files changed, 97 insertions, 110 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MemoryNameService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MemoryNameService.java
index 46a6d1c35ad..e8b0c8a66ef 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MemoryNameService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MemoryNameService.java
@@ -2,15 +2,11 @@
package com.yahoo.vespa.hosted.controller.api.integration.dns;
-import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
-import java.util.UUID;
+import java.util.TreeSet;
import java.util.stream.Collectors;
/**
@@ -20,67 +16,64 @@ import java.util.stream.Collectors;
*/
public class MemoryNameService implements NameService {
- private final Map<RecordId, Set<Record>> records = new HashMap<>();
+ private final Set<Record> records = new TreeSet<>();
- public Map<RecordId, Set<Record>> records() {
- return Collections.unmodifiableMap(records);
+ public Set<Record> records() {
+ return Collections.unmodifiableSet(records);
}
@Override
- public RecordId createCname(RecordName name, RecordData canonicalName) {
- RecordId id = new RecordId(UUID.randomUUID().toString());
- records.put(id, Set.of(new Record(id, Record.Type.CNAME, name, canonicalName)));
- return id;
+ public Record createCname(RecordName name, RecordData canonicalName) {
+ Record record = new Record(Record.Type.CNAME, name, canonicalName);
+ records.add(record);
+ return record;
}
@Override
- public RecordId createAlias(RecordName name, Set<AliasTarget> targets) {
- RecordId id = new RecordId(UUID.randomUUID().toString());
- Set<Record> records = targets.stream()
+ public List<Record> createAlias(RecordName name, Set<AliasTarget> targets) {
+ List<Record> records = targets.stream()
.sorted((a, b) -> Comparator.comparing(AliasTarget::name).compare(a, b))
- .map(target -> new Record(id, Record.Type.ALIAS, name,
+ .map(target -> new Record(Record.Type.ALIAS, name,
RecordData.fqdn(target.name().value())))
- .collect(Collectors.toCollection(LinkedHashSet::new));
+ .collect(Collectors.toList());
// Satisfy idempotency contract of interface
- findRecords(Record.Type.ALIAS, name).stream().map(Record::id).forEach(this::removeRecord);
- this.records.put(id, records);
- return id;
+ removeRecords(findRecords(Record.Type.ALIAS, name));
+ this.records.addAll(records);
+ return records;
}
@Override
public List<Record> findRecords(Record.Type type, RecordName name) {
- return records.values().stream()
- .flatMap(Collection::stream)
+ return records.stream()
.filter(record -> record.type() == type && record.name().equals(name))
.collect(Collectors.toUnmodifiableList());
}
@Override
public List<Record> findRecords(Record.Type type, RecordData data) {
- return records.values().stream()
- .flatMap(Collection::stream)
+ return records.stream()
.filter(record -> record.type() == type && record.data().equals(data))
.collect(Collectors.toUnmodifiableList());
}
@Override
- public void updateRecord(RecordId id, RecordData newData) {
- records.computeIfPresent(id, (k, records) -> {
- if (records.isEmpty()) {
- throw new IllegalArgumentException("No record with data '" + newData.asString() + "' exists");
- }
- if (records.size() > 1) {
- throw new IllegalArgumentException("Cannot update multi-value record '" + id.asString() + "' with '" +
- newData.asString() + "'");
- }
- Record existing = records.iterator().next();
- return Set.of(new Record(id, existing.type(), existing.name(), newData));
- });
+ public void updateRecord(Record record, RecordData newData) {
+ List<Record> records = findRecords(record.type(), record.name());
+ if (records.isEmpty()) {
+ throw new IllegalArgumentException("No record with data '" + newData.asString() + "' exists");
+ }
+ if (records.size() > 1) {
+ throw new IllegalArgumentException("Cannot update multi-value record '" + record.name().asString() +
+ "' with '" + newData.asString() + "'");
+ }
+ Record existing = records.get(0);
+ this.records.remove(existing);
+ this.records.add(new Record(existing.type(), existing.name(), newData));
}
@Override
- public void removeRecord(RecordId id) {
- records.remove(id);
+ public void removeRecords(List<Record> records) {
+ this.records.removeAll(records);
}
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/NameService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/NameService.java
index 537460c8b1e..444c8dda8d3 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/NameService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/NameService.java
@@ -14,24 +14,31 @@ public interface NameService {
/**
* Create a new CNAME record
*
- * @param alias The alias to create
- * @param canonicalName The canonical name which the alias should point to. This must be a FQDN.
+ * @param name The alias to create (lhs of the record)
+ * @param canonicalName The canonical name which the alias should point to (rhs of the record). This must be a FQDN.
+ * @return The created record
*/
- RecordId createCname(RecordName alias, RecordData canonicalName);
+ Record createCname(RecordName name, RecordData canonicalName);
- /** Create a non-standard ALIAS record pointing to given targets. Implementations of this are expected to be idempotent */
- RecordId createAlias(RecordName name, Set<AliasTarget> targets);
+ /**
+ * Create a non-standard ALIAS record pointing to given targets. Implementations of this can be expected to be
+ * idempotent
+ *
+ * @param targets Targets that should be resolved by this alias. pointing to given targets.
+ * @return The created records. One for each target.
+ */
+ List<Record> createAlias(RecordName name, Set<AliasTarget> targets);
- /** Find records matching type and name */
+ /** Find all records matching given type and name */
List<Record> findRecords(Record.Type type, RecordName name);
- /** Find records matching type and data */
+ /** Find all records matching given type and data */
List<Record> findRecords(Record.Type type, RecordData data);
/** Update existing record */
- void updateRecord(RecordId id, RecordData newData);
+ void updateRecord(Record record, RecordData newData);
- /** Remove record by ID */
- void removeRecord(RecordId id);
+ /** Remove given record(s) */
+ void removeRecords(List<Record> record);
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/Record.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/Record.java
index 218fc9f5266..f47f2061000 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/Record.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/Record.java
@@ -1,43 +1,41 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.api.integration.dns;
+import java.util.Comparator;
import java.util.Objects;
/**
- * A basic representation of a DNS resource record, containing the record id, type, name and value.
+ * A basic representation of a DNS resource record, containing the record type, name and data.
*
* @author mpolden
*/
-public class Record {
+public class Record implements Comparable<Record> {
+
+ private static final Comparator<Record> comparator = Comparator.comparing(Record::type)
+ .thenComparing(Record::name)
+ .thenComparing(Record::data);
- private final RecordId id;
private final Type type;
private final RecordName name;
private final RecordData data;
- public Record(RecordId id, Type type, RecordName name, RecordData data) {
- this.id = Objects.requireNonNull(id, "id cannot be null");
+ public Record(Type type, RecordName name, RecordData data) {
this.type = Objects.requireNonNull(type, "type cannot be null");
this.name = Objects.requireNonNull(name, "name cannot be null");
this.data = Objects.requireNonNull(data, "data cannot be null");
}
- /** Unique identifier for this */
- public RecordId id() {
- return id;
- }
-
/** DNS type of this */
public Type type() {
return type;
}
- /** Data in this, e.g. IP address for "A" record */
+ /** Data in this, e.g. IP address for records of type A */
public RecordData data() {
return data;
}
- /** Name of this, e.g. a FQDN for "A" record */
+ /** Name of this, e.g. a FQDN for records of type A */
public RecordName name() {
return name;
}
@@ -57,7 +55,7 @@ public class Record {
@Override
public String toString() {
- return String.format("%s: %s %s -> %s", id, type, name, data);
+ return String.format("%s %s -> %s", type, name, data);
}
@Override
@@ -65,14 +63,19 @@ public class Record {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Record record = (Record) o;
- return Objects.equals(id, record.id) &&
- type == record.type &&
- Objects.equals(name, record.name) &&
- Objects.equals(data, record.data);
+ return type == record.type &&
+ name.equals(record.name) &&
+ data.equals(record.data);
}
@Override
public int hashCode() {
- return Objects.hash(id, type, name, data);
+ return Objects.hash(type, name, data);
}
+
+ @Override
+ public int compareTo(Record that) {
+ return comparator.compare(this, that);
+ }
+
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordData.java
index 6c765efd35a..fddcd85e8af 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordData.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordData.java
@@ -10,7 +10,7 @@ import java.util.Objects;
*
* @author mpolden
*/
-public class RecordData {
+public class RecordData implements Comparable<RecordData> {
private final String data;
@@ -40,7 +40,7 @@ public class RecordData {
return data;
}
- /** Create a new record containing the given data */
+ /** Create data containing the given data */
public static RecordData from(String data) {
return new RecordData(data);
}
@@ -50,4 +50,9 @@ public class RecordData {
return from(data.endsWith(".") ? data : data + ".");
}
+ @Override
+ public int compareTo(RecordData that) {
+ return this.data.compareTo(that.data);
+ }
+
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordId.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordId.java
deleted file mode 100644
index ed628f0c827..00000000000
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordId.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.controller.api.integration.dns;
-
-import java.util.Objects;
-
-/**
- * Unique identifier for a resource record.
- *
- * @author mpolden
- */
-public class RecordId {
-
- private final String id;
-
- public RecordId(String id) {
- this.id = id;
- }
-
- public String asString() {
- return id;
- }
-
- @Override
- public String toString() {
- return id;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- RecordId recordId = (RecordId) o;
- return id.equals(recordId.id);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id);
- }
-}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordName.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordName.java
index d3abad9fb62..f092209c1d8 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordName.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/RecordName.java
@@ -4,11 +4,11 @@ package com.yahoo.vespa.hosted.controller.api.integration.dns;
import java.util.Objects;
/**
- * Represents the name field of a DNS record (NAME). This is typically a FQDN.
+ * Represents the name field of a DNS record (NAME).
*
* @author mpolden
*/
-public class RecordName {
+public class RecordName implements Comparable<RecordName> {
private final String name;
@@ -20,6 +20,16 @@ public class RecordName {
return name;
}
+ /** Returns whether this is a fully qualified domain name (ends in trailing dot) */
+ public boolean isFqdn() {
+ return name.endsWith(".");
+ }
+
+ /** Returns this as a fully qualified domain name (ends in trailing dot) */
+ public RecordName asFqdn() {
+ return isFqdn() ? this : new RecordName(name + ".");
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -42,4 +52,13 @@ public class RecordName {
return new RecordName(name);
}
+ public static RecordName fqdn(String name) {
+ return from(name).asFqdn();
+ }
+
+ @Override
+ public int compareTo(RecordName that) {
+ return this.name.compareTo(that.name);
+ }
+
}