blob: f9b1379d01284ec1b589f1d660efe62c183bffdd [file] [log] [blame]
/**
* 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 org.apache.aurora.scheduler.storage;
import java.util.Optional;
import java.util.Set;
import com.google.common.collect.ImmutableList;
import org.apache.aurora.gen.MaintenanceMode;
import org.apache.aurora.scheduler.base.Conversions;
import org.apache.aurora.scheduler.storage.Storage.StoreProvider;
import org.apache.aurora.scheduler.storage.entities.IAttribute;
import org.apache.aurora.scheduler.storage.entities.IHostAttributes;
import org.apache.mesos.v1.Protos;
/**
* Storage interface for host attributes.
*/
public interface AttributeStore {
/**
* Fetches all host attributes given by the host.
* <p>
* TODO(wfarner): We need to transition this API to key off slave ID instead of host name, as
* the host is not guaranteed to be unique (it's possible, and sometimes desirable to have
* multiple slaves on a machine). The current API ripples down into storage, since the store
* is not in the position to dictate behavior when host names collide. Most callers seem to have
* sufficient context to use slave ID instead, with the exception of those related to host
* maintenance.
*
* @param host host name.
* @return attributes associated with {@code host}, if the host is known.
*/
Optional<IHostAttributes> getHostAttributes(String host);
/**
* Fetches all attributes in the store.
*
* @return All host attributes.
*/
Set<IHostAttributes> getHostAttributes();
/**
* Attributes are considered mostly ephemeral and extremely low risk when inconsistency
* is present.
*/
interface Mutable extends AttributeStore {
/**
* Deletes all attributes in the store.
*/
void deleteHostAttributes();
/**
* Save a host attribute in the attribute store.
*
* @param hostAttributes The attribute we are going to save.
* @return {@code true} if the operation changed the attributes stored for the given
* {@link IHostAttributes#getHost() host}, or {@code false} if the save was a no-op.
*/
boolean saveHostAttributes(IHostAttributes hostAttributes);
}
final class Util {
private Util() {
}
/**
* Fetches attributes about a {@code host}.
*
* @param store Store to fetch host attributes from.
* @param host Host to fetch attributes about.
* @return Attributes associated with {@code host}, or an empty iterable if the host is
* unknown.
*/
public static Iterable<IAttribute> attributesOrNone(StoreProvider store, String host) {
Optional<IHostAttributes> attributes = store.getAttributeStore().getHostAttributes(host);
return attributes.isPresent()
? attributes.get().getAttributes() : ImmutableList.of();
}
/**
* Merges a desired maintenance mode with the existing attributes of a host, if present.
*
* @param store The store to fetch existing attributes from.
* @param host The host to merge existing attributes from.
* @param mode Maintenance mode to save if the host is known.
* @return The attributes that should be saved if there were already attributes stored for
* the {@code host}, or {@link Optional#empty() none} if the host is unknown and
* attributes should not be saved.
*/
public static Optional<IHostAttributes> mergeMode(
AttributeStore store,
String host,
MaintenanceMode mode) {
Optional<IHostAttributes> stored = store.getHostAttributes(host);
if (stored.isPresent()) {
return Optional.of(IHostAttributes.build(stored.get().newBuilder().setMode(mode)));
} else {
return Optional.empty();
}
}
/**
* Merges the attributes from an offer, applying the default maintenance mode.
*
* @param store Store to fetch the existing maintenance mode for this host.
* @param offer Offer to merge.
* @return attributes from {@code offer} and the existing (or default) maintenance mode.
*/
public static IHostAttributes mergeOffer(AttributeStore store, Protos.Offer offer) {
IHostAttributes fromOffer = Conversions.getAttributes(offer);
MaintenanceMode mode = store.getHostAttributes(fromOffer.getHost())
.map(IHostAttributes::getMode)
.orElse(MaintenanceMode.NONE);
return IHostAttributes.build(fromOffer.newBuilder().setMode(mode));
}
}
}