Add setProjectConfig for apiv11

This commit is contained in:
Greg Schueler 2014-03-07 10:07:31 -08:00
parent 92eb7acc15
commit e548c14b24
11 changed files with 230 additions and 26 deletions

View file

@ -16,19 +16,10 @@
package org.rundeck.api;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.*;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
@ -272,6 +263,27 @@ class ApiCall {
public <T> T post(ApiPathBuilder apiPath, XmlNodeParser<T> parser) throws RundeckApiException,
RundeckApiLoginException, RundeckApiTokenException {
HttpPost httpPost = new HttpPost(client.getUrl() + client.getApiEndpoint() + apiPath);
return requestWithEntity(apiPath, parser, httpPost);
}
/**
* Execute an HTTP PUT request to the RunDeck instance, on the given path. We will login first, and then execute
* the API call. At the end, the given parser will be used to convert the response to a more useful result object.
*
* @param apiPath on which we will make the HTTP request - see {@link ApiPathBuilder}
* @param parser used to parse the response
* @return the result of the call, as formatted by the parser
* @throws RundeckApiException in case of error when calling the API
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
*/
public <T> T put(ApiPathBuilder apiPath, XmlNodeParser<T> parser) throws RundeckApiException,
RundeckApiLoginException, RundeckApiTokenException {
HttpPut httpPut = new HttpPut(client.getUrl() + client.getApiEndpoint() + apiPath);
return requestWithEntity(apiPath, parser, httpPut);
}
private <T> T requestWithEntity(ApiPathBuilder apiPath, XmlNodeParser<T> parser, HttpEntityEnclosingRequestBase
httpPost) {
if(null!= apiPath.getAccept()) {
httpPost.setHeader("Accept", apiPath.getAccept());
}
@ -344,7 +356,7 @@ class ApiCall {
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
*/
private ByteArrayInputStream execute(HttpRequestBase request) throws RundeckApiException, RundeckApiLoginException,
private ByteArrayInputStream execute(HttpUriRequest request) throws RundeckApiException, RundeckApiLoginException,
RundeckApiTokenException {
HttpClient httpClient = instantiateHttpClient();
try {

View file

@ -27,6 +27,7 @@ import org.apache.commons.lang.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.dom4j.Document;
import org.rundeck.api.generator.XmlDocumentGenerator;
import org.rundeck.api.util.ParametersUtil;
/**
@ -280,6 +281,18 @@ class ApiPathBuilder {
}
return this;
}
/**
* When POSTing a request, add the given XMl Document as the content of the request.
*
* @param document XMl document to send
* @return this, for method chaining
*/
public ApiPathBuilder xml(final XmlDocumentGenerator document) {
if (document != null) {
xmlDocument = document.generateXmlDocument();
}
return this;
}
/**
* @return all attachments to be POSTed, with their names

View file

@ -25,6 +25,7 @@ import org.rundeck.api.RundeckApiException.RundeckApiLoginException;
import org.rundeck.api.RundeckApiException.RundeckApiTokenException;
import org.rundeck.api.domain.*;
import org.rundeck.api.domain.RundeckExecution.ExecutionStatus;
import org.rundeck.api.generator.ProjectConfigGenerator;
import org.rundeck.api.generator.ProjectGenerator;
import org.rundeck.api.parser.*;
import org.rundeck.api.query.ExecutionQuery;
@ -379,6 +380,28 @@ public class RundeckClient implements Serializable {
return new ApiCall(this)
.get(new ApiPathBuilder("/project/", projectName, "/config"), new ProjectConfigParser("/config"));
}
/**
* Return the configuration of a project
*
* @param projectName name of the project - mandatory
*
* @return a {@link ProjectConfig} instance - won't be null
*
* @throws RundeckApiException in case of error when calling the API (non-existent project with this name)
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
* @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace)
*/
public ProjectConfig setProjectConfig(String projectName, Map<String,String> configuration) throws
RundeckApiException, RundeckApiLoginException,
RundeckApiTokenException, IllegalArgumentException {
AssertUtil.notBlank(projectName, "projectName is mandatory to get the config of a project !");
return new ApiCall(this)
.put(new ApiPathBuilder("/project/", projectName, "/config")
.xml(new ProjectConfigGenerator(new ProjectConfig(configuration)))
, new ProjectConfigParser("/config"));
}
private Document projectDocument(String projectName, Map<String, String> configuration) {
RundeckProject project = new RundeckProject();
@ -386,7 +409,7 @@ public class RundeckClient implements Serializable {
if (null != configuration) {
project.setProjectConfig(new ProjectConfig(configuration));
}
return new ProjectGenerator(project).generate();
return new ProjectGenerator(project).generateXmlDocument();
}
/*

View file

@ -0,0 +1,18 @@
package org.rundeck.api.generator;
import org.dom4j.Document;
import org.dom4j.DocumentFactory;
/**
* BaseDocGenerator generates a document using the element as the root.
*
* @author greg
* @since 2014-02-27
*/
public abstract class BaseDocGenerator implements XmlDocumentGenerator {
@Override
public Document generateXmlDocument() {
return DocumentFactory.getInstance().createDocument(generateXmlElement());
}
}

View file

@ -0,0 +1,34 @@
package org.rundeck.api.generator;
import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.rundeck.api.domain.ProjectConfig;
/**
* ProjectConfigGenerator is ...
*
* @author greg
* @since 2014-02-27
*/
public class ProjectConfigGenerator extends BaseDocGenerator {
private ProjectConfig config;
public ProjectConfigGenerator(ProjectConfig config) {
this.config = config;
}
@Override
public Element generateXmlElement() {
Element configEl = DocumentFactory.getInstance().createElement("config");
if (null != config.getProperties()) {
for (String s : config.getProperties().keySet()) {
Element property = configEl.addElement("property");
property.addAttribute("key", s);
property.addAttribute("value", config.getProperties().get(s));
}
}
return configEl;
}
}

View file

@ -12,27 +12,21 @@ import org.rundeck.api.domain.RundeckProject;
* @author greg
* @since 2014-02-27
*/
public class ProjectGenerator {
public class ProjectGenerator extends BaseDocGenerator {
RundeckProject project;
public ProjectGenerator(RundeckProject project) {
this.project = project;
}
public Document generate() {
Document projectDom = DocumentFactory.getInstance().createDocument();
Element rootElem = projectDom.addElement("project");
@Override
public Element generateXmlElement() {
Element rootElem = DocumentFactory.getInstance().createElement("project");
rootElem.addElement("name").setText(project.getName());
ProjectConfig configuration = project.getProjectConfig();
if (null != configuration) {
Element config = rootElem.addElement("config");
for (String s : configuration.getProperties().keySet()) {
Element property = config.addElement("property");
property.addAttribute("key", s);
property.addAttribute("value", configuration.getProperties().get(s));
}
}
return projectDom;
rootElem.add(new ProjectConfigGenerator(configuration).generateXmlElement());
}
return rootElem;
}
}

View file

@ -0,0 +1,29 @@
package org.rundeck.api.generator;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
/**
* XmlDocumentGenerator is ...
*
* @author greg
* @since 2014-02-27
*/
public interface XmlDocumentGenerator {
/**
* Generate the XML {@link org.dom4j.Node}
*
* @return any object holding the converted value
*/
Element generateXmlElement();
/**
* Generate the XML {@link org.dom4j.Node}
*
* @param node
*
* @return any object holding the converted value
*/
Document generateXmlDocument();
}

View file

@ -101,6 +101,20 @@ public class RundeckClientTest {
Assert.assertEquals(9,config.getProperties().size());
Assert.assertEquals("monkey1", config.getProperties().get("project.name"));
}
@Test
@Betamax(tape = "set_project_configv11")
public void setProjectConfig() throws Exception {
HashMap<String, String> config = new HashMap<String, String>();
config.put("alphabetty", "spaghetti");
config.put("blha.blee", "a big amazing thingy so there.");
ProjectConfig result = createClient(TEST_TOKEN_6, 11).setProjectConfig("monkey1", config);
Assert.assertNotNull(result);
Assert.assertNotNull(result.getProperties());
Assert.assertEquals(3, result.getProperties().size());
Assert.assertEquals("monkey1", result.getProperties().get("project.name"));
Assert.assertEquals("spaghetti", result.getProperties().get("alphabetty"));
Assert.assertEquals("a big amazing thingy so there.", result.getProperties().get("blha.blee"));
}
@Test
@Betamax(tape = "get_history")

View file

@ -0,0 +1,41 @@
package org.rundeck.api.generator;
import junit.framework.Assert;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
import org.rundeck.api.domain.ProjectConfig;
import org.rundeck.api.domain.RundeckProject;
import java.io.UnsupportedEncodingException;
/**
* ProjectConfigGeneratorTest is ...
*
* @author greg
* @since 2014-02-27
*/
public class ProjectConfigGeneratorTest {
@Test
public void generate() throws Exception {
ProjectConfig config = new ProjectConfig();
config.setProperty("abc", "123");
config.setProperty("monkey.bonanza", "pale\ncomparison");
Document doc = new ProjectConfigGenerator(config).generateXmlDocument();
XMLWriter xmlWriter = new XMLWriter(System.out);
xmlWriter.write(doc);
xmlWriter.flush();
Element configElement = doc.getRootElement();
Assert.assertEquals("config", configElement.getName());
Assert.assertNotNull(configElement.selectSingleNode("property[1]"));
Assert.assertEquals("abc", configElement.selectSingleNode("property[1]/@key").getText());
Assert.assertEquals("123", configElement.selectSingleNode("property[1]/@value").getText());
Assert.assertNotNull(configElement.selectSingleNode("property[2]"));
Assert.assertEquals("monkey.bonanza", configElement.selectSingleNode("property[2]/@key").getText());
Assert.assertEquals("pale\ncomparison", configElement.selectSingleNode("property[2]/@value").getText());
}
}

View file

@ -17,7 +17,7 @@ public class ProjectGeneratorTest {
RundeckProject project = new RundeckProject();
project.setName("monkey1");
Document doc = new ProjectGenerator(project).generate();
Document doc = new ProjectGenerator(project).generateXmlDocument();
Assert.assertEquals("project", doc.getRootElement().getName());
Assert.assertNotNull(doc.selectSingleNode("/project/name"));
Assert.assertEquals("monkey1", doc.selectSingleNode("/project/name").getText());

View file

@ -0,0 +1,26 @@
!tape
name: set_project_configv11
interactions:
- recorded: 2014-02-27T21:00:27.197Z
request:
method: PUT
uri: http://rundeck.local:4440/api/11/project/monkey1/config
headers:
Accept: text/xml
Content-Type: application/xml
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
Transfer-Encoding: chunked
User-Agent: RunDeck API Java Client 11
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
response:
status: 200
headers:
Content-Type: application/xml;charset=UTF-8
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Server: Jetty(7.6.0.v20120127)
Set-Cookie: JSESSIONID=19npj7cd0hpm71nfljn7nlbvh8;Path=/
X-Rundeck-API-Version: '11'
X-Rundeck-API-XML-Response-Wrapper: 'false'
body: !!binary |-
PGNvbmZpZz4KICA8cHJvcGVydHkga2V5PSdwcm9qZWN0Lm5hbWUnIHZhbHVlPSdtb25rZXkxJyAvPgogIDxwcm9wZXJ0eSBrZXk9J2FscGhhYmV0dHknIHZhbHVlPSdzcGFnaGV0dGknIC8+CiAgPHByb3BlcnR5IGtleT0nYmxoYS5ibGVlJyB2YWx1ZT0nYSBiaWcgYW1hemluZyB0aGluZ3kgc28gdGhlcmUuJyAvPgo8L2NvbmZpZz4=