/* * Copyright 2016 Google LLC * * 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 * * http://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. */ package com.google.cloud.dns; import static com.google.common.base.Preconditions.checkNotNull; import com.google.api.services.dns.model.Change; import com.google.common.base.Function; import java.io.IOException; import java.io.ObjectInputStream; import java.util.List; import java.util.Objects; /** * An immutable class representing an atomic update to a collection of {@link RecordSet}s within a * {@code Zone}. * * @see Google Cloud DNS documentation */ public class ChangeRequest extends ChangeRequestInfo { private static final long serialVersionUID = 5335667200595081449L; private final DnsOptions options; private final String zone; private transient Dns dns; /** A builder for {@code ChangeRequest}s. */ public static class Builder extends ChangeRequestInfo.Builder { private final Dns dns; private final String zone; private final ChangeRequestInfo.BuilderImpl infoBuilder; private Builder(ChangeRequest cr) { this.dns = cr.dns; this.zone = cr.zone; this.infoBuilder = new ChangeRequestInfo.BuilderImpl(cr); } @Override public Builder setAdditions(List additions) { infoBuilder.setAdditions(additions); return this; } @Override public Builder setDeletions(List deletions) { infoBuilder.setDeletions(deletions); return this; } @Override public Builder add(RecordSet recordSet) { infoBuilder.add(recordSet); return this; } @Override public Builder delete(RecordSet recordSet) { infoBuilder.delete(recordSet); return this; } @Override public Builder clearAdditions() { infoBuilder.clearAdditions(); return this; } @Override public Builder clearDeletions() { infoBuilder.clearDeletions(); return this; } @Override public Builder removeAddition(RecordSet recordSet) { infoBuilder.removeAddition(recordSet); return this; } @Override public Builder removeDeletion(RecordSet recordSet) { infoBuilder.removeDeletion(recordSet); return this; } @Override Builder setGeneratedId(String generatedId) { infoBuilder.setGeneratedId(generatedId); return this; } @Override Builder setStartTime(long startTimeMillis) { infoBuilder.setStartTime(startTimeMillis); return this; } @Override Builder setStatus(Status status) { infoBuilder.setStatus(status); return this; } @Override public ChangeRequest build() { return new ChangeRequest(dns, zone, infoBuilder); } } ChangeRequest(Dns dns, String zone, ChangeRequest.BuilderImpl infoBuilder) { super(infoBuilder); this.zone = checkNotNull(zone); this.dns = checkNotNull(dns); this.options = dns.getOptions(); } /** Returns the name of the {@link Zone} associated with this change request. */ public String getZone() { return this.zone; } /** Returns the change request's {@code Dns} object used to issue requests. */ public Dns getDns() { return dns; } /** * Applies this change request to the zone identified by {@code zoneName}. * * @throws DnsException upon failure or if zone is not found */ public ChangeRequest applyTo(String zoneName, Dns.ChangeRequestOption... options) { return dns.applyChangeRequest(zoneName, this, options); } /** * Retrieves the up-to-date information about the change request from Google Cloud DNS. Parameter * {@code options} can be used to restrict the fields to be included in the updated object the * same way as in {@link Dns#getChangeRequest(String, String, Dns.ChangeRequestOption...)}. If * {@code options} are provided, any field other than generatedId which is not included in the * {@code options} will be {@code null} regardless of whether they are initialized or not in * {@code this} instance. * * @return an object with the updated information or {@code null} if it does not exist * @throws DnsException upon failure of the API call or if the associated zone was not found */ public ChangeRequest reload(Dns.ChangeRequestOption... options) { return dns.getChangeRequest(zone, getGeneratedId(), options); } /** * Returns {@code true} if the change request has been completed. If the status is not {@link * ChangeRequestInfo.Status#DONE} already, the method makes an API call to Google Cloud DNS to * update the change request first. * * @throws DnsException upon failure of the API call or if the associated zone was not found */ public boolean isDone() { if (status() == Status.DONE) { return true; } ChangeRequest updated = reload(Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); return updated == null || updated.status() == Status.DONE; } @Override public Builder toBuilder() { return new Builder(this); } @Override public final boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null || !obj.getClass().equals(ChangeRequest.class)) { return false; } ChangeRequest other = (ChangeRequest) obj; return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options) && Objects.equals(zone, other.zone); } @Override public final int hashCode() { return Objects.hash(super.hashCode(), options, zone); } private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { input.defaultReadObject(); this.dns = options.getService(); } static ChangeRequest fromPb(Dns dns, String zoneName, Change pb) { ChangeRequestInfo info = ChangeRequestInfo.fromPb(pb); return new ChangeRequest(dns, zoneName, new ChangeRequestInfo.BuilderImpl(info)); } static Function fromPbFunction(final Dns dns, final String zoneName) { return new Function() { @Override public ChangeRequest apply(Change pb) { return ChangeRequest.fromPb(dns, zoneName, pb); } }; } }