diff --git a/endpoints/getting-started/README.md b/endpoints/getting-started/README.md new file mode 100644 index 00000000000..12b5579fd9a --- /dev/null +++ b/endpoints/getting-started/README.md @@ -0,0 +1,21 @@ +# Google Cloud Endpoints & Java +This sample demonstrates how to use Google Cloud Endpoints using a Java backend. + +For a complete walkthrough showing how to run this sample in different environments, see the [Google Cloud Endpoints Quickstarts](https://cloud.google.com/endpoints/docs/quickstarts). + +## Deploying to Production + +See the [Google Cloud Endpoints Quickstarts](https://cloud.google.com/endpoints/docs/quickstarts). + +## Calling your API + +Please refer to the Google Cloud Endpoints [documentation](https://cloud.google.com/endpoints/docs/app-engine/) for App Engine Flexible Environment to learn about creating an API Key and calling your API. + +## Viewing the Endpoints graphs + +By using Endpoints, you get access to several metrics that are displayed graphically in the Cloud Console. + +To view the Endpoints graphs: + +1. Go to the [Endpoints section in Cloud Console](https://console.cloud.google.com/endpoints) of the project you deployed your API to. +2. Click on your API to view more detailed information about the metrics collected. diff --git a/endpoints/getting-started/container-engine.yaml b/endpoints/getting-started/container-engine.yaml new file mode 100644 index 00000000000..6374d012aac --- /dev/null +++ b/endpoints/getting-started/container-engine.yaml @@ -0,0 +1,56 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# 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. + +apiVersion: v1 +kind: Service +metadata: + name: esp-echo +spec: + ports: + - port: 80 + targetPort: 8081 + protocol: TCP + name: http + selector: + app: esp-echo + type: LoadBalancer +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: esp-echo +spec: + replicas: 1 + template: + metadata: + labels: + app: esp-echo + spec: + containers: + # [START esp] + - name: esp + image: b.gcr.io/endpoints/endpoints-runtime:0.3 + args: [ + "-p", "8081", + "-a", "127.0.0.1:8080", + "-s", "SERVICE_NAME", + "-v", "SERVICE_VERSION", + ] + # [END esp] + ports: + - containerPort: 8081 + - name: echo + image: gcr.io/google-samples/echo-java:1.0 + ports: + - containerPort: 8080 diff --git a/endpoints/getting-started/pom.xml b/endpoints/getting-started/pom.xml new file mode 100644 index 00000000000..1bee4f5e64d --- /dev/null +++ b/endpoints/getting-started/pom.xml @@ -0,0 +1,81 @@ + + + + 4.0.0 + war + 1.0-SNAPSHOT + com.example.endpoints + endpoints + + + doc-samples + com.google.cloud + 1.0.0 + ../.. + + + + 1.8 + 1.8 + + 2.6 + + 1.0.0 + 9.3.8.v20160314 + + false + + + + + javax.servlet + javax.servlet-api + 3.1.0 + jar + provided + + + + com.google.code.gson + gson + 2.6.2 + compile + + + + + + ${project.build.directory}/${project.build.finalName}/WEB-INF/classes + + + com.google.appengine + gcloud-maven-plugin + 2.0.9.121.v20160815 + + beta + + + + com.google.cloud.tools + appengine-maven-plugin + ${appengine.maven.plugin} + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin} + + false + + + + org.eclipse.jetty + jetty-maven-plugin + ${jetty.maven.plugin} + + + + diff --git a/endpoints/getting-started/src/main/appengine/Dockerfile b/endpoints/getting-started/src/main/appengine/Dockerfile new file mode 100644 index 00000000000..063636ed556 --- /dev/null +++ b/endpoints/getting-started/src/main/appengine/Dockerfile @@ -0,0 +1,4 @@ +FROM gcr.io/google_appengine/jetty9 + +ADD endpoints-1.0-SNAPSHOT.war $JETTY_BASE/webapps/root.war +ADD . /app diff --git a/endpoints/getting-started/src/main/appengine/app.yaml b/endpoints/getting-started/src/main/appengine/app.yaml new file mode 100644 index 00000000000..5882f5a8952 --- /dev/null +++ b/endpoints/getting-started/src/main/appengine/app.yaml @@ -0,0 +1,13 @@ +runtime: custom +env: flex + +handlers: +- url: /.* + script: this field is required, but ignored + secure: always + +beta_settings: + # Enable Google Cloud Endpoints API management. + use_endpoints_api_management: true + # Specify the Swagger API specification. + endpoints_swagger_spec_file: swagger.yaml diff --git a/endpoints/getting-started/src/main/appengine/swagger.yaml b/endpoints/getting-started/src/main/appengine/swagger.yaml new file mode 100644 index 00000000000..71bac9ce62f --- /dev/null +++ b/endpoints/getting-started/src/main/appengine/swagger.yaml @@ -0,0 +1,106 @@ +swagger: "2.0" +info: + description: "A simple Google Cloud Endpoints API example." + title: "Endpoints Example" + version: "1.0.0" +host: "YOUR-PROJECT-ID.appspot.com" +basePath: "/" +consumes: +- "application/json" +produces: +- "application/json" +schemes: +- "https" +paths: + "/echo": + post: + description: "Echo back a given message." + operationId: "echo" + produces: + - "application/json" + responses: + 200: + description: "Echo" + schema: + $ref: "#/definitions/echoMessage" + parameters: + - description: "Message to echo" + in: body + name: message + required: true + schema: + $ref: "#/definitions/echoMessage" + "/auth/info/googlejwt": + get: + description: "Returns the requests' authentication information." + operationId: "auth_info_google_jwt" + produces: + - "application/json" + responses: + 200: + description: "Authenication info." + schema: + $ref: "#/definitions/authInfoResponse" + x-security: + - google_jwt: + audiences: + # This must match the "aud" field in the JWT. You can add multiple + # audiences to accept JWTs from multiple clients. + - "echo.endpoints.sample.google.com" + "/auth/info/googleidtoken": + get: + description: "Returns the requests' authentication information." + operationId: "authInfoGoogleIdToken" + produces: + - "application/json" + responses: + 200: + description: "Authenication info." + schema: + $ref: "#/definitions/authInfoResponse" + x-security: + - google_id_token: + audiences: + # Your OAuth2 client's Client ID must be added here. You can add + # multiple client IDs to accept tokens from multiple clients. + - "YOUR-CLIENT-ID" +definitions: + echoMessage: + properties: + message: + type: "string" + authInfoResponse: + properties: + id: + type: "string" + email: + type: "string" +# This section requires all requests to any path to require an API key. +security: +- api_key: [] +securityDefinitions: + # This section configures basic authentication with an API key. + api_key: + type: "apiKey" + name: "key" + in: "query" + # This section configures authentication using Google API Service Accounts + # to sign a json web token. This is mostly used for server-to-server + # communication. + google_jwt: + authorizationUrl: "" + flow: "implicit" + type: "oauth2" + # This must match the 'iss' field in the JWT. + x-issuer: "jwt-client.endpoints.sample.google.com" + # Update this with your service account's email address. + x-jwks_uri: "https://www.googleapis.com/service_accounts/v1/jwk/YOUR-SERVICE-ACCOUNT-EMAIL" + # This section configures authentication using Google OAuth2 ID Tokens. + # ID Tokens can be obtained using OAuth2 clients, and can be used to access + # your API on behalf of a particular user. + google_id_token: + authorizationUrl: "" + flow: "implicit" + type: "oauth2" + x-issuer: "accounts.google.com" + x-jwks_uri: "https://www.googleapis.com/oauth2/v1/certs" diff --git a/endpoints/getting-started/src/main/java/com/example/endpoints/AuthInfoServlet.java b/endpoints/getting-started/src/main/java/com/example/endpoints/AuthInfoServlet.java new file mode 100644 index 00000000000..233ea414239 --- /dev/null +++ b/endpoints/getting-started/src/main/java/com/example/endpoints/AuthInfoServlet.java @@ -0,0 +1,58 @@ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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 com.example.endpoints; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import java.io.IOException; +import java.util.Base64; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * A servlet that returns authentication information. + * See swagger.yaml for authentication mechanisms (e.g. JWT tokens, Google ID token). + */ +@WebServlet("/auth/info/*") +public class AuthInfoServlet extends HttpServlet { + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String encodedInfo = req.getHeader("X-Endpoint-API-UserInfo"); + if (encodedInfo == null || encodedInfo == "") { + JsonObject anon = new JsonObject(); + anon.addProperty("id", "anonymous"); + new Gson().toJson(anon, resp.getWriter()); + return; + } + + try { + byte[] authInfo = Base64.getDecoder().decode(encodedInfo); + resp.getOutputStream().write(authInfo); + } catch (IllegalArgumentException iae) { + resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); + JsonObject error = new JsonObject(); + error.addProperty("code", HttpServletResponse.SC_BAD_REQUEST); + error.addProperty("message", "Could not decode auth info."); + new Gson().toJson(error, resp.getWriter()); + } + } +} diff --git a/endpoints/getting-started/src/main/java/com/example/endpoints/EchoServlet.java b/endpoints/getting-started/src/main/java/com/example/endpoints/EchoServlet.java new file mode 100644 index 00000000000..40e0f1f5038 --- /dev/null +++ b/endpoints/getting-started/src/main/java/com/example/endpoints/EchoServlet.java @@ -0,0 +1,56 @@ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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 com.example.endpoints; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.stream.JsonReader; + +import java.io.IOException; +import java.util.Map; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * A servlet that echoes JSON message bodies. + */ +@WebServlet("/echo") +public class EchoServlet extends HttpServlet { + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + resp.addHeader("Content-Encoding", "application/json"); + + Object responseBody; + try { + JsonReader jsonReader = new JsonReader(req.getReader()); + responseBody = new Gson().fromJson(jsonReader, Map.class); + } catch (JsonParseException je) { + resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); + JsonObject error = new JsonObject(); + error.addProperty("code", HttpServletResponse.SC_BAD_REQUEST); + error.addProperty("message", "Body was not valid JSON."); + responseBody = error; + } + + new Gson().toJson(responseBody, resp.getWriter()); + } +}