mirror of https://github.com/apache/jclouds.git
updated gae demo to work on hpcloud
This commit is contained in:
parent
c63f3119ca
commit
251754b20a
|
@ -32,10 +32,16 @@
|
|||
<description>JClouds Sample for Google App Engine</description>
|
||||
|
||||
<properties>
|
||||
<appengine.applicationid>jclouds-aws-demo</appengine.applicationid>
|
||||
<appengine.sdk.version>1.4.2</appengine.sdk.version>
|
||||
<!--
|
||||
note you must set the property ${appengine.sdk.root} to a valid
|
||||
extraction of appengine-java-sdk
|
||||
-->
|
||||
<appengine.applicationid>jclouds-hpcloud-demo</appengine.applicationid>
|
||||
<appengine.sdk.version>1.6.5</appengine.sdk.version>
|
||||
<devappserver.address>localhost</devappserver.address>
|
||||
<devappserver.port>8088</devappserver.port>
|
||||
<test.hpcloud.identity>FIXME_IDENTITY</test.hpcloud.identity>
|
||||
<test.hpcloud.credential>FIXME_CREDENTIAL</test.hpcloud.credential>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -51,13 +57,13 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>aws-s3</artifactId>
|
||||
<artifactId>hpcloud-objectstorage</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>aws-ec2</artifactId>
|
||||
<artifactId>hpcloud-compute</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
@ -71,6 +77,21 @@
|
|||
<artifactId>guice-servlet</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Google App Engine API -->
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-api-1.0-sdk</artifactId>
|
||||
<version>${appengine.sdk.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-tools-sdk</artifactId>
|
||||
<version>${appengine.sdk.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- WAR Dependencies: need to be validated -->
|
||||
<dependency>
|
||||
<groupId>displaytag</groupId>
|
||||
<artifactId>displaytag</artifactId>
|
||||
|
@ -90,14 +111,14 @@
|
|||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>standard</artifactId>
|
||||
<groupId>taglibs</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>jstl</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>standard</artifactId>
|
||||
<groupId>taglibs</groupId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
@ -107,30 +128,226 @@
|
|||
<version>2.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-tools-sdk</artifactId>
|
||||
<version>${appengine.sdk.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>2.1.1</version>
|
||||
<plugin>
|
||||
<artifactId>maven-remote-resources-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<configuration>
|
||||
<!-- see http://jira.codehaus.org/browse/MWAR-248 -->
|
||||
<packagingExcludes>WEB-INF/web.xml</packagingExcludes>
|
||||
<webResources>
|
||||
<resource>
|
||||
<directory>src/main/appengine</directory>
|
||||
<targetPath>WEB-INF/</targetPath>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</webResources>
|
||||
<!-- prevents the maven-war-plugin from including the resources in WEB-INF/classes -->
|
||||
<attached>false</attached>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>2.1.1</version>
|
||||
<configuration>
|
||||
<!-- see http://jira.codehaus.org/browse/MWAR-248 -->
|
||||
<packagingExcludes>WEB-INF/web.xml</packagingExcludes>
|
||||
<webResources>
|
||||
<resource>
|
||||
<directory>src/main/appengine</directory>
|
||||
<targetPath>WEB-INF</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<excludes>
|
||||
<exclude>.gitignore</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.ning.maven.plugins</groupId>
|
||||
<artifactId>maven-duplicate-finder-plugin</artifactId>
|
||||
<version>1.0.3</version>
|
||||
<configuration>
|
||||
<exceptions>
|
||||
<exception>
|
||||
<!-- Google App Engine Deps, some google classes are duplicated between packages -->
|
||||
<conflictingDependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-api-1.0-sdk</artifactId>
|
||||
<version>1.6.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-tools-sdk</artifactId>
|
||||
<version>1.6.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</conflictingDependencies>
|
||||
<packages>
|
||||
<package>com.google</package>
|
||||
</packages>
|
||||
</exception>
|
||||
<exception>
|
||||
<!-- Tomcat bundles the JSR250 annotations too -->
|
||||
<conflictingDependencies>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>jsr250-api</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>annotations-api</artifactId>
|
||||
<version>6.0.32</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</conflictingDependencies>
|
||||
<packages>
|
||||
<package>javax.annotation</package>
|
||||
</packages>
|
||||
</exception>
|
||||
<exception>
|
||||
<!-- commons-beanutils and commons-collections duplicate classes -->
|
||||
<conflictingDependencies>
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>1.7.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>3.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</conflictingDependencies>
|
||||
<packages>
|
||||
<package>org.apache.commons.collections</package>
|
||||
</packages>
|
||||
</exception>
|
||||
<exception>
|
||||
<!-- javax.servlet is included in the appengine-tools-sdk, with Tomcat and Jetty -->
|
||||
<conflictingDependencies>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-tools-sdk</artifactId>
|
||||
<version>1.6.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>6.0.32</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>jetty-runner</artifactId>
|
||||
<version>7.5.4.v20111024</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</conflictingDependencies>
|
||||
<packages>
|
||||
<package>javax.servlet</package>
|
||||
</packages>
|
||||
<resources>
|
||||
<!-- javax.servlet is included in the appengine-tools-sdk and Tomcat -->
|
||||
<resource>javax/servlet/resources/XMLSchema.dtd</resource>
|
||||
<resource>javax/servlet/resources/datatypes.dtd</resource>
|
||||
<resource>javax/servlet/resources/j2ee_1_4.xsd</resource>
|
||||
<resource>javax/servlet/resources/j2ee_web_services_client_1_1.xsd</resource>
|
||||
<resource>javax/servlet/resources/javaee_5.xsd</resource>
|
||||
<resource>javax/servlet/resources/javaee_web_services_client_1_2.xsd</resource>
|
||||
<resource>javax/servlet/resources/jsp_2_0.xsd</resource>
|
||||
<resource>javax/servlet/resources/jsp_2_1.xsd</resource>
|
||||
<resource>javax/servlet/resources/web-app_2_2.dtd</resource>
|
||||
<resource>javax/servlet/resources/web-app_2_3.dtd</resource>
|
||||
<resource>javax/servlet/resources/web-app_2_4.xsd</resource>
|
||||
<resource>javax/servlet/resources/web-app_2_5.xsd</resource>
|
||||
<resource>javax/servlet/resources/xml.xsd</resource>
|
||||
<resource>javax/servlet/LocalStrings.properties</resource>
|
||||
<resource>javax/servlet/LocalStrings_fr.properties</resource>
|
||||
<resource>javax/servlet/LocalStrings_ja.properties</resource>
|
||||
<resource>javax/servlet/http/LocalStrings.properties</resource>
|
||||
<resource>javax/servlet/http/LocalStrings_es.properties</resource>
|
||||
<resource>javax/servlet/http/LocalStrings_fr.properties</resource>
|
||||
<resource>javax/servlet/http/LocalStrings_ja.properties</resource>
|
||||
</resources>
|
||||
</exception>
|
||||
<exception>
|
||||
<!-- Jasper and Catalina duplicate some classes -->
|
||||
<conflictingDependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>catalina</artifactId>
|
||||
<version>6.0.32</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>jasper</artifactId>
|
||||
<version>6.0.32</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</conflictingDependencies>
|
||||
<classes>
|
||||
<class>org.apache.AnnotationProcessor</class>
|
||||
<class>org.apache.PeriodicEventListener</class>
|
||||
</classes>
|
||||
</exception>
|
||||
<exception>
|
||||
<!-- Jetty Runner includes taglibs and jstl -->
|
||||
<conflictingDependencies>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>taglibs</groupId>
|
||||
<artifactId>standard</artifactId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>jetty-runner</artifactId>
|
||||
<version>7.5.4.v20111024</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</conflictingDependencies>
|
||||
<packages>
|
||||
<package>javax.servlet.jsp.jstl</package>
|
||||
<package>org.apache.taglibs</package>
|
||||
</packages>
|
||||
<resources>
|
||||
<resource>META-INF/c-1_0-rt.tld</resource>
|
||||
<resource>META-INF/c-1_0.tld</resource>
|
||||
<resource>META-INF/c.tld</resource>
|
||||
<resource>META-INF/fmt-1_0-rt.tld</resource>
|
||||
<resource>META-INF/fmt-1_0.tld</resource>
|
||||
<resource>META-INF/fmt.tld</resource>
|
||||
<resource>META-INF/fn.tld</resource>
|
||||
<resource>META-INF/permittedTaglibs.tld</resource>
|
||||
<resource>META-INF/scriptfree.tld</resource>
|
||||
<resource>META-INF/sql-1_0-rt.tld</resource>
|
||||
<resource>META-INF/sql-1_0.tld</resource>
|
||||
<resource>META-INF/sql.tld</resource>
|
||||
<resource>META-INF/x-1_0-rt.tld</resource>
|
||||
<resource>META-INF/x-1_0.tld</resource>
|
||||
<resource>META-INF/x.tld</resource>
|
||||
<resource>org/apache/taglibs/standard/lang/jstl/Resources.properties</resource>
|
||||
<resource>org/apache/taglibs/standard/lang/jstl/Resources_ja.properties</resource>
|
||||
<resource>org/apache/taglibs/standard/resources/Resources.properties</resource>
|
||||
<resource>org/apache/taglibs/standard/resources/Resources_ja.properties</resource>
|
||||
</resources>
|
||||
</exception>
|
||||
</exceptions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
@ -152,8 +369,8 @@
|
|||
</goals>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.aws.identity>${test.aws-s3.identity}</test.aws.identity>
|
||||
<test.aws.credential>${test.aws-s3.credential}</test.aws.credential>
|
||||
<test.hpcloud.identity>${test.hpcloud.identity}</test.hpcloud.identity>
|
||||
<test.hpcloud.credential>${test.hpcloud.credential}</test.hpcloud.credential>
|
||||
<appengine.sdk.root>${appengine.sdk.root}</appengine.sdk.root>
|
||||
<devappserver.address>${devappserver.address}</devappserver.address>
|
||||
<devappserver.port>${devappserver.port}</devappserver.port>
|
||||
|
@ -166,5 +383,21 @@
|
|||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>deploy</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.kindleit</groupId>
|
||||
<artifactId>maven-gae-plugin</artifactId>
|
||||
<version>0.9.2</version>
|
||||
<configuration>
|
||||
<serverId>google-appengine</serverId>
|
||||
<sdkDir>${appengine.sdk.root}</sdkDir>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
|
|
@ -25,4 +25,5 @@
|
|||
<system-properties>
|
||||
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties" />
|
||||
</system-properties>
|
||||
<threadsafe>true</threadsafe>
|
||||
</appengine-web-app>
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
*/
|
||||
package org.jclouds.samples.googleappengine.config;
|
||||
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIMEOUT_NODE_RUNNING;
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIMEOUT_NODE_TERMINATED;
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIMEOUT_PORT_OPEN;
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIMEOUT_SCRIPT_COMPLETE;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -29,10 +29,9 @@ import java.util.Properties;
|
|||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
|
||||
import org.jclouds.ContextBuilder;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.BlobStoreContextFactory;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.gae.config.AsyncGoogleAppEngineConfigurationModule;
|
||||
import org.jclouds.samples.googleappengine.GetAllStatusController;
|
||||
|
||||
|
@ -57,19 +56,25 @@ public class GuiceServletConfig extends GuiceServletContextListener {
|
|||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||
Properties props = loadJCloudsProperties(servletContextEvent);
|
||||
props.setProperty(PROPERTY_TIMEOUT_NODE_TERMINATED, "25000");
|
||||
props.setProperty(PROPERTY_TIMEOUT_NODE_RUNNING, "25000");
|
||||
props.setProperty(PROPERTY_TIMEOUT_SCRIPT_COMPLETE, "25000");
|
||||
props.setProperty(PROPERTY_TIMEOUT_PORT_OPEN, "25000");
|
||||
Properties overrides = loadJCloudsProperties(servletContextEvent);
|
||||
overrides.setProperty(TIMEOUT_NODE_TERMINATED, "25000");
|
||||
overrides.setProperty(TIMEOUT_NODE_RUNNING, "25000");
|
||||
overrides.setProperty(TIMEOUT_SCRIPT_COMPLETE, "25000");
|
||||
overrides.setProperty(TIMEOUT_PORT_OPEN, "25000");
|
||||
|
||||
// note that this module hooks into the async urlfetchservice
|
||||
ImmutableSet<Module> modules = ImmutableSet.<Module> of(new AsyncGoogleAppEngineConfigurationModule());
|
||||
|
||||
blobsStoreContexts = ImmutableSet.<BlobStoreContext> of(new BlobStoreContextFactory().createContext("aws-s3",
|
||||
modules, props));
|
||||
computeServiceContexts = ImmutableSet.<ComputeServiceContext> of(new ComputeServiceContextFactory()
|
||||
.createContext("aws-ec2", modules, props));
|
||||
blobsStoreContexts = ImmutableSet.of(
|
||||
ContextBuilder.newBuilder("hpcloud-objectstorage")
|
||||
.modules(modules)
|
||||
.overrides(overrides)
|
||||
.buildView(BlobStoreContext.class));
|
||||
computeServiceContexts = ImmutableSet.of(
|
||||
ContextBuilder.newBuilder("hpcloud-compute")
|
||||
.modules(modules)
|
||||
.overrides(overrides)
|
||||
.buildView(ComputeServiceContext.class));
|
||||
|
||||
super.contextInitialized(servletContextEvent);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.samples.googleappengine.functions;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -38,7 +40,7 @@ public class BlobStoreContextToStatusResult implements Function<BlobStoreContext
|
|||
protected Logger logger = Logger.NULL;
|
||||
|
||||
public StatusResult apply(BlobStoreContext in) {
|
||||
String host = in.getProviderSpecificContext().getEndpoint().getHost();
|
||||
String host = URI.create(in.unwrap().getProviderMetadata().getEndpoint()).getHost();
|
||||
String status;
|
||||
String name = "not found";
|
||||
try {
|
||||
|
@ -51,6 +53,6 @@ public class BlobStoreContextToStatusResult implements Function<BlobStoreContext
|
|||
logger.error(e, "Error listing context %s", in);
|
||||
status = (e.getMessage());
|
||||
}
|
||||
return new StatusResult(in.getProviderSpecificContext().getId(), host, name, status);
|
||||
return new StatusResult(in.unwrap().getId(), host, name, status);
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.samples.googleappengine.functions;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -38,7 +40,7 @@ public class ComputeServiceContextToStatusResult implements Function<ComputeServ
|
|||
protected Logger logger = Logger.NULL;
|
||||
|
||||
public StatusResult apply(ComputeServiceContext in) {
|
||||
String host = in.getProviderSpecificContext().getEndpoint().getHost();
|
||||
String host = URI.create(in.unwrap().getProviderMetadata().getEndpoint()).getHost();
|
||||
String status;
|
||||
String name = "not found";
|
||||
try {
|
||||
|
@ -51,6 +53,6 @@ public class ComputeServiceContextToStatusResult implements Function<ComputeServ
|
|||
logger.error(e, "Error listing context %s", in);
|
||||
status = (e.getMessage());
|
||||
}
|
||||
return new StatusResult(in.getProviderSpecificContext().getId(), host, name, status);
|
||||
return new StatusResult(in.unwrap().getId(), host, name, status);
|
||||
}
|
||||
}
|
|
@ -48,14 +48,14 @@ public class GoogleAppEngineLiveTest {
|
|||
throws Exception {
|
||||
url = new URL(String.format("http://%s:%s", address, port));
|
||||
Properties props = new Properties();
|
||||
String identity = checkNotNull(System.getProperty("test.aws.identity"),
|
||||
"test.aws.identity");
|
||||
String credential = checkNotNull(System.getProperty("test.aws.credential"),
|
||||
"test.aws.credential");
|
||||
String identity = checkNotNull(System.getProperty("test.hpcloud.identity"),
|
||||
"test.hpcloud.identity");
|
||||
String credential = checkNotNull(System.getProperty("test.hpcloud.credential"),
|
||||
"test.hpcloud.credential");
|
||||
|
||||
/**
|
||||
* Since both s3 and ec2 use the same credentials, we can take a shortcut and specify both
|
||||
* here:
|
||||
* Since both objectstorage and compute use the same credentials, we can
|
||||
* take a shortcut and specify both here:
|
||||
*/
|
||||
props.setProperty("jclouds.identity", identity);
|
||||
props.setProperty("jclouds.credential", credential);
|
||||
|
|
Loading…
Reference in New Issue