Issue 907: initial jenkins api

This commit is contained in:
Adrian Cole 2012-04-24 10:54:03 -07:00
parent 95347a5b96
commit 96b9e8c8b0
28 changed files with 1721 additions and 0 deletions

123
labs/jenkins/pom.xml Normal file
View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to jclouds, Inc. (jclouds) under one or more
contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. jclouds licenses this file
to you 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<version>1.5.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds.labs</groupId>
<artifactId>jenkins</artifactId>
<name>jcloud jenkins api</name>
<description>jclouds components to access an implementation of Jenkins</description>
<packaging>bundle</packaging>
<properties>
<test.jenkins.endpoint>http://localhost:8080</test.jenkins.endpoint>
<test.jenkins.api-version>1.0</test.jenkins.api-version>
<test.jenkins.build-version>1.460</test.jenkins.build-version>
<test.jenkins.identity>ANONYMOUS</test.jenkins.identity>
<test.jenkins.credential>ANONYMOUS</test.jenkins.credential>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-slf4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemPropertyVariables>
<test.jenkins.endpoint>${test.jenkins.endpoint}</test.jenkins.endpoint>
<test.jenkins.api-version>${test.jenkins.api-version}</test.jenkins.api-version>
<test.jenkins.build-version>${test.jenkins.build-version}</test.jenkins.build-version>
<test.jenkins.identity>${test.jenkins.identity}</test.jenkins.identity>
<test.jenkins.credential>${test.jenkins.credential}</test.jenkins.credential>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Export-Package>org.jclouds.jenkins.v1*;version="${project.version}"</Export-Package>
<Import-Package>
org.jclouds.rest.internal;version="${project.version}",
org.jclouds*;version="${project.version}",
*
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,97 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1;
import java.net.URI;
import java.util.Properties;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.jenkins.v1.config.JenkinsRestClientModule;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.internal.BaseRestApiMetadata;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
import com.google.inject.Module;
/**
* Implementation of {@link ApiMetadata} for Jenkins 1.0 API
*
* @author Adrian Cole
*/
public class JenkinsApiMetadata extends BaseRestApiMetadata {
public static final String ANONYMOUS_IDENTITY = "ANONYMOUS";
/** The serialVersionUID */
private static final long serialVersionUID = 6725672099385580694L;
public static final TypeToken<RestContext<JenkinsClient, JenkinsAsyncClient>> CONTEXT_TOKEN = new TypeToken<RestContext<JenkinsClient, JenkinsAsyncClient>>() {
private static final long serialVersionUID = -5070937833892503232L;
};
@Override
public Builder toBuilder() {
return new Builder().fromApiMetadata(this);
}
public JenkinsApiMetadata() {
this(new Builder());
}
protected JenkinsApiMetadata(Builder builder) {
super(builder);
}
public static Properties defaultProperties() {
Properties properties = BaseRestApiMetadata.defaultProperties();
return properties;
}
public static class Builder extends BaseRestApiMetadata.Builder {
protected Builder() {
super(JenkinsClient.class, JenkinsAsyncClient.class);
id("jenkins")
.name("Jenkins API")
.identityName("Username (or " + ANONYMOUS_IDENTITY + " if anonymous)")
.defaultIdentity(ANONYMOUS_IDENTITY)
.credentialName("Password")
.defaultCredential(ANONYMOUS_IDENTITY)
.documentation(URI.create("https://wiki.jenkins-ci.org/display/JENKINS/Remote+access+API"))
.version("1.0")
.defaultEndpoint("http://localhost:8080")
.defaultProperties(JenkinsApiMetadata.defaultProperties())
.defaultModules(ImmutableSet.<Class<? extends Module>>of(JenkinsRestClientModule.class));
}
@Override
public JenkinsApiMetadata build() {
return new JenkinsApiMetadata(this);
}
@Override
public Builder fromApiMetadata(ApiMetadata in) {
super.fromApiMetadata(in);
return this;
}
}
}

View File

@ -0,0 +1,41 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1;
import org.jclouds.jenkins.v1.features.ComputerAsyncClient;
import org.jclouds.rest.annotations.Delegate;
/**
* Provides asynchronous access to Jenkins via their REST API.
* <p/>
*
* @see JenkinsClient
* @see <a href="https://wiki.jenkins-ci.org/display/JENKINS/Remote+access+API">api doc</a>
* @author Adrian Cole
*/
public interface JenkinsAsyncClient {
/**
* Provides asynchronous access to Computer features.
*/
@Delegate
ComputerAsyncClient getComputerClient();
}

View File

@ -0,0 +1,44 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.jenkins.v1.features.ComputerClient;
import org.jclouds.rest.annotations.Delegate;
/**
* Provides synchronous access to Jenkins.
* <p/>
*
* @see JenkinsAsyncClient
* @see <a href="https://wiki.jenkins-ci.org/display/JENKINS/Remote+access+API">api doc</a>
* @author Adrian Cole
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface JenkinsClient {
/**
* Provides synchronous access to Computer features.
*/
@Delegate
ComputerClient getComputerClient();
}

View File

@ -0,0 +1,28 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.config;
/**
* Configuration properties and constants used in Jenkins connections.
*
* @author Adrian Cole
*/
public class JenkinsProperties {
}

View File

@ -0,0 +1,59 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.config;
import java.util.Map;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.jenkins.v1.JenkinsAsyncClient;
import org.jclouds.jenkins.v1.JenkinsClient;
import org.jclouds.jenkins.v1.features.ComputerAsyncClient;
import org.jclouds.jenkins.v1.features.ComputerClient;
import org.jclouds.jenkins.v1.handlers.JenkinsErrorHandler;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
import com.google.common.collect.ImmutableMap;
/**
* Configures the Jenkins connection.
*
* @author Adrian Cole
*/
@ConfiguresRestClient
public class JenkinsRestClientModule extends RestClientModule<JenkinsClient, JenkinsAsyncClient> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
.put(ComputerClient.class, ComputerAsyncClient.class)
.build();
public JenkinsRestClientModule() {
super(DELEGATE_MAP);
}
@Override
protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(JenkinsErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(JenkinsErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(JenkinsErrorHandler.class);
}
}

View File

@ -0,0 +1,134 @@
package org.jclouds.jenkins.v1.domain;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
/**
* @author Adrian Cole
* @see <a
* href="http://ci.jruby.org/computer/api/">api
* doc</a>
*/
public class Computer implements Comparable<Computer> {
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return builder().fromComputerMetadata(this);
}
public static class Builder {
protected String displayName;
protected boolean idle;
protected boolean offline;
/**
* @see Computer#getDisplayName()
*/
public Builder displayName(String displayName) {
this.displayName = checkNotNull(displayName, "displayName");
return this;
}
/**
* @see Computer#isIdle()
*/
public Builder idle(boolean idle) {
this.idle = idle;
return this;
}
/**
* @see Computer#isOffline()
*/
public Builder offline(boolean offline) {
this.offline = offline;
return this;
}
public Computer build() {
return new Computer(displayName, idle, offline);
}
public Builder fromComputerMetadata(Computer from) {
return displayName(from.getDisplayName()).idle(from.isIdle()).offline(from.isOffline());
}
}
protected final String displayName;
protected final boolean idle;
protected final boolean offline;
public Computer(String displayName, boolean idle, boolean offline) {
this.displayName = checkNotNull(displayName, "displayName");
this.idle = idle;
this.offline = offline;
}
/**
*
* @return the displayName of the computer
*/
public String getDisplayName() {
return displayName;
}
/**
*
* @return the number of objects in the computer
*/
public boolean isIdle() {
return idle;
}
/**
* @return the total offline stored in this computer
*/
public boolean isOffline() {
return offline;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object instanceof Computer) {
final Computer other = Computer.class.cast(object);
return equal(getDisplayName(), other.getDisplayName()) && equal(isIdle(), other.isIdle())
&& equal(isOffline(), other.isOffline());
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hashCode(getDisplayName(), isIdle(), isOffline());
}
@Override
public String toString() {
return string().toString();
}
protected ToStringHelper string() {
return toStringHelper("").add("displayName", getDisplayName()).add("idle", isIdle()).add("offline", isOffline());
}
@Override
public int compareTo(Computer that) {
if (that == null)
return 1;
if (this == that)
return 0;
return this.getDisplayName().compareTo(that.getDisplayName());
}
}

View File

@ -0,0 +1,168 @@
package org.jclouds.jenkins.v1.domain;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableSet;
import com.google.gson.annotations.SerializedName;
/**
* @author Adrian Cole
* @see <a
* href="http://ci.jruby.org/computer/api/">api
* doc</a>
*/
public class ComputerView implements Comparable<ComputerView> {
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return builder().fromComputerMetadata(this);
}
public static class Builder {
protected String displayName;
protected int busyExecutors;
protected int totalExecutors;
protected Set<Computer> computers = ImmutableSet.of();
/**
* @see ComputerView#getDisplayName()
*/
public Builder displayName(String displayName) {
this.displayName = checkNotNull(displayName, "displayName");
return this;
}
/**
* @see ComputerView#getBusyExecutors()
*/
public Builder busyExecutors(int busyExecutors) {
this.busyExecutors = busyExecutors;
return this;
}
/**
* @see ComputerView#getTotalExecutors()
*/
public Builder totalExecutors(int totalExecutors) {
this.totalExecutors = totalExecutors;
return this;
}
/**
* @see ComputerView#getLinks()
*/
public Builder computers(Computer... computers) {
return computers(ImmutableSet.copyOf(checkNotNull(computers, "computers")));
}
/**
* @see ComputerView#getLinks()
*/
public Builder computers(Set<Computer> computers) {
this.computers = ImmutableSet.copyOf(checkNotNull(computers, "computers"));
return this;
}
public ComputerView build() {
return new ComputerView(displayName, busyExecutors, totalExecutors, computers);
}
public Builder fromComputerMetadata(ComputerView from) {
return displayName(from.getDisplayName()).busyExecutors(from.getBusyExecutors()).totalExecutors(from.getTotalExecutors()).computers(from.getComputers());
}
}
protected final String displayName;
protected final int busyExecutors;
protected final int totalExecutors;
@SerializedName("computer")
protected final Set<Computer> computers;
public ComputerView(String displayName, int busyExecutors, int totalExecutors, Set<Computer> computers) {
this.displayName = checkNotNull(displayName, "displayName");
this.busyExecutors = busyExecutors;
this.totalExecutors = totalExecutors;
this.computers = ImmutableSet.copyOf(checkNotNull(computers, "computers"));
}
/**
*
* @return the displayName of the computer
*/
public String getDisplayName() {
return displayName;
}
/**
*
* @return the number of objects in the computer
*/
public int getBusyExecutors() {
return busyExecutors;
}
/**
* @return the total totalExecutors stored in this computer
*/
public int getTotalExecutors() {
return totalExecutors;
}
/**
* @return the computers in this set
*/
//TODO: create type adapter for gson that understands ForwardingSet so that we can implement the Set interface
public Set<Computer> getComputers() {
return computers;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object instanceof ComputerView) {
final ComputerView other = ComputerView.class.cast(object);
return equal(getDisplayName(), other.getDisplayName()) && equal(getBusyExecutors(), other.getBusyExecutors())
&& equal(getTotalExecutors(), other.getTotalExecutors()) && equal(getComputers(), other.getComputers());
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hashCode(getDisplayName(), getBusyExecutors(), getTotalExecutors(), getComputers());
}
@Override
public String toString() {
return string().toString();
}
protected ToStringHelper string() {
return toStringHelper("").add("displayName", getDisplayName()).add("busyExecutors", getBusyExecutors()).add(
"totalExecutors", getTotalExecutors()).add("computers", getComputers());
}
@Override
public int compareTo(ComputerView that) {
if (that == null)
return 1;
if (this == that)
return 0;
return this.getDisplayName().compareTo(that.getDisplayName());
}
}

View File

@ -0,0 +1,64 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.features;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.jenkins.v1.domain.Computer;
import org.jclouds.jenkins.v1.domain.ComputerView;
import org.jclouds.jenkins.v1.filters.BasicAuthenticationUnlessAnonymous;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Computer Services
*
* @see ComputerClient
* @author Adrian Cole
* @see <a href=
* "http://ci.jruby.org/computer/api/"
* >api doc</a>
*/
@RequestFilters(BasicAuthenticationUnlessAnonymous.class)
public interface ComputerAsyncClient {
/**
* @see ComputerClient#getComputerView
*/
@GET
@Path("/computer/api/json")
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<ComputerView> getComputerView();
/**
* @see ComputerClient#getComputer
*/
@GET
@Path("/computer/{displayName}/api/json")
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Computer> getComputer(@PathParam("displayName") String displayName);
}

View File

@ -0,0 +1,48 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.jenkins.v1.domain.Computer;
import org.jclouds.jenkins.v1.domain.ComputerView;
/**
* Computer Services
*
* @see ComputerAsyncClient
* @author Adrian Cole
* @see <a href= "http://ci.jruby.org/computer/api/" >api doc</a>
*/
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
public interface ComputerClient {
/**
* @return overview of all configured computers
*/
ComputerView getComputerView();
/**
*
* @param displayName display name of the computer
* @return computer or null if not found
*/
Computer getComputer(String displayName);
}

View File

@ -0,0 +1,56 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.filters;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.jenkins.v1.JenkinsApiMetadata;
import org.jclouds.rest.annotations.Identity;
import com.google.common.base.Optional;
/**
* @author Adrian Cole
*
*/
@Singleton
public class BasicAuthenticationUnlessAnonymous implements HttpRequestFilter {
private final Optional<BasicAuthentication> auth;
@Inject
public BasicAuthenticationUnlessAnonymous(@Identity String user, BasicAuthentication auth) {
this.auth = JenkinsApiMetadata.ANONYMOUS_IDENTITY.equals(checkNotNull(user, "user")) ? Optional
.<BasicAuthentication> absent() : Optional.of(checkNotNull(auth, "auth"));
}
@Override
public HttpRequest filter(HttpRequest request) throws HttpException {
if (auth.isPresent())
return auth.get().filter(request);
return request;
}
}

View File

@ -0,0 +1,66 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.handlers;
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
import javax.inject.Singleton;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
/**
* This will parse and set an appropriate exception on the command object.
*
* @author Adrian Cole
*
*/
// TODO: is there error spec someplace? let's type errors, etc.
@Singleton
public class JenkinsErrorHandler implements HttpErrorHandler {
public void handleError(HttpCommand command, HttpResponse response) {
// it is important to always read fully and close streams
byte[] data = closeClientButKeepContentStream(response);
String message = data != null ? new String(data) : null;
Exception exception = message != null ? new HttpResponseException(command, response, message)
: new HttpResponseException(command, response);
message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(),
response.getStatusLine());
switch (response.getStatusCode()) {
case 400:
break;
case 401:
case 403:
exception = new AuthorizationException(message, exception);
break;
case 404:
if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
exception = new ResourceNotFoundException(message, exception);
}
break;
}
command.setException(exception);
}
}

View File

@ -0,0 +1 @@
org.jclouds.jenkins.v1.JenkinsApiMetadata

View File

@ -0,0 +1,37 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1;
import org.jclouds.View;
import org.jclouds.apis.internal.BaseApiMetadataTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "JenkinsApiMetadataTest")
public class JenkinsApiMetadataTest extends BaseApiMetadataTest {
public JenkinsApiMetadataTest() {
super(new JenkinsApiMetadata(), ImmutableSet.<TypeToken<? extends View>> of());
}
}

View File

@ -0,0 +1,98 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reportMatcher;
import static org.easymock.EasyMock.verify;
import java.net.URI;
import org.easymock.IArgumentMatcher;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payloads;
import org.jclouds.jenkins.v1.handlers.JenkinsErrorHandler;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.util.Strings2;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "JenkinsErrorHandlerTest")
public class JenkinsErrorHandlerTest {
@Test
public void test404WithHTMLDoesntBustParserAndMakesResourceNotFoundException() {
assertCodeMakes("GET", URI
.create("http://ci.jruby.org/computer/master/api/json"),
404, "Not Found", "<html></html>", ResourceNotFoundException.class);
}
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content,
Class<? extends Exception> expected) {
assertCodeMakes(method, uri, statusCode, message, "text/plain", content, expected);
}
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
String content, Class<? extends Exception> expected) {
JenkinsErrorHandler function = new JenkinsErrorHandler();
HttpCommand command = createMock(HttpCommand.class);
HttpRequest request = new HttpRequest(method, uri);
HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Strings2
.toInputStream(content)));
response.getPayload().getContentMetadata().setContentType(contentType);
expect(command.getCurrentRequest()).andReturn(request).atLeastOnce();
command.setException(classEq(expected));
replay(command);
function.handleError(command, response);
verify(command);
}
public static Exception classEq(final Class<? extends Exception> in) {
reportMatcher(new IArgumentMatcher() {
@Override
public void appendTo(StringBuffer buffer) {
buffer.append("classEq(");
buffer.append(in);
buffer.append(")");
}
@Override
public boolean matches(Object arg) {
return arg.getClass() == in;
}
});
return null;
}
}

View File

@ -0,0 +1,77 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.features;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.jenkins.v1.JenkinsClient;
import org.jclouds.jenkins.v1.internal.BaseJenkinsClientExpectTest;
import org.jclouds.jenkins.v1.parse.ParseComputerTest;
import org.jclouds.jenkins.v1.parse.ParseComputerViewTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ComputerClientExpectTest")
public class ComputerClientExpectTest extends BaseJenkinsClientExpectTest {
public void testGetComputerViewWhenResponseIs2xx() {
HttpRequest getComputerView = HttpRequest
.builder()
.method("GET")
.endpoint(URI.create("http://localhost:8080/computer/api/json"))
.headers(
ImmutableMultimap.<String, String> builder().put("Accept", "application/json")
.put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build()).build();
HttpResponse getComputerViewResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/computerview.json")).build();
JenkinsClient clientWhenServersExist = requestSendsResponse(getComputerView, getComputerViewResponse);
assertEquals(clientWhenServersExist.getComputerClient().getComputerView().toString(),
new ParseComputerViewTest().expected().toString());
}
public void testGetComputerWhenResponseIs2xx() {
HttpRequest getComputer = HttpRequest
.builder()
.method("GET")
.endpoint(URI.create("http://localhost:8080/computer/Ruboto/api/json"))
.headers(
ImmutableMultimap.<String, String> builder().put("Accept", "application/json")
.put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build()).build();
HttpResponse getComputerResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/computer.json")).build();
JenkinsClient clientWhenServersExist = requestSendsResponse(getComputer, getComputerResponse);
assertEquals(clientWhenServersExist.getComputerClient().getComputer("Ruboto").toString(),
new ParseComputerTest().expected().toString());
}
}

View File

@ -0,0 +1,50 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.features;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import org.jclouds.jenkins.v1.domain.Computer;
import org.jclouds.jenkins.v1.domain.ComputerView;
import org.jclouds.jenkins.v1.internal.BaseJenkinsClientLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "ComputerClientLiveTest")
public class ComputerClientLiveTest extends BaseJenkinsClientLiveTest {
public void testGetComputerView(){
ComputerView view = getClient().getComputerView();
assertNotNull(view);
assertNotNull(view.getDisplayName());
for (Computer computerFromView : view.getComputers()) {
assertNotNull(computerFromView.getDisplayName());
Computer computerFromGetRequest = getClient().getComputer(computerFromView.getDisplayName());
assertEquals(computerFromGetRequest, computerFromView);
}
}
private ComputerClient getClient() {
return context.getApi().getComputerClient();
}
}

View File

@ -0,0 +1,62 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.filters;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.jenkins.v1.JenkinsApiMetadata;
import org.jclouds.jenkins.v1.JenkinsClient;
import org.jclouds.jenkins.v1.internal.BaseJenkinsClientExpectTest;
import org.jclouds.jenkins.v1.parse.ParseComputerViewTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "BasicAuthenticationUnlessAnonymousExpectTest")
public class BasicAuthenticationUnlessAnonymousExpectTest extends BaseJenkinsClientExpectTest {
public BasicAuthenticationUnlessAnonymousExpectTest(){
identity = JenkinsApiMetadata.ANONYMOUS_IDENTITY;
}
public void testWhenIdentityIsAnonymousNoAuthorizationHeader() {
HttpRequest getComputerView = HttpRequest
.builder()
.method("GET")
.endpoint(URI.create("http://localhost:8080/computer/api/json"))
.headers(
ImmutableMultimap.<String, String> builder().put("Accept", "application/json").build()).build();
HttpResponse getComputerViewResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/computerview.json")).build();
JenkinsClient clientWhenServersExist = requestSendsResponse(getComputerView, getComputerViewResponse);
assertEquals(clientWhenServersExist.getComputerClient().getComputerView().toString(),
new ParseComputerViewTest().expected().toString());
}
}

View File

@ -0,0 +1,39 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.internal;
import java.util.Properties;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.jenkins.v1.JenkinsAsyncClient;
import com.google.common.base.Function;
import com.google.inject.Module;
/**
* Base class for writing KeyStone Rest Client Expect tests
*
* @author Adrian Cole
*/
public class BaseJenkinsAsyncClientExpectTest extends BaseJenkinsExpectTest<JenkinsAsyncClient> {
public JenkinsAsyncClient createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
return createInjector(fn, module, props).getInstance(JenkinsAsyncClient.class);
}
}

View File

@ -0,0 +1,30 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.internal;
import org.jclouds.jenkins.v1.JenkinsClient;
/**
* Base class for writing Jenkins Expect tests
*
* @author Adrian Cole
*/
public class BaseJenkinsClientExpectTest extends BaseJenkinsExpectTest<JenkinsClient> {
}

View File

@ -0,0 +1,64 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.internal;
import org.jclouds.apis.BaseContextLiveTest;
import org.jclouds.jenkins.v1.JenkinsApiMetadata;
import org.jclouds.jenkins.v1.JenkinsAsyncClient;
import org.jclouds.jenkins.v1.JenkinsClient;
import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.reflect.TypeToken;
/**
* Tests behavior of {@code JenkinsClient}
*
* @author Adrian Cole
*/
@Test(groups = "live")
public class BaseJenkinsClientLiveTest extends BaseContextLiveTest<RestContext<JenkinsClient, JenkinsAsyncClient>> {
public BaseJenkinsClientLiveTest() {
provider = "jenkins";
}
protected RestContext<JenkinsClient, JenkinsAsyncClient> jenkinsContext;
@BeforeGroups(groups = { "integration", "live" })
@Override
public void setupContext() {
super.setupContext();
jenkinsContext = context;
}
@AfterGroups(groups = "live")
protected void tearDown() {
if (jenkinsContext != null)
jenkinsContext.close();
}
@Override
protected TypeToken<RestContext<JenkinsClient, JenkinsAsyncClient>> contextType() {
return JenkinsApiMetadata.CONTEXT_TOKEN;
}
}

View File

@ -0,0 +1,32 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.internal;
import org.jclouds.rest.internal.BaseRestClientExpectTest;
/**
* Base class for writing Jenkins Expect tests
*
* @author Adrian Cole
*/
public class BaseJenkinsExpectTest<T> extends BaseRestClientExpectTest<T> {
public BaseJenkinsExpectTest() {
provider = "jenkins";
}
}

View File

@ -0,0 +1,49 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.parse;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import org.jclouds.jenkins.v1.domain.Computer;
import org.jclouds.json.BaseItemParserTest;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ParseComputerTest")
public class ParseComputerTest extends BaseItemParserTest<Computer> {
@Override
public String resource() {
return "/computer.json";
}
@Override
@Consumes(MediaType.APPLICATION_JSON)
public Computer expected() {
return Computer.builder()
.displayName("Ruboto")
.idle(true)
.offline(false)
.build();
}
}

View File

@ -0,0 +1,64 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.jclouds.jenkins.v1.parse;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import org.jclouds.jenkins.v1.domain.Computer;
import org.jclouds.jenkins.v1.domain.ComputerView;
import org.jclouds.json.BaseItemParserTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ParseComputerViewTest")
public class ParseComputerViewTest extends BaseItemParserTest<ComputerView> {
@Override
public String resource() {
return "/computerview.json";
}
@Override
@Consumes(MediaType.APPLICATION_JSON)
public ComputerView expected() {
return ComputerView.builder()
.displayName("nodes")
.totalExecutors(4)
.busyExecutors(0)
.computers(ImmutableSet.<Computer>builder()
.add(Computer.builder()
.displayName("master")
.idle(true)
.offline(false).build())
.add(Computer.builder()
.displayName("Ruboto")
.idle(true)
.offline(false).build())
.add(Computer.builder()
.displayName("winserver2008-x86")
.idle(true)
.offline(false).build()).build()).build();
}
}

View File

@ -0,0 +1,37 @@
{
"actions": [],
"displayName": "Ruboto",
"executors": [{}],
"icon": "computer.png",
"idle": true,
"jnlpAgent": true,
"launchSupported": false,
"loadStatistics": {},
"manualLaunchAllowed": true,
"monitorData": {
"hudson.node_monitors.SwapSpaceMonitor": {
"availablePhysicalMemory": 1697591296,
"availableSwapSpace": 5626036224,
"totalPhysicalMemory": 4157317120,
"totalSwapSpace": 6568271872
},
"hudson.node_monitors.ArchitectureMonitor": "Linux (amd64)",
"hudson.node_monitors.ResponseTimeMonitor": {
"average": 955
},
"hudson.node_monitors.TemporarySpaceMonitor": {
"size": 53646782464
},
"hudson.node_monitors.DiskSpaceMonitor": {
"size": 53646782464
},
"hudson.node_monitors.ClockMonitor": {
"diff": -309
}
},
"numExecutors": 1,
"offline": false,
"offlineCause": null,
"oneOffExecutors": [],
"temporarilyOffline": false
}

View File

@ -0,0 +1,114 @@
{
"busyExecutors": 0,
"computer": [{
"actions": [],
"displayName": "master",
"executors": [{}, {}],
"icon": "computer.png",
"idle": true,
"jnlpAgent": false,
"launchSupported": true,
"loadStatistics": {},
"manualLaunchAllowed": true,
"monitorData": {
"hudson.node_monitors.SwapSpaceMonitor": {
"availablePhysicalMemory": 1385115648,
"availableSwapSpace": 32208396288,
"totalPhysicalMemory": 8053207040,
"totalSwapSpace": 32218378240
},
"hudson.node_monitors.ArchitectureMonitor": "Linux (amd64)",
"hudson.node_monitors.ResponseTimeMonitor": {
"average": 1
},
"hudson.node_monitors.TemporarySpaceMonitor": {
"size": 6235500544
},
"hudson.node_monitors.DiskSpaceMonitor": {
"size": 79292284928
},
"hudson.node_monitors.ClockMonitor": {
"diff": 0
}
},
"numExecutors": 2,
"offline": false,
"offlineCause": null,
"oneOffExecutors": [],
"temporarilyOffline": false
}, {
"actions": [],
"displayName": "Ruboto",
"executors": [{}],
"icon": "computer.png",
"idle": true,
"jnlpAgent": true,
"launchSupported": false,
"loadStatistics": {},
"manualLaunchAllowed": true,
"monitorData": {
"hudson.node_monitors.SwapSpaceMonitor": {
"availablePhysicalMemory": 1684832256,
"availableSwapSpace": 5625421824,
"totalPhysicalMemory": 4157317120,
"totalSwapSpace": 6568271872
},
"hudson.node_monitors.ArchitectureMonitor": "Linux (amd64)",
"hudson.node_monitors.ResponseTimeMonitor": {
"average": 856
},
"hudson.node_monitors.TemporarySpaceMonitor": {
"size": 53648973824
},
"hudson.node_monitors.DiskSpaceMonitor": {
"size": 53648969728
},
"hudson.node_monitors.ClockMonitor": {
"diff": -462
}
},
"numExecutors": 1,
"offline": false,
"offlineCause": null,
"oneOffExecutors": [],
"temporarilyOffline": false
}, {
"actions": [],
"displayName": "winserver2008-x86",
"executors": [{}],
"icon": "computer.png",
"idle": true,
"jnlpAgent": true,
"launchSupported": false,
"loadStatistics": {},
"manualLaunchAllowed": true,
"monitorData": {
"hudson.node_monitors.SwapSpaceMonitor": {
"availablePhysicalMemory": 1117851648,
"availableSwapSpace": 1429299200,
"totalPhysicalMemory": 1781420032,
"totalSwapSpace": 1994350592
},
"hudson.node_monitors.ArchitectureMonitor": "Windows Server 2008 (x86)",
"hudson.node_monitors.ResponseTimeMonitor": {
"average": 1
},
"hudson.node_monitors.TemporarySpaceMonitor": {
"size": 19072663552
},
"hudson.node_monitors.DiskSpaceMonitor": {
"size": 19072663552
},
"hudson.node_monitors.ClockMonitor": {
"diff": 71
}
},
"numExecutors": 1,
"offline": false,
"offlineCause": null,
"oneOffExecutors": [],
"temporarilyOffline": false
}],
"displayName": "nodes",
"totalExecutors": 4
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0"?>
<configuration scan="false">
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>target/test-data/jclouds.log</file>
<encoder>
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
</encoder>
</appender>
<appender name="WIREFILE" class="ch.qos.logback.core.FileAppender">
<file>target/test-data/jclouds-wire.log</file>
<encoder>
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
</encoder>
</appender>
<root>
<level value="warn" />
</root>
<logger name="org.jclouds">
<level value="DEBUG" />
<appender-ref ref="FILE" />
</logger>
<logger name="jclouds.wire">
<level value="DEBUG" />
<appender-ref ref="WIREFILE" />
</logger>
<logger name="jclouds.headers">
<level value="DEBUG" />
<appender-ref ref="WIREFILE" />
</logger>
</configuration>

View File

@ -42,5 +42,6 @@
<module>dmtf</module>
<module>carrenza-vcloud-director</module>
<module>openstack-swift</module>
<module>jenkins</module>
</modules>
</project>