mirror of https://github.com/apache/jclouds.git
Issue 230: corrected URI parsing so that we can access ibm image manifests
This commit is contained in:
parent
ab5e8b3ab4
commit
50b1aa3cae
|
@ -250,10 +250,16 @@ public class HttpUtils {
|
||||||
/**
|
/**
|
||||||
* Used to extract the URI and authentication data from a String. Note that the java URI class
|
* Used to extract the URI and authentication data from a String. Note that the java URI class
|
||||||
* breaks, if there are special characters like '/' present. Otherwise, we wouldn't need this
|
* breaks, if there are special characters like '/' present. Otherwise, we wouldn't need this
|
||||||
* class, and we could simply use URI.create("uri").getUserData();
|
* class, and we could simply use URI.create("uri").getUserData(); Also, URI breaks if there
|
||||||
|
* are curly braces.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static URI createUri(String uriPath) {
|
public static URI createUri(String uriPath) {
|
||||||
|
List<String> onQuery = Lists.newArrayList(Splitter.on('?').split(uriPath));
|
||||||
|
if (onQuery.size() == 2){
|
||||||
|
onQuery.add(urlEncode(onQuery.remove(1), '=','&'));
|
||||||
|
uriPath = Joiner.on('?').join(onQuery);
|
||||||
|
}
|
||||||
if (uriPath.indexOf('@') != 1) {
|
if (uriPath.indexOf('@') != 1) {
|
||||||
List<String> parts = Lists.newArrayList(Splitter.on('@').split(uriPath));
|
List<String> parts = Lists.newArrayList(Splitter.on('@').split(uriPath));
|
||||||
String path = parts.remove(parts.size() - 1);
|
String path = parts.remove(parts.size() - 1);
|
||||||
|
@ -268,7 +274,7 @@ public class HttpUtils {
|
||||||
parts.add(urlEncode(path, ':'));
|
parts.add(urlEncode(path, ':'));
|
||||||
uriPath = Joiner.on('/').join(parts);
|
uriPath = Joiner.on('/').join(parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PATTERN_THAT_BREAKS_URI.matcher(uriPath).matches()) {
|
if (PATTERN_THAT_BREAKS_URI.matcher(uriPath).matches()) {
|
||||||
// Compile and use regular expression
|
// Compile and use regular expression
|
||||||
Matcher matcher = URI_PATTERN.matcher(uriPath);
|
Matcher matcher = URI_PATTERN.matcher(uriPath);
|
||||||
|
|
|
@ -44,6 +44,12 @@ public class HttpUtilsTest extends PerformanceTest {
|
||||||
"/read-tests/%73%6f%6d%65%20%66%69%6c%65");
|
"/read-tests/%73%6f%6d%65%20%66%69%6c%65");
|
||||||
assertEquals(HttpUtils.urlEncode("/read-tests/ tep", '/'), "/read-tests/%20tep");
|
assertEquals(HttpUtils.urlEncode("/read-tests/ tep", '/'), "/read-tests/%20tep");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIBM() {
|
||||||
|
URI ibm = HttpUtils
|
||||||
|
.createUri("https://www-180.ibm.com/cloud/enterprise/beta/ram/assetDetail/generalDetails.faces?guid={A31FF849-0E97-431A-0324-097385A46298}&v=1.2");
|
||||||
|
assertEquals(ibm.getQuery(), "guid={A31FF849-0E97-431A-0324-097385A46298}&v=1.2");
|
||||||
|
}
|
||||||
|
|
||||||
public void testAtmos() {
|
public void testAtmos() {
|
||||||
URI creds = HttpUtils
|
URI creds = HttpUtils
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.jclouds.ibmdev.config;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.http.HttpUtils;
|
||||||
|
import org.jclouds.http.functions.config.ParserModule.DateAdapter;
|
||||||
|
import org.jclouds.http.functions.config.ParserModule.LongDateAdapter;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class IBMDeveloperCloudParserModule extends AbstractModule {
|
||||||
|
@Singleton
|
||||||
|
public static class CurlyBraceCapableURIAdapter implements JsonDeserializer<URI> {
|
||||||
|
@Override
|
||||||
|
public URI deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
String toParse = jsonElement.getAsJsonPrimitive().getAsString();
|
||||||
|
URI toReturn = HttpUtils.createUri(toParse);
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named(Constants.PROPERTY_GSON_ADAPTERS)
|
||||||
|
public Map<Class, Object> provideCustomAdapterBindings(CurlyBraceCapableURIAdapter adapter) {
|
||||||
|
return ImmutableMap.<Class, Object> of(URI.class, adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(DateAdapter.class).to(LongDateAdapter.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,8 +32,6 @@ import org.jclouds.http.annotation.ClientError;
|
||||||
import org.jclouds.http.annotation.Redirection;
|
import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.http.filters.BasicAuthentication;
|
import org.jclouds.http.filters.BasicAuthentication;
|
||||||
import org.jclouds.http.functions.config.ParserModule.DateAdapter;
|
|
||||||
import org.jclouds.http.functions.config.ParserModule.LongDateAdapter;
|
|
||||||
import org.jclouds.ibmdev.IBMDeveloperCloud;
|
import org.jclouds.ibmdev.IBMDeveloperCloud;
|
||||||
import org.jclouds.ibmdev.IBMDeveloperCloudAsyncClient;
|
import org.jclouds.ibmdev.IBMDeveloperCloudAsyncClient;
|
||||||
import org.jclouds.ibmdev.IBMDeveloperCloudClient;
|
import org.jclouds.ibmdev.IBMDeveloperCloudClient;
|
||||||
|
@ -63,6 +61,7 @@ public class IBMDeveloperCloudRestClientModule extends
|
||||||
super(IBMDeveloperCloudClient.class, IBMDeveloperCloudAsyncClient.class);
|
super(IBMDeveloperCloudClient.class, IBMDeveloperCloudAsyncClient.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
public BasicAuthentication provideBasicAuthentication(
|
public BasicAuthentication provideBasicAuthentication(
|
||||||
|
@ -92,7 +91,7 @@ public class IBMDeveloperCloudRestClientModule extends
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(DateAdapter.class).to(LongDateAdapter.class);
|
install(new IBMDeveloperCloudParserModule());
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.ibmdev.domain;
|
package org.jclouds.ibmdev.domain;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -61,10 +62,8 @@ public class Image {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
/**
|
|
||||||
* Note that this isn't a URI, as parsing fails due to IBM including '{' characters in the path.
|
private URI manifest;
|
||||||
*/
|
|
||||||
private String manifest;
|
|
||||||
private int state;
|
private int state;
|
||||||
private Visibility visibility;
|
private Visibility visibility;
|
||||||
private String owner;
|
private String owner;
|
||||||
|
@ -74,10 +73,7 @@ public class Image {
|
||||||
private String location;
|
private String location;
|
||||||
private Set<String> supportedInstanceTypes = Sets.newLinkedHashSet();
|
private Set<String> supportedInstanceTypes = Sets.newLinkedHashSet();
|
||||||
private Set<String> productCodes = Sets.newLinkedHashSet();
|
private Set<String> productCodes = Sets.newLinkedHashSet();
|
||||||
/**
|
private URI documentation;
|
||||||
* Note that this isn't a URI, as parsing fails due to IBM including '{' characters in the path.
|
|
||||||
*/
|
|
||||||
private String documentation;
|
|
||||||
private String id;
|
private String id;
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
@ -89,11 +85,11 @@ public class Image {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getManifest() {
|
public URI getManifest() {
|
||||||
return manifest;
|
return manifest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setManifest(String manifest) {
|
public void setManifest(URI manifest) {
|
||||||
this.manifest = manifest;
|
this.manifest = manifest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,11 +165,11 @@ public class Image {
|
||||||
this.productCodes = productCodes;
|
this.productCodes = productCodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDocumentation() {
|
public URI getDocumentation() {
|
||||||
return documentation;
|
return documentation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDocumentation(String documentation) {
|
public void setDocumentation(URI documentation) {
|
||||||
this.documentation = documentation;
|
this.documentation = documentation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,9 @@ import java.io.IOException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.http.functions.config.ParserModule;
|
import org.jclouds.http.functions.config.ParserModule;
|
||||||
|
import org.jclouds.ibmdev.config.IBMDeveloperCloudParserModule;
|
||||||
import org.jclouds.ibmdev.domain.Image;
|
import org.jclouds.ibmdev.domain.Image;
|
||||||
import org.jclouds.ibmdev.domain.Image.Visibility;
|
import org.jclouds.ibmdev.domain.Image.Visibility;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
|
@ -47,13 +49,8 @@ public class ParseImageFromJsonTest {
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeTest
|
||||||
protected void setUpInjector() throws IOException {
|
protected void setUpInjector() throws IOException {
|
||||||
Injector injector = Guice.createInjector(new ParserModule() {
|
Injector injector = Guice.createInjector(new ParserModule(),
|
||||||
@Override
|
new IBMDeveloperCloudParserModule());
|
||||||
protected void configure() {
|
|
||||||
bind(DateAdapter.class).to(LongDateAdapter.class);
|
|
||||||
super.configure();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
handler = injector.getInstance(ParseImageFromJson.class);
|
handler = injector.getInstance(ParseImageFromJson.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +59,8 @@ public class ParseImageFromJsonTest {
|
||||||
Image image = new Image();
|
Image image = new Image();
|
||||||
image.setName("Rational Requirements Composer");
|
image.setName("Rational Requirements Composer");
|
||||||
image
|
image
|
||||||
.setManifest("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{28C7B870-2C0A-003F-F886-B89F5B413B77}/1.0/parameters.xml");
|
.setManifest(HttpUtils
|
||||||
|
.createUri("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{28C7B870-2C0A-003F-F886-B89F5B413B77}/1.0/parameters.xml"));
|
||||||
image.setState(1);
|
image.setState(1);
|
||||||
image.setVisibility(Visibility.PUBLIC);
|
image.setVisibility(Visibility.PUBLIC);
|
||||||
image.setOwner("mutdosch@us.ibm.com");
|
image.setOwner("mutdosch@us.ibm.com");
|
||||||
|
@ -73,7 +71,8 @@ public class ParseImageFromJsonTest {
|
||||||
image.setSupportedInstanceTypes(ImmutableSet.of("LARGE", "MEDIUM"));
|
image.setSupportedInstanceTypes(ImmutableSet.of("LARGE", "MEDIUM"));
|
||||||
// image.setProductCodes();
|
// image.setProductCodes();
|
||||||
image
|
image
|
||||||
.setDocumentation("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{28C7B870-2C0A-003F-F886-B89F5B413B77}/1.0/GettingStarted.html");
|
.setDocumentation(HttpUtils
|
||||||
|
.createUri("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{28C7B870-2C0A-003F-F886-B89F5B413B77}/1.0/GettingStarted.html"));
|
||||||
image.setId("10005598");
|
image.setId("10005598");
|
||||||
image
|
image
|
||||||
.setDescription("Rational Requirements Composer helps teams define and use requirements effectively across the project lifecycle.");
|
.setDescription("Rational Requirements Composer helps teams define and use requirements effectively across the project lifecycle.");
|
||||||
|
|
|
@ -24,7 +24,9 @@ import java.util.Date;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.http.functions.config.ParserModule;
|
import org.jclouds.http.functions.config.ParserModule;
|
||||||
|
import org.jclouds.ibmdev.config.IBMDeveloperCloudParserModule;
|
||||||
import org.jclouds.ibmdev.domain.Image;
|
import org.jclouds.ibmdev.domain.Image;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -45,13 +47,8 @@ public class ParseImagesFromJsonTest {
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeTest
|
||||||
protected void setUpInjector() throws IOException {
|
protected void setUpInjector() throws IOException {
|
||||||
Injector injector = Guice.createInjector(new ParserModule() {
|
Injector injector = Guice.createInjector(new ParserModule(),
|
||||||
@Override
|
new IBMDeveloperCloudParserModule());
|
||||||
protected void configure() {
|
|
||||||
bind(DateAdapter.class).to(LongDateAdapter.class);
|
|
||||||
super.configure();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
handler = injector.getInstance(ParseImagesFromJson.class);
|
handler = injector.getInstance(ParseImagesFromJson.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +57,8 @@ public class ParseImagesFromJsonTest {
|
||||||
|
|
||||||
image1.setName("Rational Build Forge Agent");
|
image1.setName("Rational Build Forge Agent");
|
||||||
image1
|
image1
|
||||||
.setManifest("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{A233F5A0-05A5-F21D-3E92-3793B722DFBD}/1.0/parameters.xml");
|
.setManifest(HttpUtils
|
||||||
|
.createUri("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{A233F5A0-05A5-F21D-3E92-3793B722DFBD}/1.0/parameters.xml"));
|
||||||
image1.setState(1);
|
image1.setState(1);
|
||||||
image1.setVisibility(Image.Visibility.PUBLIC);
|
image1.setVisibility(Image.Visibility.PUBLIC);
|
||||||
image1.setOwner("SYSTEM");
|
image1.setOwner("SYSTEM");
|
||||||
|
@ -71,7 +69,8 @@ public class ParseImagesFromJsonTest {
|
||||||
image1.setSupportedInstanceTypes(ImmutableSet.of("SMALL", "MEDIUM", "LARGE"));
|
image1.setSupportedInstanceTypes(ImmutableSet.of("SMALL", "MEDIUM", "LARGE"));
|
||||||
image1.setProductCodes(ImmutableSet.of("fd2d0478b132490897526b9b4433a334"));
|
image1.setProductCodes(ImmutableSet.of("fd2d0478b132490897526b9b4433a334"));
|
||||||
image1
|
image1
|
||||||
.setDocumentation("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{A233F5A0-05A5-F21D-3E92-3793B722DFBD}/1.0/GettingStarted.html");
|
.setDocumentation(HttpUtils
|
||||||
|
.createUri("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{A233F5A0-05A5-F21D-3E92-3793B722DFBD}/1.0/GettingStarted.html"));
|
||||||
image1.setId("2");
|
image1.setId("2");
|
||||||
image1
|
image1
|
||||||
.setDescription("Rational Build Forge provides an adaptive process execution framework that automates, orchestrates, manages, and tracks all the processes between each handoff within the assembly line of software development, creating an automated software factory.");
|
.setDescription("Rational Build Forge provides an adaptive process execution framework that automates, orchestrates, manages, and tracks all the processes between each handoff within the assembly line of software development, creating an automated software factory.");
|
||||||
|
@ -79,7 +78,8 @@ public class ParseImagesFromJsonTest {
|
||||||
Image image2 = new Image();
|
Image image2 = new Image();
|
||||||
image2.setName("Rational Requirements Composer");
|
image2.setName("Rational Requirements Composer");
|
||||||
image2
|
image2
|
||||||
.setManifest("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{28C7B870-2C0A-003F-F886-B89F5B413B77}/1.0/parameters.xml");
|
.setManifest(HttpUtils
|
||||||
|
.createUri("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{28C7B870-2C0A-003F-F886-B89F5B413B77}/1.0/parameters.xml"));
|
||||||
image2.setState(1);
|
image2.setState(1);
|
||||||
image2.setVisibility(Image.Visibility.PUBLIC);
|
image2.setVisibility(Image.Visibility.PUBLIC);
|
||||||
image2.setOwner("mutdosch@us.ibm.com");
|
image2.setOwner("mutdosch@us.ibm.com");
|
||||||
|
@ -90,7 +90,8 @@ public class ParseImagesFromJsonTest {
|
||||||
image2.setSupportedInstanceTypes(ImmutableSet.of("LARGE", "MEDIUM"));
|
image2.setSupportedInstanceTypes(ImmutableSet.of("LARGE", "MEDIUM"));
|
||||||
// image.setProductCodes();
|
// image.setProductCodes();
|
||||||
image2
|
image2
|
||||||
.setDocumentation("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{28C7B870-2C0A-003F-F886-B89F5B413B77}/1.0/GettingStarted.html");
|
.setDocumentation(HttpUtils
|
||||||
|
.createUri("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{28C7B870-2C0A-003F-F886-B89F5B413B77}/1.0/GettingStarted.html"));
|
||||||
image2.setId("10005598");
|
image2.setId("10005598");
|
||||||
image2
|
image2
|
||||||
.setDescription("Rational Requirements Composer helps teams define and use requirements effectively across the project lifecycle.");
|
.setDescription("Rational Requirements Composer helps teams define and use requirements effectively across the project lifecycle.");
|
||||||
|
|
Loading…
Reference in New Issue