/**
* 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.base;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import com.google.common.base.Optional;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import org.apache.aurora.gen.JobKey;
import org.apache.aurora.scheduler.storage.entities.IJobConfiguration;
import org.apache.aurora.scheduler.storage.entities.IJobKey;
import org.apache.aurora.scheduler.storage.entities.ITaskQuery;
import static com.google.common.base.Preconditions.checkArgument;
/**
* Utility class providing convenience functions relating to JobKeys.
*/
public final class JobKeys {
private JobKeys() {
// Utility class.
}
public static String getRole(IJobConfiguration jobConfiguration) {
return jobConfiguration.getKey().getRole();
}
/**
* Check that a jobKey struct is valid.
*
* @param jobKey The jobKey to validate.
* @return {@code true} if the jobKey validates.
*/
public static boolean isValid(@Nullable IJobKey jobKey) {
return jobKey != null
&& UserProvidedStrings.isGoodIdentifier(jobKey.getRole())
&& UserProvidedStrings.isGoodIdentifier(jobKey.getEnvironment())
&& UserProvidedStrings.isGoodIdentifier(jobKey.getName());
}
/**
* Assert that a jobKey struct is valid.
*
* @param jobKey The key struct to validate.
* @return The validated jobKey argument.
* @throws IllegalArgumentException if the key struct fails to validate.
*/
public static IJobKey assertValid(IJobKey jobKey) throws IllegalArgumentException {
checkArgument(isValid(jobKey));
return jobKey;
}
/**
* Attempt to create a valid JobKey from the given (role, environment, name) triple.
*
* @param role The job's role.
* @param environment The job's environment.
* @param name The job's name.
* @return A valid JobKey if it can be created.
* @throws IllegalArgumentException if the key fails to validate.
*/
public static IJobKey from(String role, String environment, String name)
throws IllegalArgumentException {
IJobKey job = IJobKey.build(new JobKey()
.setRole(role)
.setEnvironment(environment)
.setName(name));
return assertValid(job);
}
/**
* Create a "/"-delimited representation of job key usable as a unique identifier in this cluster.
*
* It is guaranteed that {@code k.equals(JobKeys.parse(JobKeys.canonicalString(k))}.
*
* @see #parse(String)
* @param jobKey Key to represent.
* @return Canonical "/"-delimited representation of the key.
*/
public static String canonicalString(IJobKey jobKey) {
return String.join("/", jobKey.getRole(), jobKey.getEnvironment(), jobKey.getName());
}
/**
* Create a job key from a "role/environment/name" representation.
*
* It is guaranteed that {@code k.equals(JobKeys.parse(JobKeys.canonicalString(k))}.
*
* @see #canonicalString(IJobKey)
* @param string Input to parse.
* @return Parsed representation.
* @throws IllegalArgumentException when the string fails to parse.
*/
public static IJobKey parse(String string) throws IllegalArgumentException {
List<String> components = Splitter.on("/").splitToList(string);
checkArgument(components.size() == 3);
return from(components.get(0), components.get(1), components.get(2));
}
/**
* Attempt to extract job keys from the given query if it is job scoped.
*
* @param query Query to extract the keys from.
* @return A present if keys can be extracted, absent otherwise.
*/
public static Optional<Set<IJobKey>> from(Query.Builder query) {
if (Query.isJobScoped(query)) {
ITaskQuery taskQuery = query.get();
ImmutableSet.Builder<IJobKey> builder = ImmutableSet.builder();
if (taskQuery.isSetJobName()) {
builder.add(from(
taskQuery.getRole(),
taskQuery.getEnvironment(),
taskQuery.getJobName()));
}
builder.addAll(taskQuery.getJobKeys());
return Optional.of(assertValid(builder.build()));
} else {
return Optional.absent();
}
}
private static Set<IJobKey> assertValid(Set<IJobKey> jobKeys)
throws IllegalArgumentException {
for (IJobKey jobKey : jobKeys) {
checkArgument(isValid(jobKey), "Invalid job key format: %s", jobKey);
}
return jobKeys;
}
}