mirror of https://github.com/apache/jclouds.git
Issue 88: remove buggy httpnio module; also remove outdated codegen mod since we now have maven archetypes
This commit is contained in:
parent
b432bbbe8c
commit
1349a8bdd1
|
@ -1,9 +0,0 @@
|
|||
# use glob syntax.
|
||||
syntax: glob
|
||||
target
|
||||
.settings
|
||||
.classpath
|
||||
.project
|
||||
jclouds-codegen.iml
|
||||
jclouds-codegen.ipr
|
||||
jclouds-codegen.iws
|
|
@ -1,9 +0,0 @@
|
|||
# use glob syntax.
|
||||
syntax: glob
|
||||
target
|
||||
.settings
|
||||
.classpath
|
||||
.project
|
||||
jclouds-codegen-core.iml
|
||||
jclouds-codegen-core.ipr
|
||||
jclouds-codegen-core.iws
|
|
@ -1,113 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
|
||||
<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">
|
||||
<parent>
|
||||
<artifactId>jclouds-codegen-project</artifactId>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jclouds-codegen-core</artifactId>
|
||||
<name>jclouds code generator</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>jclouds code generator</description>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/codegen/core</connection>
|
||||
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/codegen/core</developerConnection>
|
||||
<url>http://jclouds.googlecode.com/svn/trunk/codegen/core</url>
|
||||
</scm>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gson</id>
|
||||
<url>http://google-gson.googlecode.com/svn/mavenrepo</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId>
|
||||
<version>2.3.14</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>r03</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<version>1.3.9</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>org.jclouds.codegen.util.CodeGenerator</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -1,52 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.model;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
* @author James Murty
|
||||
*/
|
||||
public class API {
|
||||
private List<Package> packages;
|
||||
private Map<String, DomainType> domain;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getPackages().toString();
|
||||
}
|
||||
|
||||
public void setPackages(List<Package> packages) {
|
||||
this.packages = packages;
|
||||
}
|
||||
|
||||
public List<Package> getPackages() {
|
||||
return packages;
|
||||
}
|
||||
|
||||
public void setDomain(Map<String, DomainType> domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
public Map<String, DomainType> getDomain() {
|
||||
return domain;
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.model;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
* @author James Murty
|
||||
*/
|
||||
public class Command extends TopLevelType {
|
||||
private TopLevelType options;
|
||||
private TopLevelType handler;
|
||||
private DomainType response;
|
||||
private String description;
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setOptions(TopLevelType options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public TopLevelType getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public void setHandler(TopLevelType handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public TopLevelType getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
public void setResponse(DomainType response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
public DomainType getResponse() {
|
||||
return response;
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.model;
|
||||
|
||||
|
||||
public class DomainType extends Type {
|
||||
|
||||
private String ancestor;
|
||||
|
||||
public void setAncestor(String ancestor) {
|
||||
this.ancestor = ancestor;
|
||||
}
|
||||
|
||||
public String getAncestor() {
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class Field {
|
||||
|
||||
private String constraints;
|
||||
private String defaultValue;
|
||||
private String desc;
|
||||
private String name;
|
||||
private String javaName;
|
||||
private boolean optional = true;
|
||||
private String type;
|
||||
private String javaType;
|
||||
private Map<String, String> valueMap;
|
||||
|
||||
public void setConstraints(String constraints) {
|
||||
this.constraints = constraints;
|
||||
}
|
||||
|
||||
public String getConstraints() {
|
||||
return constraints;
|
||||
}
|
||||
|
||||
public void setDefaultValue(String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void setDesc(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public void setValueMap(Map<String, String> valueMap) {
|
||||
this.valueMap = valueMap;
|
||||
}
|
||||
|
||||
public Map<String, String> getValueMap() {
|
||||
return valueMap;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setOptional(boolean optional) {
|
||||
this.optional = optional;
|
||||
}
|
||||
|
||||
public boolean getOptional() {
|
||||
return optional;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setJavaName(String javaName) {
|
||||
this.javaName = javaName;
|
||||
}
|
||||
|
||||
public String getJavaName() {
|
||||
return javaName;
|
||||
}
|
||||
|
||||
public void setJavaType(String javaType) {
|
||||
this.javaType = javaType;
|
||||
}
|
||||
|
||||
public String getJavaType() {
|
||||
return javaType;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author James Murty
|
||||
*/
|
||||
public class Package {
|
||||
private String name;
|
||||
private List<Command> commands;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("{'name':'%1$s', 'commands':%2$s", name, commands);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<Command> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TopLevelType extends Type {
|
||||
|
||||
private String ancestor;
|
||||
private List<String> exampleCode;
|
||||
private List<String> exampleHTML;
|
||||
|
||||
public void setAncestor(String ancestor) {
|
||||
this.ancestor = ancestor;
|
||||
}
|
||||
|
||||
public String getAncestor() {
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
public void setExampleCode(List<String> exampleCode) {
|
||||
this.exampleCode = exampleCode;
|
||||
}
|
||||
|
||||
public List<String> getExampleCode() {
|
||||
return exampleCode;
|
||||
}
|
||||
|
||||
public void setExampleHTML(List<String> exampleHTML) {
|
||||
this.exampleHTML = exampleHTML;
|
||||
}
|
||||
|
||||
public List<String> getExampleHTML() {
|
||||
return exampleHTML;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.model;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class Type {
|
||||
|
||||
private String packageName;
|
||||
private String name;
|
||||
private String javaName;
|
||||
private Set<String> see;
|
||||
private Set<Field> fields;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setJavaName(String javaName) {
|
||||
this.javaName = javaName;
|
||||
}
|
||||
|
||||
public String getJavaName() {
|
||||
return javaName;
|
||||
}
|
||||
|
||||
public void setSee(Set<String> see) {
|
||||
this.see = see;
|
||||
}
|
||||
|
||||
public Set<String> getSee() {
|
||||
return see;
|
||||
}
|
||||
|
||||
public void setFields(Set<Field> fields) {
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
public Set<Field> getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,191 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.codegen.model.API;
|
||||
import org.jclouds.codegen.model.Command;
|
||||
import org.jclouds.codegen.model.DomainType;
|
||||
import org.jclouds.codegen.model.Package;
|
||||
import org.jclouds.codegen.model.Type;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
|
||||
/**
|
||||
* Converts object models representing AWS API beans into Java classes.
|
||||
* <p>
|
||||
* This implementation is designed to perform the following steps:
|
||||
* <ul>
|
||||
* <li>Parse the JSON object representation produced by the <tt>parse_ec2.pl</tt> perl script</li>
|
||||
* <li>Convert the JSON into Java object models (@see org.jclouds.aws.codegen.models)</li>
|
||||
* <li>Iterate through the Command objects generated above and with each one:
|
||||
* <ul>
|
||||
* <li>Load the <a href="http://freemarker.org/">FreeMarker</a>template file for the given object</li>
|
||||
* <li>Create a package directory to receive the Java file, if necessary</li>
|
||||
* <li>Process the object through the template, producing a Java implementation of the object</li>
|
||||
* <ul></li>
|
||||
*
|
||||
* @author James Murty
|
||||
*/
|
||||
public class CodeGenerator {
|
||||
public final static String COMMAND_TEMPLATE_FILENAME = "Command.ftl";
|
||||
public final static String BEAN_TEMPLATE_FILENAME = "Bean.ftl";
|
||||
public final static String OPTIONS_TEMPLATE_FILENAME = "Options.ftl";
|
||||
public final static String VALUE_TEMPLATE_FILENAME = "Value.ftl";
|
||||
public final static String RESPONSE_TEMPLATE_FILENAME = "Response.ftl";
|
||||
|
||||
private final File targetDirectory;
|
||||
private final String rootPackageName;
|
||||
private final Configuration config;
|
||||
|
||||
public CodeGenerator(String rootPackageName, File targetDirectory) throws IOException {
|
||||
this.rootPackageName = rootPackageName;
|
||||
this.targetDirectory = targetDirectory;
|
||||
|
||||
config = new Configuration();
|
||||
config.setClassForTemplateLoading(this.getClass(), "/templates");
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a JSON object model file (as generated by <tt>aws/src/main/bin/parse_ec2.pl</tt>) and
|
||||
* convert it into a Java object graph.
|
||||
*
|
||||
* @param objectModelFile
|
||||
* @return
|
||||
* @throws JsonParseException
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public API parseModelFromJSON(File objectModelFile) throws JsonParseException,
|
||||
FileNotFoundException {
|
||||
Gson gson = new Gson();
|
||||
return gson.fromJson(new FileReader(objectModelFile), API.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a JSON object model file and iterate over the resulting objects generating Java code
|
||||
* files.
|
||||
*
|
||||
* @param objectModelFile
|
||||
* @throws JsonParseException
|
||||
* @throws IOException
|
||||
* @throws TemplateException
|
||||
*/
|
||||
public void generateCode(File objectModelFile) throws JsonParseException, IOException,
|
||||
TemplateException {
|
||||
API model = parseModelFromJSON(objectModelFile);
|
||||
|
||||
for (Package pkg : model.getPackages()) {
|
||||
for (Command command : pkg.getCommands()) {
|
||||
generateClassFile(command, COMMAND_TEMPLATE_FILENAME);
|
||||
|
||||
if (command.getHandler() != null) {
|
||||
generateClassFile(command.getHandler(), BEAN_TEMPLATE_FILENAME);
|
||||
}
|
||||
if (command.getOptions() != null
|
||||
&& command.getOptions().getJavaName().indexOf(
|
||||
"BaseEC2RequestOptions<EC2RequestOptions>") == -1) {
|
||||
generateClassFile(command.getOptions(), OPTIONS_TEMPLATE_FILENAME);
|
||||
}
|
||||
if (command.getResponse() != null
|
||||
&& !command.getResponse().getJavaName().equals("Boolean")) {
|
||||
generateClassFile(command.getResponse(), RESPONSE_TEMPLATE_FILENAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (DomainType value : model.getDomain().values()) {
|
||||
generateClassFile(value, VALUE_TEMPLATE_FILENAME);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Java code file for the given object model bean, using the given template name as
|
||||
* the basis for the Java class.
|
||||
*
|
||||
* @param bean
|
||||
* @param templateFileName
|
||||
* @throws IOException
|
||||
* @throws TemplateException
|
||||
*/
|
||||
public void generateClassFile(Type bean, String templateFileName) throws IOException,
|
||||
TemplateException {
|
||||
String shortClassName = bean.getJavaName().substring(
|
||||
bean.getJavaName().lastIndexOf('.') + 1);
|
||||
|
||||
Map<String, Object> objectMap = new HashMap<String, Object>();
|
||||
objectMap.put("bean", bean);
|
||||
objectMap.put("rootPackageName", this.rootPackageName);
|
||||
objectMap.put("shortClassName", shortClassName);
|
||||
|
||||
File packageDir = new File(this.targetDirectory, bean.getPackageName().replace('.', '/'));
|
||||
|
||||
if (packageDir.exists() || packageDir.mkdirs()) {
|
||||
File javaFile = new File(packageDir, shortClassName + ".java");
|
||||
FileWriter fw = new FileWriter(javaFile);
|
||||
System.out.println("Generated " + javaFile);
|
||||
applyTemplate(templateFileName, objectMap, fw);
|
||||
} else {
|
||||
throw new IllegalStateException("Unable to create target package directory: " + packageDir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the given template to the given object, and output the results into the given writer.
|
||||
*
|
||||
* @param templateFileName
|
||||
* @param objectMap
|
||||
* @param writer
|
||||
* @throws IOException
|
||||
* @throws TemplateException
|
||||
*/
|
||||
public void applyTemplate(String templateFileName, Map<String, Object> objectMap, Writer writer)
|
||||
throws IOException, TemplateException {
|
||||
Template template = this.config.getTemplate(templateFileName, "UTF-8");
|
||||
template.process(objectMap, writer);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length != 3) {
|
||||
System.out.println("Usage: CodeGenerator objectModelFile rootPackage targetDir");
|
||||
System.out.println(" E.g: CodeGenerator ec2.json org.jclouds.aws.ec2 aws/ec2/api/src");
|
||||
System.exit(1);
|
||||
}
|
||||
File objectModelFile = new File(args[0]);
|
||||
|
||||
String rootPackage = args[1];
|
||||
|
||||
File targetDir = new File(args[2]);
|
||||
|
||||
new CodeGenerator(rootPackage, targetDir).generateCode(objectModelFile);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
[#ftl]
|
||||
[#--
|
||||
|
||||
|
||||
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 ${bean.packageName};
|
||||
|
||||
[#if bean.packageName != rootPackageName]
|
||||
import ${rootPackageName}.*;
|
||||
[/#if]
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
[#list bean.see as see]
|
||||
[#if see?contains(".html")]
|
||||
* @see <a href='${see}' />
|
||||
[#else]
|
||||
* @see ${see}
|
||||
[/#if]
|
||||
[/#list]
|
||||
* @author Generated
|
||||
*/
|
||||
public class ${shortClassName} {
|
||||
|
||||
[#-- Print fields --]
|
||||
[#list bean.parameters![] as field]
|
||||
/**
|
||||
*
|
||||
* ${field.desc}
|
||||
*/
|
||||
private ${field.javaType} ${field.javaName?uncap_first};
|
||||
|
||||
[/#list]
|
||||
|
||||
[#-- Print get/set --]
|
||||
[#list bean.parameters![] as field]
|
||||
[#assign lowerName = field.javaName?uncap_first]
|
||||
[#assign upperName = field.javaName?cap_first]
|
||||
/**
|
||||
*
|
||||
* @return ${field.desc}
|
||||
*/
|
||||
public ${field.javaType} get${upperName}(){
|
||||
return this.${lowerName};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ${lowerName}
|
||||
* ${field.desc}
|
||||
*/
|
||||
public void set${upperName}(${field.javaType} ${lowerName}) {
|
||||
this.${lowerName} = ${lowerName};
|
||||
}
|
||||
|
||||
[/#list]
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
[#ftl]
|
||||
[#--
|
||||
|
||||
|
||||
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 ${bean.packageName};
|
||||
|
||||
import ${rootPackageName}.domain.*;
|
||||
[#if bean.response??]
|
||||
import ${bean.response.packageName}.*;
|
||||
[/#if]
|
||||
[#if bean.options??]
|
||||
import ${bean.options.packageName}.*;
|
||||
[/#if]
|
||||
import org.jclouds.aws.reference.AWSConstants;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.http.commands.callables.xml.ParseSax;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.name.Named;
|
||||
|
||||
import org.jclouds.http.HttpFutureCommand;
|
||||
|
||||
/**
|
||||
*
|
||||
[#list bean.see as see]
|
||||
[#if see?contains(".html")]
|
||||
* @see <a href='${see}' />
|
||||
[#else]
|
||||
* @see ${see}
|
||||
[/#if]
|
||||
[/#list]
|
||||
* @author Generated
|
||||
*/
|
||||
[#assign RT = bean.response.javaType]
|
||||
public class ${shortClassName} extends HttpFutureCommand<${RT}> {
|
||||
@Inject
|
||||
public ${shortClassName}(@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String awsAccessKeyId,
|
||||
@Named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY) String awsSecretAccessKey,
|
||||
ParseSax<${RT}> callable,
|
||||
[#if bean.options.javaType?? ]
|
||||
@Assisted ${bean.options.javaType} options
|
||||
[#else]
|
||||
@Assisted BaseEC2RequestOptions<EC2RequestOptions> options
|
||||
[/#if]
|
||||
[#list bean.parameters![] as param]
|
||||
,@Assisted ${param.javaType} ${param.javaName?uncap_first}[#rt]
|
||||
[/#list]) {
|
||||
super("GET",
|
||||
"/" + options
|
||||
[#list bean.parameters![] as param]
|
||||
.with${param.javaName?cap_first}(${param.javaName?uncap_first})
|
||||
[/#list]
|
||||
.signWith(awsAccessKeyId,awsSecretAccessKey).buildQueryString(), callable);
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
[#ftl]
|
||||
[#--
|
||||
|
||||
|
||||
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 ${bean.packageName};
|
||||
|
||||
[#if bean.packageName != rootPackageName]
|
||||
import ${rootPackageName}.*;
|
||||
[/#if]
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
[#list bean.see as see]
|
||||
[#if see?contains(".html")]
|
||||
* @see <a href='${see}' />
|
||||
[#else]
|
||||
* @see ${see}
|
||||
[/#if]
|
||||
[/#list]
|
||||
* @author Generated
|
||||
*/
|
||||
public class ${shortClassName} {
|
||||
|
||||
[#-- Print fields --]
|
||||
[#list bean.parameters![] as field]
|
||||
/**
|
||||
*
|
||||
* ${field.desc}
|
||||
*/
|
||||
private ${field.javaType} ${field.javaName?uncap_first};
|
||||
|
||||
[/#list]
|
||||
|
||||
[#-- Print get/set --]
|
||||
[#list bean.parameters![] as field]
|
||||
[#assign lowerName = field.javaName?uncap_first]
|
||||
[#assign upperName = field.javaName?cap_first]
|
||||
/**
|
||||
*
|
||||
* @return ${field.desc}
|
||||
*/
|
||||
public ${field.javaType} get${upperName}(){
|
||||
return this.${lowerName};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ${lowerName}
|
||||
* ${field.desc}
|
||||
*/
|
||||
public void set${upperName}(${field.javaType} ${lowerName}) {
|
||||
this.${lowerName} = ${lowerName};
|
||||
}
|
||||
|
||||
[/#list]
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
[#ftl]
|
||||
[#--
|
||||
|
||||
|
||||
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 ${bean.packageName};
|
||||
|
||||
[#if bean.packageName != rootPackageName]
|
||||
import ${rootPackageName}.*;
|
||||
[/#if]
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.aws.ec2.commands.options.BaseEC2RequestOptions;
|
||||
|
||||
/**
|
||||
* <p/>
|
||||
* <code>
|
||||
* ${bean.example}
|
||||
* </code>
|
||||
[#list bean.see as see]
|
||||
[#if see?contains(".html")]
|
||||
* @see <a href='${see}'> ${shortClassName}</a>
|
||||
[#else]
|
||||
* @see ${see}
|
||||
[/#if]
|
||||
[/#list]
|
||||
* @author Generated
|
||||
*/
|
||||
public class ${shortClassName} extends
|
||||
BaseEC2RequestOptions<${shortClassName}> {
|
||||
|
||||
|
||||
public static final ${shortClassName} NONE = new ${shortClassName}();
|
||||
|
||||
static {
|
||||
realClass = ${shortClassName}.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAction() {
|
||||
return "${shortClassName}".replaceAll("Options","");
|
||||
}
|
||||
|
||||
[#list bean.parameters![] as field]
|
||||
[#assign lowerName = field.javaName?uncap_first]
|
||||
[#assign upperName = field.javaName?cap_first]
|
||||
|
||||
/**
|
||||
* @see ${shortClassName}#with${upperName}(String)
|
||||
*/
|
||||
public String get${upperName}() {
|
||||
return parameters.get("${lowerName}");
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: document this bad boy
|
||||
*
|
||||
*/
|
||||
public ${shortClassName} with${upperName}(String ${lowerName}) {
|
||||
encodeAndReplaceParameter("${lowerName}", ${lowerName});
|
||||
return this;
|
||||
}
|
||||
[/#list]
|
||||
|
||||
|
||||
public static class Builder {
|
||||
|
||||
[#list bean.parameters![] as field]
|
||||
[#assign lowerName = field.javaName?uncap_first]
|
||||
[#assign upperName = field.javaName?cap_first]
|
||||
/**
|
||||
* @see ${shortClassName}#withId(String)
|
||||
*/
|
||||
public static ${shortClassName} with${upperName}(String ${lowerName}) {
|
||||
${shortClassName} options = new ${shortClassName}();
|
||||
return options.with${upperName}(${lowerName});
|
||||
}
|
||||
|
||||
[/#list]
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
[#ftl]
|
||||
[#--
|
||||
|
||||
|
||||
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 ${bean.packageName};
|
||||
|
||||
[#if bean.packageName != rootPackageName]
|
||||
import ${rootPackageName}.domain.*;
|
||||
[/#if]
|
||||
import org.joda.time.DateTime;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
[#list bean.see as see]
|
||||
[#if see?contains(".html")]
|
||||
* @see <a href='${see}' />
|
||||
[#else]
|
||||
* @see ${see}
|
||||
[/#if]
|
||||
[/#list]
|
||||
* @author Generated
|
||||
*/
|
||||
public class ${shortClassName} {
|
||||
|
||||
[#-- Print fields --]
|
||||
[#list bean.fields![] as field]
|
||||
|
||||
private ${field.javaType} ${field.javaName?uncap_first};
|
||||
|
||||
[/#list]
|
||||
|
||||
[#-- Print get/set --]
|
||||
[#list bean.fields![] as field]
|
||||
[#assign lowerName = field.javaName?uncap_first]
|
||||
[#assign upperName = field.javaName?cap_first]
|
||||
|
||||
public ${field.javaType} get${upperName}(){
|
||||
return this.${lowerName};
|
||||
}
|
||||
|
||||
public void set${upperName}(${field.javaType} ${lowerName}) {
|
||||
this.${lowerName} = ${lowerName};
|
||||
}
|
||||
|
||||
[/#list]
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
[#ftl]
|
||||
[#--
|
||||
|
||||
|
||||
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 ${bean.packageName};
|
||||
|
||||
[#if bean.packageName != rootPackageName]
|
||||
import ${rootPackageName}.*;
|
||||
[/#if]
|
||||
import org.joda.time.DateTime;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
[#list bean.see as see]
|
||||
[#if see?contains(".html")]
|
||||
* @see <a href='${see}' />
|
||||
[#else]
|
||||
* @see ${see}
|
||||
[/#if]
|
||||
[/#list]
|
||||
* @author Generated
|
||||
*/
|
||||
public class ${shortClassName} {
|
||||
|
||||
[#-- Print fields --]
|
||||
[#list bean.fields![] as field]
|
||||
|
||||
private ${field.javaType} ${field.javaName?uncap_first};
|
||||
|
||||
[/#list]
|
||||
|
||||
[#-- Print get/set --]
|
||||
[#list bean.fields![] as field]
|
||||
[#assign lowerName = field.javaName?uncap_first]
|
||||
[#assign upperName = field.javaName?cap_first]
|
||||
|
||||
public ${field.javaType} get${upperName}(){
|
||||
return this.${lowerName};
|
||||
}
|
||||
|
||||
public void set${upperName}(${field.javaType} ${lowerName}) {
|
||||
this.${lowerName} = ${lowerName};
|
||||
}
|
||||
|
||||
[/#list]
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
# use glob syntax.
|
||||
syntax: glob
|
||||
target
|
||||
.settings
|
||||
.classpath
|
||||
.project
|
||||
jclouds-codegen-ec2.iml
|
||||
jclouds-codegen-ec2.ipr
|
||||
jclouds-codegen-ec2.iws
|
|
@ -1,58 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
|
||||
<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">
|
||||
<parent>
|
||||
<artifactId>jclouds-codegen-project</artifactId>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jclouds-codegen-ec2</artifactId>
|
||||
<name>jclouds code generator for amazon ec2</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>jclouds code generator</description>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/codegen/ec2</connection>
|
||||
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/codegen/ec2</developerConnection>
|
||||
<url>http://jclouds.googlecode.com/svn/trunk/codegen/ec2</url>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-codegen-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-codegen-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -1,386 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
# ====================================================================
|
||||
#
|
||||
#
|
||||
#
|
||||
# Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
#
|
||||
# ====================================================================
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF 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.
|
||||
# ====================================================================
|
||||
#
|
||||
####
|
||||
# Parse EC2
|
||||
#
|
||||
# Builds an object tree used to create a REST service for the current EC2 api.
|
||||
#
|
||||
# Prerequisites:
|
||||
# * install HTML-Tree (http://search.cpan.org/~petek/HTML-Tree/)
|
||||
# 1. download and extract the archive
|
||||
# 2. cd to that location
|
||||
# 3. perl MakeFile.PL
|
||||
# 4. sudo make install
|
||||
# * install JSON (http://search.cpan.org/~makamaka/JSON-2.14/lib/JSON.pm)
|
||||
# 1. download and extract the archive
|
||||
# 2. cd to that location
|
||||
# 3. perl MakeFile.PL
|
||||
# 4. sudo make install
|
||||
#
|
||||
# Usage:
|
||||
# * execute the script with no arguments. If you've downloaded the content locally, adjust refUrl and parse
|
||||
#
|
||||
# Tips: use $tree->dump to view the current html tree and print Dumper($object) to see a reference
|
||||
# this code is formatted with PerlTidy
|
||||
# Author: Adrian Cole
|
||||
####
|
||||
use strict;
|
||||
use HTML::TreeBuilder 2.97;
|
||||
use LWP::UserAgent;
|
||||
use Data::Dumper;
|
||||
use JSON;
|
||||
|
||||
my $refUrl = "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference";
|
||||
|
||||
#my $refUrl = "/tmp/scrape";
|
||||
|
||||
my $apiUrl = "${refUrl}/OperationList-query.html";
|
||||
|
||||
my $dataTypes = {};
|
||||
|
||||
sub parse_file {
|
||||
my $file = $_[0] || die "What File?";
|
||||
my $tree = HTML::TreeBuilder->new();
|
||||
$tree->parse_file($file);
|
||||
$tree->eof;
|
||||
return $tree;
|
||||
}
|
||||
|
||||
sub parse {
|
||||
|
||||
#return parse_file(shift);
|
||||
|
||||
return parse_url(shift);
|
||||
}
|
||||
|
||||
sub get_subtypes {
|
||||
$_ = shift;
|
||||
if ( /^[A-Z]/ && $_ ne 'String' && $_ ne 'Integer' && $_ ne 'Boolean' ) {
|
||||
my $type = $_;
|
||||
$dataTypes->{$type} = build_item($type);
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_url {
|
||||
my $url = $_[0] || die "What URL?";
|
||||
|
||||
my $response =
|
||||
LWP::UserAgent->new->request( HTTP::Request->new( GET => $url ) );
|
||||
unless ( $response->is_success ) {
|
||||
warn "Couldn't get $url: ", $response->status_line, "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
my $tree = HTML::TreeBuilder->new();
|
||||
$tree->parse( $response->content );
|
||||
$tree->eof;
|
||||
return $tree;
|
||||
}
|
||||
|
||||
sub build_categories {
|
||||
my $tree = parse( $_[0] );
|
||||
my @out;
|
||||
foreach my $link (
|
||||
( $tree->look_down( '_tag', 'div', 'class', 'itemizedlist' ) ) )
|
||||
{
|
||||
my $category = $link->look_down( '_tag', 'b' )->as_text();
|
||||
|
||||
my $queries;
|
||||
foreach my $class ( $link->look_down( '_tag', 'a' ) ) {
|
||||
my $type = $class->attr('title');
|
||||
my $query = build_query($type);
|
||||
|
||||
# add a dataTypes object for the response type
|
||||
$dataTypes->{ $type . "ResponseType" } =
|
||||
build_item( $type . "ResponseType", "ResponseType" );
|
||||
|
||||
$query->{responseType} = $type . "ResponseType";
|
||||
|
||||
$queries->{$type} = $query;
|
||||
}
|
||||
|
||||
push @out,
|
||||
{
|
||||
name => $category,
|
||||
queries => $queries,
|
||||
};
|
||||
}
|
||||
$tree->eof;
|
||||
$tree->delete;
|
||||
return \@out;
|
||||
}
|
||||
|
||||
sub build_api {
|
||||
my $url = shift;
|
||||
my $categories = {};
|
||||
|
||||
foreach ( @{ build_categories($url) } ) {
|
||||
$categories->{ $_->{name} } = $_;
|
||||
}
|
||||
return {
|
||||
see => [$url],
|
||||
categories => $categories,
|
||||
dataTypes => $dataTypes
|
||||
};
|
||||
}
|
||||
|
||||
sub build_query {
|
||||
my $type = shift;
|
||||
my $query = build_item( $type, "Request" );
|
||||
my $tree = parse( ${ $query->{see} }[0] );
|
||||
|
||||
my @{seeAlsoA} =
|
||||
$tree->look_down( '_tag', 'div', 'class', 'itemizedlist' )
|
||||
->look_down( '_tag', 'a' );
|
||||
|
||||
foreach ( @{seeAlsoA} ) {
|
||||
push @{ $query->{see} }, $_->as_text();
|
||||
}
|
||||
|
||||
$tree->eof;
|
||||
$tree->delete;
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
sub build_contents {
|
||||
|
||||
#TODO handle The ${query} operation does not have any request parameters. Right now, it parses the response object
|
||||
my @{contentRows} = @_;
|
||||
my @params;
|
||||
foreach my $contentRow ( @{contentRows} ) {
|
||||
my @{row} = $contentRow->look_down( '_tag', 'td' );
|
||||
my %param;
|
||||
$param{name} = ${row}[0]->as_text();
|
||||
my $enumDiv =
|
||||
${row}[1]->look_down( '_tag', 'div', "class", "itemizedlist" );
|
||||
if ( defined $enumDiv ) {
|
||||
my $enum;
|
||||
my @enumEntries = $enumDiv->look_down( '_tag', 'p' );
|
||||
foreach my $enumEntry (@enumEntries) {
|
||||
$enumEntry = $enumEntry->as_text();
|
||||
my ( $code, $state ) = split( /: /, $enumEntry );
|
||||
chomp($code);
|
||||
chomp($state);
|
||||
$enum->{$code} = $state;
|
||||
}
|
||||
$param{valueMap} = $enum;
|
||||
$param{desc} = ${row}[1]->look_down( '_tag', 'p' )->as_text();
|
||||
}
|
||||
else {
|
||||
my @{data} = ${row}[1]->look_down( '_tag', 'p' );
|
||||
foreach ( @{data} ) {
|
||||
$_ = $_->as_text();
|
||||
if (s/Default: //) {
|
||||
$param{defaultValue} = $_;
|
||||
}
|
||||
elsif (s/Type: //) {
|
||||
$param{type} = $_;
|
||||
get_subtypes($_);
|
||||
}
|
||||
elsif (s/Constraints: //) {
|
||||
$param{constraints} = $_;
|
||||
if (m/.*default: ([0-9]+)/) {
|
||||
$param{defaultValue} = $1;
|
||||
}
|
||||
}
|
||||
elsif (s/Valid Values: //) {
|
||||
if (/\|/) {
|
||||
my @valid_values = split(' \| ');
|
||||
my $enum;
|
||||
foreach my $value (@valid_values) {
|
||||
$enum->{$value} = $value;
|
||||
}
|
||||
$param{valueMap} = $enum;
|
||||
}
|
||||
elsif (/([0-9]+) ?\-([0-9]+)/) {
|
||||
$param{constraints} = "$1-$2";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$param{desc} = $_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( defined ${row}[2] && ${row}[2]->as_text() =~ /No/ ) {
|
||||
$param{optional} = 'true';
|
||||
}
|
||||
else {
|
||||
$param{optional} = 'false';
|
||||
}
|
||||
push @params, \%param;
|
||||
}
|
||||
|
||||
# Attribute query parameters come in as separate parameters, so
|
||||
# we coallate them into one
|
||||
my %attribute;
|
||||
for ( 0 .. $#params ) {
|
||||
my $param = $params[$_];
|
||||
if ( $param->{name} =~ /Attribute=/ ) {
|
||||
delete $params[$_];
|
||||
if ( !defined %attribute ) {
|
||||
$attribute{name} = "Attribute";
|
||||
$attribute{type} = "String";
|
||||
$attribute{optional} = "true";
|
||||
$attribute{defaultValue} = "true";
|
||||
}
|
||||
my $enum = $attribute{valueMap};
|
||||
$_ = $param->{name};
|
||||
s/Attribute=//;
|
||||
$enum->{$_} = $param->{desc};
|
||||
$attribute{valueMap} = $enum;
|
||||
}
|
||||
}
|
||||
if ( defined %attribute ) {
|
||||
push @params, \%attribute;
|
||||
}
|
||||
|
||||
return \@params;
|
||||
}
|
||||
|
||||
sub build_item {
|
||||
my $type = shift;
|
||||
my $class = shift;
|
||||
my $item = { type => $type, };
|
||||
|
||||
my $see = "${refUrl}/ApiReference-ItemType-${type}.html";
|
||||
if ( defined $class ) {
|
||||
$_ = $type;
|
||||
if ( $class =~ /Response/ ) {
|
||||
|
||||
# responses are related to the query. In this case, we must take
|
||||
# off the suffix Response to get the correct metadata url.
|
||||
s/$class//;
|
||||
}
|
||||
else {
|
||||
|
||||
# if we are the query object, then there is a different master url.
|
||||
$see = "${refUrl}/ApiReference-query-${type}.html";
|
||||
}
|
||||
my $query = "${refUrl}/ApiReference-query-${_}.html";
|
||||
push @{ $item->{see} }, $query;
|
||||
my $tree = parse($query);
|
||||
|
||||
if ( !defined $tree ) {
|
||||
print "could not parse tree $_[0]\n";
|
||||
return {};
|
||||
}
|
||||
unless ( $class =~ /Response/ ) {
|
||||
|
||||
#$tree->dump;
|
||||
my ${descriptionDiv} =
|
||||
$tree->look_down( '_tag', 'h2', 'id',
|
||||
"ApiReference-query-${_}-Description" )
|
||||
->look_up( '_tag', 'div', 'class', 'section' );
|
||||
$item->{description} =
|
||||
${descriptionDiv}->look_down( '_tag', 'p' )->as_text();
|
||||
}
|
||||
for my $I ( 1 .. 10 ) {
|
||||
my $id = "ApiReference-query-${_}-Example-${class}-$I";
|
||||
my ${requestExampleH3} =
|
||||
$tree->look_down( '_tag', 'h3', 'id', "$id" );
|
||||
last unless defined ${requestExampleH3};
|
||||
my ${requestExampleDiv} =
|
||||
${requestExampleH3}->look_up( '_tag', 'div', 'class', 'section' );
|
||||
push @{ $item->{exampleHTML} }, ${requestExampleDiv}->as_HTML();
|
||||
push @{ $item->{exampleCode} },
|
||||
${requestExampleDiv}
|
||||
->look_down( '_tag', 'pre', 'class', 'programlisting' )
|
||||
->as_text();
|
||||
}
|
||||
|
||||
$tree->eof;
|
||||
$tree->delete;
|
||||
|
||||
}
|
||||
push @{ $item->{see} }, $see unless defined $item->{see};
|
||||
|
||||
my $tree = parse($see);
|
||||
|
||||
if ( !defined $tree ) {
|
||||
print "could not parse tree $_[0]\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
# $tree->dump();
|
||||
$tree->eof;
|
||||
|
||||
# Query and Response Types are top-level objects and therefore have no Ancestors
|
||||
if ( !defined $class ) {
|
||||
|
||||
my $id = "ApiReference-ItemType-${type}-Ancestors";
|
||||
my ${ancestorH2} = $tree->look_down( '_tag', 'h2', 'id', "$id" );
|
||||
my ${ancestorDiv} =
|
||||
${ancestorH2}->look_up( '_tag', 'div', 'class', 'section' )
|
||||
if defined ${ancestorH2};
|
||||
my ${ancestorLink} =
|
||||
${ancestorDiv}->look_down( '_tag', 'a', 'class', 'xref' )
|
||||
if defined ${ancestorDiv};
|
||||
if ( defined ${ancestorLink} ) {
|
||||
$item->{ancestor} = ${ancestorLink}->as_text();
|
||||
}
|
||||
else {
|
||||
$item->{ancestor} = "None";
|
||||
}
|
||||
}
|
||||
my @{contentRows} = my $body = ${tree}->look_down( '_tag', 'tbody' );
|
||||
|
||||
if ( !defined $body ) {
|
||||
print "could not parse body $_[0]\n";
|
||||
return [];
|
||||
}
|
||||
|
||||
@{contentRows} = $body->look_down( '_tag', 'tr' );
|
||||
|
||||
my $contents = build_contents( @{contentRows} );
|
||||
$tree->delete;
|
||||
$item->{contents} = $contents;
|
||||
return $item;
|
||||
|
||||
}
|
||||
|
||||
# start app!
|
||||
my $api = build_api($apiUrl);
|
||||
my $api_json = to_json( $api, { utf8 => 1, pretty => 1 } );
|
||||
print $api_json. "\n";
|
|
@ -1,57 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AmazonEC2QueryAPI {
|
||||
private Map<String, Category> categories;
|
||||
private Map<String, DataType> dataTypes;
|
||||
private Set<String> see;
|
||||
|
||||
public void setCategories(Map<String, Category> categories) {
|
||||
this.categories = categories;
|
||||
}
|
||||
|
||||
public Map<String, Category> getCategories() {
|
||||
return categories;
|
||||
}
|
||||
|
||||
public void setDataTypes(Map<String, DataType> dataTypes) {
|
||||
this.dataTypes = dataTypes;
|
||||
}
|
||||
|
||||
public Map<String, DataType> getDataTypes() {
|
||||
return dataTypes;
|
||||
}
|
||||
|
||||
public void setSee(Set<String> see) {
|
||||
this.see = see;
|
||||
}
|
||||
|
||||
public Set<String> getSee() {
|
||||
return see;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class Category {
|
||||
private Map<String, Query> queries;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Category");
|
||||
sb.append("{queries=").append(queries);
|
||||
sb.append(", name='").append(name).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
public void setQueries(Map<String, Query> categories) {
|
||||
this.queries = categories;
|
||||
}
|
||||
|
||||
public Map<String, Query> getQueries() {
|
||||
return queries;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class Content {
|
||||
|
||||
private String constraints;
|
||||
private String defaultValue;
|
||||
private String desc;
|
||||
private Map<String, String> valueMap;
|
||||
private String name;
|
||||
private String optional;
|
||||
private String type;
|
||||
|
||||
public void setConstraints(String constraints) {
|
||||
this.constraints = constraints;
|
||||
}
|
||||
|
||||
public String getConstraints() {
|
||||
return constraints;
|
||||
}
|
||||
|
||||
public void setDefaultValue(String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void setDesc(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public void setValueMap(Map<String, String> valueMap) {
|
||||
this.valueMap = valueMap;
|
||||
}
|
||||
|
||||
public Map<String, String> getValueMap() {
|
||||
return valueMap;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setOptional(String optional) {
|
||||
this.optional = optional;
|
||||
}
|
||||
|
||||
public String getOptional() {
|
||||
return optional;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class DataType {
|
||||
|
||||
private String type;
|
||||
private String ancestor;
|
||||
private Set<String> see;
|
||||
private List<String> exampleCode;
|
||||
private List<String> exampleHTML;
|
||||
private Set<Content> contents;
|
||||
|
||||
public DataType() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setAncestor(String ancestor) {
|
||||
this.ancestor = ancestor;
|
||||
}
|
||||
|
||||
public String getAncestor() {
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
public void setSee(Set<String> see) {
|
||||
this.see = see;
|
||||
}
|
||||
|
||||
public Set<String> getSee() {
|
||||
return see;
|
||||
}
|
||||
|
||||
public void setContents(Set<Content> contents) {
|
||||
this.contents = contents;
|
||||
}
|
||||
|
||||
public Set<Content> getContents() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
public void setExampleCode(List<String> exampleCode) {
|
||||
this.exampleCode = exampleCode;
|
||||
}
|
||||
|
||||
public List<String> getExampleCode() {
|
||||
return exampleCode;
|
||||
}
|
||||
|
||||
public void setExampleHTML(List<String> exampleHTML) {
|
||||
this.exampleHTML = exampleHTML;
|
||||
}
|
||||
|
||||
public List<String> getExampleHTML() {
|
||||
return exampleHTML;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class Query extends DataType {
|
||||
|
||||
private String responseType;
|
||||
private String description;
|
||||
|
||||
public void setResponseType(String responseType) {
|
||||
this.responseType = responseType;
|
||||
}
|
||||
|
||||
public String getResponseType() {
|
||||
return responseType;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
|
@ -1,275 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi.parser;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
public class AmazonEC2QueryAPIExpectations {
|
||||
protected final Set<String> queryNames;
|
||||
|
||||
public AmazonEC2QueryAPIExpectations() {
|
||||
queryNames = Sets.newHashSet();
|
||||
for (Set<String> qNames : expectedQueryNamesForCategoryName.values()) {
|
||||
queryNames.addAll(qNames);
|
||||
}
|
||||
}
|
||||
|
||||
// Please do not reformat this class, as it will not likely look as nice.
|
||||
protected static final Map<String, Set<String>> expectedQueryNamesForCategoryName = new ImmutableMap.Builder<String, Set<String>>()
|
||||
.put("Amazon DevPay", ImmutableSet.of("ConfirmProductInstance")).put(
|
||||
"AMIs",
|
||||
ImmutableSet.of("DeregisterImage", "ModifyImageAttribute",
|
||||
"DescribeImageAttribute", "DescribeImages")).put(
|
||||
"Availability Zones and Regions",
|
||||
ImmutableSet.of("DescribeAvailabilityZones", "DescribeRegions")).put(
|
||||
"Elastic Block Store",
|
||||
ImmutableSet.of("DeleteVolume", "DescribeSnapshots", "DescribeVolumes",
|
||||
"DetachVolume", "AttachVolume", "CreateSnapshot", "CreateVolume",
|
||||
"DeleteSnapshot")).put(
|
||||
"Elastic IP Addresses",
|
||||
ImmutableSet.of("AllocateAddress", "DisassociateAddress", "ReleaseAddress",
|
||||
"AssociateAddress", "DescribeAddresses")).put("General",
|
||||
ImmutableSet.of("GetConsoleOutput")).put("Images",
|
||||
ImmutableSet.of("ResetImageAttribute", "RegisterImage")).put(
|
||||
"Instances",
|
||||
ImmutableSet.of("TerminateInstances", "DescribeInstances", "RunInstances",
|
||||
"RebootInstances")).put("Key Pairs",
|
||||
ImmutableSet.of("DescribeKeyPairs", "CreateKeyPair", "DeleteKeyPair")).put(
|
||||
"Monitoring", ImmutableSet.of("MonitorInstances", "UnmonitorInstances")).put(
|
||||
"Reserved Instances",
|
||||
ImmutableSet.of("DescribeReservedInstances",
|
||||
"DescribeReservedInstancesOfferings",
|
||||
"PurchaseReservedInstancesOffering")).put(
|
||||
"Security Groups",
|
||||
ImmutableSet.of("DescribeSecurityGroups", "AuthorizeSecurityGroupIngress",
|
||||
"CreateSecurityGroup", "DeleteSecurityGroup",
|
||||
"RevokeSecurityGroupIngress")).put("Windows",
|
||||
ImmutableSet.of("CancelBundleTask", "DescribeBundleTasks", "BundleInstance"))
|
||||
.build();
|
||||
protected static final Map<String, Set<String>> expectedFieldNamesForDataTypeName = new ImmutableMap.Builder<String, Set<String>>()
|
||||
.put("ReservationSetType", ImmutableSet.of("item")).put("DeleteKeyPairResponse",
|
||||
ImmutableSet.of("return", "requestId")).put(
|
||||
"DescribeKeyPairsResponseInfoType", ImmutableSet.of("item")).put(
|
||||
"AuthorizeSecurityGroupIngressResponse",
|
||||
ImmutableSet.of("return", "requestId")).put("AttachmentSetItemResponseType",
|
||||
ImmutableSet.of("device", "status", "volumeId", "instanceId", "attachTime"))
|
||||
.put("DescribeAddressesResponseInfoType", ImmutableSet.of("item")).put(
|
||||
"DescribeReservedInstancesResponse",
|
||||
ImmutableSet.of("requestId", "reservedInstancesSet")).put(
|
||||
"DescribeVolumesSetItemResponseType",
|
||||
ImmutableSet.of("status", "size", "createTime", "snapshotId",
|
||||
"availabilityZone", "volumeId", "attachmentSet")).put(
|
||||
"LaunchPermissionItemType", ImmutableSet.of("group", "userId")).put(
|
||||
"DescribeSnapshotsSetItemResponseType",
|
||||
ImmutableSet.of("status", "snapshotId", "volumeId", "startTime", "progress"))
|
||||
.put(
|
||||
"RunningInstancesItemType",
|
||||
ImmutableSet.of("dnsName", "instanceState", "launchTime", "privateDnsName",
|
||||
"reason", "monitoring", "platform", "productCodes", "amiLaunchIndex",
|
||||
"keyName", "ramdiskId", "kernelId", "imageId", "instanceType",
|
||||
"instanceId", "placement")).put(
|
||||
"DescribeReservedInstancesOfferingsResponse",
|
||||
ImmutableSet.of("requestId", "reservedInstancesOfferingsSet")).put(
|
||||
"BlockDeviceMappingType", ImmutableSet.of("item")).put(
|
||||
"ResetImageAttributeResponse", ImmutableSet.of("requestId", "imageId")).put(
|
||||
"AvailabilityZoneSetType", ImmutableSet.of("item")).put(
|
||||
"RevokeSecurityGroupIngressResponse", ImmutableSet.of("return", "requestId"))
|
||||
.put("ReservationInfoType",
|
||||
ImmutableSet.of("groupSet", "reservationId", "instancesSet", "ownerId")).put(
|
||||
"RebootInstancesResponse", ImmutableSet.of("return", "requestId")).put(
|
||||
"GroupItemType", ImmutableSet.of("groupId")).put("AvailabilityZoneItemType",
|
||||
ImmutableSet.of("regionName", "zoneName", "zoneState")).put(
|
||||
"RunningInstancesSetType", ImmutableSet.of("item")).put(
|
||||
"CreateSecurityGroupResponse", ImmutableSet.of("return", "requestId")).put(
|
||||
"ReleaseAddressResponse", ImmutableSet.of("return", "requestId")).put(
|
||||
"SecurityGroupItemType",
|
||||
ImmutableSet.of("groupName", "ipPermissions", "groupDescription", "ownerId"))
|
||||
.put("NullableAttributeValueType", ImmutableSet.of("value")).put(
|
||||
"DescribeSnapshotsResponse", ImmutableSet.of("requestId", "snapshotSet")).put(
|
||||
"BundleInstanceResponse", ImmutableSet.of("bundleInstanceTask", "requestId"))
|
||||
.put("DescribeKeyPairsResponseItemType", ImmutableSet.of("keyName", "keyFingerprint"))
|
||||
.put("BundleInstanceTasksSetType", ImmutableSet.of("bundleInstanceTask"))
|
||||
.put("DescribeAddressesResponseItemType", ImmutableSet.of("publicIp", "instanceId"))
|
||||
.put("MonitorInstancesResponse", ImmutableSet.of("requestId", "instancesSet")).put(
|
||||
"DescribeImagesResponse", ImmutableSet.of("imagesSet", "requestId")).put(
|
||||
"MonitorInstancesResponseSetItemType",
|
||||
ImmutableSet.of("monitoring", "instanceId")).put(
|
||||
"BundleInstanceTaskErrorType", ImmutableSet.of("code", "message")).put(
|
||||
"ProductCodesSetType", ImmutableSet.of("item")).put(
|
||||
"UnmonitorInstancesResponse", ImmutableSet.of("instancesSet", "requestId"))
|
||||
.put(
|
||||
"IpPermissionType",
|
||||
ImmutableSet.of("groups", "portRange", "fromPort", "ipProtocol", "icmpPort",
|
||||
"toPort", "ipRanges")).put("IpPermissionSetType",
|
||||
ImmutableSet.of("item")).put("DeleteSecurityGroupResponse",
|
||||
ImmutableSet.of("requestId", "return")).put(
|
||||
"RunInstancesResponse",
|
||||
ImmutableSet.of("instancesSet", "requesterId", "groupSet", "reservationId",
|
||||
"requestId", "ownerId")).put("DeregisterImageResponse",
|
||||
ImmutableSet.of("return", "requestId")).put("TerminateInstancesResponse",
|
||||
ImmutableSet.of("requestId", "instancesSet")).put(
|
||||
"DescribeSnapshotsSetResponseType", ImmutableSet.of("item")).put(
|
||||
"DescribeReservedInstancesOfferingsResponseSetType", ImmutableSet.of("item"))
|
||||
.put(
|
||||
"BundleInstanceTaskType",
|
||||
ImmutableSet.of("updateTime", "startTime", "progress", "instanceId", "state",
|
||||
"bundleId", "storage", "error")).put(
|
||||
"ConfirmProductInstanceResponse",
|
||||
ImmutableSet.of("ownerId", "requestId", "return")).put(
|
||||
"CreateKeyPairResponse",
|
||||
ImmutableSet.of("keyName", "keyMaterial", "requestId", "keyFingerprint")).put(
|
||||
"RegisterImageResponse", ImmutableSet.of("imageId", "requestId")).put(
|
||||
"IpRangeSetType", ImmutableSet.of("item")).put("RegionSetType",
|
||||
ImmutableSet.of("item")).put("InstanceStateType",
|
||||
ImmutableSet.of("name", "code")).put(
|
||||
"DescribeReservedInstancesOfferingsResponseSetItemType",
|
||||
ImmutableSet.of("productDescription", "reservedInstancesOfferingId",
|
||||
"usagePrice", "fixedPrice", "availabilityZone", "duration",
|
||||
"instanceType")).put(
|
||||
"BundleInstanceS3StorageType",
|
||||
ImmutableSet.of("awsAccessKeyId", "uploadPolicy", "secret-access-key",
|
||||
"bucket", "prefix", "uploadPolicySignature")).put(
|
||||
"DescribeVolumesResponse", ImmutableSet.of("requestId", "volumeSet")).put(
|
||||
"TerminateInstancesResponseInfoType", ImmutableSet.of("item")).put(
|
||||
"DeleteSnapshotResponse", ImmutableSet.of("return", "requestId")).put(
|
||||
"BundleInstanceTaskStorageType", ImmutableSet.of("S3")).put(
|
||||
"DescribeAvailabilityZonesResponse",
|
||||
ImmutableSet.of("requestId", "availabilityZoneInfo")).put(
|
||||
"CreateVolumeResponse",
|
||||
ImmutableSet.of("snapshotId", "size", "volumeId", "availabilityZone",
|
||||
"requestId", "createTime", "status")).put(
|
||||
"DescribeReservedInstancesResponseSetType", ImmutableSet.of("item")).put(
|
||||
"DescribeAddressesResponse", ImmutableSet.of("requestId", "addressesSet"))
|
||||
.put("InstanceMonitoringStateType", ImmutableSet.of("state")).put(
|
||||
"DetachVolumeResponse",
|
||||
ImmutableSet.of("status", "requestId", "instanceId", "volumeId", "device",
|
||||
"attachTime")).put("DescribeKeyPairsResponse",
|
||||
ImmutableSet.of("requestId", "keySet")).put(
|
||||
"AttachVolumeResponse",
|
||||
ImmutableSet.of("device", "attachTime", "requestId", "volumeId", "status",
|
||||
"instanceId")).put("DescribeBundleTasksResponse",
|
||||
ImmutableSet.of("bundleInstanceTasksSet", "requestId")).put(
|
||||
"TerminateInstancesResponseItemType",
|
||||
ImmutableSet.of("shutdownState", "previousState", "instanceId")).put(
|
||||
"SecurityGroupSetType", ImmutableSet.of("item")).put(
|
||||
"AttachmentSetResponseType", ImmutableSet.of("item")).put(
|
||||
"DescribeImageAttributeResponse",
|
||||
ImmutableSet.of("kernel", "productCodes", "requestId", "ramdisk",
|
||||
"launchPermission", "blockDeviceMapping", "imageId")).put(
|
||||
"PurchaseReservedInstancesOfferingResponse",
|
||||
ImmutableSet.of("reservedInstancesId", "requestId")).put(
|
||||
"CreateSnapshotResponse",
|
||||
ImmutableSet.of("requestId", "status", "startTime", "volumeId", "snapshotId",
|
||||
"progress")).put("GroupSetType", ImmutableSet.of("item")).put(
|
||||
"ProductCodesSetItemType", ImmutableSet.of("productCode")).put(
|
||||
"AllocateAddressResponse", ImmutableSet.of("requestId", "publicIp")).put(
|
||||
"ProductCodeItemType", ImmutableSet.of("productCode")).put(
|
||||
"UserIdGroupPairType", ImmutableSet.of("userId", "groupName ")).put(
|
||||
"DescribeVolumesSetResponseType", ImmutableSet.of("item")).put(
|
||||
"ProductCodeListType", ImmutableSet.of("item")).put("DescribeRegionsResponse",
|
||||
ImmutableSet.of("requestId", "regionInfo")).put("RegionItemType",
|
||||
ImmutableSet.of("regionEndpoint", "regionName")).put(
|
||||
"DescribeInstancesResponse", ImmutableSet.of("requestId", "reservationSet"))
|
||||
.put(
|
||||
"DescribeImagesResponseItemType",
|
||||
ImmutableSet.of("kernelId", "productCodes", "isPublic", "imageId",
|
||||
"ramdiskId", "imageOwnerId", "platform", "imageType", "imageState",
|
||||
"imageLocation", "architecture")).put("LaunchPermissionListType",
|
||||
ImmutableSet.of("item")).put("BlockDeviceMappingItemType",
|
||||
ImmutableSet.of("virtualName", "deviceName")).put("DeleteVolumeResponse",
|
||||
ImmutableSet.of("return", "requestId")).put("DescribeImagesResponseInfoType",
|
||||
ImmutableSet.of("item")).put("IpRangeItemType", ImmutableSet.of("cidrIp "))
|
||||
.put("DisassociateAddressResponse", ImmutableSet.of("requestId", "return")).put(
|
||||
"UserIdGroupPairSetType", ImmutableSet.of("item"))
|
||||
.put("CancelBundleTaskResponse", ImmutableSet.of("bundleInstanceTask", "requestId"))
|
||||
.put("MonitorInstancesResponseSetType", ImmutableSet.of("item")).put(
|
||||
"DescribeReservedInstancesResponseSetItemType",
|
||||
ImmutableSet.of("state", "duration", "usagePrice", "instanceType",
|
||||
"instanceCount", "productDescription", "reservedInstancesId",
|
||||
"fixedPrice", "availabilityZone", "start")).put(
|
||||
"DescribeSecurityGroupsResponse",
|
||||
ImmutableSet.of("requestId", "securityGroupInfo")).put(
|
||||
"GetConsoleOutputResponse",
|
||||
ImmutableSet.of("requestId", "output", "instanceId", "timestamp")).put(
|
||||
"ModifyImageAttributeResponse", ImmutableSet.of("requestId", "return"))
|
||||
.put("AssociateAddressResponse", ImmutableSet.of("requestId", "publicIp", "return"))
|
||||
.put("ConfirmProductInstance", ImmutableSet.of("ProductCode", "InstanceId")).put(
|
||||
"DeregisterImage", ImmutableSet.of("ImageId")).put(
|
||||
"ModifyImageAttribute",
|
||||
ImmutableSet.of("Group.n", "UserId.n", "ImageId", "ProductCode.n", "Group.n",
|
||||
"UserId.n")).put("DescribeImageAttribute",
|
||||
ImmutableSet.of("Attribute", "ImageId")).put("DescribeImages",
|
||||
ImmutableSet.of("explicit", "public", "implicit")).put(
|
||||
"DescribeAvailabilityZones", ImmutableSet.of("ZoneName")).put(
|
||||
"DescribeRegions", ImmutableSet.of("RegionName.n")).put("DeleteVolume",
|
||||
ImmutableSet.of("VolumeId")).put("DescribeSnapshots",
|
||||
ImmutableSet.of("SnapshotId.n")).put("DescribeVolumes",
|
||||
ImmutableSet.of("VolumeId")).put("DetachVolume",
|
||||
ImmutableSet.of("Device", "VolumeId", "InstanceId", "Force")).put(
|
||||
"AttachVolume", ImmutableSet.of("InstanceId", "Device", "VolumeId")).put(
|
||||
"CreateSnapshot", ImmutableSet.of("VolumeId")).put("CreateVolume",
|
||||
ImmutableSet.of("SnapshotId", "Size", "AvailabilityZone")).put(
|
||||
"DeleteSnapshot", ImmutableSet.of("SnapshotId")).put("AllocateAddress",
|
||||
ImmutableSet.of("AllocateAddressResponse", "requestId", "publicIp")).put(
|
||||
"DisassociateAddress", ImmutableSet.of("PublicIp")).put("ReleaseAddress",
|
||||
ImmutableSet.of("PublicIp")).put("AssociateAddress",
|
||||
ImmutableSet.of("InstanceId", "PublicIp")).put("DescribeAddresses",
|
||||
ImmutableSet.of("PublicIp.n")).put("GetConsoleOutput",
|
||||
ImmutableSet.of("InstanceId")).put("ResetImageAttribute",
|
||||
ImmutableSet.of("ImageId")).put("RegisterImage",
|
||||
ImmutableSet.of("ImageLocation")).put("TerminateInstances",
|
||||
ImmutableSet.of("InstanceId.n")).put("DescribeInstances",
|
||||
ImmutableSet.of("InstanceId.n")).put(
|
||||
"RunInstances",
|
||||
ImmutableSet.of("Monitoring.Enabled", "Encoding", "AvailabilityZone",
|
||||
"KernelId", "MaxCount", "Data", "ImageId", "InstanceType",
|
||||
"MinCount", "groupId", "VirtualName", "AddressingType", "KeyName",
|
||||
"DeviceName", "Version", "RamdiskId")).put("RebootInstances",
|
||||
ImmutableSet.of("InstanceId.n")).put("DescribeKeyPairs",
|
||||
ImmutableSet.of("KeyName.n")).put("CreateKeyPair", ImmutableSet.of("KeyName"))
|
||||
.put("DeleteKeyPair", ImmutableSet.of("KeyName")).put("MonitorInstances",
|
||||
ImmutableSet.of("InstanceId.n")).put("UnmonitorInstances",
|
||||
ImmutableSet.of("InstanceId.n")).put("DescribeReservedInstances",
|
||||
ImmutableSet.of("ReservedInstancesId.n")).put(
|
||||
"DescribeReservedInstancesOfferings",
|
||||
ImmutableSet.of("ProductDescription", "ReservedInstancesOfferingId",
|
||||
"AvailabilityZone", "InstanceType")).put(
|
||||
"PurchaseReservedInstancesOffering",
|
||||
ImmutableSet.of("ReservedInstancesOfferingId.n", "InstanceCount.n")).put(
|
||||
"DescribeSecurityGroups", ImmutableSet.of("GroupName.n")).put(
|
||||
"AuthorizeSecurityGroupIngress",
|
||||
ImmutableSet.of("GroupName", "GroupName", "UserId", "IpProtocol", "CidrIp",
|
||||
"ToPort", "FromPort", "UserId")).put("CreateSecurityGroup",
|
||||
ImmutableSet.of("GroupDescription", "GroupName")).put("DeleteSecurityGroup",
|
||||
ImmutableSet.of("GroupName")).put(
|
||||
"RevokeSecurityGroupIngress",
|
||||
ImmutableSet.of("IpProtocol", "GroupName", "UserId", "CidrIp", "FromPort",
|
||||
"ToPort", "GroupName", "UserId")).put("CancelBundleTask",
|
||||
ImmutableSet.of("BundleId")).put("DescribeBundleTasks",
|
||||
ImmutableSet.of("BundleId")).put(
|
||||
"BundleInstance",
|
||||
ImmutableSet.of("Storage.S3.UploadPolicy", "InstanceId", "Storage.S3.Prefix",
|
||||
"Storage.S3.AWSAccessKeyId", "Storage.S3.Bucket",
|
||||
"Storage.S3.UploadPolicySignature")).build();
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi.parser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import org.jclouds.codegen.ec2.queryapi.AmazonEC2QueryAPI;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.common.io.Closeables;
|
||||
|
||||
/**
|
||||
* Converts object models representing AWS API beans into Java classes.
|
||||
* <p>
|
||||
* This implementation is designed to perform the following steps:
|
||||
* <ul>
|
||||
* <li>Parse the JSON object representation produced by the <tt>parse_ec2.pl</tt> perl script</li>
|
||||
* <li>Convert the JSON into Java object models (@see org.jclouds.aws.codegen.models)</li>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AmazonEC2QueryAPIParser {
|
||||
|
||||
public AmazonEC2QueryAPI parseJSONResource(String resource) {
|
||||
InputStream in = AmazonEC2QueryAPI.class.getResourceAsStream(resource);
|
||||
return parseJSONInputStream(in);
|
||||
}
|
||||
|
||||
public AmazonEC2QueryAPI parseJSONFile(File file) throws FileNotFoundException {
|
||||
InputStream in = new FileInputStream(file);
|
||||
return parseJSONInputStream(in);
|
||||
}
|
||||
|
||||
public AmazonEC2QueryAPI parseJSONInputStream(InputStream in) {
|
||||
assert in != null;
|
||||
Gson gson = new Gson();
|
||||
try {
|
||||
AmazonEC2QueryAPIValidator validator = new AmazonEC2QueryAPIValidator();
|
||||
validator.setModel(gson.fromJson(new InputStreamReader(in), AmazonEC2QueryAPI.class));
|
||||
validator.validateCategories().validateCommands().validateDomain();
|
||||
return validator.getModel();
|
||||
} finally {
|
||||
Closeables.closeQuietly(in);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi.parser;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.codegen.ec2.queryapi.AmazonEC2QueryAPI;
|
||||
import org.jclouds.codegen.ec2.queryapi.Category;
|
||||
import org.jclouds.codegen.ec2.queryapi.Content;
|
||||
import org.jclouds.codegen.ec2.queryapi.DataType;
|
||||
import org.jclouds.codegen.ec2.queryapi.Query;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
public class AmazonEC2QueryAPIValidator extends AmazonEC2QueryAPIExpectations {
|
||||
protected AmazonEC2QueryAPIValidator validateQueriesInCategory(String categoryName) {
|
||||
for (String query : expectedQueryNamesForCategoryName.get(categoryName)) {
|
||||
validateQueryInCategory(query, categoryName);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
protected AmazonEC2QueryAPIValidator validateQueryInCategory(String queryName,
|
||||
String categoryName) {
|
||||
Category category = getModel().getCategories().get(categoryName);
|
||||
checkState(category != null, String.format("category %1$s not present", categoryName));
|
||||
Query query = category.getQueries().get(queryName);
|
||||
validateTopLevelType(query);
|
||||
checkState(category != null, String.format("query %1$s not present in category %2$s",
|
||||
queryName, categoryName));
|
||||
checkState(query.getResponseType().equals(query.getType() + "Response"), String.format(
|
||||
"Invalid responseType for %1$s [%2$s] should be %1$sResponse", queryName, query
|
||||
.getResponseType()));
|
||||
checkNotNull(query.getDescription(), String.format("%1$s: getDescription()", query.getType()));
|
||||
|
||||
validateTopLevelType(query);
|
||||
|
||||
DataType response = getModel().getDataTypes().get(query.getResponseType());
|
||||
checkNotNull(response, String.format("response %1$s not present in domain for %2$s", query
|
||||
.getResponseType(), query.getType()));
|
||||
checkState(query.getResponseType().equals(query.getType() + "Response"));
|
||||
checkState(response.getType().equals(query.getType() + "Response"));
|
||||
validateTopLevelType(response);
|
||||
return validateDataType(query);
|
||||
}
|
||||
|
||||
protected void validateTopLevelType(DataType type) {
|
||||
checkState(type.getAncestor() == null, String
|
||||
.format("%1$s should not have an ancestor", type));
|
||||
checkNotNull(type.getExampleCode(), String.format("%1$s: getExampleCode()", type.getType()));
|
||||
checkNotNull(type.getExampleHTML(), String.format("%1$s: getExampleHTML()", type.getType()));
|
||||
}
|
||||
|
||||
protected AmazonEC2QueryAPIValidator validateDataType(DataType dataType) {
|
||||
checkState(dataType.getSee().size() >= 1, "see should have at least one entry");
|
||||
Set<String> fieldNames = Sets.newTreeSet(Iterables.transform(dataType.getContents(),
|
||||
new Function<Content, String>() {
|
||||
public String apply(Content field) {
|
||||
return field.getName();
|
||||
}
|
||||
}));
|
||||
checkState(Sets.difference(fieldNames,
|
||||
expectedFieldNamesForDataTypeName.get(dataType.getType())).size() == 0, String
|
||||
.format("%1$s hasn't the correct fields. has [%2$s] should have [%3$s]", dataType
|
||||
.getType(), fieldNames, expectedFieldNamesForDataTypeName.get(dataType
|
||||
.getType())));
|
||||
return this;
|
||||
}
|
||||
|
||||
private AmazonEC2QueryAPI model;
|
||||
|
||||
public AmazonEC2QueryAPIValidator validateCommands() {
|
||||
for (String categoryName : expectedQueryNamesForCategoryName.keySet()) {
|
||||
for (String queryName : expectedQueryNamesForCategoryName.get(categoryName)) {
|
||||
validateQueryInCategory(queryName, categoryName);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public AmazonEC2QueryAPIValidator validateDomain() {
|
||||
for (String dataTypeName : expectedFieldNamesForDataTypeName.keySet()) {
|
||||
if (!this.queryNames.contains(dataTypeName))
|
||||
validateDataType(checkNotNull(getModel().getDataTypes().get(dataTypeName), dataTypeName));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public AmazonEC2QueryAPIValidator validateCategories() {
|
||||
checkState(Sets.difference(getModel().getCategories().keySet(),
|
||||
expectedQueryNamesForCategoryName.keySet()).size() == 0);
|
||||
checkState(getModel().getCategories().keySet().size() == expectedQueryNamesForCategoryName
|
||||
.keySet().size());
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setModel(AmazonEC2QueryAPI model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public AmazonEC2QueryAPI getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi.transform;
|
||||
|
||||
import org.jclouds.codegen.ec2.queryapi.AmazonEC2QueryAPI;
|
||||
import org.jclouds.codegen.model.API;
|
||||
|
||||
/**
|
||||
* Converts object models representing AWS API beans into Java classes.
|
||||
* <p>
|
||||
* This implementation is designed to perform the following steps:
|
||||
* <ul>
|
||||
* <li>Parse the JSON object representation produced by the <tt>parse_ec2.pl</tt> perl script</li>
|
||||
* <li>Convert the JSON into Java object models (@see org.jclouds.aws.codegen.models)</li>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AmazonEC2QueryAPITransformer {
|
||||
|
||||
public API transform(AmazonEC2QueryAPI amazonAPI) {
|
||||
API api = new API();
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi.transform;
|
||||
|
||||
import org.jclouds.codegen.ec2.queryapi.Content;
|
||||
import org.jclouds.codegen.model.Field;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* Converts object models representing AWS API beans into Java classes.
|
||||
* <p>
|
||||
* This implementation is designed to perform the following steps:
|
||||
* <ul>
|
||||
* <li>Parse the JSON object representation produced by the <tt>parse_ec2.pl</tt> perl script</li>
|
||||
* <li>Convert the JSON into Java object models (@see org.jclouds.aws.codegen.models)</li>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ConvertContentToField implements Function<Content, Field> {
|
||||
|
||||
public Field apply(Content from) {
|
||||
Field field = new Field();
|
||||
field.setConstraints(from.getConstraints());
|
||||
field.setDefaultValue(from.getDefaultValue());
|
||||
field.setDesc(from.getDesc());
|
||||
field.setName(from.getName());
|
||||
field.setJavaName(parseJavaName(from.getName()));
|
||||
field.setOptional(Boolean.parseBoolean(from.getOptional()));
|
||||
field.setType(from.getType());
|
||||
field.setValueMap(from.getValueMap());
|
||||
field.setJavaType(parseJavaType(from.getType()));
|
||||
return field;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String parseJavaType(String type) {
|
||||
if (type.indexOf("xsd:") >= 0) {
|
||||
return parseJavaTypeForXsd(type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String parseJavaTypeForXsd(String type) {
|
||||
if (type.equals("xsd:string")) {
|
||||
return "String";
|
||||
} else if (type.equals("xsd:Int")) {
|
||||
return "Integer";
|
||||
} else if (type.equals("xsd:boolean")) {
|
||||
return "Boolean";
|
||||
} else if (type.equals("xsd:dateTime")) {
|
||||
return "org.joda.time.DateTime";
|
||||
} else {
|
||||
throw new IllegalArgumentException("type not supported: " + type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String parseJavaName(String name) {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,899 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi.parser;
|
||||
|
||||
import org.jclouds.codegen.ec2.queryapi.Category;
|
||||
import org.jclouds.codegen.ec2.queryapi.Content;
|
||||
import org.jclouds.codegen.ec2.queryapi.DataType;
|
||||
import org.jclouds.codegen.ec2.queryapi.Query;
|
||||
import org.jclouds.codegen.ec2.queryapi.parser.AmazonEC2QueryAPIParser;
|
||||
import org.jclouds.codegen.ec2.queryapi.parser.AmazonEC2QueryAPIValidator;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests to ensure that the json file parsed from the EC2 site appears correct.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(testName = "ec2.AmazonEC2QueryAPIParserTest")
|
||||
public class AmazonEC2QueryAPIParserTest extends AmazonEC2QueryAPIValidator {
|
||||
@BeforeTest
|
||||
public void setUp() throws Exception {
|
||||
setModel(new AmazonEC2QueryAPIParser().parseJSONResource("/objmodels/ec2.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCategoriesParsedNames() {
|
||||
super.validateCategories();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void tearDown() throws Exception {
|
||||
setModel(null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void codeUsedToGenerateThisClass() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder
|
||||
.append(" private Map<String, Set<String>> expectedQueryNamesForCategoryName = new ImmutableMap.Builder");
|
||||
builder.append("<String, Set<String>>()").append("\n");
|
||||
|
||||
for (Category category : getModel().getCategories().values()) {
|
||||
builder.append(String.format(".put(\"%1$s\",%n ImmutableSet.of(", category.getName()));
|
||||
for (String string : category.getQueries().keySet()) {
|
||||
builder.append(String.format("\"%1$s\",", string));
|
||||
}
|
||||
builder.append(String.format("))%n"));
|
||||
}
|
||||
builder.append(String.format(".build();"));
|
||||
System.out.println(builder.toString().replaceAll(",\\)", ")"));
|
||||
|
||||
builder = new StringBuilder();
|
||||
builder
|
||||
.append(" private Map<String, Set<String>> expectedFieldNamesForBeanName = new ImmutableMap.Builder");
|
||||
builder.append("<String, Set<String>>()").append("\n");
|
||||
|
||||
for (DataType bean : getModel().getDataTypes().values()) {
|
||||
builder.append(String.format(".put(\"%1$s\",%n ImmutableSet.of(", bean.getType()));
|
||||
for (Content field : bean.getContents()) {
|
||||
builder.append(String.format("\"%1$s\",", field.getName()));
|
||||
}
|
||||
builder.append(String.format("))%n"));
|
||||
}
|
||||
for (Category category : getModel().getCategories().values()) {
|
||||
for (DataType bean : category.getQueries().values()) {
|
||||
builder.append(String.format(".put(\"%1$s\",%n ImmutableSet.of(", bean.getType()));
|
||||
for (Content field : bean.getContents()) {
|
||||
builder.append(String.format("\"%1$s\",", field.getName()));
|
||||
}
|
||||
builder.append(String.format("))%n"));
|
||||
}
|
||||
}
|
||||
builder.append(String.format(".build();"));
|
||||
System.out.println(builder.toString().replaceAll(",\\)", ")"));
|
||||
|
||||
for (String string : getModel().getCategories().keySet()) {
|
||||
System.out.printf(" @Test%n public void test%1$sQueryNames(){%n "
|
||||
+ "validateQueriesInCategory(\"%2$s\");" + "}%n", string.replaceAll(" ", ""),
|
||||
string);
|
||||
}
|
||||
|
||||
for (Category cat : getModel().getCategories().values()) {
|
||||
for (Query bean : cat.getQueries().values()) {
|
||||
System.out.printf(" @Test%n public void test%1$sQuery(){%n "
|
||||
+ "validateQueryInCategory(\"%1$s\", \"%2$s\");%n}%n", bean.getType(), cat
|
||||
.getName());
|
||||
}
|
||||
|
||||
}
|
||||
for (DataType bean : getModel().getDataTypes().values()) {
|
||||
System.out.printf(" @Test%n public void test%1$sBean(){%n "
|
||||
+ "validateFieldsOfBean(getModel().getDomain().get(\"%1$s\"));%n}%n", bean
|
||||
.getType());
|
||||
}
|
||||
System.out.printf(" public EC2ModelValidator validateCommands() {%n");
|
||||
for (Category cat : getModel().getCategories().values()) {
|
||||
for (Query bean : cat.getQueries().values()) {
|
||||
System.out.printf("validateQueryInCategory(\"%1$s\", \"%2$s\");%n", bean.getType(), cat
|
||||
.getName());
|
||||
}
|
||||
}
|
||||
System.out.printf("return this;%n }%n");
|
||||
|
||||
System.out.printf(" public EC2ModelValidator validateDomain() {%n");
|
||||
for (DataType bean : getModel().getDataTypes().values()) {
|
||||
System.out.printf("validateFieldsOfBean(getModel().getDomain().get(\"%1$s\"));%n", bean
|
||||
.getType());
|
||||
}
|
||||
|
||||
System.out.printf("return this;%n }%n");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmazonDevPayQueryNames() {
|
||||
validateQueriesInCategory("Amazon DevPay");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAMIsQueryNames() {
|
||||
validateQueriesInCategory("AMIs");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailabilityZonesandRegionsQueryNames() {
|
||||
validateQueriesInCategory("Availability Zones and Regions");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElasticBlockStoreQueryNames() {
|
||||
validateQueriesInCategory("Elastic Block Store");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElasticIPAddressesQueryNames() {
|
||||
validateQueriesInCategory("Elastic IP Addresses");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneralQueryNames() {
|
||||
validateQueriesInCategory("General");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImagesQueryNames() {
|
||||
validateQueriesInCategory("Images");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstancesQueryNames() {
|
||||
validateQueriesInCategory("Instances");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyPairsQueryNames() {
|
||||
validateQueriesInCategory("Key Pairs");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMonitoringQueryNames() {
|
||||
validateQueriesInCategory("Monitoring");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReservedInstancesQueryNames() {
|
||||
validateQueriesInCategory("Reserved Instances");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecurityGroupsQueryNames() {
|
||||
validateQueriesInCategory("Security Groups");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWindowsQueryNames() {
|
||||
validateQueriesInCategory("Windows");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfirmProductInstanceQuery() {
|
||||
validateQueryInCategory("ConfirmProductInstance", "Amazon DevPay");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeregisterImageQuery() {
|
||||
validateQueryInCategory("DeregisterImage", "AMIs");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModifyImageAttributeQuery() {
|
||||
validateQueryInCategory("ModifyImageAttribute", "AMIs");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeImageAttributeQuery() {
|
||||
validateQueryInCategory("DescribeImageAttribute", "AMIs");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeImagesQuery() {
|
||||
validateQueryInCategory("DescribeImages", "AMIs");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeAvailabilityZonesQuery() {
|
||||
validateQueryInCategory("DescribeAvailabilityZones", "Availability Zones and Regions");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeRegionsQuery() {
|
||||
validateQueryInCategory("DescribeRegions", "Availability Zones and Regions");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteVolumeQuery() {
|
||||
validateQueryInCategory("DeleteVolume", "Elastic Block Store");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeSnapshotsQuery() {
|
||||
validateQueryInCategory("DescribeSnapshots", "Elastic Block Store");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeVolumesQuery() {
|
||||
validateQueryInCategory("DescribeVolumes", "Elastic Block Store");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetachVolumeQuery() {
|
||||
validateQueryInCategory("DetachVolume", "Elastic Block Store");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttachVolumeQuery() {
|
||||
validateQueryInCategory("AttachVolume", "Elastic Block Store");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSnapshotQuery() {
|
||||
validateQueryInCategory("CreateSnapshot", "Elastic Block Store");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateVolumeQuery() {
|
||||
validateQueryInCategory("CreateVolume", "Elastic Block Store");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSnapshotQuery() {
|
||||
validateQueryInCategory("DeleteSnapshot", "Elastic Block Store");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateAddressQuery() {
|
||||
validateQueryInCategory("AllocateAddress", "Elastic IP Addresses");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisassociateAddressQuery() {
|
||||
validateQueryInCategory("DisassociateAddress", "Elastic IP Addresses");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleaseAddressQuery() {
|
||||
validateQueryInCategory("ReleaseAddress", "Elastic IP Addresses");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAssociateAddressQuery() {
|
||||
validateQueryInCategory("AssociateAddress", "Elastic IP Addresses");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeAddressesQuery() {
|
||||
validateQueryInCategory("DescribeAddresses", "Elastic IP Addresses");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConsoleOutputQuery() {
|
||||
validateQueryInCategory("GetConsoleOutput", "General");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetImageAttributeQuery() {
|
||||
validateQueryInCategory("ResetImageAttribute", "Images");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterImageQuery() {
|
||||
validateQueryInCategory("RegisterImage", "Images");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTerminateInstancesQuery() {
|
||||
validateQueryInCategory("TerminateInstances", "Instances");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeInstancesQuery() {
|
||||
validateQueryInCategory("DescribeInstances", "Instances");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunInstancesQuery() {
|
||||
validateQueryInCategory("RunInstances", "Instances");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRebootInstancesQuery() {
|
||||
validateQueryInCategory("RebootInstances", "Instances");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeKeyPairsQuery() {
|
||||
validateQueryInCategory("DescribeKeyPairs", "Key Pairs");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateKeyPairQuery() {
|
||||
validateQueryInCategory("CreateKeyPair", "Key Pairs");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteKeyPairQuery() {
|
||||
validateQueryInCategory("DeleteKeyPair", "Key Pairs");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMonitorInstancesQuery() {
|
||||
validateQueryInCategory("MonitorInstances", "Monitoring");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnmonitorInstancesQuery() {
|
||||
validateQueryInCategory("UnmonitorInstances", "Monitoring");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeReservedInstancesQuery() {
|
||||
validateQueryInCategory("DescribeReservedInstances", "Reserved Instances");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeReservedInstancesOfferingsQuery() {
|
||||
validateQueryInCategory("DescribeReservedInstancesOfferings", "Reserved Instances");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPurchaseReservedInstancesOfferingQuery() {
|
||||
validateQueryInCategory("PurchaseReservedInstancesOffering", "Reserved Instances");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeSecurityGroupsQuery() {
|
||||
validateQueryInCategory("DescribeSecurityGroups", "Security Groups");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthorizeSecurityGroupIngressQuery() {
|
||||
validateQueryInCategory("AuthorizeSecurityGroupIngress", "Security Groups");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSecurityGroupQuery() {
|
||||
validateQueryInCategory("CreateSecurityGroup", "Security Groups");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSecurityGroupQuery() {
|
||||
validateQueryInCategory("DeleteSecurityGroup", "Security Groups");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevokeSecurityGroupIngressQuery() {
|
||||
validateQueryInCategory("RevokeSecurityGroupIngress", "Security Groups");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelBundleTaskQuery() {
|
||||
validateQueryInCategory("CancelBundleTask", "Windows");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeBundleTasksQuery() {
|
||||
validateQueryInCategory("DescribeBundleTasks", "Windows");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBundleInstanceQuery() {
|
||||
validateQueryInCategory("BundleInstance", "Windows");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReservationSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("ReservationSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteKeyPairResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DeleteKeyPairResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeKeyPairsResponseInfoTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeKeyPairsResponseInfoType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthorizeSecurityGroupIngressResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("AuthorizeSecurityGroupIngressResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttachmentSetItemResponseTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("AttachmentSetItemResponseType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeAddressesResponseInfoTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeAddressesResponseInfoType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeReservedInstancesResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeReservedInstancesResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeVolumesSetItemResponseTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeVolumesSetItemResponseType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchPermissionItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("LaunchPermissionItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeSnapshotsSetItemResponseTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeSnapshotsSetItemResponseType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunningInstancesItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("RunningInstancesItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeReservedInstancesOfferingsResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeReservedInstancesOfferingsResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockDeviceMappingTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("BlockDeviceMappingType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetImageAttributeResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("ResetImageAttributeResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailabilityZoneSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("AvailabilityZoneSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevokeSecurityGroupIngressResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("RevokeSecurityGroupIngressResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReservationInfoTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("ReservationInfoType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRebootInstancesResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("RebootInstancesResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGroupItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("GroupItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailabilityZoneItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("AvailabilityZoneItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunningInstancesSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("RunningInstancesSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSecurityGroupResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("CreateSecurityGroupResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleaseAddressResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("ReleaseAddressResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecurityGroupItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("SecurityGroupItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullableAttributeValueTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("NullableAttributeValueType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeSnapshotsResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeSnapshotsResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBundleInstanceResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("BundleInstanceResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeKeyPairsResponseItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeKeyPairsResponseItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBundleInstanceTasksSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("BundleInstanceTasksSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeAddressesResponseItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeAddressesResponseItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMonitorInstancesResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("MonitorInstancesResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeImagesResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeImagesResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMonitorInstancesResponseSetItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("MonitorInstancesResponseSetItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBundleInstanceTaskErrorTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("BundleInstanceTaskErrorType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProductCodesSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("ProductCodesSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnmonitorInstancesResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("UnmonitorInstancesResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIpPermissionTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("IpPermissionType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIpPermissionSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("IpPermissionSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSecurityGroupResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DeleteSecurityGroupResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunInstancesResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("RunInstancesResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeregisterImageResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DeregisterImageResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTerminateInstancesResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("TerminateInstancesResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeSnapshotsSetResponseTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeSnapshotsSetResponseType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeReservedInstancesOfferingsResponseSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get(
|
||||
"DescribeReservedInstancesOfferingsResponseSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBundleInstanceTaskTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("BundleInstanceTaskType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfirmProductInstanceResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("ConfirmProductInstanceResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateKeyPairResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("CreateKeyPairResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterImageResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("RegisterImageResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIpRangeSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("IpRangeSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegionSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("RegionSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstanceStateTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("InstanceStateType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeReservedInstancesOfferingsResponseSetItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get(
|
||||
"DescribeReservedInstancesOfferingsResponseSetItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBundleInstanceS3StorageTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("BundleInstanceS3StorageType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeVolumesResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeVolumesResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTerminateInstancesResponseInfoTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("TerminateInstancesResponseInfoType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSnapshotResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DeleteSnapshotResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBundleInstanceTaskStorageTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("BundleInstanceTaskStorageType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeAvailabilityZonesResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeAvailabilityZonesResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateVolumeResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("CreateVolumeResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeReservedInstancesResponseSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeReservedInstancesResponseSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeAddressesResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeAddressesResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstanceMonitoringStateTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("InstanceMonitoringStateType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetachVolumeResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DetachVolumeResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeKeyPairsResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeKeyPairsResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttachVolumeResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("AttachVolumeResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeBundleTasksResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeBundleTasksResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTerminateInstancesResponseItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("TerminateInstancesResponseItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecurityGroupSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("SecurityGroupSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttachmentSetResponseTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("AttachmentSetResponseType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeImageAttributeResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeImageAttributeResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPurchaseReservedInstancesOfferingResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("PurchaseReservedInstancesOfferingResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSnapshotResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("CreateSnapshotResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGroupSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("GroupSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProductCodesSetItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("ProductCodesSetItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateAddressResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("AllocateAddressResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProductCodeItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("ProductCodeItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserIdGroupPairTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("UserIdGroupPairType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeVolumesSetResponseTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeVolumesSetResponseType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProductCodeListTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("ProductCodeListType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeRegionsResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeRegionsResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegionItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("RegionItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeInstancesResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeInstancesResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeImagesResponseItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeImagesResponseItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchPermissionListTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("LaunchPermissionListType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockDeviceMappingItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("BlockDeviceMappingItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteVolumeResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DeleteVolumeResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeImagesResponseInfoTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeImagesResponseInfoType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIpRangeItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("IpRangeItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisassociateAddressResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DisassociateAddressResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserIdGroupPairSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("UserIdGroupPairSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelBundleTaskResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("CancelBundleTaskResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMonitorInstancesResponseSetTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get("MonitorInstancesResponseSetType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeReservedInstancesResponseSetItemTypeBean() {
|
||||
validateDataType(getModel().getDataTypes().get(
|
||||
"DescribeReservedInstancesResponseSetItemType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeSecurityGroupsResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("DescribeSecurityGroupsResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConsoleOutputResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("GetConsoleOutputResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModifyImageAttributeResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("ModifyImageAttributeResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAssociateAddressResponseBean() {
|
||||
validateDataType(getModel().getDataTypes().get("AssociateAddressResponse"));
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.codegen.ec2.queryapi.transform;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests to ensure that we can transform EC2 {@link Content contents} to jclouds {@link Field
|
||||
* fields}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(testName = "ec2.ConvertContentToFieldTest")
|
||||
public class ConvertContentToFieldTest {
|
||||
|
||||
// sub parse_java_type {
|
||||
// $_ = shift;
|
||||
// s/xsd:string/String/;
|
||||
// s/xsd:boolean/Boolean/;
|
||||
// s/xsd:Int/Integer/;
|
||||
// s/xsd:dateTime/DateTime/;
|
||||
// if (/Type/ || /Item/ || /Info/) {
|
||||
// my $awsType = $_;
|
||||
// my $javaType = get_java_name($awsType);
|
||||
// #if ( !/Response/ ) {
|
||||
// $domain->{$awsType} = {
|
||||
// awsType => $awsType,
|
||||
// javaType => $javaType,
|
||||
// packageName => $domain_package,
|
||||
// className => $domain_package . "." . $javaType,
|
||||
// see => ["${refUrl}/ApiReference-ItemType-${awsType}.html"],
|
||||
// fields =>
|
||||
// build_fields("${refUrl}/ApiReference-ItemType-$awsType.html")
|
||||
// };
|
||||
// #}
|
||||
// $_ = $javaType;
|
||||
// }
|
||||
//
|
||||
// return $_;
|
||||
// }
|
||||
//
|
||||
// sub get_java_name {
|
||||
// $_ = shift;
|
||||
// if (/sSetType/) {
|
||||
// s/sSetType//;
|
||||
// return "Set<$_>";
|
||||
// }
|
||||
// if (/ListType/) {
|
||||
// s/ListType//;
|
||||
// return "List<$_>";
|
||||
// }
|
||||
// if (/sResponseInfoType/){
|
||||
// s/sResponseInfoType//;
|
||||
// return "Set<$_>";
|
||||
// }
|
||||
// if (/sSetItemType/) {
|
||||
// s/sSetItemType//;
|
||||
// }
|
||||
// if (/sResponseItemType/){
|
||||
// s/sResponseItemType//;
|
||||
// }
|
||||
// if (/sItemType/) {
|
||||
// s/sItemType//;
|
||||
// }
|
||||
// if (/sSet/) {
|
||||
// s/sSet//;
|
||||
// }
|
||||
// if (/Set/) {
|
||||
// s/Set//;
|
||||
// }
|
||||
// if (/Type/) {
|
||||
// s/Type//;
|
||||
// }
|
||||
// if (/Item/) {
|
||||
// s/Item//;
|
||||
// }
|
||||
// if (/Info/) {
|
||||
// s/Info//;
|
||||
// }
|
||||
// return $_;
|
||||
// }
|
||||
|
||||
@Test
|
||||
void testParseJavaTypeForxsd_string() {
|
||||
ConvertContentToField converter = new ConvertContentToField();
|
||||
assertEquals(converter.parseJavaType("xsd:string"), "String");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseJavaTypeForxsd_Int() {
|
||||
ConvertContentToField converter = new ConvertContentToField();
|
||||
assertEquals(converter.parseJavaType("xsd:Int"), "Integer");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseJavaTypeForxsd_boolean() {
|
||||
ConvertContentToField converter = new ConvertContentToField();
|
||||
assertEquals(converter.parseJavaType("xsd:boolean"), "Boolean");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseJavaTypeForxsd_dateTime() {
|
||||
ConvertContentToField converter = new ConvertContentToField();
|
||||
assertEquals(converter.parseJavaType("xsd:dateTime"), "org.joda.time.DateTime");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
|
||||
<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">
|
||||
<parent>
|
||||
<artifactId>jclouds-project</artifactId>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../project/pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jclouds-codegen-project</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>jclouds codegen project</name>
|
||||
<modules>
|
||||
<module>core</module>
|
||||
<module>ec2</module>
|
||||
</modules>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
|
@ -32,7 +32,6 @@
|
|||
:lognull 'org.jclouds.logging.config.NullLoggingModule
|
||||
:ssh 'org.jclouds.ssh.jsch.config.JschSshClientModule
|
||||
:enterprise 'org.jclouds.enterprise.config.EnterpriseConfigurationModule
|
||||
:httpnio 'org.jclouds.http.httpnio.config.NioTransformingHttpCommandExecutorServiceModule
|
||||
:apachehc 'org.jclouds.http.apachehc.config.ApacheHCHttpCommandExecutorServiceModule
|
||||
:bouncycastle 'org.jclouds.encryption.bouncycastle.config.BouncyCastleEncryptionServiceModule
|
||||
:joda 'org.jclouds.date.joda.config.JodaDateServiceModule
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
# use glob syntax.
|
||||
syntax: glob
|
||||
target
|
||||
.settings
|
||||
.classpath
|
||||
.project
|
||||
jclouds-httpnio.iml
|
||||
jclouds-httpnio.ipr
|
||||
jclouds-httpnio.iws
|
|
@ -1,23 +0,0 @@
|
|||
====
|
||||
|
||||
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.
|
||||
====================================================================
|
||||
====
|
||||
#
|
||||
# An extension that allows jclouds to use non-blocking I/O (http://en.wikipedia.org/wiki/New_I/O)
|
||||
# for its HTTP connections.
|
||||
#
|
||||
# TODO: Usage example.
|
|
@ -1,53 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
|
||||
<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>
|
||||
<artifactId>jclouds-extensions-project</artifactId>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jclouds-httpnio</artifactId>
|
||||
<name>jclouds HttpNio Client</name>
|
||||
<description>HttpNio Connection Pooling client</description>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk</connection>
|
||||
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk</developerConnection>
|
||||
<url>http://jclouds.googlecode.com/svn/trunk</url>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore-nio</artifactId>
|
||||
<version>4.1-alpha1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>jetty</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -1,229 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.httpnio.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.http.ConnectionReuseStrategy;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.impl.DefaultConnectionReuseStrategy;
|
||||
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
|
||||
import org.apache.http.nio.NHttpConnection;
|
||||
import org.apache.http.nio.entity.BufferingNHttpEntity;
|
||||
import org.apache.http.nio.entity.ConsumingNHttpEntity;
|
||||
import org.apache.http.nio.protocol.AsyncNHttpClientHandler;
|
||||
import org.apache.http.nio.protocol.NHttpRequestExecutionHandler;
|
||||
import org.apache.http.nio.reactor.IOReactorException;
|
||||
import org.apache.http.nio.util.ByteBufferAllocator;
|
||||
import org.apache.http.nio.util.HeapByteBufferAllocator;
|
||||
import org.apache.http.params.BasicHttpParams;
|
||||
import org.apache.http.params.CoreConnectionPNames;
|
||||
import org.apache.http.params.CoreProtocolPNames;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.params.HttpProtocolParams;
|
||||
import org.apache.http.protocol.BasicHttpProcessor;
|
||||
import org.apache.http.protocol.RequestConnControl;
|
||||
import org.apache.http.protocol.RequestContent;
|
||||
import org.apache.http.protocol.RequestExpectContinue;
|
||||
import org.apache.http.protocol.RequestTargetHost;
|
||||
import org.apache.http.protocol.RequestUserAgent;
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.http.HttpCommandRendezvous;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.TransformingHttpCommandExecutorService;
|
||||
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
|
||||
import org.jclouds.http.httpnio.pool.NioHttpCommandConnectionPool;
|
||||
import org.jclouds.http.httpnio.pool.NioHttpCommandExecutionHandler;
|
||||
import org.jclouds.http.httpnio.pool.NioTransformingHttpCommandExecutorService;
|
||||
import org.jclouds.http.httpnio.pool.NioHttpCommandExecutionHandler.ConsumingNHttpEntityFactory;
|
||||
import org.jclouds.http.pool.config.ConnectionPoolCommandExecutorServiceModule;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@ConfiguresHttpCommandExecutorService
|
||||
public class NioTransformingHttpCommandExecutorServiceModule extends
|
||||
ConnectionPoolCommandExecutorServiceModule<NHttpConnection> {
|
||||
|
||||
@Provides
|
||||
// @Singleton per uri...
|
||||
public AsyncNHttpClientHandler provideAsyncNttpConnectionHandler(
|
||||
BasicHttpProcessor httpProcessor, NHttpRequestExecutionHandler execHandler,
|
||||
ConnectionReuseStrategy connStrategy, ByteBufferAllocator allocator, HttpParams params) {
|
||||
return new AsyncNHttpClientHandler(httpProcessor, execHandler, connStrategy, allocator,
|
||||
params);
|
||||
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public BasicHttpProcessor provideConnectionProcessor() {
|
||||
BasicHttpProcessor httpproc = new BasicHttpProcessor();
|
||||
httpproc.addInterceptor(new RequestContent());
|
||||
httpproc.addInterceptor(new RequestTargetHost());
|
||||
httpproc.addInterceptor(new RequestConnControl());
|
||||
httpproc.addInterceptor(new RequestUserAgent());
|
||||
httpproc.addInterceptor(new RequestExpectContinue());
|
||||
return httpproc;
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
HttpParams newBasicHttpParams(HttpUtils utils) {
|
||||
BasicHttpParams params = new BasicHttpParams();
|
||||
|
||||
params.setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
|
||||
.setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, true)
|
||||
.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true).setParameter(
|
||||
CoreProtocolPNames.ORIGIN_SERVER, "jclouds/1.0");
|
||||
|
||||
if (utils.getConnectionTimeout() > 0) {
|
||||
params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, utils
|
||||
.getConnectionTimeout());
|
||||
}
|
||||
|
||||
if (utils.getSocketOpenTimeout() > 0) {
|
||||
params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, utils.getSocketOpenTimeout());
|
||||
}
|
||||
|
||||
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
|
||||
return params;
|
||||
}
|
||||
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bind(TransformingHttpCommandExecutorService.class).to(
|
||||
NioTransformingHttpCommandExecutorService.class);
|
||||
bind(new TypeLiteral<BlockingQueue<HttpCommandRendezvous<?>>>() {
|
||||
}).to(new TypeLiteral<LinkedBlockingQueue<HttpCommandRendezvous<?>>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(NioHttpCommandExecutionHandler.ConsumingNHttpEntityFactory.class).to(
|
||||
ConsumingNHttpEntityFactoryImpl.class).in(Scopes.SINGLETON);
|
||||
bind(NHttpRequestExecutionHandler.class).to(NioHttpCommandExecutionHandler.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(ConnectionReuseStrategy.class).to(DefaultConnectionReuseStrategy.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(ByteBufferAllocator.class).to(HeapByteBufferAllocator.class);
|
||||
bind(NioHttpCommandConnectionPool.Factory.class).to(Factory.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
private static class Factory implements NioHttpCommandConnectionPool.Factory {
|
||||
|
||||
Closer closer;
|
||||
ExecutorService executor;
|
||||
int maxConnectionReuse;
|
||||
int maxSessionFailures;
|
||||
Provider<Semaphore> allConnections;
|
||||
Provider<BlockingQueue<HttpCommandRendezvous<?>>> commandQueue;
|
||||
Provider<BlockingQueue<NHttpConnection>> available;
|
||||
Provider<AsyncNHttpClientHandler> clientHandler;
|
||||
Provider<DefaultConnectingIOReactor> ioReactor;
|
||||
HttpParams params;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Inject
|
||||
Factory(Closer closer, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||
@Named(Constants.PROPERTY_MAX_CONNECTION_REUSE) int maxConnectionReuse,
|
||||
@Named(Constants.PROPERTY_MAX_SESSION_FAILURES) int maxSessionFailures,
|
||||
Provider<Semaphore> allConnections,
|
||||
Provider<BlockingQueue<HttpCommandRendezvous<?>>> commandQueue,
|
||||
Provider<BlockingQueue<NHttpConnection>> available,
|
||||
Provider<AsyncNHttpClientHandler> clientHandler,
|
||||
Provider<DefaultConnectingIOReactor> ioReactor, HttpParams params) {
|
||||
this.closer = closer;
|
||||
this.executor = executor;
|
||||
this.maxConnectionReuse = maxConnectionReuse;
|
||||
this.maxSessionFailures = maxSessionFailures;
|
||||
this.allConnections = allConnections;
|
||||
this.commandQueue = commandQueue;
|
||||
this.available = available;
|
||||
this.clientHandler = clientHandler;
|
||||
this.ioReactor = ioReactor;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public NioHttpCommandConnectionPool create(URI endPoint) {
|
||||
NioHttpCommandConnectionPool pool = new NioHttpCommandConnectionPool(executor,
|
||||
allConnections.get(), commandQueue.get(), available.get(), clientHandler.get(),
|
||||
ioReactor.get(), params, endPoint, maxConnectionReuse, maxSessionFailures);
|
||||
pool.start();
|
||||
closer.addToClose(new PoolCloser(pool));
|
||||
return pool;
|
||||
}
|
||||
|
||||
private static class PoolCloser implements Closeable {
|
||||
private final NioHttpCommandConnectionPool pool;
|
||||
|
||||
protected PoolCloser(NioHttpCommandConnectionPool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
pool.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ConsumingNHttpEntityFactoryImpl implements ConsumingNHttpEntityFactory {
|
||||
@Inject
|
||||
javax.inject.Provider<ByteBufferAllocator> allocatorProvider;
|
||||
|
||||
public ConsumingNHttpEntity create(HttpEntity httpEntity) {
|
||||
return new BufferingNHttpEntity(httpEntity, allocatorProvider.get());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockingQueue<NHttpConnection> provideAvailablePool(HttpUtils utils) throws Exception {
|
||||
return new ArrayBlockingQueue<NHttpConnection>(utils.getMaxConnectionsPerHost() != 0 ? utils
|
||||
.getMaxConnectionsPerHost() : utils.getMaxConnections(), true);
|
||||
}
|
||||
|
||||
@Provides
|
||||
// uri scope
|
||||
public DefaultConnectingIOReactor provideDefaultConnectingIOReactor(
|
||||
@Named(Constants.PROPERTY_IO_WORKER_THREADS) int maxWorkerThreads, HttpParams params)
|
||||
throws IOReactorException {
|
||||
checkState(maxWorkerThreads > 0, "io reactor needs at least 1 thread");
|
||||
return new DefaultConnectingIOReactor(maxWorkerThreads, params);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.httpnio.pool;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import org.apache.http.nio.NHttpConnection;
|
||||
import org.jclouds.http.HttpCommandRendezvous;
|
||||
import org.jclouds.http.pool.HttpCommandConnectionHandle;
|
||||
|
||||
/**
|
||||
* // TODO: Adrian: Document this!
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class NioHttpCommandConnectionHandle extends HttpCommandConnectionHandle<NHttpConnection> {
|
||||
|
||||
public NioHttpCommandConnectionHandle(Semaphore maxConnections,
|
||||
BlockingQueue<NHttpConnection> available, URI endPoint,
|
||||
HttpCommandRendezvous<?> command, NHttpConnection conn) throws InterruptedException {
|
||||
super(maxConnections, available, endPoint, command, conn);
|
||||
}
|
||||
|
||||
public void startConnection() {
|
||||
conn.getContext().setAttribute("command", command);
|
||||
conn.requestOutput();
|
||||
}
|
||||
|
||||
public void shutdownConnection() throws IOException {
|
||||
conn.shutdown();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,336 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.httpnio.pool;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.UnmappableCharacterException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.impl.nio.DefaultClientIOEventDispatch;
|
||||
import org.apache.http.impl.nio.SSLClientIOEventDispatch;
|
||||
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
|
||||
import org.apache.http.nio.NHttpConnection;
|
||||
import org.apache.http.nio.protocol.AsyncNHttpClientHandler;
|
||||
import org.apache.http.nio.protocol.EventListener;
|
||||
import org.apache.http.nio.reactor.IOEventDispatch;
|
||||
import org.apache.http.nio.reactor.IOReactorStatus;
|
||||
import org.apache.http.nio.reactor.SessionRequest;
|
||||
import org.apache.http.nio.reactor.SessionRequestCallback;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.http.HttpCommandRendezvous;
|
||||
import org.jclouds.http.TransformingHttpCommand;
|
||||
import org.jclouds.http.pool.HttpCommandConnectionHandle;
|
||||
import org.jclouds.http.pool.HttpCommandConnectionPool;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* Connection Pool for HTTP requests that utilizes Apache HTTPNio
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class NioHttpCommandConnectionPool extends HttpCommandConnectionPool<NHttpConnection>
|
||||
implements EventListener {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NioHttpCommandConnectionPool [ target=" + target + ", endPoint=" + getEndPoint()
|
||||
+ ", hashCode=" + hashCode() + " ]";
|
||||
}
|
||||
|
||||
private final NHttpClientConnectionPoolSessionRequestCallback sessionCallback;
|
||||
private final DefaultConnectingIOReactor ioReactor;
|
||||
private final IOEventDispatch dispatch;
|
||||
private final InetSocketAddress target;
|
||||
|
||||
public static interface Factory extends HttpCommandConnectionPool.Factory<NHttpConnection> {
|
||||
NioHttpCommandConnectionPool create(URI endPoint);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public NioHttpCommandConnectionPool(ExecutorService executor, Semaphore allConnections,
|
||||
BlockingQueue<HttpCommandRendezvous<?>> commandQueue,
|
||||
BlockingQueue<NHttpConnection> available, AsyncNHttpClientHandler clientHandler,
|
||||
DefaultConnectingIOReactor ioReactor, HttpParams params, URI endPoint,
|
||||
@Named(Constants.PROPERTY_MAX_CONNECTION_REUSE) int maxConnectionReuse,
|
||||
@Named(Constants.PROPERTY_MAX_SESSION_FAILURES) int maxSessionFailures) {
|
||||
super(executor, allConnections, commandQueue, available, endPoint, maxConnectionReuse,
|
||||
maxSessionFailures);
|
||||
String host = checkNotNull(checkNotNull(endPoint, "endPoint").getHost(), String.format(
|
||||
"Host null for endpoint %s", endPoint));
|
||||
int port = endPoint.getPort();
|
||||
if (endPoint.getScheme().equals("https")) {
|
||||
try {
|
||||
this.dispatch = provideSSLClientEventDispatch(clientHandler, params);
|
||||
} catch (KeyManagementException e) {
|
||||
throw new RuntimeException("SSL error creating a connection to " + endPoint, e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("SSL error creating a connection to " + endPoint, e);
|
||||
}
|
||||
if (port == -1)
|
||||
port = 443;
|
||||
} else {
|
||||
this.dispatch = provideClientEventDispatch(clientHandler, params);
|
||||
if (port == -1)
|
||||
port = 80;
|
||||
}
|
||||
checkArgument(port > 0, String.format("Port %d not in range for endpoint %s", endPoint
|
||||
.getPort(), endPoint));
|
||||
this.ioReactor = ioReactor;
|
||||
this.sessionCallback = new NHttpClientConnectionPoolSessionRequestCallback();
|
||||
this.target = new InetSocketAddress(host, port);
|
||||
clientHandler.setEventListener(this);
|
||||
}
|
||||
|
||||
public static IOEventDispatch provideSSLClientEventDispatch(AsyncNHttpClientHandler handler,
|
||||
HttpParams params) throws NoSuchAlgorithmException, KeyManagementException {
|
||||
SSLContext context = SSLContext.getInstance("TLS");
|
||||
context.init(null, null, null);
|
||||
return new SSLClientIOEventDispatch(handler, context, params);
|
||||
}
|
||||
|
||||
public static IOEventDispatch provideClientEventDispatch(AsyncNHttpClientHandler handler,
|
||||
HttpParams params) {
|
||||
return new DefaultClientIOEventDispatch(handler, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
synchronized (this.statusLock) {
|
||||
if (this.status.compareTo(Status.INACTIVE) == 0) {
|
||||
executorService.execute(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
ioReactor.execute(dispatch);
|
||||
} catch (IOException e) {
|
||||
exception.set(e);
|
||||
logger.error(e, "Error dispatching %1$s", dispatch);
|
||||
status = Status.SHUTDOWN_REQUEST;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
super.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdownReactor(long waitMs) {
|
||||
try {
|
||||
this.ioReactor.shutdown(waitMs);
|
||||
} catch (IOException e) {
|
||||
logger.error(e, "Error shutting down reactor");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connectionValid(NHttpConnection conn) {
|
||||
boolean isOpen = conn.isOpen();
|
||||
boolean isStale = conn.isStale();
|
||||
long requestCount = conn.getMetrics().getRequestCount();
|
||||
return isOpen && !isStale && requestCount < maxConnectionReuse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdownConnection(NHttpConnection conn) {
|
||||
if (conn.getStatus() == NHttpConnection.ACTIVE) {
|
||||
try {
|
||||
conn.shutdown();
|
||||
} catch (IOException e) {
|
||||
logger.error(e, "Error shutting down connection");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doWork() throws Exception {
|
||||
createNewConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doShutdown() {
|
||||
// Give the I/O reactor 1 sec to shut down
|
||||
shutdownReactor(1000);
|
||||
assert this.ioReactor.getStatus().equals(IOReactorStatus.SHUT_DOWN) : "incorrect status after io reactor shutdown :"
|
||||
+ this.ioReactor.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createNewConnection() throws InterruptedException {
|
||||
boolean acquired = allConnections.tryAcquire(1, TimeUnit.SECONDS);
|
||||
if (acquired) {
|
||||
if (shouldDoWork()) {
|
||||
logger.trace("Opening: %s", getTarget());
|
||||
ioReactor.connect(getTarget(), null, null, sessionCallback);
|
||||
} else {
|
||||
allConnections.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void associateHandleWithConnection(
|
||||
HttpCommandConnectionHandle<NHttpConnection> handle, NHttpConnection connection) {
|
||||
connection.getContext().setAttribute("command-handle", handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NioHttpCommandConnectionHandle getHandleFromConnection(NHttpConnection connection) {
|
||||
return (NioHttpCommandConnectionHandle) connection.getContext()
|
||||
.getAttribute("command-handle");
|
||||
}
|
||||
|
||||
class NHttpClientConnectionPoolSessionRequestCallback implements SessionRequestCallback {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void completed(SessionRequest request) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see releaseConnectionAndSetResponseException
|
||||
*/
|
||||
@Override
|
||||
public void cancelled(SessionRequest request) {
|
||||
releaseConnectionAndSetResponseException(request, new CancellationException(
|
||||
"Cancelled request: " + request.getRemoteAddress()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases a connection and associates the current exception with the request using the
|
||||
* session.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
void releaseConnectionAndSetResponseException(SessionRequest request, Exception e) {
|
||||
allConnections.release();
|
||||
TransformingHttpCommand<?> frequest = (TransformingHttpCommand<?>) request.getAttachment();
|
||||
if (frequest != null) {
|
||||
frequest.setException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the pool, if {@code maxSessionFailures} is reached}
|
||||
*
|
||||
* @see releaseConnectionAndSetResponseException
|
||||
*/
|
||||
@Override
|
||||
public void failed(SessionRequest request) {
|
||||
int count = currentSessionFailures.getAndIncrement();
|
||||
releaseConnectionAndSetResponseException(request, request.getException());
|
||||
if (count >= maxSessionFailures) {
|
||||
logger.error(request.getException(),
|
||||
"Exceeded maximum Session failures: %d, Disabling pool for %s",
|
||||
maxSessionFailures, getTarget());
|
||||
exception.set(request.getException());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see releaseConnectionAndSetResponseException
|
||||
*/
|
||||
@Override
|
||||
public void timeout(SessionRequest request) {
|
||||
releaseConnectionAndSetResponseException(request, new TimeoutException("Timeout on: "
|
||||
+ request.getRemoteAddress()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void connectionOpen(NHttpConnection conn) {
|
||||
conn.setSocketTimeout(0);
|
||||
available.offer(conn);
|
||||
logger.trace("Opened: %s", getTarget());
|
||||
}
|
||||
|
||||
public void connectionTimeout(NHttpConnection conn) {
|
||||
String message = String.format("Timeout on : %s - timeout %d", getTarget(), conn
|
||||
.getSocketTimeout());
|
||||
logger.warn(message);
|
||||
resubmitIfRequestIsReplayable(conn, new TimeoutException(message));
|
||||
}
|
||||
|
||||
public void connectionClosed(NHttpConnection conn) {
|
||||
logger.trace("Closed: %s", getTarget());
|
||||
}
|
||||
|
||||
public void fatalIOException(IOException ex, NHttpConnection conn) {
|
||||
logger.error(ex, "IO Exception: %s", getTarget());
|
||||
HttpCommandRendezvous<?> rendezvous = getCommandFromConnection(conn);
|
||||
if (rendezvous != null) {
|
||||
/**
|
||||
* these exceptions, while technically i/o are unresolvable. set the error on the command
|
||||
* itself so that it doesn't replay.
|
||||
*/
|
||||
if (ex instanceof UnmappableCharacterException) {
|
||||
setExceptionOnCommand(ex, rendezvous);
|
||||
} else {
|
||||
resubmitIfRequestIsReplayable(conn, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fatalProtocolException(HttpException ex, NHttpConnection conn) {
|
||||
logger.error(ex, "Protocol Exception: %s", getTarget());
|
||||
setExceptionOnCommand(conn, ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NioHttpCommandConnectionHandle createHandle(HttpCommandRendezvous<?> command,
|
||||
NHttpConnection conn) {
|
||||
try {
|
||||
return new NioHttpCommandConnectionHandle(allConnections, available, endPoint, command,
|
||||
conn);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException("Interrupted creating a handle to " + conn, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReplayable(HttpCommandRendezvous<?> rendezvous) {
|
||||
return rendezvous.getCommand().isReplayable();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
InetSocketAddress getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,180 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.httpnio.pool;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.nio.entity.ConsumingNHttpEntity;
|
||||
import org.apache.http.nio.protocol.NHttpRequestExecutionHandler;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpCommandRendezvous;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.Payloads;
|
||||
import org.jclouds.http.handlers.DelegatingErrorHandler;
|
||||
import org.jclouds.http.handlers.DelegatingRetryHandler;
|
||||
import org.jclouds.http.httpnio.util.NioHttpUtils;
|
||||
import org.jclouds.http.internal.HttpWire;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.io.Closeables;
|
||||
|
||||
/**
|
||||
* // TODO: Adrian: Document this!
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class NioHttpCommandExecutionHandler implements NHttpRequestExecutionHandler {
|
||||
private final ConsumingNHttpEntityFactory EntityFactory;
|
||||
private final DelegatingRetryHandler retryHandler;
|
||||
private final DelegatingErrorHandler errorHandler;
|
||||
private final HttpWire wire;
|
||||
|
||||
/**
|
||||
* inputOnly: nothing is taken from this queue.
|
||||
*/
|
||||
private final BlockingQueue<HttpCommandRendezvous<?>> resubmitQueue;
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
@Resource
|
||||
@Named(Constants.LOGGER_HTTP_HEADERS)
|
||||
protected Logger headerLog = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
public NioHttpCommandExecutionHandler(ConsumingNHttpEntityFactory EntityFactory,
|
||||
BlockingQueue<HttpCommandRendezvous<?>> resubmitQueue,
|
||||
DelegatingRetryHandler retryHandler, DelegatingErrorHandler errorHandler, HttpWire wire) {
|
||||
this.EntityFactory = EntityFactory;
|
||||
this.resubmitQueue = resubmitQueue;
|
||||
this.retryHandler = retryHandler;
|
||||
this.errorHandler = errorHandler;
|
||||
this.wire = wire;
|
||||
}
|
||||
|
||||
public interface ConsumingNHttpEntityFactory {
|
||||
public ConsumingNHttpEntity create(HttpEntity httpEntity);
|
||||
}
|
||||
|
||||
public void initalizeContext(HttpContext context, Object attachment) {
|
||||
}
|
||||
|
||||
public HttpEntityEnclosingRequest submitRequest(HttpContext context) {
|
||||
HttpCommandRendezvous<?> rendezvous = (HttpCommandRendezvous<?>) context
|
||||
.removeAttribute("command");
|
||||
if (rendezvous != null) {
|
||||
HttpRequest request = rendezvous.getCommand().getRequest();
|
||||
for (HttpRequestFilter filter : request.getFilters()) {
|
||||
filter.filter(request);
|
||||
}
|
||||
logger.debug("Sending request %s: %s", request.hashCode(), request.getRequestLine());
|
||||
if (request.getPayload() != null && wire.enabled())
|
||||
request.setPayload(Payloads.newPayload(wire
|
||||
.output(request.getPayload().getRawContent())));
|
||||
HttpEntityEnclosingRequest nativeRequest = NioHttpUtils.convertToApacheRequest(request);
|
||||
HttpUtils.logRequest(headerLog, request, ">>");
|
||||
return nativeRequest;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ConsumingNHttpEntity responseEntity(HttpResponse response, HttpContext context)
|
||||
throws IOException {
|
||||
return EntityFactory.create(response.getEntity());
|
||||
}
|
||||
|
||||
public void handleResponse(HttpResponse apacheResponse, HttpContext context) throws IOException {
|
||||
NioHttpCommandConnectionHandle handle = (NioHttpCommandConnectionHandle) context
|
||||
.removeAttribute("command-handle");
|
||||
if (handle != null) {
|
||||
try {
|
||||
HttpCommandRendezvous<?> rendezvous = handle.getCommandRendezvous();
|
||||
HttpCommand command = rendezvous.getCommand();
|
||||
org.jclouds.http.HttpResponse response = NioHttpUtils
|
||||
.convertToJCloudsResponse(apacheResponse);
|
||||
logger
|
||||
.debug("Receiving response %s: %s", response.hashCode(), response
|
||||
.getStatusLine());
|
||||
HttpUtils.logResponse(headerLog, response, "<<");
|
||||
if (response.getContent() != null && wire.enabled())
|
||||
response.setContent(wire.input(response.getContent()));
|
||||
int statusCode = response.getStatusCode();
|
||||
if (statusCode >= 300) {
|
||||
if (retryHandler.shouldRetryRequest(command, response)) {
|
||||
resubmitQueue.add(rendezvous);
|
||||
} else {
|
||||
errorHandler.handleError(command, response);
|
||||
Closeables.closeQuietly(response.getContent());
|
||||
assert command.getException() != null : "errorHandler should have set an exception!";
|
||||
rendezvous.setException(command.getException());
|
||||
}
|
||||
} else {
|
||||
// Close early, if there is no content.
|
||||
String header = response.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH);
|
||||
if (response.getStatusCode() == 204 || (header != null && header.equals("0"))) {
|
||||
Closeables.closeQuietly(response.getContent());
|
||||
}
|
||||
// TODO, the connection should be released when the input stream is closed
|
||||
rendezvous.setResponse(response);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(e, "interrupted processing response task");
|
||||
} finally {
|
||||
// This here is probably invalid, as the connection is really tied to the server
|
||||
// response.
|
||||
releaseConnectionToPool(handle);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(String.format(
|
||||
"No command-handle associated with command %1$s", context));
|
||||
}
|
||||
}
|
||||
|
||||
protected void releaseConnectionToPool(NioHttpCommandConnectionHandle handle) {
|
||||
try {
|
||||
handle.release();
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(e, "Interrupted releasing handle %1$s", handle);
|
||||
}
|
||||
}
|
||||
|
||||
public void finalizeContext(HttpContext context) {
|
||||
NioHttpCommandConnectionHandle handle = (NioHttpCommandConnectionHandle) context
|
||||
.removeAttribute("command-handle");
|
||||
if (handle != null) {
|
||||
try {
|
||||
handle.cancel();
|
||||
} catch (Exception e) {
|
||||
logger.error(e, "Error cancelling handle %1$s", handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.httpnio.pool;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.http.nio.NHttpConnection;
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.http.HttpCommandRendezvous;
|
||||
import org.jclouds.http.pool.ConnectionPoolTransformingHttpCommandExecutorService;
|
||||
|
||||
/**
|
||||
* // TODO: Adrian: Document this!
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class NioTransformingHttpCommandExecutorService extends
|
||||
ConnectionPoolTransformingHttpCommandExecutorService<NHttpConnection> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("NioTransformingHttpCommandExecutorService [ hashCode=%d ]", hashCode());
|
||||
}
|
||||
|
||||
@Inject
|
||||
public NioTransformingHttpCommandExecutorService(
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||
NioHttpCommandConnectionPool.Factory poolFactory,
|
||||
BlockingQueue<HttpCommandRendezvous<?>> commandQueue) {
|
||||
super(executor, poolFactory, commandQueue);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.httpnio.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.entity.InputStreamEntity;
|
||||
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
|
||||
import org.apache.http.nio.entity.NByteArrayEntity;
|
||||
import org.apache.http.nio.entity.NFileEntity;
|
||||
import org.apache.http.nio.entity.NStringEntity;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.Payload;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class NioHttpUtils {
|
||||
public static final String USER_AGENT = "jclouds/1.0 httpcore-nio/4.1-alpha1";
|
||||
|
||||
public static HttpEntityEnclosingRequest convertToApacheRequest(HttpRequest request) {
|
||||
|
||||
String path = request.getEndpoint().getRawPath();
|
||||
if (request.getEndpoint().getQuery() != null)
|
||||
path += "?" + request.getEndpoint().getQuery();
|
||||
BasicHttpEntityEnclosingRequest apacheRequest = new BasicHttpEntityEnclosingRequest(request
|
||||
.getMethod(), path, HttpVersion.HTTP_1_1);
|
||||
|
||||
Payload payload = request.getPayload();
|
||||
|
||||
// Since we may remove headers, ensure they are added to the apache
|
||||
// request after this block
|
||||
if (payload != null) {
|
||||
String lengthString = request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH);
|
||||
if (lengthString == null) {
|
||||
throw new IllegalStateException("no Content-Length header on request: " + apacheRequest);
|
||||
}
|
||||
long contentLength = Long.parseLong(lengthString);
|
||||
String contentType = request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE);
|
||||
addEntityForContent(apacheRequest, payload.getRawContent(), contentType, contentLength);
|
||||
}
|
||||
|
||||
for (String header : request.getHeaders().keySet()) {
|
||||
for (String value : request.getHeaders().get(header))
|
||||
// apache automatically tries to add content length header
|
||||
if (!header.equals(HttpHeaders.CONTENT_LENGTH))
|
||||
apacheRequest.addHeader(header, value);
|
||||
}
|
||||
apacheRequest.addHeader(HttpHeaders.USER_AGENT, USER_AGENT);
|
||||
|
||||
return apacheRequest;
|
||||
}
|
||||
|
||||
public static void addEntityForContent(BasicHttpEntityEnclosingRequest apacheRequest,
|
||||
Object content, String contentType, long length) {
|
||||
if (content instanceof InputStream) {
|
||||
InputStream inputStream = (InputStream) content;
|
||||
if (length == -1)
|
||||
throw new IllegalArgumentException(
|
||||
"you must specify size when content is an InputStream");
|
||||
InputStreamEntity Entity = new InputStreamEntity(inputStream, length);
|
||||
Entity.setContentType(contentType);
|
||||
apacheRequest.setEntity(Entity);
|
||||
} else if (content instanceof String) {
|
||||
NStringEntity nStringEntity = null;
|
||||
try {
|
||||
nStringEntity = new NStringEntity((String) content);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new UnsupportedOperationException("Encoding not supported", e);
|
||||
}
|
||||
nStringEntity.setContentType(contentType);
|
||||
apacheRequest.setEntity(nStringEntity);
|
||||
} else if (content instanceof File) {
|
||||
apacheRequest.setEntity(new NFileEntity((File) content, contentType, true));
|
||||
} else if (content instanceof byte[]) {
|
||||
NByteArrayEntity Entity = new NByteArrayEntity((byte[]) content);
|
||||
Entity.setContentType(contentType);
|
||||
apacheRequest.setEntity(Entity);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Content class not supported: "
|
||||
+ content.getClass().getName());
|
||||
}
|
||||
assert (apacheRequest.getEntity() != null);
|
||||
}
|
||||
|
||||
public static HttpResponse convertToJCloudsResponse(org.apache.http.HttpResponse apacheResponse)
|
||||
throws IOException {
|
||||
HttpResponse response = new HttpResponse();
|
||||
if (apacheResponse.getEntity() != null) {
|
||||
response.setContent(apacheResponse.getEntity().getContent());
|
||||
}
|
||||
for (Header header : apacheResponse.getAllHeaders()) {
|
||||
response.getHeaders().put(header.getName(), header.getValue());
|
||||
}
|
||||
response.setStatusCode(apacheResponse.getStatusLine().getStatusCode());
|
||||
response.setMessage(apacheResponse.getStatusLine().getReasonPhrase());
|
||||
return response;
|
||||
}
|
||||
}
|
|
@ -1,217 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.pool;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static org.jclouds.concurrent.ConcurrentUtils.makeListenable;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpCommandRendezvous;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.TransformingHttpCommandExecutorService;
|
||||
import org.jclouds.lifecycle.BaseLifeCycle;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ConnectionPoolTransformingHttpCommandExecutorService<C> extends BaseLifeCycle
|
||||
implements TransformingHttpCommandExecutorService {
|
||||
|
||||
private final ConcurrentMap<URI, HttpCommandConnectionPool<C>> poolMap;
|
||||
private final BlockingQueue<HttpCommandRendezvous<?>> commandQueue;
|
||||
private final HttpCommandConnectionPool.Factory<C> poolFactory;
|
||||
|
||||
@Inject
|
||||
public ConnectionPoolTransformingHttpCommandExecutorService(ExecutorService executor,
|
||||
HttpCommandConnectionPool.Factory<C> pf,
|
||||
BlockingQueue<HttpCommandRendezvous<?>> commandQueue) {
|
||||
super(executor);
|
||||
this.poolFactory = pf;
|
||||
// TODO inject this.
|
||||
poolMap = new MapMaker().makeComputingMap(new Function<URI, HttpCommandConnectionPool<C>>() {
|
||||
public HttpCommandConnectionPool<C> apply(URI endPoint) {
|
||||
checkArgument(endPoint.getHost() != null, String.format(
|
||||
"endPoint.getHost() is null for %s", endPoint));
|
||||
try {
|
||||
HttpCommandConnectionPool<C> pool = poolFactory.create(endPoint);
|
||||
addDependency(pool);
|
||||
return pool;
|
||||
} catch (RuntimeException e) {
|
||||
logger.error(e, "error creating entry for %s", endPoint);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.commandQueue = commandQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* If the reason we are shutting down is due an exception, we set that exception on all pending
|
||||
* commands. Otherwise, we cancel the pending commands.
|
||||
*/
|
||||
@Override
|
||||
protected void doShutdown() {
|
||||
exception.compareAndSet(null, getExceptionFromDependenciesOrNull());
|
||||
while (!commandQueue.isEmpty()) {
|
||||
HttpCommandRendezvous<?> rendezvous = (HttpCommandRendezvous<?>) commandQueue.remove();
|
||||
if (rendezvous != null) {
|
||||
try {
|
||||
if (exception.get() != null)
|
||||
rendezvous.setException(exception.get());
|
||||
else
|
||||
rendezvous.setException(new CancellationException("shutdown"));
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(e, "Error cancelling command %s", rendezvous.getCommand());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doWork() throws InterruptedException {
|
||||
takeACommandOffTheQueueAndInvokeIt();
|
||||
}
|
||||
|
||||
private void takeACommandOffTheQueueAndInvokeIt() throws InterruptedException {
|
||||
HttpCommandRendezvous<?> rendezvous = commandQueue.poll(1, TimeUnit.SECONDS);
|
||||
if (rendezvous != null) {
|
||||
try {
|
||||
invoke(rendezvous);
|
||||
} catch (Exception e) {
|
||||
Throwables.propagateIfPossible(e, InterruptedException.class);
|
||||
logger.error(e, "Error processing command %s", rendezvous.getCommand());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an asynchronous operation that puts the <code>command</code> onto a queue. Later, it
|
||||
* will be processed via the {@link #invoke(HttpCommandRendezvous) invoke}
|
||||
* method.
|
||||
*/
|
||||
public <T> ListenableFuture<T> submit(HttpCommand command,
|
||||
final Function<HttpResponse, T> responseTransformer) {
|
||||
exceptionIfNotActive();
|
||||
final SynchronousQueue<?> channel = new SynchronousQueue<Object>();
|
||||
// should block and immediately parse the response on exit.
|
||||
ListenableFuture<T> future = makeListenable(executorService.submit(new Callable<T>() {
|
||||
public T call() throws Exception {
|
||||
Object o = channel.take();
|
||||
if (o instanceof Exception) {
|
||||
throw (Exception) o;
|
||||
}
|
||||
return responseTransformer.apply((HttpResponse) o);
|
||||
}
|
||||
}), executorService);
|
||||
|
||||
HttpCommandRendezvous<T> rendezvous = new HttpCommandRendezvous<T>(command, channel, future);
|
||||
commandQueue.add(rendezvous);
|
||||
return rendezvous.getListenableFuture();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke binds a command with a connection from the pool. This binding is called a
|
||||
* {@link HttpCommandConnectionHandle handle}. The handle will keep this binding until the
|
||||
* command's response is parsed or an exception is set on the Command object.
|
||||
*
|
||||
* @param command
|
||||
*/
|
||||
protected void invoke(HttpCommandRendezvous<?> command) {
|
||||
exceptionIfNotActive();
|
||||
|
||||
URI endpoint = createBaseEndpointFor(command);
|
||||
|
||||
HttpCommandConnectionPool<C> pool = poolMap.get(endpoint);
|
||||
if (pool == null) {
|
||||
// TODO limit;
|
||||
logger.warn("pool not available for command %s; retrying", command.getCommand());
|
||||
commandQueue.add(command);
|
||||
return;
|
||||
}
|
||||
|
||||
HttpCommandConnectionHandle<C> connectionHandle = null;
|
||||
try {
|
||||
connectionHandle = pool.getHandle(command);
|
||||
} catch (InterruptedException e) {
|
||||
logger.warn(e, "Interrupted getting a connection for command %s; retrying", command
|
||||
.getCommand());
|
||||
commandQueue.add(command);
|
||||
return;
|
||||
} catch (TimeoutException e) {
|
||||
logger.warn(e, "Timeout getting a connection for command %s on pool %s; retrying", command
|
||||
.getCommand(), pool);
|
||||
commandQueue.add(command);
|
||||
return;
|
||||
} catch (RuntimeException e) {
|
||||
logger.warn(e, "Error getting a connection for command %s on pool %s; retrying", command
|
||||
.getCommand(), pool);
|
||||
discardPool(endpoint, pool);
|
||||
commandQueue.add(command);
|
||||
return;
|
||||
}
|
||||
|
||||
if (connectionHandle == null) {
|
||||
logger.error("Failed to obtain connection for command %s; retrying", command.getCommand());
|
||||
commandQueue.add(command);
|
||||
return;
|
||||
}
|
||||
connectionHandle.startConnection();
|
||||
}
|
||||
|
||||
private void discardPool(URI endpoint, HttpCommandConnectionPool<C> pool) {
|
||||
poolMap.remove(endpoint, pool);
|
||||
pool.shutdown();
|
||||
this.dependencies.remove(pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* keys to the map are only used for socket information, not path. In this case, you should
|
||||
* remove any path or query details from the URI.
|
||||
*/
|
||||
private URI createBaseEndpointFor(HttpCommandRendezvous<?> command) {
|
||||
URI endpoint = command.getCommand().getRequest().getEndpoint();
|
||||
if (endpoint.getPort() == -1) {
|
||||
return URI.create(String.format("%s://%s", endpoint.getScheme(), endpoint.getHost()));
|
||||
} else {
|
||||
return URI.create(String.format("%s://%s:%d", endpoint.getScheme(), endpoint.getHost(),
|
||||
endpoint.getPort()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.pool;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import org.jclouds.http.HttpCommandRendezvous;
|
||||
|
||||
/**
|
||||
* Associates a command with an open connection to a service.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public abstract class HttpCommandConnectionHandle<C> {
|
||||
protected final BlockingQueue<C> available;
|
||||
protected final Semaphore maxConnections;
|
||||
protected final Semaphore completed;
|
||||
protected final URI endPoint;
|
||||
protected C conn;
|
||||
protected HttpCommandRendezvous<?> command;
|
||||
|
||||
public HttpCommandConnectionHandle(Semaphore maxConnections, BlockingQueue<C> available,
|
||||
URI endPoint, HttpCommandRendezvous<?> command, C conn) throws InterruptedException {
|
||||
this.available = available;
|
||||
this.maxConnections = maxConnections;
|
||||
this.completed = new Semaphore(1);
|
||||
this.endPoint = endPoint;
|
||||
this.command = command;
|
||||
this.conn = conn;
|
||||
completed.acquire();
|
||||
}
|
||||
|
||||
public HttpCommandRendezvous<?> getCommandRendezvous() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public abstract void startConnection();
|
||||
|
||||
public boolean isCompleted() {
|
||||
return (completed.availablePermits() == 1);
|
||||
}
|
||||
|
||||
public void release() throws InterruptedException {
|
||||
if (isCompleted() || alreadyReleased()) {
|
||||
return;
|
||||
}
|
||||
available.put(conn);
|
||||
conn = null;
|
||||
command = null;
|
||||
completed.release();
|
||||
}
|
||||
|
||||
private boolean alreadyReleased() {
|
||||
return conn == null;
|
||||
}
|
||||
|
||||
public void cancel() throws IOException {
|
||||
if (isCompleted()) {
|
||||
return;
|
||||
}
|
||||
if (conn != null) {
|
||||
try {
|
||||
shutdownConnection();
|
||||
} finally {
|
||||
conn = null;
|
||||
command = null;
|
||||
maxConnections.release();
|
||||
}
|
||||
}
|
||||
completed.release();
|
||||
}
|
||||
|
||||
public abstract void shutdownConnection() throws IOException;
|
||||
|
||||
public void waitFor() throws InterruptedException {
|
||||
completed.acquire();
|
||||
completed.release();
|
||||
}
|
||||
}
|
|
@ -1,207 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.pool;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.http.HttpCommandRendezvous;
|
||||
import org.jclouds.lifecycle.BaseLifeCycle;
|
||||
|
||||
/**
|
||||
* // TODO: Adrian: Document this!
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public abstract class HttpCommandConnectionPool<C> extends BaseLifeCycle {
|
||||
|
||||
protected final Semaphore allConnections;
|
||||
protected final BlockingQueue<C> available;
|
||||
|
||||
/**
|
||||
* inputOnly: nothing is taken from this queue.
|
||||
*/
|
||||
protected final BlockingQueue<HttpCommandRendezvous<?>> resubmitQueue;
|
||||
protected final AtomicInteger currentSessionFailures = new AtomicInteger(0);
|
||||
protected volatile boolean hitBottom = false;
|
||||
protected final URI endPoint;
|
||||
|
||||
protected int maxConnectionReuse;
|
||||
protected int maxSessionFailures;
|
||||
|
||||
public URI getEndPoint() {
|
||||
return endPoint;
|
||||
}
|
||||
|
||||
public static interface Factory<C> {
|
||||
HttpCommandConnectionPool<C> create(URI endPoint);
|
||||
}
|
||||
|
||||
public HttpCommandConnectionPool(ExecutorService executor, Semaphore allConnections,
|
||||
BlockingQueue<HttpCommandRendezvous<?>> rendezvousQueue, BlockingQueue<C> available,
|
||||
URI endPoint, @Named(Constants.PROPERTY_MAX_CONNECTION_REUSE) int maxConnectionReuse,
|
||||
@Named(Constants.PROPERTY_MAX_SESSION_FAILURES) int maxSessionFailures) {
|
||||
super(executor);
|
||||
checkArgument(maxConnectionReuse >= 1, "maxConnectionReuse must be positive");
|
||||
checkArgument(maxSessionFailures >= 1, "maxSessionFailures must be positive");
|
||||
this.maxConnectionReuse = maxConnectionReuse;
|
||||
this.maxSessionFailures = maxSessionFailures;
|
||||
this.allConnections = allConnections;
|
||||
this.resubmitQueue = rendezvousQueue;
|
||||
this.available = available;
|
||||
this.endPoint = endPoint;
|
||||
}
|
||||
|
||||
protected void setResponseException(Exception ex, C conn) {
|
||||
HttpCommandRendezvous<?> rendezvous = getHandleFromConnection(conn).getCommandRendezvous();
|
||||
setExceptionOnCommand(ex, rendezvous);
|
||||
}
|
||||
|
||||
protected void cancel(C conn) {
|
||||
HttpCommandRendezvous<?> rendezvous = getHandleFromConnection(conn).getCommandRendezvous();
|
||||
rendezvous.cancel();
|
||||
}
|
||||
|
||||
protected C getConnection() throws InterruptedException, TimeoutException {
|
||||
exceptionIfNotActive();
|
||||
if (!hitBottom) {
|
||||
hitBottom = available.size() == 0 && allConnections.availablePermits() == 0;
|
||||
if (hitBottom)
|
||||
logger.warn("saturated connection pool");
|
||||
}
|
||||
logger.trace("Blocking up to %ds for a connection to %s", 5, getEndPoint());
|
||||
C conn = available.poll(5, TimeUnit.SECONDS);
|
||||
if (conn == null)
|
||||
throw new TimeoutException(String.format("Timeout after %ds for a connection to %s", 5,
|
||||
getEndPoint()));
|
||||
|
||||
if (connectionValid(conn)) {
|
||||
return conn;
|
||||
} else {
|
||||
logger.debug("Connection %s unusable for endpoint %s", conn.hashCode(), getEndPoint());
|
||||
shutdownConnection(conn);
|
||||
allConnections.release();
|
||||
return getConnection();
|
||||
}
|
||||
}
|
||||
|
||||
protected void fatalException(Exception ex, C conn) {
|
||||
setResponseException(ex, conn);
|
||||
exception.set(ex);
|
||||
shutdown();
|
||||
}
|
||||
|
||||
protected abstract void shutdownConnection(C conn);
|
||||
|
||||
protected abstract boolean connectionValid(C conn);
|
||||
|
||||
public HttpCommandConnectionHandle<C> getHandle(HttpCommandRendezvous<?> rendezvous)
|
||||
throws InterruptedException, TimeoutException {
|
||||
exceptionIfNotActive();
|
||||
C conn = getConnection();
|
||||
HttpCommandConnectionHandle<C> handle = createHandle(rendezvous, conn);
|
||||
associateHandleWithConnection(handle, conn);
|
||||
return handle;
|
||||
}
|
||||
|
||||
protected abstract HttpCommandConnectionHandle<C> createHandle(
|
||||
HttpCommandRendezvous<?> rendezvous, C conn);
|
||||
|
||||
protected void resubmitIfRequestIsReplayable(C connection, Exception e) {
|
||||
HttpCommandRendezvous<?> rendezvous = getCommandFromConnection(connection);
|
||||
if (rendezvous != null) {
|
||||
if (isReplayable(rendezvous)) {
|
||||
logger.info("resubmitting request: %s", rendezvous.getCommand().getRequest()
|
||||
.getRequestLine());
|
||||
resubmitQueue.add(rendezvous);
|
||||
} else {
|
||||
setExceptionOnCommand(e, rendezvous);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean isReplayable(HttpCommandRendezvous<?> rendezvous);
|
||||
|
||||
protected HttpCommandRendezvous<?> getCommandFromConnection(C connection) {
|
||||
HttpCommandConnectionHandle<C> handle = getHandleFromConnection(connection);
|
||||
if (handle != null && handle.getCommandRendezvous() != null) {
|
||||
return handle.getCommandRendezvous();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void setExceptionOnCommand(C connection, Exception e) {
|
||||
HttpCommandRendezvous<?> rendezvous = getCommandFromConnection(connection);
|
||||
if (rendezvous != null) {
|
||||
setExceptionOnCommand(e, rendezvous);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setExceptionOnCommand(Exception e, HttpCommandRendezvous<?> rendezvous) {
|
||||
logger.warn(e, "Exception processing command: %s", rendezvous.getCommand());
|
||||
try {
|
||||
rendezvous.setException(e);
|
||||
} catch (InterruptedException e1) {
|
||||
logger.error(e, "interrupted setting exception on command", rendezvous.getCommand());
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void associateHandleWithConnection(HttpCommandConnectionHandle<C> handle,
|
||||
C connection);
|
||||
|
||||
protected abstract HttpCommandConnectionHandle<C> getHandleFromConnection(C connection);
|
||||
|
||||
protected abstract void createNewConnection() throws InterruptedException;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((endPoint == null) ? 0 : endPoint.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
HttpCommandConnectionPool<?> other = (HttpCommandConnectionPool<?>) obj;
|
||||
if (endPoint == null) {
|
||||
if (other.endPoint != null)
|
||||
return false;
|
||||
} else if (!endPoint.equals(other.endPoint))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.pool.config;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.lifecycle.config.LifeCycleModule;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public abstract class ConnectionPoolCommandExecutorServiceModule<C> extends AbstractModule {
|
||||
|
||||
protected void configure() {
|
||||
install(new LifeCycleModule());
|
||||
bind(AtomicInteger.class).toInstance(new AtomicInteger());// max errors
|
||||
binder().requestInjection(this);
|
||||
}
|
||||
|
||||
@Provides
|
||||
// @Singleton per uri...
|
||||
public abstract BlockingQueue<C> provideAvailablePool(HttpUtils utils) throws Exception;
|
||||
|
||||
/**
|
||||
* controls production and destruction of real connections.
|
||||
* <p/>
|
||||
* aquire before a new connection is created release after an error has occurred
|
||||
*
|
||||
* @param max
|
||||
* @throws Exception
|
||||
*/
|
||||
@Provides
|
||||
// @Singleton per uri...
|
||||
public Semaphore provideTotalConnectionSemaphore(HttpUtils utils) throws Exception {
|
||||
return new Semaphore(utils.getMaxConnectionsPerHost() != 0 ? utils.getMaxConnectionsPerHost()
|
||||
: utils.getMaxConnections(), true);
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.httpnio.pool;
|
||||
|
||||
import org.jclouds.http.BackoffLimitedRetryJavaTest;
|
||||
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||
import org.jclouds.http.httpnio.config.NioTransformingHttpCommandExecutorServiceModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Tests the retry behavior of the default {@link RetryHandler} implementation
|
||||
* {@link BackoffLimitedRetryHandler} to ensure that retries up to the default limit succeed.
|
||||
*
|
||||
* TODO: Should either explicitly set retry limit or get it from Guice, rather than assuming it's 5.
|
||||
*
|
||||
* @author James Murty
|
||||
*/
|
||||
@Test(sequential = true)
|
||||
public class NioBackoffLimitedRetryJavaIntegrationTest extends
|
||||
BackoffLimitedRetryJavaTest {
|
||||
|
||||
protected Module createConnectionModule() {
|
||||
return new NioTransformingHttpCommandExecutorServiceModule();
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.httpnio.pool;
|
||||
|
||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.http.nio.protocol.AsyncNHttpClientHandler;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests parsing of nio
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(testName = "httpnio.NioHttpCommandConnectionPool")
|
||||
public class NioHttpCommandConnectionPoolTest {
|
||||
|
||||
public void testConstructorGoodPort() throws Exception {
|
||||
NioHttpCommandConnectionPool pool = new NioHttpCommandConnectionPool(null, null, null, null,
|
||||
createNiceMock(AsyncNHttpClientHandler.class), null,
|
||||
createNiceMock(HttpParams.class), URI.create("http://localhost:80"), 1, 1);
|
||||
assertEquals(pool.getTarget(), new InetSocketAddress("localhost", 80));
|
||||
}
|
||||
|
||||
public void testConstructorGoodSSLPort() throws Exception {
|
||||
NioHttpCommandConnectionPool pool = new NioHttpCommandConnectionPool(null, null, null, null,
|
||||
createNiceMock(AsyncNHttpClientHandler.class), null,
|
||||
createNiceMock(HttpParams.class), URI.create("https://localhost:443"), 1, 1);
|
||||
assertEquals(pool.getTarget(), new InetSocketAddress("localhost", 443));
|
||||
}
|
||||
|
||||
public void testConstructorUnspecifiedPort() throws Exception {
|
||||
NioHttpCommandConnectionPool pool = new NioHttpCommandConnectionPool(null, null, null, null,
|
||||
createNiceMock(AsyncNHttpClientHandler.class), null,
|
||||
createNiceMock(HttpParams.class), URI.create("http://localhost"), 1, 1);
|
||||
assertEquals(pool.getTarget(), new InetSocketAddress("localhost", 80));
|
||||
}
|
||||
|
||||
public void testConstructorUnspecifiedSSLPort() throws Exception {
|
||||
NioHttpCommandConnectionPool pool = new NioHttpCommandConnectionPool(null, null, null, null,
|
||||
createNiceMock(AsyncNHttpClientHandler.class), null,
|
||||
createNiceMock(HttpParams.class), URI.create("https://localhost"), 1, 1);
|
||||
assertEquals(pool.getTarget(), new InetSocketAddress("localhost", 443));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testConstructorNullURI() throws Exception {
|
||||
new NioHttpCommandConnectionPool(null, null, null, null,
|
||||
createNiceMock(AsyncNHttpClientHandler.class), null,
|
||||
createNiceMock(HttpParams.class), null, 1, 1);
|
||||
}
|
||||
|
||||
public void testConstructorWeirdName() throws Exception {
|
||||
NioHttpCommandConnectionPool pool = new NioHttpCommandConnectionPool(null, null, null, null,
|
||||
createNiceMock(AsyncNHttpClientHandler.class), null,
|
||||
createNiceMock(HttpParams.class), URI
|
||||
.create("http://adriancole.blobstore1138eu.s3-external-3.amazonaws.com"),
|
||||
1, 1);
|
||||
assertEquals(pool.getTarget(), new InetSocketAddress(
|
||||
"adriancole.blobstore1138eu.s3-external-3.amazonaws.com", 80));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.httpnio.pool;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_IO_WORKER_THREADS;
|
||||
import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_HOST;
|
||||
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.http.BaseHttpCommandExecutorServiceIntegrationTest;
|
||||
import org.jclouds.http.httpnio.config.NioTransformingHttpCommandExecutorServiceModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Tests for {@link HttpNioConnectionPoolListenableFutureCommandClient}.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(threadPoolSize = 10, sequential = true)
|
||||
public class NioTransformingHttpCommandExecutorServiceTest extends
|
||||
BaseHttpCommandExecutorServiceIntegrationTest {
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testPostAsInputStream() throws MalformedURLException, ExecutionException,
|
||||
InterruptedException, TimeoutException {
|
||||
// TODO when these fail, we hang
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testPostResults() {
|
||||
// see above
|
||||
}
|
||||
|
||||
protected Module createConnectionModule() {
|
||||
return new NioTransformingHttpCommandExecutorServiceModule();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addConnectionProperties(Properties props) {
|
||||
props.setProperty(PROPERTY_MAX_CONNECTIONS_PER_HOST, 12 + "");
|
||||
props.setProperty(PROPERTY_IO_WORKER_THREADS, 3 + "");
|
||||
props.setProperty(PROPERTY_USER_THREADS, 0 + "");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testGetBigFile() throws MalformedURLException, ExecutionException,
|
||||
InterruptedException, TimeoutException {
|
||||
// disabled since test data is too big
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testUploadBigFile() throws IOException {
|
||||
// disabled since test data is too big
|
||||
}
|
||||
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.http.httpnio.util;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.mortbay.jetty.HttpMethods;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
|
||||
/**
|
||||
* Tests parsing of nio
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(testName = "httpnio.NioHttpUtilsTest")
|
||||
public class NioHttpUtilsTest {
|
||||
@DataProvider(name = "gets")
|
||||
public Object[][] createData() {
|
||||
return new Object[][] { { "object" }, { "/path" }, { "sp%20ace" }, { "unic₪de" },
|
||||
{ "qu?stion" } };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "gets")
|
||||
public void testConvert(String uri) {
|
||||
HttpEntityEnclosingRequest apacheRequest = NioHttpUtils
|
||||
.convertToApacheRequest(new HttpRequest(HttpMethods.GET, URI
|
||||
.create("https://s3.amazonaws.com:443/" + uri), ImmutableMultimap.of(
|
||||
"Host", "s3.amazonaws.com")));
|
||||
assertEquals(apacheRequest.getHeaders("Host")[0].getValue(), "s3.amazonaws.com");
|
||||
assertEquals(apacheRequest.getRequestLine().getMethod(), "GET");
|
||||
assertEquals(apacheRequest.getRequestLine().getUri(), "/" + uri);
|
||||
}
|
||||
|
||||
public void testConvertWithQuery() {
|
||||
HttpEntityEnclosingRequest apacheRequest = NioHttpUtils
|
||||
.convertToApacheRequest(new HttpRequest(HttpMethods.GET, URI
|
||||
.create("https://s3.amazonaws.com:443/?max-keys=0"), ImmutableMultimap.of(
|
||||
"Host", "s3.amazonaws.com")));
|
||||
assertEquals(apacheRequest.getHeaders("Host")[0].getValue(), "s3.amazonaws.com");
|
||||
assertEquals(apacheRequest.getRequestLine().getMethod(), "GET");
|
||||
assertEquals(apacheRequest.getRequestLine().getUri(), "/?max-keys=0");
|
||||
}
|
||||
}
|
|
@ -33,7 +33,6 @@
|
|||
<name>jclouds extensions project</name>
|
||||
<modules>
|
||||
<module>gae</module>
|
||||
<module>httpnio</module>
|
||||
<module>apachehc</module>
|
||||
<module>joda</module>
|
||||
<module>bouncycastle</module>
|
||||
|
|
Loading…
Reference in New Issue