cloudendpoints / endpoints-java

A Java framework for building RESTful APIs on Google App Engine
Apache License 2.0
32 stars 35 forks source link

endpoints v2 on flexible environment - exec:java -DGetSwaggerDoc not working #24

Open Eng-Fouad opened 7 years ago

Eng-Fouad commented 7 years ago

I am trying to apply this example https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/appengine/endpoints-frameworks-v2/backend on the flexible environment.

However, when I try to generate the Open API spec file using: exec:java -DGetSwaggerDoc

I got the following error:

Error: Could not locate D:\IdeaProjects*\-server-backend-1.0-SNAPSHOT\WEB-INF\appengine-web.xml

My configuration file is located on a different path: appengine/app.yml as per the documentation of the flexible environment.

I believe you need to update AppEngineUtil.java class to support flexible environment.

Eng-Fouad commented 7 years ago

Any plan to fix this soon?

tangiel commented 7 years ago

@Eng-Fouad I think you need to build first. Try mvn package exec:java -DGetSwaggerDoc.

Eng-Fouad commented 7 years ago

[INFO] --- exec-maven-plugin:1.5.0:java (default-cli) @ test-server-backend --- Dec 20, 2016 8:44:05 AM com.google.apphosting.utils.config.AppEngineWebXmlReader readAppEngineWebXml SEVERE: Received exception processing target/test-server-backend-1.0-SNAPSHOT\WEB-INF/appengine-web.xml com.google.apphosting.utils.config.AppEngineConfigException: Could not locate C:\Users\Fouad\IdeaProjects\Test\Backend\target\test-ser ver-backend-1.0-SNAPSHOT\WEB-INF\appengine-web.xml at com.google.apphosting.utils.config.AppEngineWebXmlReader.getInputStream(AppEngineWebXmlReader.java:141) at com.google.apphosting.utils.config.AppEngineWebXmlReader.readAppEngineWebXml(AppEngineWebXmlReader.java:75) at com.google.api.server.spi.tools.AppEngineUtil.getAppProperty(AppEngineUtil.java:129) at com.google.api.server.spi.tools.AppEngineUtil.getApplicationId(AppEngineUtil.java:52) at com.google.api.server.spi.tools.AppEngineUtil.getApplicationDefaultHostname(AppEngineUtil.java:91) at com.google.api.server.spi.tools.EndpointsToolAction.getHostname(EndpointsToolAction.java:226) at com.google.api.server.spi.tools.GetOpenApiDocAction.execute(GetOpenApiDocAction.java:83) at com.google.api.server.spi.tools.EndpointsTool.execute(EndpointsTool.java:84) at com.google.api.server.spi.tools.EndpointsTool.main(EndpointsTool.java:116) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:294) at java.lang.Thread.run(Thread.java:745) Caused by: java.io.FileNotFoundException: target\test-server-backend-1.0-SNAPSHOT\WEB-INF\appengine-web.xml (The system cannot find the fi le specified) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.(FileInputStream.java:138) at java.io.FileInputStream.(FileInputStream.java:93) at com.google.apphosting.utils.config.AppEngineWebXmlReader.getInputStream(AppEngineWebXmlReader.java:137) ... 14 more

Error: Could not locate C:\Users\Fouad\IdeaProjects\Test\Backend\target\test-server-backend-1.0-SNAPSHOT\WEB-INF\appengine-web.xml

and here is part of my pom.xml:

<properties>
    <endpoints.framework.version>2.0.0-beta.12</endpoints.framework.version>
    <endpoints.management.version>1.0.0-beta.12</endpoints.management.version>
</properties>

<dependencies>
    <!-- Compile/runtime dependencies -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.google.endpoints</groupId>
        <artifactId>endpoints-framework</artifactId>
        <version>${endpoints.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>com.google.endpoints</groupId>
        <artifactId>endpoints-framework-tools</artifactId>
        <version>${endpoints.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>com.google.endpoints</groupId>
        <artifactId>endpoints-management-control</artifactId>
        <version>${endpoints.management.version}</version>
    </dependency>
    <dependency>
        <groupId>com.google.endpoints</groupId>
        <artifactId>endpoints-management-control-appengine</artifactId>
        <version>${endpoints.management.version}</version>
    </dependency>
    <dependency>
        <groupId>com.google.endpoints</groupId>
        <artifactId>endpoints-framework-auth</artifactId>
        <version>${endpoints.management.version}</version>
    </dependency>
    <dependency>
        <groupId>com.google.endpoints</groupId>
        <artifactId>endpoints-management-protos</artifactId>
        <version>${endpoints.management.version}</version>
    </dependency>
    <dependency>
        <groupId>com.google.endpoints</groupId>
        <artifactId>endpoints-management-config</artifactId>
        <version>${endpoints.management.version}</version>
    </dependency>
    <dependency>
        <groupId>com.google.endpoints</groupId>
        <artifactId>endpoints-management-api-client</artifactId>
        <version>${endpoints.management.version}</version>
    </dependency>
    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.inject.extensions</groupId>
        <artifactId>guice-servlet</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.endpoints</groupId>
        <artifactId>endpoints-framework-guice</artifactId>
        <version>${endpoints.framework.version}</version>
    </dependency>

    <!-- Test Dependencies -->

</dependencies>

<profiles>
    <profile>
        <id>GetSwaggerDoc</id>
        <activation>
            <property>
                <name>GetSwaggerDoc</name>
            </property>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>1.5.0</version>
                    <configuration>
                        <includePluginDependencies>true</includePluginDependencies>
                        <mainClass>com.google.api.server.spi.tools.EndpointsTool</mainClass>
                        <arguments>
                            <argument>get-swagger-doc</argument>
                            <argument>--hostname=test-backend-api.test-dev.appspot.com</argument>
                            <argument>--war=target/test-server-backend-1.0-SNAPSHOT</argument>
                            <argument>com.test.server.backend.endpoints.apis.AuthAPI</argument>
                        </arguments>
                    </configuration>
                    <dependencies>
                        <dependency>
                            <groupId>org.slf4j</groupId>
                            <artifactId>slf4j-jdk14</artifactId>
                            <version>1.7.21</version>
                        </dependency>
                    </dependencies>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

<build>
    <!-- for hot reload of the web application -->
    <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>

    <plugins>
        <plugin>
            <groupId>com.google.cloud.tools</groupId>
            <artifactId>appengine-maven-plugin</artifactId>
            <version>${appengine.maven.plugin.version}</version>
        </plugin>
        <plugin>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-maven-plugin</artifactId>
            <version>${jetty-maven-plugin}</version>
            <configuration>
                <httpConnector>
                    <port>8081</port>
                </httpConnector>
            </configuration>
        </plugin>
    </plugins>
</build>
tangiel commented 7 years ago

@Eng-Fouad does target/echo-1.0-SNAPSHOT has app.yaml in it? If not, can you run mvn appengine:stage and tell me if target/appengine-staging has app.yaml?

Eng-Fouad commented 7 years ago

does target/echo-1.0-SNAPSHOT has app.yaml in it?

No.

If not, can you run mvn appengine:stage and tell me if target/appengine-staging has app.yaml?

Yes, it has app.yaml and also the war file.

Eng-Fouad commented 7 years ago

The new version 2.0.0 didn't solve this issue. Same error occurs.

I also tried to manually copy app.yaml to target\test-server-backend-1.0-SNAPSHOT, but then I got the following error:

Error: Line 1, column 4: Unable to find property 'env' on class: com.google.apphosting.utils.config.AppYaml

I changed env to the old name vm, but still doesn't work:

Error: Line 1, column 3: Unable to find property 'vm' on class: com.google.apphosting.utils.config.AppYaml

I searched for com.google.apphosting.utils.config.AppYaml and it turned out that it is included in Appengine Testing. Is it outdated?

Eng-Fouad commented 7 years ago

The following command doesn't work either:

mvn clean package appengine:stage exec:java -DGetSwaggerDoc

SEVERE: Received exception processing target/test-server-backend-1.0-SNAPSHOT\WEB-INF/appengine-web.xml com.google.apphosting.utils.config.AppEngineConfigException: Could not locate C:\Users\Fouad\IdeaProjects\Test\Backend\target\test-s erver-backend-1.0-SNAPSHOT\WEB-INF\appengine-web.xml at com.google.apphosting.utils.config.AppEngineWebXmlReader.getInputStream(AppEngineWebXmlReader.java:141) at com.google.apphosting.utils.config.AppEngineWebXmlReader.readAppEngineWebXml(AppEngineWebXmlReader.java:75) at com.google.api.server.spi.tools.AppEngineUtil.getAppProperty(AppEngineUtil.java:138) at com.google.api.server.spi.tools.AppEngineUtil.getApplicationId(AppEngineUtil.java:57) at com.google.api.server.spi.tools.AppEngineUtil.getApplicationDefaultHostname(AppEngineUtil.java:96) at com.google.api.server.spi.tools.EndpointsToolAction.getHostname(EndpointsToolAction.java:226) at com.google.api.server.spi.tools.GetOpenApiDocAction.execute(GetOpenApiDocAction.java:83) at com.google.api.server.spi.tools.EndpointsTool.execute(EndpointsTool.java:84) at com.google.api.server.spi.tools.EndpointsTool.main(EndpointsTool.java:116) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:294) at java.lang.Thread.run(Thread.java:745) Caused by: java.io.FileNotFoundException: target\test-server-backend-1.0-SNAPSHOT\WEB-INF\appengine-web.xml (The system cannot find the file specified) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.(FileInputStream.java:138) at java.io.FileInputStream.(FileInputStream.java:93) at com.google.apphosting.utils.config.AppEngineWebXmlReader.getInputStream(AppEngineWebXmlReader.java:137) ... 14 more

Error: Could not locate C:\Users\Fouad\IdeaProjects\Test\Backend\target\test-server-backend-1.0-SNAPSHOT\WEB-INF\appengine-web.xml

Eng-Fouad commented 7 years ago

OK, I solved the first issue (finding app.yaml) by replacing:

<argument>--war=target/test-server-backend-1.0-SNAPSHOT</argument>

with

<argument>--war=target/appengine-staging</argument>

in pom.xml.

However, the following command still doesn't solve the second issue:

mvn clean package appengine:stage exec:java -DGetSwaggerDoc

Error: Line 1, column 4: Unable to find property 'env' on class: com.google.apphosting.utils.config.AppYaml

Eng-Fouad commented 7 years ago

After reading the source code of endpoints-framework-tools, I found the problem:

protected String getHostname(Option hostnameOption, String warPath) {
    return getOptionOrDefault(hostnameOption, AppEngineUtil.getApplicationDefaultHostname(warPath));
}

The code tries to get the hostname by extracting it from the application id which is located in the config file. However, app.yaml doesn't have application id! Also, isn't the hostname currently different from the application id (e.g. test-backend-api.endpoints.test-dev.cloud.goog)?

I think the fix to this problem is to not try extracting the hostname if it is already passed as an option. Something like this:

protected String getHostname(Option hostnameOption, String warPath) {
    String hostname = hostnameOption.getValue();
    return hostname != null ? hostname : AppEngineUtil.getApplicationDefaultHostname(warPath);
}
tangiel commented 7 years ago

Thanks. See #42.