/*
*
* Copyright 2014 Netflix, Inc.
*
* 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.netflix.genie.client;
import com.google.common.collect.Multimap;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpRequest.Verb;
import com.netflix.genie.common.client.BaseGenieClient;
import com.netflix.genie.common.exceptions.GenieException;
import com.netflix.genie.common.exceptions.GeniePreconditionException;
import com.netflix.genie.common.model.Application;
import com.netflix.genie.common.model.Command;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
/**
* Singleton class, which acts as the client library for the Application
* Configuration Service.
*
* @author tgianos
*/
public final class ApplicationServiceClient extends BaseGenieClient {
private static final String BASE_CONFIG_APPLICATION_REST_URL
= BASE_REST_URL + "config/applications";
// reference to the instance object
private static ApplicationServiceClient instance;
/**
* Private constructor for singleton class.
*
* @throws IOException if there is any error during initialization
*/
private ApplicationServiceClient() throws IOException {
super(null);
}
/**
* Returns the singleton instance that can be used by clients.
*
* @return ApplicationServiceClient instance
* @throws IOException if there is an error instantiating client
*/
public static synchronized ApplicationServiceClient getInstance() throws IOException {
if (instance == null) {
instance = new ApplicationServiceClient();
}
return instance;
}
/**
* Create a new application configuration.
*
* @param application the object encapsulating the new application
* configuration to create
* @return The application that was created
* @throws GenieException For any other error.
*/
public Application createApplication(final Application application)
throws GenieException {
if (application == null) {
throw new GeniePreconditionException("No application passed in. Unable to validate.");
}
application.validate();
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.POST,
BASE_CONFIG_APPLICATION_REST_URL,
null,
application);
return (Application) this.executeRequest(request, null, Application.class);
}
/**
* Create or update an application configuration.
*
* @param id the id for the application to create or update
* @param application the object encapsulating the new application to create
* @return extracted application configuration response
* @throws GenieException For any other error.
*/
public Application updateApplication(
final String id,
final Application application)
throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Required parameter id is missing. Unable to update.");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.PUT,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id},
SLASH),
null,
application);
return (Application) this.executeRequest(request, null, Application.class);
}
/**
* Gets information for a given id.
*
* @param id the application id to get (can't be null or empty)
* @return the application for this id
* @throws GenieException For any other error.
*/
public Application getApplication(final String id) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Required parameter id is missing. Unable to get.");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.GET,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id},
SLASH),
null,
null);
return (Application) this.executeRequest(request, null, Application.class);
}
/**
* Gets a set of application configurations for the given parameters.
*
* @param params key/value pairs in a map object.<br>
* More details on the parameters can be found on the Genie User Guide on
* GitHub.
* @return List of application configuration elements that match the filter
* @throws GenieException For any other error.
*/
public List<Application> getApplications(final Multimap<String, String> params)
throws GenieException {
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.GET,
BASE_CONFIG_APPLICATION_REST_URL,
params,
null);
@SuppressWarnings("unchecked")
final List<Application> apps = (List<Application>) this.executeRequest(request, List.class, Application.class);
return apps;
}
/**
* Delete all the applications in the database.
*
* @return the should be empty set.
* @throws GenieException For any other error.
*/
public List<Application> deleteAllApplications() throws GenieException {
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.DELETE,
BASE_CONFIG_APPLICATION_REST_URL,
null,
null);
@SuppressWarnings("unchecked")
final List<Application> apps = (List<Application>) this.executeRequest(request, List.class, Application.class);
return apps;
}
/**
* Delete an application configuration using its id.
*
* @param id the id for the application to delete
* @return the deleted application
* @throws GenieException For any other error.
*/
public Application deleteApplication(final String id) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.DELETE,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id},
SLASH),
null,
null);
return (Application) this.executeRequest(request, null, Application.class);
}
/**
* Add some more configuration files to a given application.
*
* @param id The id of the application to add configurations to. Not
* Null/empty/blank.
* @param configs The configuration files to add. Not null or empty.
* @return The new set of configuration files for the given application.
* @throws GenieException For any other error.
*/
public Set<String> addConfigsToApplication(
final String id,
final Set<String> configs) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
if (configs == null || configs.isEmpty()) {
throw new GeniePreconditionException("Missing required parameter: configs");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.POST,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "configs"},
SLASH),
null,
configs);
@SuppressWarnings("unchecked")
final Set<String> newConfigs = (Set<String>) this.executeRequest(request, Set.class, String.class);
return newConfigs;
}
/**
* Get the active set of configuration files for the given application.
*
* @param id The id of the application to get configurations for. Not
* Null/empty/blank.
* @return The set of configuration files for the given application.
* @throws GenieException For any other error.
*/
public Set<String> getConfigsForApplication(final String id) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.GET,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "configs"},
SLASH),
null,
null);
@SuppressWarnings("unchecked")
final Set<String> configs = (Set<String>) this.executeRequest(request, Set.class, String.class);
return configs;
}
/**
* Update the configuration files for a given application.
*
* @param id The id of the application to update the configuration files
* for. Not null/empty/blank.
* @param configs The configuration files to replace existing configuration
* files with. Not null.
* @return The new set of application configurations.
* @throws GenieException For any other error.
*/
public Set<String> updateConfigsForApplication(
final String id,
final Set<String> configs) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
if (configs == null) {
throw new GeniePreconditionException("Missing required parameter: configs");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.PUT,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "configs"},
SLASH),
null,
configs);
@SuppressWarnings("unchecked")
final Set<String> newConfigs = (Set<String>) this.executeRequest(request, Set.class, String.class);
return newConfigs;
}
/**
* Delete the all configuration files from a given application.
*
* @param id The id of the application to delete the configuration files
* from. Not null/empty/blank.
* @return Empty set if successful
* @throws GenieException For any other error.
*/
public Set<String> removeAllConfigsForApplication(
final String id) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.DELETE,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "configs"},
SLASH),
null,
null);
@SuppressWarnings("unchecked")
final Set<String> configs = (Set<String>) this.executeRequest(request, Set.class, String.class);
return configs;
}
/**
* Add some more jar files to a given application.
*
* @param id The id of the application to add jars to. Not
* Null/empty/blank.
* @param jars The jar files to add. Not null or empty.
* @return The new set of jar files for the given application.
* @throws GenieException For any other error.
*/
public Set<String> addJarsToApplication(
final String id,
final Set<String> jars) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
if (jars == null || jars.isEmpty()) {
throw new GeniePreconditionException("Missing required parameter: jars");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.POST,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "jars"},
SLASH),
null,
jars);
@SuppressWarnings("unchecked")
final Set<String> newJars = (Set<String>) this.executeRequest(request, Set.class, String.class);
return newJars;
}
/**
* Get the active set of jar files for the given application.
*
* @param id The id of the application to get jars for. Not
* Null/empty/blank.
* @return The set of jar files for the given application.
* @throws GenieException For any other error.
*/
public Set<String> getJarsForApplication(final String id) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.GET,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "jars"},
SLASH),
null,
null);
@SuppressWarnings("unchecked")
final Set<String> jars = (Set<String>) this.executeRequest(request, Set.class, String.class);
return jars;
}
/**
* Update the jar files for a given application.
*
* @param id The id of the application to update the jar files
* for. Not null/empty/blank.
* @param jars The jar files to replace existing jar
* files with. Not null.
* @return The new set of application jars.
* @throws GenieException For any other error.
*/
public Set<String> updateJarsForApplication(
final String id,
final Set<String> jars) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
if (jars == null) {
throw new GeniePreconditionException("Missing required parameter: jars");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.PUT,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "jars"},
SLASH),
null,
jars);
@SuppressWarnings("unchecked")
final Set<String> newJars = (Set<String>) this.executeRequest(request, Set.class, String.class);
return newJars;
}
/**
* Delete the all jar files from a given application.
*
* @param id The id of the application to delete the jar files
* from. Not null/empty/blank.
* @return Empty set if successful
* @throws GenieException For any other error.
*/
public Set<String> removeAllJarsForApplication(
final String id) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.DELETE,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "jars"},
SLASH),
null,
null);
@SuppressWarnings("unchecked")
final Set<String> jars = (Set<String>) this.executeRequest(request, Set.class, String.class);
return jars;
}
/**
* Get all the commands this application is associated with.
*
* @param id The id of the application to get the commands for. Not
* NULL/empty/blank.
* @return The set of commands.
* @throws GenieException For any error.
*/
public Set<Command> getCommandsForApplication(
final String id) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.GET,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "commands"},
SLASH),
null,
null);
@SuppressWarnings("unchecked")
final Set<Command> commands = (Set<Command>) this.executeRequest(request, Set.class, Command.class);
return commands;
}
/**
* Add some more tags to a given application.
*
* @param id The id of the application to add tags to. Not
* Null/empty/blank.
* @param tags The tags to add. Not null or empty.
* @return The new set of tags for the given application.
* @throws GenieException For any other error.
*/
public Set<String> addTagsToApplication(
final String id,
final Set<String> tags) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
if (tags == null || tags.isEmpty()) {
throw new GeniePreconditionException("Missing required parameter: tags");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.POST,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "tags"},
SLASH),
null,
tags);
@SuppressWarnings("unchecked")
final Set<String> newTags = (Set<String>) this.executeRequest(request, Set.class, String.class);
return newTags;
}
/**
* Get the active set of tags for the given application.
*
* @param id The id of the application to get tags for. Not
* Null/empty/blank.
* @return The set of tags for the given application.
* @throws GenieException For any other error.
*/
public Set<String> getTagsForApplication(final String id) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.GET,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "tags"},
SLASH),
null,
null);
@SuppressWarnings("unchecked")
final Set<String> tags = (Set<String>) this.executeRequest(request, Set.class, String.class);
return tags;
}
/**
* Update the tags for a given application.
*
* @param id The id of the application to update the tags for.
* Not null/empty/blank.
* @param tags The tags to replace existing tag
* files with. Not null.
* @return The new set of application tags.
* @throws GenieException For any other error.
*/
public Set<String> updateTagsForApplication(
final String id,
final Set<String> tags) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
if (tags == null) {
throw new GeniePreconditionException("Missing required parameter: tags");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.PUT,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "tags"},
SLASH),
null,
tags);
@SuppressWarnings("unchecked")
final Set<String> newTags = (Set<String>) this.executeRequest(request, Set.class, String.class);
return newTags;
}
/**
* Delete all the tags from a given application.
*
* @param id The id of the application to delete the tags from.
* Not null/empty/blank.
* @return Empty set if successful
* @throws GenieException For any error.
*/
public Set<String> removeAllTagsForApplication(
final String id) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.DELETE,
StringUtils.join(
new String[]{BASE_CONFIG_APPLICATION_REST_URL, id, "tags"},
SLASH),
null,
null);
@SuppressWarnings("unchecked")
final Set<String> tags = (Set<String>) this.executeRequest(request, Set.class, String.class);
return tags;
}
/**
* Remove tag from a given application.
*
* @param id The id of the application to delete the tag from. Not
* null/empty/blank.
* @param tag The tag to remove. Not null/empty/blank.
* @return The tag for the application.
* @throws GenieException For any error.
*/
public Set<String> removeTagForApplication(
final String id,
final String tag) throws GenieException {
if (StringUtils.isBlank(id)) {
throw new GeniePreconditionException("Missing required parameter: id");
}
final HttpRequest request = BaseGenieClient.buildRequest(
Verb.DELETE,
StringUtils.join(
new String[]{
BASE_CONFIG_APPLICATION_REST_URL,
id,
"tags",
tag
},
SLASH),
null,
null);
@SuppressWarnings("unchecked")
final Set<String> tags = (Set<String>) this.executeRequest(request, Set.class, String.class);
return tags;
}
}