From 69373507d4c4d3c23799dc41c494c95e5e669ab3 Mon Sep 17 00:00:00 2001 From: Alejandro Butron Date: Fri, 22 Aug 2025 22:30:05 +0000 Subject: [PATCH 1/2] chore:upgrade java8 to java21 for appidentity folder --- appengine-java21/appidentity/README.md | 22 +++ appengine-java21/appidentity/pom.xml | 139 ++++++++++++++++++ .../appidentity/IdentityServlet.java | 43 ++++++ .../appidentity/SignForAppServlet.java | 116 +++++++++++++++ .../appengine/appidentity/UrlShortener.java | 78 ++++++++++ .../appidentity/UrlShortenerServlet.java | 80 ++++++++++ .../src/main/webapp/WEB-INF/appengine-web.xml | 5 + .../src/main/webapp/WEB-INF/web.xml | 9 ++ .../appidentity/IdentityServletTest.java | 79 ++++++++++ .../appidentity/SignForAppServletTest.java | 75 ++++++++++ 10 files changed, 646 insertions(+) create mode 100644 appengine-java21/appidentity/README.md create mode 100644 appengine-java21/appidentity/pom.xml create mode 100644 appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/IdentityServlet.java create mode 100644 appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/SignForAppServlet.java create mode 100644 appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortener.java create mode 100644 appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortenerServlet.java create mode 100644 appengine-java21/appidentity/src/main/webapp/WEB-INF/appengine-web.xml create mode 100644 appengine-java21/appidentity/src/main/webapp/WEB-INF/web.xml create mode 100644 appengine-java21/appidentity/src/test/java/com/example/appengine/appidentity/IdentityServletTest.java create mode 100644 appengine-java21/appidentity/src/test/java/com/example/appengine/appidentity/SignForAppServletTest.java diff --git a/appengine-java21/appidentity/README.md b/appengine-java21/appidentity/README.md new file mode 100644 index 00000000000..44e79dbb91e --- /dev/null +++ b/appengine-java21/appidentity/README.md @@ -0,0 +1,22 @@ +# App Identity sample for Google App Engine + + +Open in Cloud Shell + + +This sample demonstrates how to use the [App Identity API][appid] on [Google App +Engine][ae-docs]. + +[appid]: https://cloud.google.com/appengine/docs/java/appidentity/ +[ae-docs]: https://cloud.google.com/appengine/docs/java/ + +## Running locally +This example uses the +[Maven Cloud SDK based plugin](https://cloud.google.com/appengine/docs/java/tools/using-maven). +To run this sample locally: + + $ mvn appengine:run + +## Deploying + + $ mvn clean package appengine:deploy diff --git a/appengine-java21/appidentity/pom.xml b/appengine-java21/appidentity/pom.xml new file mode 100644 index 00000000000..9c3fe31f356 --- /dev/null +++ b/appengine-java21/appidentity/pom.xml @@ -0,0 +1,139 @@ + + + 4.0.0 + war + 1.0-SNAPSHOT + com.example.appengine + appengine-appidentity-j21 + + + + com.google.cloud.samples + shared-configuration + 1.2.0 + + + + 1.8 + 1.8 + + + + + + libraries-bom + com.google.cloud + import + pom + 26.28.0 + + + + + + + com.google.appengine + appengine-api-1.0-sdk + 2.0.23 + + + + com.google.guava + guava + + + + org.json + json + 20231013 + + + + javax.servlet + javax.servlet-api + 3.1.0 + jar + provided + + + + + com.google.appengine + appengine-api-stubs + 2.0.23 + test + + + com.google.appengine + appengine-tools-sdk + 2.0.23 + test + + + + junit + junit + 4.13.2 + test + + + org.mockito + mockito-core + 4.11.0 + test + + + com.google.appengine + appengine-testing + 2.0.23 + test + + + com.google.truth + truth + 1.1.5 + test + + + + + ${project.build.directory}/${project.build.finalName}/WEB-INF/classes + + + org.apache.maven.plugins + maven-war-plugin + 3.4.0 + + + com.google.cloud.tools + appengine-maven-plugin + 2.5.0 + + GCLOUD_CONFIG + GCLOUD_CONFIG + true + true + + + + + diff --git a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/IdentityServlet.java b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/IdentityServlet.java new file mode 100644 index 00000000000..b3ed51b9fbc --- /dev/null +++ b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/IdentityServlet.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015 Google Inc. + * + * 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.appengine.appidentity; + +import com.google.apphosting.api.ApiProxy; +import java.io.IOException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@SuppressWarnings("serial") +// With @WebServlet annotation the webapp/WEB-INF/web.xml is no longer required. +@WebServlet( + name = "appidentity", + description = "AppIdentity: Get the Host Name", + urlPatterns = "/appidentity/identity" +) +public class IdentityServlet extends HttpServlet { + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + resp.setContentType("text/plain"); + ApiProxy.Environment env = ApiProxy.getCurrentEnvironment(); + resp.getWriter().print("default_version_hostname: "); + resp.getWriter() + .println(env.getAttributes().get("com.google.appengine.runtime.default_version_hostname")); + } +} diff --git a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/SignForAppServlet.java b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/SignForAppServlet.java new file mode 100644 index 00000000000..80d62b5ca3a --- /dev/null +++ b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/SignForAppServlet.java @@ -0,0 +1,116 @@ +/* + * Copyright 2016 Google Inc. + * + * 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.appengine.appidentity; + +import com.google.appengine.api.appidentity.AppIdentityService; +import com.google.appengine.api.appidentity.AppIdentityServiceFactory; +import com.google.appengine.api.appidentity.PublicCertificate; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@SuppressWarnings("serial") +// With @WebServlet annotation the webapp/WEB-INF/web.xml is no longer required. +@WebServlet( + name = "signforapp", + description = "AppIdentity: Sign 'abcdefg'", + urlPatterns = "/appidentity/sign" +) +public class SignForAppServlet extends HttpServlet { + + private final AppIdentityService appIdentity; + + public SignForAppServlet() { + appIdentity = AppIdentityServiceFactory.getAppIdentityService(); + } + + // [START gae_java8_app_identity_other_services] + // Note that the algorithm used by AppIdentity.signForApp() and + // getPublicCertificatesForApp() is "SHA256withRSA" + + private byte[] signBlob(byte[] blob) { + AppIdentityService.SigningResult result = appIdentity.signForApp(blob); + return result.getSignature(); + } + + private byte[] getPublicCertificate() throws UnsupportedEncodingException { + Collection certs = appIdentity.getPublicCertificatesForApp(); + PublicCertificate publicCert = certs.iterator().next(); + return publicCert.getX509CertificateInPemFormat().getBytes("UTF-8"); + } + + private Certificate parsePublicCertificate(byte[] publicCert) + throws CertificateException, NoSuchAlgorithmException { + InputStream stream = new ByteArrayInputStream(publicCert); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + return cf.generateCertificate(stream); + } + + private boolean verifySignature(byte[] blob, byte[] blobSignature, PublicKey pk) + throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { + Signature signature = Signature.getInstance("SHA256withRSA"); + signature.initVerify(pk); + signature.update(blob); + return signature.verify(blobSignature); + } + + private String simulateIdentityAssertion() + throws CertificateException, UnsupportedEncodingException, NoSuchAlgorithmException, + InvalidKeyException, SignatureException { + // Simulate the sending app. + String message = "abcdefg " + Calendar.getInstance().getTime().toString(); + byte[] blob = message.getBytes(); + byte[] blobSignature = signBlob(blob); + byte[] publicCert = getPublicCertificate(); + + // Simulate the receiving app, which gets the certificate, blob, and signature. + Certificate cert = parsePublicCertificate(publicCert); + PublicKey pk = cert.getPublicKey(); + boolean isValid = verifySignature(blob, blobSignature, pk); + + return String.format( + "isValid=%b for message: %s\n\tsignature: %s\n\tpublic cert: %s", + isValid, message, Arrays.toString(blobSignature), Arrays.toString(publicCert)); + } + // [END gae_java8_app_identity_other_services] + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + resp.setContentType("text/plain"); + try { + resp.getWriter().println(simulateIdentityAssertion()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortener.java b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortener.java new file mode 100644 index 00000000000..4a0a2fdd677 --- /dev/null +++ b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortener.java @@ -0,0 +1,78 @@ +/* + * Copyright 2016 Google Inc. + * + * 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.appengine.appidentity; + +import com.google.appengine.api.appidentity.AppIdentityService; +import com.google.appengine.api.appidentity.AppIdentityServiceFactory; +import com.google.common.io.CharStreams; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import org.json.JSONObject; +import org.json.JSONTokener; + +@SuppressWarnings("serial") +class UrlShortener { + // [START gae_java21_app_identity_google_apis] + + /** + * Returns a shortened URL by calling the Google URL Shortener API. + * + *

Note: Error handling elided for simplicity. + */ + public String createShortUrl(String longUrl) throws Exception { + ArrayList scopes = new ArrayList<>(); + scopes.add("https://www.googleapis.com/auth/urlshortener"); + final AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService(); + final AppIdentityService.GetAccessTokenResult accessToken = appIdentity.getAccessToken(scopes); + // The token asserts the identity reported by appIdentity.getServiceAccountName() + JSONObject request = new JSONObject(); + request.put("longUrl", longUrl); + + URL url = new URL("https://www.googleapis.com/urlshortener/v1/url?pp=1"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoOutput(true); + connection.setRequestMethod("POST"); + connection.addRequestProperty("Content-Type", "application/json"); + connection.addRequestProperty("Authorization", "Bearer " + accessToken.getAccessToken()); + + OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); + request.write(writer); + writer.close(); + + if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { + // Note: Should check the content-encoding. + // Any JSON parser can be used; this one is used for illustrative purposes. + JSONTokener responseTokens = new JSONTokener(connection.getInputStream()); + JSONObject response = new JSONObject(responseTokens); + return (String) response.get("id"); + } else { + try (InputStream s = connection.getErrorStream(); + InputStreamReader r = new InputStreamReader(s, StandardCharsets.UTF_8)) { + throw new RuntimeException( + String.format( + "got error (%d) response %s from %s", + connection.getResponseCode(), CharStreams.toString(r), connection.toString())); + } + } + } + // [START gae_java21_app_identity_google_apis] +} diff --git a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortenerServlet.java b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortenerServlet.java new file mode 100644 index 00000000000..8e622793479 --- /dev/null +++ b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortenerServlet.java @@ -0,0 +1,80 @@ +/* + * Copyright 2016 Google Inc. + * + * 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.appengine.appidentity; + +import java.io.IOException; +import java.io.PrintWriter; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@SuppressWarnings("serial") +// With @WebServlet annotation the webapp/WEB-INF/web.xml is no longer required. +@WebServlet( + name = "UrlShortener", + description = "AppIdentity: Url Shortener", + urlPatterns = "/appidentity/shorten" +) +public class UrlShortenerServlet extends HttpServlet { + + private final UrlShortener shortener; + + public UrlShortenerServlet() { + shortener = new UrlShortener(); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + PrintWriter writer = resp.getWriter(); + writer.println(""); + writer.println(""); + writer.println( + "Asserting Identity to Google APIs - App Engine App Identity Example"); + writer.println("

"); + writer.println(""); + writer.println(""); + writer.println(""); + writer.println("
"); + } + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + resp.setContentType("text/plain"); + String longUrl = req.getParameter("longUrl"); + if (longUrl == null) { + resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "missing longUrl parameter"); + return; + } + + String shortUrl; + PrintWriter writer = resp.getWriter(); + try { + shortUrl = shortener.createShortUrl(longUrl); + } catch (Exception e) { + resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + writer.println("error shortening URL: " + longUrl); + e.printStackTrace(writer); + return; + } + + writer.print("long URL: "); + writer.println(longUrl); + writer.print("short URL: "); + writer.println(shortUrl); + } +} diff --git a/appengine-java21/appidentity/src/main/webapp/WEB-INF/appengine-web.xml b/appengine-java21/appidentity/src/main/webapp/WEB-INF/appengine-web.xml new file mode 100644 index 00000000000..0f80dd41fc5 --- /dev/null +++ b/appengine-java21/appidentity/src/main/webapp/WEB-INF/appengine-web.xml @@ -0,0 +1,5 @@ + + + true + java21 + diff --git a/appengine-java21/appidentity/src/main/webapp/WEB-INF/web.xml b/appengine-java21/appidentity/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..d07ac01365d --- /dev/null +++ b/appengine-java21/appidentity/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,9 @@ + + + + appidentity/identity + + diff --git a/appengine-java21/appidentity/src/test/java/com/example/appengine/appidentity/IdentityServletTest.java b/appengine-java21/appidentity/src/test/java/com/example/appengine/appidentity/IdentityServletTest.java new file mode 100644 index 00000000000..58c57c457c4 --- /dev/null +++ b/appengine-java21/appidentity/src/test/java/com/example/appengine/appidentity/IdentityServletTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2015 Google Inc. + * + * 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.appengine.appidentity; + +import static com.google.common.truth.Truth.assertWithMessage; +import static org.mockito.Mockito.when; + +import com.google.appengine.tools.development.testing.LocalServiceTestHelper; +import java.io.PrintWriter; +import java.io.StringWriter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Unit tests for {@link IdentityServlet}. + */ +@RunWith(JUnit4.class) +public class IdentityServletTest { + + // Set up a helper so that the ApiProxy returns a valid environment for local testing. + private final LocalServiceTestHelper helper = new LocalServiceTestHelper(); + + @Mock + private HttpServletRequest mockRequest; + @Mock + private HttpServletResponse mockResponse; + private StringWriter responseWriter; + private IdentityServlet servletUnderTest; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.openMocks(this); + helper.setUp(); + + // Set up a fake HTTP response. + responseWriter = new StringWriter(); + when(mockResponse.getWriter()).thenReturn(new PrintWriter(responseWriter)); + + servletUnderTest = new IdentityServlet(); + } + + @After + public void tearDown() { + helper.tearDown(); + } + + @Test + public void doGet_defaultEnvironment_writesResponse() throws Exception { + servletUnderTest.doGet(mockRequest, mockResponse); + + // We don't have any guarantee over what the local App Engine environment returns for + // "com.google.appengine.runtime.default_version_hostname". Only assert that the response + // contains part of the string we have control over. + assertWithMessage("IdentityServlet response") + .that(responseWriter.toString()) + .contains("default_version_hostname:"); + } +} diff --git a/appengine-java21/appidentity/src/test/java/com/example/appengine/appidentity/SignForAppServletTest.java b/appengine-java21/appidentity/src/test/java/com/example/appengine/appidentity/SignForAppServletTest.java new file mode 100644 index 00000000000..cf2488005f1 --- /dev/null +++ b/appengine-java21/appidentity/src/test/java/com/example/appengine/appidentity/SignForAppServletTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2016 Google Inc. + * + * 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.appengine.appidentity; + +import static com.google.common.truth.Truth.assertWithMessage; +import static org.mockito.Mockito.when; + +import com.google.appengine.tools.development.testing.LocalServiceTestHelper; +import java.io.PrintWriter; +import java.io.StringWriter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Unit tests for {@link SignForAppServlet}. + */ +@RunWith(JUnit4.class) +public class SignForAppServletTest { + + private final LocalServiceTestHelper helper = new LocalServiceTestHelper(); + + @Mock + private HttpServletRequest mockRequest; + @Mock + private HttpServletResponse mockResponse; + private StringWriter responseWriter; + private SignForAppServlet servletUnderTest; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.openMocks(this); + helper.setUp(); + + // Set up a fake HTTP response. + responseWriter = new StringWriter(); + when(mockResponse.getWriter()).thenReturn(new PrintWriter(responseWriter)); + + servletUnderTest = new SignForAppServlet(); + } + + @After + public void tearDown() { + helper.tearDown(); + } + + @Test + public void doGet_defaultEnvironment_successfullyVerifiesSignature() throws Exception { + servletUnderTest.doGet(mockRequest, mockResponse); + + assertWithMessage("SignForAppServlet response") + .that(responseWriter.toString()) + .contains("isValid=true for message: abcdefg"); + } +} From cfbb85d92b58d221b6aa2b28fa2c93674745cd58 Mon Sep 17 00:00:00 2001 From: Alejandro Butron Date: Wed, 27 Aug 2025 03:42:43 +0000 Subject: [PATCH 2/2] chore:upgrade java8 to java21 for appidentity folder --- appengine-java21/appidentity/pom.xml | 11 +++++------ .../appengine/appidentity/IdentityServlet.java | 3 ++- .../appengine/appidentity/SignForAppServlet.java | 6 +++--- .../example/appengine/appidentity/UrlShortener.java | 4 ++-- .../appengine/appidentity/UrlShortenerServlet.java | 2 +- .../appidentity/src/main/webapp/WEB-INF/web.xml | 5 ++--- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/appengine-java21/appidentity/pom.xml b/appengine-java21/appidentity/pom.xml index 9c3fe31f356..18fcb73866c 100644 --- a/appengine-java21/appidentity/pom.xml +++ b/appengine-java21/appidentity/pom.xml @@ -33,8 +33,8 @@ - 1.8 - 1.8 + 21 + 21 @@ -68,10 +68,9 @@ - javax.servlet - javax.servlet-api - 3.1.0 - jar + jakarta.servlet + jakarta.servlet-api + 6.0.0 provided diff --git a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/IdentityServlet.java b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/IdentityServlet.java index b3ed51b9fbc..f27495ab738 100644 --- a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/IdentityServlet.java +++ b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/IdentityServlet.java @@ -31,6 +31,7 @@ urlPatterns = "/appidentity/identity" ) public class IdentityServlet extends HttpServlet { + private static final String DEFAULT_VERSION_HOSTNAME_ATTRIBUTE = "com.google.appengine.runtime.default_version_hostname"; @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { @@ -38,6 +39,6 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOExc ApiProxy.Environment env = ApiProxy.getCurrentEnvironment(); resp.getWriter().print("default_version_hostname: "); resp.getWriter() - .println(env.getAttributes().get("com.google.appengine.runtime.default_version_hostname")); + .println(env.getAttributes().get(DEFAULT_VERSION_HOSTNAME_ATTRIBUTE)); } } diff --git a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/SignForAppServlet.java b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/SignForAppServlet.java index 80d62b5ca3a..2fe87ce2658 100644 --- a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/SignForAppServlet.java +++ b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/SignForAppServlet.java @@ -66,7 +66,7 @@ private byte[] signBlob(byte[] blob) { private byte[] getPublicCertificate() throws UnsupportedEncodingException { Collection certs = appIdentity.getPublicCertificatesForApp(); PublicCertificate publicCert = certs.iterator().next(); - return publicCert.getX509CertificateInPemFormat().getBytes("UTF-8"); + return publicCert.getX509CertificateInPemFormat().getBytes(java.nio.charset.StandardCharsets.UTF_8); } private Certificate parsePublicCertificate(byte[] publicCert) @@ -88,7 +88,7 @@ private String simulateIdentityAssertion() throws CertificateException, UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { // Simulate the sending app. - String message = "abcdefg " + Calendar.getInstance().getTime().toString(); + String message = "abcdefg " + java.time.Instant.now().toString(); byte[] blob = message.getBytes(); byte[] blobSignature = signBlob(blob); byte[] publicCert = getPublicCertificate(); @@ -110,7 +110,7 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOExc try { resp.getWriter().println(simulateIdentityAssertion()); } catch (Exception e) { - throw new RuntimeException(e); + throw new javax.servlet.ServletException(e); } } } diff --git a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortener.java b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortener.java index 4a0a2fdd677..c6c6df50f9b 100644 --- a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortener.java +++ b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortener.java @@ -38,7 +38,7 @@ class UrlShortener { * *

Note: Error handling elided for simplicity. */ - public String createShortUrl(String longUrl) throws Exception { + public String createShortUrl(String longUrl) throws IOException { ArrayList scopes = new ArrayList<>(); scopes.add("https://www.googleapis.com/auth/urlshortener"); final AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService(); @@ -54,7 +54,7 @@ public String createShortUrl(String longUrl) throws Exception { connection.addRequestProperty("Content-Type", "application/json"); connection.addRequestProperty("Authorization", "Bearer " + accessToken.getAccessToken()); - OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); + OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), StandardCharsets.UTF_8); request.write(writer); writer.close(); diff --git a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortenerServlet.java b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortenerServlet.java index 8e622793479..41bf8aebf8d 100644 --- a/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortenerServlet.java +++ b/appengine-java21/appidentity/src/main/java/com/example/appengine/appidentity/UrlShortenerServlet.java @@ -68,7 +68,7 @@ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOEx } catch (Exception e) { resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); writer.println("error shortening URL: " + longUrl); - e.printStackTrace(writer); + e.printStackTrace(); return; } diff --git a/appengine-java21/appidentity/src/main/webapp/WEB-INF/web.xml b/appengine-java21/appidentity/src/main/webapp/WEB-INF/web.xml index d07ac01365d..21e14d226e3 100644 --- a/appengine-java21/appidentity/src/main/webapp/WEB-INF/web.xml +++ b/appengine-java21/appidentity/src/main/webapp/WEB-INF/web.xml @@ -1,8 +1,7 @@ - + xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd" version="6.0"> appidentity/identity