├── .github └── workflows │ ├── build.yml │ ├── markdown-link-check.yml │ └── mlc_config.json ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── config-client-polling ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── microsoft │ │ └── sample │ │ ├── Application.java │ │ └── ConfigClientAutoRefreshConfiguration.java │ └── resources │ └── bootstrap.yml ├── config-server-yaml-samples ├── README.md ├── config-server-http-basic-auth.yml ├── config-server-pattern.yml ├── config-server-ssh-auth.yml └── config-server-startup.yml ├── custom-config-server-client ├── .gitignore ├── README.md ├── pom.xml ├── setup-env-variables-template.sh └── src │ └── main │ ├── java │ └── com │ │ └── microsoft │ │ └── sample │ │ └── customConfigServerClient │ │ ├── AccessTokenManager.java │ │ ├── Application.java │ │ ├── AuthorizationHeaderRequestInterceptor.java │ │ ├── CustomBootstrapRegistryInitializer.java │ │ └── HelloController.java │ └── resources │ ├── META-INF │ └── spring.factories │ └── application.properties ├── custom-eureka-client ├── .gitignore ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── microsoft │ │ └── sample │ │ └── customEurekaClient │ │ ├── AccessTokenManager.java │ │ ├── Application.java │ │ ├── CustomRestTemplateTransportClientFactories.java │ │ ├── CustomRestTemplateTransportClientFactory.java │ │ └── HelloController.java │ └── resources │ └── application.properties ├── hystrix-turbine-sample ├── Readme.md ├── hystrix-turbine │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── mynotes │ │ │ └── spring │ │ │ └── cloud │ │ │ └── hystrix │ │ │ └── turbine │ │ │ └── HystrixTurbineApplication.java │ │ └── resources │ │ └── application.properties ├── recommendation-service │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── mynotes │ │ │ └── spring │ │ │ └── cloud │ │ │ └── service │ │ │ ├── Product.java │ │ │ ├── RecommendationServiceApplication.java │ │ │ └── RecommendationServiceRestController.java │ │ └── resources │ │ └── application.properties ├── setup-env-variables-template.sh └── user-service │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── com │ │ └── mynotes │ │ └── spring │ │ └── cloud │ │ └── hystrix │ │ ├── Application.java │ │ ├── Product.java │ │ └── UserRestController.java │ └── resources │ └── application.properties ├── java-11-sample ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── microsoft │ └── sample │ ├── Application.java │ └── HelloController.java ├── java-17-sample ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── azure │ │ └── asa │ │ └── sample │ │ ├── EurekaController.java │ │ ├── HelloController.java │ │ └── Java17SampleApplication.java │ └── resources │ └── application.properties ├── java-8-sample ├── README.md ├── application.yml ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── microsoft │ │ │ └── sample │ │ │ └── java8ASCdemo │ │ │ └── Java8AscDemoApplication.java │ └── resources │ │ └── application.yml │ └── test │ ├── java │ └── com │ │ └── microsoft │ │ └── sample │ │ └── java8ASCdemo │ │ └── Java8AscDemoApplicationTests.java │ └── resources │ └── application.yaml ├── job-samples ├── football-billboard │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── microsoft │ │ │ └── sample │ │ │ └── football │ │ │ ├── BillboardApplication.java │ │ │ ├── BillboardController.java │ │ │ ├── BillboardService.java │ │ │ └── ResultReport.java │ │ └── resources │ │ ├── application.properties │ │ └── static │ │ ├── background.jpg │ │ └── index.html ├── football │ ├── README.md │ ├── pom.xml │ ├── setup-env-variables-template.sh │ └── src │ │ └── main │ │ ├── java │ │ ├── com │ │ │ └── microsoft │ │ │ │ └── sample │ │ │ │ ├── DiscoveryClientConfiguration.java │ │ │ │ ├── FootballJobApplication.java │ │ │ │ └── ResultReport.java │ │ └── org │ │ │ └── springframework │ │ │ └── batch │ │ │ └── samples │ │ │ └── football │ │ │ ├── FootballJobConfiguration.java │ │ │ ├── Game.java │ │ │ ├── Player.java │ │ │ ├── PlayerDao.java │ │ │ ├── PlayerSummary.java │ │ │ └── internal │ │ │ ├── GameFieldSetMapper.java │ │ │ ├── JdbcGameDao.java │ │ │ ├── JdbcPlayerDao.java │ │ │ ├── JdbcPlayerSummaryDao.java │ │ │ ├── PlayerFieldSetMapper.java │ │ │ ├── PlayerItemWriter.java │ │ │ ├── PlayerSummaryMapper.java │ │ │ └── PlayerSummaryRowMapper.java │ │ └── resources │ │ ├── application.properties │ │ ├── org │ │ └── springframework │ │ │ └── batch │ │ │ └── samples │ │ │ ├── common │ │ │ └── business-schema-hsqldb.sql │ │ │ └── football │ │ │ ├── data │ │ │ ├── games-small.csv │ │ │ ├── games.csv │ │ │ ├── player-containsBadRecords.csv │ │ │ ├── player-small1.csv │ │ │ ├── player-small2.csv │ │ │ └── player.csv │ │ │ ├── job │ │ │ └── footballJob.xml │ │ │ └── sql │ │ │ └── schema.sql │ │ └── simplelogger.properties └── hello-world │ ├── README.md │ ├── pom.xml │ ├── setup-env-variables-template.sh │ └── src │ └── main │ ├── java │ └── com │ │ └── microsoft │ │ └── sample │ │ └── HelloWorldJobApplication.java │ └── resources │ ├── application.properties │ └── simplelogger.properties ├── k8s-service-registry ├── .gitignore ├── gateway │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── microsoft │ │ └── azure │ │ └── sample │ │ ├── Application.java │ │ └── controller │ │ └── Entrance.java ├── greeting-client │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── microsoft │ │ │ └── azure │ │ │ └── sample │ │ │ ├── Application.java │ │ │ └── HelloClient.java │ │ └── resources │ │ └── application.properties ├── greeting-server │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── microsoft │ │ └── azure │ │ └── sample │ │ └── Application.java ├── media │ ├── service-registry-arch.jpeg │ └── service-registry.jpeg ├── pom.xml └── readme.md ├── managed-identity-function ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── microsoft │ │ └── azure │ │ ├── MainController.java │ │ └── ManagedIdentityFunctionApplication.java │ └── resources │ └── application.properties ├── managed-identity-keyvault ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── microsoft │ │ └── azure │ │ ├── MainController.java │ │ └── ManagedIdentityKeyVaultApplication.java │ └── resources │ └── application.properties ├── managed-identity-mysql ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── microsoft │ │ └── azure │ │ ├── MainController.java │ │ ├── ManagedIdentityMysqlApplication.java │ │ ├── Todo.java │ │ └── TodoRepository.java │ └── resources │ ├── application.properties │ └── schema.sql ├── managed-identity-storage-blob ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── microsoft │ │ └── azure │ │ ├── MainController.java │ │ └── ManagedIdentityStorageBlobApplication.java │ └── resources │ └── application.properties ├── service-binding-cosmosdb-mongo ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── microsoft │ └── azure │ ├── MainController.java │ ├── ServiceBindingMongodbApplication.java │ ├── User.java │ └── UserRepository.java ├── service-binding-cosmosdb-sql ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── microsoft │ └── azure │ ├── MainController.java │ ├── ServiceBindingCosmosDbApplication.java │ ├── User.java │ └── UserRepository.java ├── service-binding-mysql ├── pom.xml ├── readme.md └── src │ └── main │ ├── java │ └── com │ │ └── microsoft │ │ └── azure │ │ ├── MainController.java │ │ ├── ServiceBindingMysqlApplication.java │ │ ├── User.java │ │ └── UserRepository.java │ └── resources │ └── application.properties ├── service-binding-redis ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── microsoft │ └── azure │ ├── MainController.java │ └── ServiceBindingRedisApplication.java ├── steeltoe-sample ├── .gitignore ├── Microsoft.Azure.SpringCloud.Samples.sln ├── config │ ├── planet-weather-provider.yml │ └── solar-system-weather.yml └── src │ ├── planet-weather-provider │ ├── Controllers │ │ └── WeatherForecastController.cs │ ├── Microsoft.Azure.SpringCloud.Sample.PlanetWeatherProvider.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ └── appsettings.json │ └── solar-system-weather │ ├── Controllers │ └── WeatherForecastController.cs │ ├── Microsoft.Azure.SpringCloud.Sample.SolarSystemWeather.csproj │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ └── appsettings.json └── storage-sample ├── README.md ├── pom.xml └── src └── main └── java └── com └── microsoft └── sample ├── Application.java └── StorageController.java /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | pull_request: 5 | branches: [ "main" ] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - name: Set up JDK 11 13 | uses: actions/setup-java@v3 14 | with: 15 | java-version: '11' 16 | distribution: 'temurin' 17 | cache: maven 18 | - name: Build java-8-sample 19 | run: mvn -B package -D skipTests -f java-8-sample/pom.xml 20 | - name: Build java-11-sample 21 | run: mvn -B package -D skipTests -f java-11-sample/pom.xml 22 | - name: Build hystrix-turbine-sample 23 | run: mvn -B package -D skipTests -f hystrix-turbine-sample/user-service/pom.xml 24 | -------------------------------------------------------------------------------- /.github/workflows/markdown-link-check.yml: -------------------------------------------------------------------------------- 1 | name: Markdown Links Check 2 | 3 | on: 4 | pull_request: 5 | branches: [ "main" ] 6 | 7 | jobs: 8 | markdown-link-check: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@master 12 | - uses: gaurav-nelson/github-action-markdown-link-check@1.0.15 13 | with: 14 | use-quiet-mode: 'yes' 15 | use-verbose-mode: 'yes' 16 | config-file: '.github/workflows/mlc_config.json' 17 | -------------------------------------------------------------------------------- /.github/workflows/mlc_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": [ 3 | { 4 | "pattern": "^http://127.0.0.1" 5 | }, 6 | { 7 | "pattern": "^https://127.0.0.1" 8 | }, 9 | { 10 | "pattern": "^http://localhost" 11 | }, 12 | { 13 | "pattern": "^https://localhost" 14 | }, 15 | { 16 | "pattern": "^http://proxyserver" 17 | } 18 | ], 19 | "timeout": "20s", 20 | "retryOn429": true, 21 | "retryCount": 5, 22 | "aliveStatusCodes": [200] 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | pom.xml.tag 3 | pom.xml.releaseBackup 4 | pom.xml.versionsBackup 5 | pom.xml.next 6 | release.properties 7 | dependency-reduced-pom.xml 8 | buildNumber.properties 9 | .mvn/timing.properties 10 | .classpath 11 | .factorypath 12 | 13 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) 14 | !/.mvn/wrapper/maven-wrapper.jar 15 | 16 | # Package Files # 17 | *.jar 18 | *.war 19 | *.ear 20 | *.zip 21 | *.tar.gz 22 | *.rar 23 | 24 | # IntelliJ 25 | .idea/ 26 | *.iml 27 | .project 28 | .settings 29 | 30 | # Publish 31 | publish/ 32 | 33 | # VS Code 34 | .vscode/ 35 | 36 | setup-env-variables.sh 37 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://www.microsoft.com/msrc/definition-of-a-security-vulnerability), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/msrc/pgp-key-msrc). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://www.microsoft.com/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /config-client-polling/README.md: -------------------------------------------------------------------------------- 1 | ## Auto refresh config server changes in Azure Spring Apps 2 | 3 | This sample shows how to auto refresh config server changes by letting the config client to poll for changes based on a refresh internal. 4 | 5 | ## Prerequisite 6 | 7 | * [JDK 8](https://docs.microsoft.com/azure/java/jdk/java-jdk-install) 8 | * [Maven 3.0 and above](http://maven.apache.org/install.html) 9 | * [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/overview) 10 | 11 | ## How to run 12 | 13 | 1. Clone this repo and go to folder 14 | 15 | ```bash 16 | git clone https://github.com/Azure-Samples/azure-spring-apps-samples 17 | cd azure-spring-apps-samples/config-client-polling 18 | ``` 19 | 20 | 1. Package the app using maven 21 | 22 | ```bash 23 | mvn clean package -D skipTests 24 | ``` 25 | 26 | 1. Install Azure CLI extension for Azure Spring Apps 27 | 28 | ```bash 29 | az extension add --name spring-cloud 30 | ``` 31 | 32 | 1. Create an instance of Azure Spring Apps 33 | 34 | ```bash 35 | az spring-cloud create -n -g 36 | ``` 37 | 38 | 1. Create a public repo that only has the provided `application.yml` file 39 | 40 | 1. Using the URI of that repo, configure Azure Spring Apps to pull config from it 41 | 42 | ```bash 43 | az spring-cloud config-server git set --name --uri 44 | ``` 45 | 1. Create an app with public domain assigned 46 | ```bash 47 | az spring-cloud app create -n -s -g --is-public true 48 | ``` 49 | 1. Get the app url: 50 | ```bash 51 | az spring cloud app show -n -s -g --query properties.url 52 | ``` 53 | 1. Deploy the newly created jar 54 | 55 | ```bash 56 | az spring-cloud app deploy -n -s -g --jar-path ./target/config-client-polling-1.0-SNAPSHOT.jar 57 | ``` 58 | 59 | 1. Change the config server configuration "timeout", after you change the property, the value "connectTimeout" in Application.class will change automatically in 10 seconds. Run below command, you will see the timeout value. The url is fetched from previous step. 60 | 61 | ```bash 62 | Curl {url}/hello 63 | ``` -------------------------------------------------------------------------------- /config-client-polling/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.asc 8 | config-client-polling 9 | 1.0-SNAPSHOT 10 | 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 2.3.4.RELEASE 15 | 16 | 17 | 18 | 19 | 1.8 20 | Hoxton.SR8 21 | 22 | 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-web 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-starter-netflix-eureka-client 31 | 32 | 33 | org.springframework.cloud 34 | spring-cloud-starter-config 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-actuator 39 | 40 | 41 | 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-dependencies 46 | ${spring-cloud.version} 47 | pom 48 | import 49 | 50 | 51 | 52 | 53 | 54 | 55 | nexus-snapshots 56 | https://oss.sonatype.org/content/repositories/snapshots/ 57 | 58 | true 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | org.springframework.boot 67 | spring-boot-maven-plugin 68 | 69 | 70 | org.apache.maven.plugins 71 | maven-compiler-plugin 72 | 73 | 8 74 | 8 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /config-client-polling/src/main/java/com/microsoft/sample/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample; 8 | 9 | import org.springframework.beans.factory.annotation.Value; 10 | import org.springframework.boot.SpringApplication; 11 | import org.springframework.boot.autoconfigure.SpringBootApplication; 12 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 13 | import org.springframework.cloud.context.config.annotation.RefreshScope; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RestController; 16 | 17 | @EnableDiscoveryClient 18 | @RestController 19 | @RefreshScope 20 | @SpringBootApplication 21 | public class Application { 22 | 23 | @Value("${timeout:4000}") 24 | private String connectTimeout; 25 | 26 | @RequestMapping("/hello") 27 | public String hello() { 28 | System.out.println("hello client, connectTimeout: " + connectTimeout); 29 | return "hello client, connectTimeout: " + connectTimeout; 30 | } 31 | 32 | public static void main(String[] args) { 33 | SpringApplication.run(Application.class, args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /config-client-polling/src/main/java/com/microsoft/sample/ConfigClientAutoRefreshConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample; 8 | 9 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 10 | import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; 11 | import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration; 12 | import org.springframework.cloud.endpoint.RefreshEndpoint; 13 | import org.springframework.scheduling.annotation.EnableScheduling; 14 | import org.springframework.scheduling.annotation.SchedulingConfigurer; 15 | import org.springframework.scheduling.config.ScheduledTaskRegistrar; 16 | import org.springframework.stereotype.Component; 17 | 18 | @Component 19 | @AutoConfigureAfter({RefreshAutoConfiguration.class, RefreshEndpointAutoConfiguration.class}) 20 | @EnableScheduling 21 | public class ConfigClientAutoRefreshConfiguration implements SchedulingConfigurer { 22 | 23 | private RefreshEndpoint refreshEndpoint; 24 | 25 | public ConfigClientAutoRefreshConfiguration(RefreshEndpoint refreshEndpoint) { 26 | this.refreshEndpoint = refreshEndpoint; 27 | } 28 | 29 | @Override 30 | public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { 31 | // set refresh interval to 10 seconds 32 | int refreshInterval = 10; 33 | scheduledTaskRegistrar.addFixedRateTask(() -> refreshEndpoint.refresh(), refreshInterval * 1000); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /config-client-polling/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | config: 4 | enabled: true 5 | 6 | management: 7 | endpoints: 8 | web: 9 | exposure: 10 | include: refresh -------------------------------------------------------------------------------- /config-server-yaml-samples/README.md: -------------------------------------------------------------------------------- 1 | ## Config Server Git Repository `application.yml` Samples. 2 | 3 | This folder holds some samples of `application.yml` files, which can be imported into `Config Server` blade of Azure Spring Apps service on Azure portal. For more details, please see [Import Settings from YAML File](https://docs.microsoft.com/azure/spring-cloud/spring-cloud-tutorial-config-server#enter-repository-information-into-a-yaml-file). 4 | 5 | ### Startup 6 | 7 | The startup [config-server-startup.yml](./config-server-startup.yml) file for `Config Server` is very simple, which contains only one property named `uri`. The uri specifies one public `uri` of one git repository. 8 | 9 | ### Http Basic Authentication 10 | 11 | The http basic authentication [config-server-http-basic-auth.yml](./config-server-http-basic-auth.yml) file for `Config Server` focus on access private git repository with [Http Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication). Of course, the `username` and the `password` should be provided from the yaml file. 12 | 13 | ### SSH Authentication 14 | 15 | The ssh authentication [config-server-ssh-auth.yml](./config-server-ssh-auth.yml) file for `Config Server` focus on access private git repository with [SSH](https://en.wikipedia.org/wiki/Secure_Shell). Almost the same as `Http Basic Authentication`, at least the `private key` of `SSH` should be provided. 16 | 17 | ### Pattern 18 | 19 | The more complex like pattern matching on the application and profile name is also supported. The pattern format is a comma-separated list of `{application}/{profile}` names with wildcards, see [config-server-pattern.yml](./config-server-pattern.yml). 20 | 21 | ### Reference 22 | 23 | 1. https://docs.spring.io/spring-cloud-config/reference/server/environment-repository/git-backend.html -------------------------------------------------------------------------------- /config-server-yaml-samples/config-server-http-basic-auth.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | config: 4 | server: 5 | git: 6 | uri: ${your-git-repository-uri} 7 | username: ${your-git-repository-username} 8 | password: ${your-git-repository-password-or-token} 9 | 10 | # Reference: https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.1.4.RELEASE/single/spring-cloud-config.html#_authentication 11 | -------------------------------------------------------------------------------- /config-server-yaml-samples/config-server-pattern.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | config: 4 | server: 5 | git: 6 | uri: ${your-git-repository-uri} 7 | default-label: master 8 | search-paths: 9 | - / 10 | repos: 11 | sample: 12 | pattern: 13 | - sample/* 14 | - dev/* 15 | uri: ${your-git-repository-uri} 16 | username: ${your-git-repository-username} 17 | password: ${your-git-repository-password-or-token} 18 | test: 19 | pattern: 20 | - test/* 21 | uri: ${your-git-repository-uri} 22 | private-key: ${your-git-repository-ssh-private-key} 23 | 24 | # Reference: https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.1.4.RELEASE/single/spring-cloud-config.html#_pattern_matching_and_multiple_repositories 25 | -------------------------------------------------------------------------------- /config-server-yaml-samples/config-server-ssh-auth.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | config: 4 | server: 5 | git: 6 | uri: ${your-git-repository-uri} 7 | private-key: ${your-git-repository-ssh-private-key} 8 | 9 | # Reference: https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.1.4.RELEASE/single/spring-cloud-config.html#_git_ssh_configuration_using_properties 10 | -------------------------------------------------------------------------------- /config-server-yaml-samples/config-server-startup.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | config: 4 | server: 5 | git: 6 | uri: ${your-public-git-repository-uri} 7 | 8 | # Reference: https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.1.4.RELEASE/single/spring-cloud-config.html#_git_backend 9 | -------------------------------------------------------------------------------- /custom-config-server-client/.gitignore: -------------------------------------------------------------------------------- 1 | *# 2 | *.iml 3 | *.ipr 4 | *.iws 5 | *.jar 6 | *.sw? 7 | *~ 8 | .#* 9 | .*.md.html 10 | .DS_Store 11 | .attach_pid* 12 | .classpath 13 | .factorypath 14 | .gradle 15 | .idea 16 | .metadata 17 | .project 18 | .recommenders 19 | .settings 20 | .springBeans 21 | .vscode 22 | /code 23 | MANIFEST.MF 24 | _site/ 25 | activemq-data 26 | bin 27 | build 28 | !/**/src/**/bin 29 | !/**/src/**/build 30 | build.log 31 | dependency-reduced-pom.xml 32 | dump.rdb 33 | interpolated*.xml 34 | lib/ 35 | manifest.yml 36 | out 37 | overridedb.* 38 | target 39 | transaction-logs 40 | .flattened-pom.xml 41 | secrets.yml 42 | .gradletasknamecache 43 | .sts4-cache 44 | 45 | -------------------------------------------------------------------------------- /custom-config-server-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 3.2.0 10 | 11 | com.microsoft.sample 12 | custom-config-server-client 13 | 0.0.1-SNAPSHOT 14 | custom-config-server-client 15 | Demo project for showing how to access Azure Spring Apps 16 | managed Config Server through Azure RBAC when your applications are 17 | running outside Azure Spring Apps 18 | 19 | 17 20 | 2023.0.0 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter-config 30 | 31 | 32 | com.azure 33 | azure-core-management 34 | 35 | 36 | com.azure 37 | azure-identity 38 | compile 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-actuator 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.cloud 51 | spring-cloud-dependencies 52 | ${spring-cloud.version} 53 | pom 54 | import 55 | 56 | 57 | com.azure 58 | azure-sdk-bom 59 | 1.2.19 60 | pom 61 | import 62 | 63 | 64 | 65 | 66 | 67 | 68 | org.springframework.boot 69 | spring-boot-maven-plugin 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /custom-config-server-client/setup-env-variables-template.sh: -------------------------------------------------------------------------------- 1 | export SUBSCRIPTION='subscription-id' # replace it with your subscription-id 2 | export RESOURCE_GROUP='resource-group-name' # existing resource group or one that will be created in next steps 3 | export SPRING_APPS_SERVICE='azure-spring-apps-name' # name of the service that will be created in the next steps 4 | 5 | echo "SUBSCRIPTION=$SUBSCRIPTION" 6 | echo "RESOURCE_GROUP=$RESOURCE_GROUP" 7 | echo "SPRING_APPS_SERVICE=$SPRING_APPS_SERVICE" 8 | -------------------------------------------------------------------------------- /custom-config-server-client/src/main/java/com/microsoft/sample/customConfigServerClient/AccessTokenManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample.customConfigServerClient; 8 | 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.time.OffsetDateTime; 12 | import java.util.Properties; 13 | 14 | import com.azure.core.credential.AccessToken; 15 | import com.azure.core.credential.TokenCredential; 16 | import com.azure.core.credential.TokenRequestContext; 17 | import com.azure.core.management.AzureEnvironment; 18 | import com.azure.identity.ClientSecretCredentialBuilder; 19 | 20 | public class AccessTokenManager { 21 | 22 | static { 23 | Properties prop = new Properties(); 24 | InputStream in = AccessTokenManager.class.getResourceAsStream("/application.properties"); 25 | try { 26 | prop.load(in); 27 | 28 | clientId = prop.getProperty("access.token.clientId"); 29 | tenantId = prop.getProperty("access.token.tenantId"); 30 | secret = prop.getProperty("access.token.secret"); 31 | 32 | } catch (IOException e) { 33 | System.err.println(e.getMessage()); 34 | } 35 | } 36 | 37 | private static String clientId; 38 | 39 | private static String secret; 40 | 41 | private static String tenantId; 42 | 43 | private AccessToken token; 44 | 45 | public String getToken() throws IOException { 46 | if (token == null || token.getExpiresAt().isBefore(OffsetDateTime.now().plusMinutes(5))) { 47 | TokenCredential credential = new ClientSecretCredentialBuilder() 48 | .clientId(clientId) 49 | .clientSecret(secret) 50 | .tenantId(tenantId) 51 | .build(); 52 | token = credential.getTokenSync(new TokenRequestContext() 53 | .setTenantId(tenantId) 54 | .addScopes(String.format("%s/.default", AzureEnvironment.AZURE.getManagementEndpoint()))); 55 | } 56 | return token.getToken(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /custom-config-server-client/src/main/java/com/microsoft/sample/customConfigServerClient/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample.customConfigServerClient; 8 | 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | 12 | @SpringBootApplication 13 | public class Application { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(Application.class, args); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /custom-config-server-client/src/main/java/com/microsoft/sample/customConfigServerClient/AuthorizationHeaderRequestInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.sample.customConfigServerClient; 7 | 8 | import java.io.IOException; 9 | 10 | import org.springframework.http.HttpRequest; 11 | import org.springframework.http.client.ClientHttpRequestExecution; 12 | import org.springframework.http.client.ClientHttpRequestInterceptor; 13 | import org.springframework.http.client.ClientHttpResponse; 14 | 15 | public class AuthorizationHeaderRequestInterceptor implements ClientHttpRequestInterceptor { 16 | 17 | public AuthorizationHeaderRequestInterceptor() { 18 | accessTokenManager = new AccessTokenManager(); 19 | } 20 | 21 | private AccessTokenManager accessTokenManager; 22 | 23 | @Override 24 | public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) 25 | throws IOException { 26 | if (!request.getHeaders().containsKey("Authorization")) { 27 | request.getHeaders().add("Authorization", "Bearer " + accessTokenManager.getToken()); 28 | } 29 | return execution.execute(request, body); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /custom-config-server-client/src/main/java/com/microsoft/sample/customConfigServerClient/CustomBootstrapRegistryInitializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.sample.customConfigServerClient; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import org.springframework.boot.BootstrapRegistry; 12 | import org.springframework.boot.BootstrapRegistryInitializer; 13 | import org.springframework.http.client.ClientHttpRequestInterceptor; 14 | import org.springframework.web.client.RestTemplate; 15 | 16 | public class CustomBootstrapRegistryInitializer implements BootstrapRegistryInitializer { 17 | 18 | @Override 19 | public void initialize(BootstrapRegistry registry) { 20 | registry.register(RestTemplate.class, context -> { 21 | RestTemplate template = new RestTemplate(); 22 | List interceptors = template.getInterceptors(); 23 | if (interceptors == null) { 24 | interceptors = new ArrayList<>(); 25 | } 26 | interceptors.add(new AuthorizationHeaderRequestInterceptor()); 27 | template.setInterceptors(interceptors); 28 | return template; 29 | }); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /custom-config-server-client/src/main/java/com/microsoft/sample/customConfigServerClient/HelloController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample.customConfigServerClient; 8 | 9 | import org.springframework.beans.factory.annotation.Value; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | public class HelloController { 15 | 16 | /** 17 | * This is the example that user can read the properties from Config Server. 18 | */ 19 | @Value("${hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds}") 20 | private int timeout; 21 | 22 | @GetMapping("/config") 23 | public String getConfig() { 24 | return String.valueOf(timeout); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /custom-config-server-client/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.BootstrapRegistryInitializer=com.microsoft.sample.customConfigServerClient.CustomBootstrapRegistryInitializer 2 | -------------------------------------------------------------------------------- /custom-config-server-client/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=test 2 | # Config Server endpoint from Azure Spring Apps service runtime data plane 3 | spring.config.import=configserver:https://.svc.azuremicroservices.io/config 4 | # The below configuration is the properties of a service principle which has the read permission to 5 | # the Azure Spring Apps data plane 6 | access.token.clientId= 7 | access.token.secret= 8 | access.token.tenantId= 9 | -------------------------------------------------------------------------------- /custom-eureka-client/.gitignore: -------------------------------------------------------------------------------- 1 | *# 2 | *.iml 3 | *.ipr 4 | *.iws 5 | *.jar 6 | *.sw? 7 | *~ 8 | .#* 9 | .*.md.html 10 | .DS_Store 11 | .attach_pid* 12 | .classpath 13 | .factorypath 14 | .gradle 15 | .idea 16 | .metadata 17 | .project 18 | .recommenders 19 | .settings 20 | .springBeans 21 | .vscode 22 | /code 23 | MANIFEST.MF 24 | _site/ 25 | activemq-data 26 | bin 27 | build 28 | !/**/src/**/bin 29 | !/**/src/**/build 30 | build.log 31 | dependency-reduced-pom.xml 32 | dump.rdb 33 | interpolated*.xml 34 | lib/ 35 | manifest.yml 36 | out 37 | overridedb.* 38 | target 39 | transaction-logs 40 | .flattened-pom.xml 41 | secrets.yml 42 | .gradletasknamecache 43 | .sts4-cache 44 | 45 | -------------------------------------------------------------------------------- /custom-eureka-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.3.RELEASE 9 | 10 | 11 | com.microsoft.sample 12 | custom-eureka-client 13 | 0.0.1-SNAPSHOT 14 | custom-eureka-client 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter-netflix-eureka-client 30 | 2.2.5.RELEASE 31 | 32 | 33 | 34 | com.microsoft.azure 35 | azure 36 | 1.34.0 37 | 38 | 39 | 40 | com.microsoft.azure 41 | azure-mgmt-graph-rbac 42 | 1.34.0 43 | 44 | 45 | 46 | com.azure 47 | azure-core 48 | 1.3.0 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-starter-actuator 55 | 56 | 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-starter-test 62 | test 63 | 64 | 65 | org.projectlombok 66 | lombok 67 | 1.18.20 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | org.springframework.boot 76 | spring-boot-maven-plugin 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /custom-eureka-client/src/main/java/com/microsoft/sample/customEurekaClient/AccessTokenManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample.customEurekaClient; 8 | 9 | import com.microsoft.azure.AzureEnvironment; 10 | import com.microsoft.azure.credentials.ApplicationTokenCredentials; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.util.Properties; 14 | 15 | public class AccessTokenManager { 16 | 17 | static { 18 | Properties prop = new Properties(); 19 | InputStream in = AccessTokenManager.class.getResourceAsStream("/application.properties"); 20 | try { 21 | prop.load(in); 22 | tokenClientId = prop.getProperty("access.token.clientId"); 23 | String tenantId = prop.getProperty("access.token.tenantId"); 24 | String secret = prop.getProperty("access.token.secret"); 25 | String clientId = prop.getProperty("access.token.clientId"); 26 | credentials = new ApplicationTokenCredentials( 27 | clientId, tenantId, secret, AzureEnvironment.AZURE); 28 | } catch (IOException e) { 29 | System.err.println(e.getMessage()); 30 | } 31 | } 32 | 33 | private static String tokenClientId; 34 | 35 | private static ApplicationTokenCredentials credentials; 36 | 37 | public static String getToken() throws IOException { 38 | return credentials.getToken(tokenClientId); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /custom-eureka-client/src/main/java/com/microsoft/sample/customEurekaClient/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample.customEurekaClient; 8 | 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 12 | 13 | @EnableDiscoveryClient 14 | @SpringBootApplication 15 | public class Application { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(Application.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /custom-eureka-client/src/main/java/com/microsoft/sample/customEurekaClient/CustomRestTemplateTransportClientFactories.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample.customEurekaClient; 8 | 9 | import com.netflix.appinfo.InstanceInfo; 10 | import com.netflix.discovery.EurekaClientConfig; 11 | import com.netflix.discovery.shared.transport.TransportClientFactory; 12 | import java.util.Collection; 13 | import java.util.Optional; 14 | import javax.net.ssl.HostnameVerifier; 15 | import javax.net.ssl.SSLContext; 16 | import org.springframework.cloud.netflix.eureka.http.RestTemplateTransportClientFactories; 17 | 18 | public class CustomRestTemplateTransportClientFactories extends RestTemplateTransportClientFactories { 19 | 20 | @Override 21 | public TransportClientFactory newTransportClientFactory(final EurekaClientConfig clientConfig, 22 | final Collection additionalFilters, final InstanceInfo myInstanceInfo, 23 | final Optional sslContext, final Optional hostnameVerifier) { 24 | return new CustomRestTemplateTransportClientFactory(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /custom-eureka-client/src/main/java/com/microsoft/sample/customEurekaClient/HelloController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample.customEurekaClient; 8 | 9 | import java.util.List; 10 | import org.apache.http.conn.ssl.NoopHostnameVerifier; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.cloud.client.ServiceInstance; 13 | import org.springframework.cloud.client.discovery.DiscoveryClient; 14 | import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs; 15 | import org.springframework.context.annotation.Bean; 16 | import org.springframework.web.bind.annotation.PathVariable; 17 | import org.springframework.web.bind.annotation.RequestMapping; 18 | import org.springframework.web.bind.annotation.RestController; 19 | import org.springframework.web.client.RestTemplate; 20 | 21 | @RestController 22 | public class HelloController { 23 | 24 | @Autowired 25 | private RestTemplate restTemplate; 26 | 27 | @Bean 28 | public RestTemplateDiscoveryClientOptionalArgs discoveryClientOptionalArgs() throws Exception { 29 | RestTemplateDiscoveryClientOptionalArgs args = new RestTemplateDiscoveryClientOptionalArgs(); 30 | args.setHostnameVerifier(NoopHostnameVerifier.INSTANCE); 31 | args.setTransportClientFactories(new CustomRestTemplateTransportClientFactories()); 32 | return args; 33 | } 34 | 35 | @Bean 36 | public RestTemplate restTemplate() { 37 | return new RestTemplate(); 38 | } 39 | 40 | @Autowired 41 | private DiscoveryClient discoveryClient; 42 | 43 | @RequestMapping("/{applicationName}") 44 | public List serviceInstancesByApplicationName( 45 | @PathVariable String applicationName) { 46 | return this.discoveryClient.getInstances(applicationName); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /custom-eureka-client/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=test 2 | # Config Server endpoint from Azure Spring Apps service runtime data plane 3 | eureka.client.serviceUrl.defaultZone=https://.svc.azuremicroservices.io/eureka/eureka 4 | # The below configuration is the properties of a service principle which has the read permission to 5 | # the Azure Spring Apps data plane 6 | access.token.clientId= 7 | access.token.secret= 8 | access.token.tenantId= 9 | 10 | -------------------------------------------------------------------------------- /hystrix-turbine-sample/hystrix-turbine/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.0.RELEASE 9 | 10 | 11 | 12 | com.mynotes.spring.cloud 13 | hystrix-turbine 14 | 1.0.0-SNAPSHOT 15 | hystrix-turbine 16 | Demo project for Spring Cloud cloud hystrix-turbine 17 | 18 | 19 | UTF-8 20 | UTF-8 21 | 1.8 22 | Hoxton.SR8 23 | 24 | 25 | 26 | 27 | org.springframework.cloud 28 | spring-cloud-dependencies 29 | ${spring-cloud.version} 30 | pom 31 | import 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.cloud 38 | spring-cloud-starter-sleuth 39 | 40 | 41 | org.springframework.cloud 42 | spring-cloud-starter-zipkin 43 | 44 | 45 | org.springframework.cloud 46 | spring-cloud-starter-netflix-hystrix-dashboard 47 | 2.1.5.RELEASE 48 | 49 | 50 | org.springframework.cloud 51 | spring-cloud-starter-netflix-turbine 52 | 53 | 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-maven-plugin 59 | 60 | ${project.name} 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /hystrix-turbine-sample/hystrix-turbine/src/main/java/com/mynotes/spring/cloud/hystrix/turbine/HystrixTurbineApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.mynotes.spring.cloud.hystrix.turbine; 7 | 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 11 | import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; 12 | import org.springframework.cloud.netflix.turbine.EnableTurbine; 13 | 14 | @SpringBootApplication 15 | @EnableTurbine 16 | @EnableDiscoveryClient 17 | @EnableHystrixDashboard 18 | public class HystrixTurbineApplication { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(HystrixTurbineApplication.class, args); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /hystrix-turbine-sample/hystrix-turbine/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #server.port= 9090 2 | 3 | spring.application.name= hystirx-turbine 4 | 5 | # https://docs.spring.io/spring-cloud-netflix/docs/2.2.x-SNAPSHOT/reference/html/#netflix-hystrix-dashboard-starter 6 | hystrix.dashboard.proxy-stream-allow-list=** 7 | 8 | #eureka.client.serviceUrl.defaultZone= http://localhost:8761/eureka/ 9 | 10 | turbine.appConfig= user-service,recommendation-service 11 | 12 | #turbine.aggregator.clusterConfig= USER-SERVICE,RECOMMENDATION-SERVICE 13 | #or 14 | turbine.clusterNameExpression= new String("default") -------------------------------------------------------------------------------- /hystrix-turbine-sample/recommendation-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.0.RELEASE 9 | 10 | 11 | 12 | com.mynotes.spring.cloud 13 | recommendation-service 14 | 1.0.0-SNAPSHOT 15 | recommendation-service 16 | Demo project for Spring Cloud cloud recommendation-service 17 | 18 | 19 | UTF-8 20 | UTF-8 21 | 1.8 22 | Hoxton.SR8 23 | 24 | 25 | 26 | 27 | org.springframework.cloud 28 | spring-cloud-dependencies 29 | ${spring-cloud.version} 30 | pom 31 | import 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.cloud 38 | spring-cloud-starter-sleuth 39 | 40 | 41 | org.springframework.cloud 42 | spring-cloud-starter-zipkin 43 | 44 | 45 | org.springframework.cloud 46 | spring-cloud-starter-netflix-eureka-client 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-web 51 | 52 | 53 | org.springframework.cloud 54 | spring-cloud-starter-netflix-hystrix 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-starter-actuator 59 | 60 | 61 | 62 | 63 | 64 | org.springframework.boot 65 | spring-boot-maven-plugin 66 | 67 | ${project.name} 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /hystrix-turbine-sample/recommendation-service/src/main/java/com/mynotes/spring/cloud/service/Product.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.mynotes.spring.cloud.service; 7 | 8 | public class Product { 9 | 10 | private String name; 11 | 12 | private String description; 13 | 14 | private String detailsLink; 15 | 16 | public Product(String name, String description, String detailsLink) { 17 | super(); 18 | this.name = name; 19 | this.description = description; 20 | this.detailsLink = detailsLink; 21 | } 22 | 23 | public Product() { 24 | // TODO Auto-generated constructor stub 25 | } 26 | 27 | public String getName() { 28 | return name; 29 | } 30 | 31 | public void setName(String name) { 32 | this.name = name; 33 | } 34 | 35 | public String getDescription() { 36 | return description; 37 | } 38 | 39 | public void setDescription(String description) { 40 | this.description = description; 41 | } 42 | 43 | public String getDetailsLink() { 44 | return detailsLink; 45 | } 46 | 47 | public void setDetailsLink(String detailsLink) { 48 | this.detailsLink = detailsLink; 49 | } 50 | 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /hystrix-turbine-sample/recommendation-service/src/main/java/com/mynotes/spring/cloud/service/RecommendationServiceApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.mynotes.spring.cloud.service; 7 | 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 11 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 12 | 13 | @SpringBootApplication 14 | @EnableDiscoveryClient 15 | @EnableCircuitBreaker 16 | public class RecommendationServiceApplication { 17 | 18 | public static void main(String[] args) { 19 | SpringApplication.run(RecommendationServiceApplication.class, args); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /hystrix-turbine-sample/recommendation-service/src/main/java/com/mynotes/spring/cloud/service/RecommendationServiceRestController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.mynotes.spring.cloud.service; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | import org.springframework.web.bind.annotation.RestController; 15 | 16 | 17 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 18 | 19 | @RestController 20 | public class RecommendationServiceRestController { 21 | 22 | @RequestMapping(value = "/recommendations", method = RequestMethod.GET) 23 | @HystrixCommand(fallbackMethod = "recommendationFallback") 24 | @ResponseBody 25 | public List recommendations() { 26 | System.out.println("=======Get Called========="); 27 | List products = new ArrayList(); 28 | products.add(new Product("Product1", "Description1", "link1")); 29 | products.add(new Product("Product2", "Description2", "link3")); 30 | products.add(new Product("Product3", "Description3", "link3")); 31 | System.out.println("=======Done processing========="); 32 | return products; 33 | } 34 | 35 | public List recommendationFallback() { 36 | System.out.println("=======recommendationFallback========="); 37 | return new ArrayList(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /hystrix-turbine-sample/recommendation-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #server.port= 1025 2 | 3 | spring.application.name= recommendation-service 4 | 5 | #eureka.client.serviceUrl.defaultZone= http://localhost:8761/eureka/ 6 | 7 | management.endpoints.web.exposure.include=* -------------------------------------------------------------------------------- /hystrix-turbine-sample/setup-env-variables-template.sh: -------------------------------------------------------------------------------- 1 | export SUBSCRIPTION='subscription-id' # replace it with your subscription-id 2 | export RESOURCE_GROUP='resource-group-name' # existing resource group or one that will be created in next steps 3 | export SPRING_APPS_SERVICE='azure-spring-apps-name' # name of the service that will be created in the next steps 4 | 5 | echo "SUBSCRIPTION=$SUBSCRIPTION" 6 | echo "RESOURCE_GROUP=$RESOURCE_GROUP" 7 | echo "SPRING_APPS_SERVICE=$SPRING_APPS_SERVICE" -------------------------------------------------------------------------------- /hystrix-turbine-sample/user-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.0.RELEASE 9 | 10 | 11 | 12 | com.mynotes.spring.cloud 13 | user-service 14 | 1.0.0-SNAPSHOT 15 | user-service 16 | Demo project for Spring Cloud cloud user-service hystrix 17 | 18 | 19 | UTF-8 20 | UTF-8 21 | 1.8 22 | Hoxton.SR8 23 | 24 | 25 | 26 | 27 | org.springframework.cloud 28 | spring-cloud-dependencies 29 | ${spring-cloud.version} 30 | pom 31 | import 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.cloud 38 | spring-cloud-starter-sleuth 39 | 40 | 41 | org.springframework.cloud 42 | spring-cloud-starter-zipkin 43 | 44 | 45 | org.springframework.cloud 46 | spring-cloud-starter-netflix-eureka-client 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-web 51 | 52 | 53 | org.springframework.cloud 54 | spring-cloud-starter-netflix-hystrix 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-starter-actuator 59 | 60 | 61 | 62 | 63 | 64 | org.springframework.boot 65 | spring-boot-maven-plugin 66 | 67 | ${project.name} 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /hystrix-turbine-sample/user-service/src/main/java/com/mynotes/spring/cloud/hystrix/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.mynotes.spring.cloud.hystrix; 7 | 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 11 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 12 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 13 | import org.springframework.context.annotation.Bean; 14 | import org.springframework.web.client.RestTemplate; 15 | 16 | @SpringBootApplication 17 | @EnableDiscoveryClient 18 | @EnableCircuitBreaker 19 | public class Application { 20 | 21 | public static void main(String[] args) { 22 | SpringApplication.run(Application.class, args); 23 | } 24 | 25 | @LoadBalanced 26 | @Bean 27 | RestTemplate restTemplate() { 28 | return new RestTemplate(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /hystrix-turbine-sample/user-service/src/main/java/com/mynotes/spring/cloud/hystrix/Product.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.mynotes.spring.cloud.hystrix; 7 | 8 | public class Product { 9 | 10 | private String name; 11 | 12 | private String description; 13 | 14 | private String detailsLink; 15 | 16 | public Product(String name, String description, String detailsLink) { 17 | super(); 18 | this.name = name; 19 | this.description = description; 20 | this.detailsLink = detailsLink; 21 | } 22 | 23 | public Product() { 24 | // TODO Auto-generated constructor stub 25 | } 26 | 27 | public String getName() { 28 | return name; 29 | } 30 | 31 | public void setName(String name) { 32 | this.name = name; 33 | } 34 | 35 | public String getDescription() { 36 | return description; 37 | } 38 | 39 | public void setDescription(String description) { 40 | this.description = description; 41 | } 42 | 43 | public String getDetailsLink() { 44 | return detailsLink; 45 | } 46 | 47 | public void setDetailsLink(String detailsLink) { 48 | this.detailsLink = detailsLink; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /hystrix-turbine-sample/user-service/src/main/java/com/mynotes/spring/cloud/hystrix/UserRestController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.mynotes.spring.cloud.hystrix; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.RestController; 12 | import org.springframework.web.client.RestTemplate; 13 | 14 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 15 | 16 | @RestController 17 | public class UserRestController { 18 | 19 | @Autowired 20 | RestTemplate restTemplate; 21 | 22 | @GetMapping(value = "/personalized/{id}") 23 | @HystrixCommand(fallbackMethod = "recommendationFallback") 24 | public Product[] personalized(@PathVariable int id) { 25 | 26 | Product[] result = new Product[0]; 27 | 28 | System.out.println("=======Calling=========" + id); 29 | try{ 30 | result = restTemplate.getForObject("http://recommendation-service/recommendations", Product[].class); 31 | }catch (Exception e) { 32 | System.out.println(e); 33 | } 34 | System.out.println("=======Done Calling=========" + result); 35 | 36 | return result; 37 | } 38 | 39 | public Product[] recommendationFallback(int id) { 40 | System.out.println("=======recommendationFallback=========" + id); 41 | return new Product[0]; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /hystrix-turbine-sample/user-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #server.port= 8060 2 | 3 | spring.application.name= user-service 4 | 5 | #eureka.client.serviceUrl.defaultZone= http://localhost:8761/eureka/ 6 | 7 | management.endpoints.web.exposure.include=* -------------------------------------------------------------------------------- /java-11-sample/README.md: -------------------------------------------------------------------------------- 1 | # Run Java 11 app in Azure Spring Apps 2 | 3 | This sample shows how to run Java 11 app in `Azure Spring Apps`. 4 | 5 | ### Prerequisite 6 | 7 | * [JDK 11](https://docs.microsoft.com/azure/java/jdk/java-jdk-install) 8 | * [Maven 3.0 and above](http://maven.apache.org/install.html) 9 | * [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/overview) 10 | 11 | ### How to run 12 | 13 | 1. Run `mvn clean package` under `java-11-sample`. 14 | 1. Install Azure CLI extension for Azure Spring Apps by running below command. 15 | ```bash 16 | az extension add --name spring 17 | ``` 18 | 1. Create an instance of Azure Spring Apps. 19 | ```bash 20 | az spring create -n -g 21 | ``` 22 | 1. Create an app with public domain assigned. 23 | ```bash 24 | az spring app create -n -s -g --runtime-version Java_11 --is-public true 25 | ``` 26 | 1. Deploy app with jar 27 | ```bash 28 | az spring app deploy -n -s -g --artifact-path ./target/hello-world-11-1.0-SNAPSHOT.jar 29 | ``` 30 | 1. Verify app is running. Instances should have status `RUNNING` and discoveryStatus `UP`. 31 | ```bash 32 | az spring app show -n -s -g 33 | ``` 34 | 1. Verify sample is working. The url is fetch from previous step. 35 | ```bash 36 | curl {url}/{name} 37 | Hello {name} 38 | ``` 39 | -------------------------------------------------------------------------------- /java-11-sample/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.asc 8 | hello-world-11 9 | 1.0-SNAPSHOT 10 | 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 2.3.0.RELEASE 15 | 16 | 17 | 18 | 11 19 | 2021.0.8 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-config 34 | 35 | 36 | org.springframework.cloud 37 | spring-cloud-starter-netflix-eureka-client 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-dependencies 46 | ${spring-cloud.version} 47 | pom 48 | import 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | org.springframework.boot 57 | spring-boot-maven-plugin 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /java-11-sample/src/main/java/com/microsoft/sample/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample; 8 | 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 12 | 13 | @SpringBootApplication 14 | @EnableDiscoveryClient 15 | public class Application { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(Application.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /java-11-sample/src/main/java/com/microsoft/sample/HelloController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample; 8 | 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | public class HelloController { 15 | 16 | @GetMapping(value = "/{name}") 17 | public String sayHello(@PathVariable String name) { 18 | var hello = "Hello %s"; 19 | return String.format(hello, name); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java-17-sample/README.md: -------------------------------------------------------------------------------- 1 | # Local Development 2 | 3 | ```shell 4 | docker run --rm -p 8761:8761 springcloud/demo-eureka-server 5 | ``` 6 | 7 | # Prepare Variables 8 | ```shell 9 | SUBSCRIPTION= 10 | LOCATION= 11 | RESOURCE_GROUP= 12 | SERVICE_NAME= 13 | 14 | az account set --subscription $SUBSCRIPTION 15 | ``` 16 | 17 | # Standard Plan 18 | 19 | ## Deploy Application 20 | ```shell 21 | mvn clean package 22 | az spring app create -n java17sample --service $SERVICE_NAME -g $RESOURCE_GROUP --runtime-version Java_17 --assign-endpoint true 23 | az spring app deploy -n java17sample --service $SERVICE_NAME -g $RESOURCE_GROUP --artifact-path ./target/java-17-sample-1.0-SNAPSHOT.jar 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /java-17-sample/src/main/java/com/azure/asa/sample/EurekaController.java: -------------------------------------------------------------------------------- 1 | package com.azure.asa.sample; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | import com.netflix.discovery.EurekaClient; 5 | import com.netflix.discovery.shared.Application; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import java.util.List; 11 | import java.util.Set; 12 | 13 | @RestController 14 | public class EurekaController { 15 | 16 | @Autowired 17 | private EurekaClient discoveryClient; 18 | 19 | @GetMapping("/eureka") 20 | public String getEurekaState() { 21 | StringBuilder sb = new StringBuilder(); 22 | 23 | sb.append("

Known Regions

"); 24 | sb.append("
    "); 25 | Set regions = discoveryClient.getAllKnownRegions(); 26 | for(String region : regions) { 27 | sb.append("
  • ").append(region).append("
  • "); 28 | } 29 | sb.append("
"); 30 | 31 | List apps = discoveryClient.getApplications().getRegisteredApplications(); 32 | sb.append("

Registered Applications

"); 33 | sb.append("
    "); 34 | for(Application app : apps) { 35 | sb.append("

    Application=").append(app.getName()).append("

    "); 36 | sb.append("
      "); 37 | List instances = app.getInstances(); 38 | for(InstanceInfo instance : instances) { 39 | sb.append("
        "); 40 | sb.append("
      • InstanceId=").append(instance.getInstanceId()).append("
      • "); 41 | sb.append("
      • Status=").append(instance.getStatus().toString()).append("
      • "); 42 | sb.append("
      • IPAddr=").append(instance.getIPAddr()).append("
      • "); 43 | sb.append("
      "); 44 | } 45 | sb.append("
    "); 46 | } 47 | sb.append("
"); 48 | 49 | sb.append("

Client Configuration

"); 50 | sb.append("
    ").append(discoveryClient.getEurekaClientConfig().toString()).append("
"); 51 | 52 | return sb.toString(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /java-17-sample/src/main/java/com/azure/asa/sample/HelloController.java: -------------------------------------------------------------------------------- 1 | package com.azure.asa.sample; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.PostMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | @RestController 11 | public class HelloController { 12 | 13 | @GetMapping("/") 14 | public String index() { 15 | StringBuilder sb = new StringBuilder(); 16 | sb.append("

Greetings from Spring Boot!

"); 17 | 18 | return sb.toString(); 19 | } 20 | 21 | private List memory = new ArrayList<>(); 22 | 23 | @PostMapping("/memory/add") 24 | public String increaseMemory() { 25 | byte[] bytes = new byte[32 * 1024 * 1024]; 26 | memory.add(bytes); 27 | return "Current length is " + memory.size(); 28 | } 29 | } -------------------------------------------------------------------------------- /java-17-sample/src/main/java/com/azure/asa/sample/Java17SampleApplication.java: -------------------------------------------------------------------------------- 1 | package com.azure.asa.sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Java17SampleApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(Java17SampleApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java-17-sample/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=java-17-sample 2 | management.endpoints.web.exposure.include=* 3 | management.endpoint.env.show-values=ALWAYS 4 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 5 | eureka.client.healthcheck.enabled=true 6 | spring.cloud.config.enabled=false -------------------------------------------------------------------------------- /java-8-sample/README.md: -------------------------------------------------------------------------------- 1 | # Run Java 8 app in Azure Spring Apps 2 | 3 | This sample shows how to run Java 8 app in Azure Spring Apps. 4 | 5 | ## Prerequisite 6 | 7 | * [JDK 8](https://docs.microsoft.com/azure/java/jdk/java-jdk-install) 8 | * [Maven 3.0 and above](http://maven.apache.org/install.html) 9 | * [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/overview) 10 | 11 | ## How to run 12 | 13 | 1. Clone this repo and go to folder 14 | 15 | ```bash 16 | git clone https://github.com/Azure-Samples/azure-spring-apps-samples 17 | cd azure-spring-apps-samples/java-8-sample 18 | ``` 19 | 20 | 1. Package the app using maven 21 | 22 | ```bash 23 | mvn clean package -D skipTests 24 | ``` 25 | 26 | 1. Install Azure CLI extension for Azure Spring Apps 27 | 28 | ```bash 29 | az extension add --name spring 30 | ``` 31 | 32 | 1. Create an instance of Azure Spring Apps 33 | 34 | ```bash 35 | az spring create -n -g 36 | ``` 37 | 38 | 1. Create a public repo that only has the provided `application.yml` file 39 | 40 | 1. Using the URI of that repo, configure Azure Spring Apps to pull config from it 41 | 42 | ```bash 43 | az spring config-server git set --name -g --uri 44 | ``` 45 | 46 | 1. Create an app with public domain assigned 47 | 48 | ```bash 49 | az spring app create -n -s -g --runtime-version Java_8 --is-public true 50 | ``` 51 | 52 | 1. Deploy the newly created jar 53 | 54 | ```bash 55 | az spring app deploy -n -s -g --artifact-path ./target/java8-ASC-demo-0.0.1-SNAPSHOT.jar 56 | ``` 57 | 58 | 1. Using the output of the new app instance, retrieve the "App Instance Name" and use in the following command to review the logs 59 | 60 | ```bash 61 | az spring app logs -f -n -s -g 62 | ``` 63 | 64 | 1. Verify app is running. Instances should have status `RUNNING` and discoveryStatus `UP` 65 | 66 | ```bash 67 | az spring app show -n -s -g 68 | ``` 69 | 70 | 1. Visit the Azure portal to see further information about the application. 71 | -------------------------------------------------------------------------------- /java-8-sample/application.yml: -------------------------------------------------------------------------------- 1 | 2 | message: "hello from config" -------------------------------------------------------------------------------- /java-8-sample/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.7.17 9 | 10 | 11 | com.microsoft.sample 12 | java8-ASC-demo 13 | 0.0.1-SNAPSHOT 14 | java8-ASC-demo 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 2021.0.8 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-actuator 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-config 34 | 35 | 36 | org.springframework.cloud 37 | spring-cloud-starter-netflix-eureka-client 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-test 42 | test 43 | 44 | 45 | 46 | 47 | 48 | org.springframework.cloud 49 | spring-cloud-dependencies 50 | ${spring-cloud.version} 51 | pom 52 | import 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-maven-plugin 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /java-8-sample/src/main/java/com/microsoft/sample/java8ASCdemo/Java8AscDemoApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample.java8ASCdemo; 8 | 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 12 | import org.springframework.cloud.context.config.annotation.RefreshScope; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RestController; 15 | import org.springframework.beans.factory.annotation.Value; 16 | 17 | @SpringBootApplication 18 | @EnableDiscoveryClient 19 | public class Java8AscDemoApplication { 20 | 21 | public static void main(String[] args) { 22 | SpringApplication.run(Java8AscDemoApplication.class, args); 23 | } 24 | 25 | } 26 | @RefreshScope 27 | @RestController 28 | class MessageRestController { 29 | 30 | @Value("${message:Hello default}") 31 | private String message; 32 | 33 | @RequestMapping("/") 34 | String getMessage() { 35 | return this.message; 36 | } 37 | } -------------------------------------------------------------------------------- /java-8-sample/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | config: 3 | import: "optional:configserver:" -------------------------------------------------------------------------------- /java-8-sample/src/test/java/com/microsoft/sample/java8ASCdemo/Java8AscDemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample.java8ASCdemo; 8 | 9 | import org.junit.jupiter.api.Test; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | 12 | @SpringBootTest(classes = Java8AscDemoApplicationTests.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK) 13 | class Java8AscDemoApplicationTests { 14 | 15 | @Test 16 | void contextLoads() { 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /java-8-sample/src/test/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | config: 4 | enable: false 5 | 6 | message: "hello from test" -------------------------------------------------------------------------------- /job-samples/football-billboard/README.md: -------------------------------------------------------------------------------- 1 | # Football Job Billboard 2 | 3 | ## About the sample 4 | This web application project is designed to receive update from Spring Batch sample [football](../football/) job application. 5 | 6 | To create and deploy this application is similar to other Azure Spring Apps. You need to bind service registry to this application to make it discoverable in ASA service instance. Please reference [Quickstart](https://aka.ms/first-spring-batch-job) to learn more and deploy application. 7 | -------------------------------------------------------------------------------- /job-samples/football-billboard/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | com.microsoft.sample 7 | spring-batch-football-billboard 8 | 0.0.1-SNAPSHOT 9 | spring-batch-football-billboard 10 | Demo app to show execution result 11 | 12 | 13 | 17 14 | 17 15 | UTF-8 16 | 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-web 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter-config 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-netflix-eureka-client 34 | 35 | 36 | 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-parent 42 | 3.2.5 43 | pom 44 | import 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-dependencies 49 | 2023.0.1 50 | pom 51 | import 52 | 53 | 54 | 55 | 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-maven-plugin 60 | 3.2.5 61 | 62 | 63 | 64 | repackage 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /job-samples/football-billboard/src/main/java/com/microsoft/sample/football/BillboardApplication.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.sample.football; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | @SpringBootApplication 8 | @EnableDiscoveryClient 9 | public class BillboardApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(BillboardApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /job-samples/football-billboard/src/main/java/com/microsoft/sample/football/BillboardController.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.sample.football; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.PostMapping; 6 | import org.springframework.web.bind.annotation.RequestBody; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | @RestController 10 | public class BillboardController { 11 | 12 | @Autowired 13 | private BillboardService billboardService; 14 | 15 | @GetMapping(value = "/api/result") 16 | public ResultReport sayHello() { 17 | return billboardService.getResultReport(); 18 | } 19 | 20 | 21 | @PostMapping(value = "/api/result/update") 22 | public void updateResultReport(@RequestBody ResultReport resultReport) { 23 | if(resultReport != null) { 24 | billboardService.setResultReport(resultReport); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /job-samples/football-billboard/src/main/java/com/microsoft/sample/football/BillboardService.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.sample.football; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | @Service 6 | public class BillboardService { 7 | 8 | private ResultReport resultReport; 9 | 10 | /** 11 | * @return the resultReport 12 | */ 13 | public ResultReport getResultReport() { 14 | return resultReport; 15 | } 16 | 17 | /** 18 | * @param resultReport the resultReport to set 19 | */ 20 | public void setResultReport(ResultReport resultReport) { 21 | if (resultReport == null) { 22 | return; 23 | } 24 | 25 | if (this.resultReport == null) { 26 | this.resultReport = resultReport; 27 | } else { 28 | this.resultReport.setSummaryCount(this.resultReport.getSummaryCount() + resultReport.getSummaryCount()); 29 | this.resultReport.setLastExecuted(resultReport.getLastExecuted()); 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /job-samples/football-billboard/src/main/java/com/microsoft/sample/football/ResultReport.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.sample.football; 2 | 3 | import java.util.Date; 4 | 5 | public class ResultReport { 6 | 7 | private Date lastExecuted; 8 | 9 | private int summaryCount; 10 | 11 | /** 12 | * @return the lastExecuted 13 | */ 14 | public Date getLastExecuted() { 15 | return lastExecuted; 16 | } 17 | 18 | /** 19 | * @param lastExecuted the lastExecuted to set 20 | */ 21 | public void setLastExecuted(Date lastExecuted) { 22 | this.lastExecuted = lastExecuted; 23 | } 24 | 25 | /** 26 | * @return the summaryCount 27 | */ 28 | public int getSummaryCount() { 29 | return summaryCount; 30 | } 31 | 32 | /** 33 | * @param summaryCount the summaryCount to set 34 | */ 35 | public void setSummaryCount(int summaryCount) { 36 | this.summaryCount = summaryCount; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /job-samples/football-billboard/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.cloud.config.enabled=false 2 | spring.web.resources.static-locations=classpath:/static/ -------------------------------------------------------------------------------- /job-samples/football-billboard/src/main/resources/static/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-spring-apps-samples/30a68f24e61c58e761a5bfabfd2977ae45ee2297/job-samples/football-billboard/src/main/resources/static/background.jpg -------------------------------------------------------------------------------- /job-samples/football-billboard/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello 4 | 51 | 84 | 85 | 86 |
87 |
88 |
89 |
90 |
91 |
92 | 95 |
96 | 97 | -------------------------------------------------------------------------------- /job-samples/football/setup-env-variables-template.sh: -------------------------------------------------------------------------------- 1 | export SUBSCRIPTION='subscription-id' # replace it with your subscription-id 2 | export RESOURCE_GROUP='resource-group-name' # existing resource group or one that will be created in next steps 3 | export SPRING_APPS_SERVICE='azure-spring-apps-name' # name of the service that will be created in the next steps 4 | export REGION='region' # region where the resources will be created 5 | 6 | echo "SUBSCRIPTION=$SUBSCRIPTION" 7 | echo "RESOURCE_GROUP=$RESOURCE_GROUP" 8 | echo "SPRING_APPS_SERVICE=$SPRING_APPS_SERVICE" 9 | echo "REGION=$REGION" -------------------------------------------------------------------------------- /job-samples/football/src/main/java/com/microsoft/sample/DiscoveryClientConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.sample; 2 | 3 | import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class DiscoveryClientConfiguration { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /job-samples/football/src/main/java/com/microsoft/sample/ResultReport.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.sample; 2 | 3 | import java.util.Date; 4 | 5 | public class ResultReport { 6 | 7 | private Date lastExecuted; 8 | 9 | private int summaryCount; 10 | 11 | /** 12 | * @return the lastExecuted 13 | */ 14 | public Date getLastExecuted() { 15 | return lastExecuted; 16 | } 17 | 18 | /** 19 | * @param lastExecuted the lastExecuted to set 20 | */ 21 | public void setLastExecuted(Date lastExecuted) { 22 | this.lastExecuted = lastExecuted; 23 | } 24 | 25 | /** 26 | * @return the summaryCount 27 | */ 28 | public int getSummaryCount() { 29 | return summaryCount; 30 | } 31 | 32 | /** 33 | * @param summaryCount the summaryCount to set 34 | */ 35 | public void setSummaryCount(int summaryCount) { 36 | this.summaryCount = summaryCount; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /job-samples/football/src/main/java/org/springframework/batch/samples/football/Player.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.batch.samples.football; 18 | 19 | import java.io.Serializable; 20 | 21 | @SuppressWarnings("serial") 22 | public class Player implements Serializable { 23 | 24 | private String id; 25 | 26 | private String lastName; 27 | 28 | private String firstName; 29 | 30 | private String position; 31 | 32 | private int birthYear; 33 | 34 | private int debutYear; 35 | 36 | @Override 37 | public String toString() { 38 | 39 | return "PLAYER:id=" + id + ",Last Name=" + lastName + ",First Name=" + firstName + ",Position=" + position 40 | + ",Birth Year=" + birthYear + ",DebutYear=" + debutYear; 41 | } 42 | 43 | public String getId() { 44 | return id; 45 | } 46 | 47 | public String getLastName() { 48 | return lastName; 49 | } 50 | 51 | public String getFirstName() { 52 | return firstName; 53 | } 54 | 55 | public String getPosition() { 56 | return position; 57 | } 58 | 59 | public int getBirthYear() { 60 | return birthYear; 61 | } 62 | 63 | public int getDebutYear() { 64 | return debutYear; 65 | } 66 | 67 | public void setId(String id) { 68 | this.id = id; 69 | } 70 | 71 | public void setLastName(String lastName) { 72 | this.lastName = lastName; 73 | } 74 | 75 | public void setFirstName(String firstName) { 76 | this.firstName = firstName; 77 | } 78 | 79 | public void setPosition(String position) { 80 | this.position = position; 81 | } 82 | 83 | public void setBirthYear(int birthYear) { 84 | this.birthYear = birthYear; 85 | } 86 | 87 | public void setDebutYear(int debutYear) { 88 | this.debutYear = debutYear; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /job-samples/football/src/main/java/org/springframework/batch/samples/football/PlayerDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2007 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.batch.samples.football; 18 | 19 | /** 20 | * Interface for writing {@link Player} objects to arbitrary output. 21 | */ 22 | public interface PlayerDao { 23 | 24 | void savePlayer(Player player); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /job-samples/football/src/main/java/org/springframework/batch/samples/football/internal/GameFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2007 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.batch.samples.football.internal; 18 | 19 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 20 | import org.springframework.batch.item.file.transform.FieldSet; 21 | import org.springframework.batch.samples.football.Game; 22 | 23 | public class GameFieldSetMapper implements FieldSetMapper { 24 | 25 | @Override 26 | public Game mapFieldSet(FieldSet fs) { 27 | 28 | if (fs == null) { 29 | return null; 30 | } 31 | 32 | Game game = new Game(); 33 | game.setId(fs.readString("id")); 34 | game.setYear(fs.readInt("year")); 35 | game.setTeam(fs.readString("team")); 36 | game.setWeek(fs.readInt("week")); 37 | game.setOpponent(fs.readString("opponent")); 38 | game.setCompletes(fs.readInt("completes")); 39 | game.setAttempts(fs.readInt("attempts")); 40 | game.setPassingYards(fs.readInt("passingYards")); 41 | game.setPassingTd(fs.readInt("passingTd")); 42 | game.setInterceptions(fs.readInt("interceptions")); 43 | game.setRushes(fs.readInt("rushes")); 44 | game.setRushYards(fs.readInt("rushYards")); 45 | game.setReceptions(fs.readInt("receptions", 0)); 46 | game.setReceptionYards(fs.readInt("receptionYards")); 47 | game.setTotalTd(fs.readInt("totalTd")); 48 | 49 | return game; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /job-samples/football/src/main/java/org/springframework/batch/samples/football/internal/JdbcGameDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.batch.samples.football.internal; 18 | 19 | import org.springframework.batch.item.Chunk; 20 | import org.springframework.batch.item.ItemWriter; 21 | import org.springframework.batch.samples.football.Game; 22 | import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; 23 | import org.springframework.jdbc.core.namedparam.SqlParameterSource; 24 | import org.springframework.jdbc.core.simple.SimpleJdbcInsert; 25 | import org.springframework.jdbc.core.support.JdbcDaoSupport; 26 | 27 | public class JdbcGameDao extends JdbcDaoSupport implements ItemWriter { 28 | 29 | private SimpleJdbcInsert insertGame; 30 | 31 | @Override 32 | protected void initDao() throws Exception { 33 | super.initDao(); 34 | insertGame = new SimpleJdbcInsert(getDataSource()).withTableName("GAMES") 35 | .usingColumns("player_id", "year_no", "team", "week", "opponent", " completes", "attempts", "passing_yards", 36 | "passing_td", "interceptions", "rushes", "rush_yards", "receptions", "receptions_yards", 37 | "total_td"); 38 | } 39 | 40 | @Override 41 | public void write(Chunk games) { 42 | 43 | for (Game game : games) { 44 | 45 | SqlParameterSource values = new MapSqlParameterSource().addValue("player_id", game.getId()) 46 | .addValue("year_no", game.getYear()) 47 | .addValue("team", game.getTeam()) 48 | .addValue("week", game.getWeek()) 49 | .addValue("opponent", game.getOpponent()) 50 | .addValue("completes", game.getCompletes()) 51 | .addValue("attempts", game.getAttempts()) 52 | .addValue("passing_yards", game.getPassingYards()) 53 | .addValue("passing_td", game.getPassingTd()) 54 | .addValue("interceptions", game.getInterceptions()) 55 | .addValue("rushes", game.getRushes()) 56 | .addValue("rush_yards", game.getRushYards()) 57 | .addValue("receptions", game.getReceptions()) 58 | .addValue("receptions_yards", game.getReceptionYards()) 59 | .addValue("total_td", game.getTotalTd()); 60 | this.insertGame.execute(values); 61 | 62 | } 63 | 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /job-samples/football/src/main/java/org/springframework/batch/samples/football/internal/JdbcPlayerDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.batch.samples.football.internal; 18 | 19 | import javax.sql.DataSource; 20 | 21 | import org.springframework.batch.samples.football.Player; 22 | import org.springframework.batch.samples.football.PlayerDao; 23 | import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; 24 | import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; 25 | import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; 26 | 27 | /** 28 | * @author Lucas Ward 29 | * 30 | */ 31 | public class JdbcPlayerDao implements PlayerDao { 32 | 33 | public static final String INSERT_PLAYER = "INSERT into PLAYERS (player_id, last_name, first_name, pos, year_of_birth, year_drafted)" 34 | + " values (:id, :lastName, :firstName, :position, :birthYear, :debutYear)"; 35 | 36 | private NamedParameterJdbcOperations namedParameterJdbcTemplate; 37 | 38 | @Override 39 | public void savePlayer(Player player) { 40 | namedParameterJdbcTemplate.update(INSERT_PLAYER, new BeanPropertySqlParameterSource(player)); 41 | } 42 | 43 | public void setDataSource(DataSource dataSource) { 44 | this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /job-samples/football/src/main/java/org/springframework/batch/samples/football/internal/JdbcPlayerSummaryDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.batch.samples.football.internal; 18 | 19 | import javax.sql.DataSource; 20 | 21 | import org.springframework.batch.item.Chunk; 22 | import org.springframework.batch.item.ItemWriter; 23 | import org.springframework.batch.samples.football.PlayerSummary; 24 | import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; 25 | import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; 26 | import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; 27 | 28 | public class JdbcPlayerSummaryDao implements ItemWriter { 29 | 30 | private static final String INSERT_SUMMARY = "INSERT into PLAYER_SUMMARY(ID, YEAR_NO, COMPLETES, ATTEMPTS, PASSING_YARDS, PASSING_TD, " 31 | + "INTERCEPTIONS, RUSHES, RUSH_YARDS, RECEPTIONS, RECEPTIONS_YARDS, TOTAL_TD) " 32 | + "values(:id, :year, :completes, :attempts, :passingYards, :passingTd, " 33 | + ":interceptions, :rushes, :rushYards, :receptions, :receptionYards, :totalTd)"; 34 | 35 | private NamedParameterJdbcOperations namedParameterJdbcTemplate; 36 | 37 | @Override 38 | public void write(Chunk summaries) { 39 | 40 | for (PlayerSummary summary : summaries) { 41 | 42 | MapSqlParameterSource args = new MapSqlParameterSource().addValue("id", summary.getId()) 43 | .addValue("year", summary.getYear()) 44 | .addValue("completes", summary.getCompletes()) 45 | .addValue("attempts", summary.getAttempts()) 46 | .addValue("passingYards", summary.getPassingYards()) 47 | .addValue("passingTd", summary.getPassingTd()) 48 | .addValue("interceptions", summary.getInterceptions()) 49 | .addValue("rushes", summary.getRushes()) 50 | .addValue("rushYards", summary.getRushYards()) 51 | .addValue("receptions", summary.getReceptions()) 52 | .addValue("receptionYards", summary.getReceptionYards()) 53 | .addValue("totalTd", summary.getTotalTd()); 54 | 55 | namedParameterJdbcTemplate.update(INSERT_SUMMARY, args); 56 | } 57 | } 58 | 59 | public void setDataSource(DataSource dataSource) { 60 | this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /job-samples/football/src/main/java/org/springframework/batch/samples/football/internal/PlayerFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2007 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.batch.samples.football.internal; 18 | 19 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 20 | import org.springframework.batch.item.file.transform.FieldSet; 21 | import org.springframework.batch.samples.football.Player; 22 | 23 | public class PlayerFieldSetMapper implements FieldSetMapper { 24 | 25 | @Override 26 | public Player mapFieldSet(FieldSet fs) { 27 | 28 | if (fs == null) { 29 | return null; 30 | } 31 | 32 | Player player = new Player(); 33 | player.setId(fs.readString("ID")); 34 | player.setLastName(fs.readString("lastName")); 35 | player.setFirstName(fs.readString("firstName")); 36 | player.setPosition(fs.readString("position")); 37 | player.setDebutYear(fs.readInt("debutYear")); 38 | player.setBirthYear(fs.readInt("birthYear")); 39 | 40 | return player; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /job-samples/football/src/main/java/org/springframework/batch/samples/football/internal/PlayerItemWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.batch.samples.football.internal; 18 | 19 | import org.springframework.batch.item.Chunk; 20 | import org.springframework.batch.item.ItemWriter; 21 | import org.springframework.batch.samples.football.Player; 22 | import org.springframework.batch.samples.football.PlayerDao; 23 | 24 | public class PlayerItemWriter implements ItemWriter { 25 | 26 | private PlayerDao playerDao; 27 | 28 | @Override 29 | public void write(Chunk players) throws Exception { 30 | for (Player player : players) { 31 | playerDao.savePlayer(player); 32 | } 33 | } 34 | 35 | public void setPlayerDao(PlayerDao playerDao) { 36 | this.playerDao = playerDao; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /job-samples/football/src/main/java/org/springframework/batch/samples/football/internal/PlayerSummaryMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.batch.samples.football.internal; 17 | 18 | import java.sql.ResultSet; 19 | import java.sql.SQLException; 20 | 21 | import org.springframework.batch.samples.football.PlayerSummary; 22 | import org.springframework.jdbc.core.RowMapper; 23 | 24 | /** 25 | * RowMapper used to map a ResultSet to a {@link PlayerSummary} 26 | * 27 | * @author Lucas Ward 28 | * @author Mahmoud Ben Hassine 29 | * 30 | */ 31 | public class PlayerSummaryMapper implements RowMapper { 32 | 33 | /* 34 | * (non-Javadoc) 35 | * 36 | * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int) 37 | */ 38 | @Override 39 | public PlayerSummary mapRow(ResultSet rs, int rowNum) throws SQLException { 40 | 41 | PlayerSummary summary = new PlayerSummary(); 42 | 43 | summary.setId(rs.getString(1)); 44 | summary.setYear(rs.getInt(2)); 45 | summary.setCompletes(rs.getInt(3)); 46 | summary.setAttempts(rs.getInt(4)); 47 | summary.setPassingYards(rs.getInt(5)); 48 | summary.setPassingTd(rs.getInt(6)); 49 | summary.setInterceptions(rs.getInt(7)); 50 | summary.setRushes(rs.getInt(8)); 51 | summary.setRushYards(rs.getInt(9)); 52 | summary.setReceptions(rs.getInt(10)); 53 | summary.setReceptionYards(rs.getInt(11)); 54 | summary.setTotalTd(rs.getInt(12)); 55 | 56 | return summary; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /job-samples/football/src/main/java/org/springframework/batch/samples/football/internal/PlayerSummaryRowMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.batch.samples.football.internal; 17 | 18 | import java.sql.ResultSet; 19 | import java.sql.SQLException; 20 | 21 | import org.springframework.batch.samples.football.PlayerSummary; 22 | import org.springframework.jdbc.core.RowMapper; 23 | 24 | /** 25 | * RowMapper used to map a ResultSet to a {@link PlayerSummary} 26 | * 27 | * @author Lucas Ward 28 | * @author Mahmoud Ben Hassine 29 | * 30 | */ 31 | public class PlayerSummaryRowMapper implements RowMapper { 32 | 33 | /* 34 | * (non-Javadoc) 35 | * 36 | * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int) 37 | */ 38 | @Override 39 | public PlayerSummary mapRow(ResultSet rs, int rowNum) throws SQLException { 40 | 41 | PlayerSummary summary = new PlayerSummary(); 42 | 43 | summary.setId(rs.getString(1)); 44 | summary.setYear(rs.getInt(2)); 45 | summary.setCompletes(rs.getInt(3)); 46 | summary.setAttempts(rs.getInt(4)); 47 | summary.setPassingYards(rs.getInt(5)); 48 | summary.setPassingTd(rs.getInt(6)); 49 | summary.setInterceptions(rs.getInt(7)); 50 | summary.setRushes(rs.getInt(8)); 51 | summary.setRushYards(rs.getInt(9)); 52 | summary.setReceptions(rs.getInt(10)); 53 | summary.setReceptionYards(rs.getInt(11)); 54 | summary.setTotalTd(rs.getInt(12)); 55 | 56 | return summary; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /job-samples/football/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ -------------------------------------------------------------------------------- /job-samples/football/src/main/resources/org/springframework/batch/samples/football/data/games-small.csv: -------------------------------------------------------------------------------- 1 | AbduKa00,1996,mia,10,nwe,0,0,0,0,0,29,104,,16,2 2 | AbduKa00,1996,mia,11,clt,0,0,0,0,0,18,70,,11,2 3 | AbduKa00,1996,mia,12,oti,0,0,0,0,0,18,59,,0,0 4 | AbduKa00,1996,mia,13,pit,0,0,0,0,0,16,57,,0,0 5 | AbduKa00,1996,mia,14,rai,0,0,0,0,0,18,39,,7,0 6 | -------------------------------------------------------------------------------- /job-samples/football/src/main/resources/org/springframework/batch/samples/football/data/player-containsBadRecords.csv: -------------------------------------------------------------------------------- 1 | AbduKa00,Abdul-Jabbar,Karim,rb,1974,1996 2 | AbduRa00,Abdullah,Rabih,rb,1975,1999 3 | AberWa00,Abercrombie,Walter,rb,1959,1982 4 | AbraDa00,Abramowicz,Danny,wr,1945,1967 5 | AdamBo00,Adams,Bob,te,1946,1969 6 | AdamCh00,Adams,Charlie,wr,1979,2003 7 | AdamCu00,Adams,Curtis,rb,1962 8 | AdamGe00,Adams,George,rb,1962,1985 9 | AdamGr00,Adams,Grant,2000,2005 10 | AdamJo00,Adams,John,rb,1937,1959 11 | Adams,Michael,wr,1974,1997 12 | AdamMi01,Adamle,Mike,rb,1949,1971 13 | AdamTo00,Adams,Tony,qb,1950,1975 14 | AdamTo01,Adams,Tom,wr,1940,1962 15 | AdamTo02,Adamle,Tony,rb,,1950 16 | AdamWi00,Adams,Willie,wr,1956,1979 17 | AddaJo00,Addai,Joseph,1983,2006,rb 18 | AdkiJa00,Adkisson,James,te,1980,2005 19 | AdkiMa00,Adkins,Margene,wr,1947,1970 20 | AdkiSa00,Adkins,Sam,qb,1955,1977 21 | -------------------------------------------------------------------------------- /job-samples/football/src/main/resources/org/springframework/batch/samples/football/data/player-small1.csv: -------------------------------------------------------------------------------- 1 | AbduKa00,Abdul-Jabbar,Karim,rb,1974,1996 2 | AbduRa00,Abdullah,Rabih,rb,1975,1999 3 | AberWa00,Abercrombie,Walter,rb,1959,1982 4 | AbraDa00,Abramowicz,Danny,wr,1945,1967 5 | AdamBo00,Adams,Bob,te,1946,1969 6 | AdamCh00,Adams,Charlie,wr,1979,2003 7 | AdamCu00,Adams,Curtis,rb,1962,1985 8 | AdamGe00,Adams,George,rb,1962,1985 9 | AdamGr00,Adams,Grant,wr,2000,2005 10 | AdamJo00,Adams,John,rb,1937,1959 11 | AdamMi00,Adams,Michael,wr,1974,1997 12 | AdamMi01,Adamle,Mike,rb,1949,1971 13 | AdamTo00,Adams,Tony,qb,1950,1975 14 | AdamTo01,Adams,Tom,wr,1940,1962 15 | AdamTo02,Adamle,Tony,rb,1924,1950 16 | AdamWi00,Adams,Willie,wr,1956,1979 17 | AddaJo00,Addai,Joseph,rb,1983,2006 18 | AdkiJa00,Adkisson,James,te,1980,2005 19 | AdkiMa00,Adkins,Margene,wr,1947,1970 20 | AdkiSa00,Adkins,Sam,qb,1955,1977 21 | -------------------------------------------------------------------------------- /job-samples/football/src/main/resources/org/springframework/batch/samples/football/data/player-small2.csv: -------------------------------------------------------------------------------- 1 | AffhEr00,Affholter,Erik,wr,1966,1991 2 | AgeeTo00,Agee,Tommie,rb,1964,1988 3 | AikeSa00,Aiken,Sam,wr,1980,2003 4 | AikmTr00,Aikman,Troy,qb,1966,1989 5 | AkinFr00,Akins,Frank,rb,1919,1943 6 | AlbeFr00,Albert,Frankie,qb,1920,1950 7 | AldrBe00,Aldridge,Bennie,rb,1926,1950 8 | AlexCh00,Alexander,Charles,rb,1957,1979 9 | AlexDe00,Alexander,Derrick,wr,1971,1994 10 | AlexGl00,Alexander,Glenn,wr,1947,1970 11 | AlexJe00,Alexander,Jeff,rb,1965,1989 12 | AlexKe00,Alexander,Kevin,wr,1975,1996 13 | AlexMi00,Alexander,Mike,wr,1965,1989 14 | AlexRa00,Alexander,Ray,wr,1962,1984 15 | AlexRi00,Alexis,Rich,rb,1981,2005 16 | AlexSh00,Alexander,Shaun,rb,1977,2000 17 | AlexSt00,Alexander,Stephen,te,1975,1998 18 | AlfoBr00,Alford,Brian,wr,1975,1998 19 | AlfoBr01,Alford,Bruce,wr,1922,1950 20 | AlleAn00,Allen,Anthony,wr,1959,1985 21 | -------------------------------------------------------------------------------- /job-samples/football/src/main/resources/org/springframework/batch/samples/football/sql/schema.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE PLAYERS IF EXISTS; 2 | DROP TABLE GAMES IF EXISTS; 3 | DROP TABLE PLAYER_SUMMARY IF EXISTS; 4 | 5 | CREATE TABLE PLAYERS ( 6 | PLAYER_ID CHAR(8) NOT NULL PRIMARY KEY, 7 | LAST_NAME VARCHAR(35) NOT NULL, 8 | FIRST_NAME VARCHAR(25) NOT NULL, 9 | POS VARCHAR(10) , 10 | YEAR_OF_BIRTH BIGINT NOT NULL, 11 | YEAR_DRAFTED BIGINT NOT NULL 12 | ) ; 13 | 14 | CREATE TABLE GAMES ( 15 | PLAYER_ID CHAR(8) NOT NULL, 16 | YEAR_NO BIGINT NOT NULL, 17 | TEAM CHAR(3) NOT NULL, 18 | WEEK BIGINT NOT NULL, 19 | OPPONENT CHAR(3) , 20 | COMPLETES BIGINT , 21 | ATTEMPTS BIGINT , 22 | PASSING_YARDS BIGINT , 23 | PASSING_TD BIGINT , 24 | INTERCEPTIONS BIGINT , 25 | RUSHES BIGINT , 26 | RUSH_YARDS BIGINT , 27 | RECEPTIONS BIGINT , 28 | RECEPTIONS_YARDS BIGINT , 29 | TOTAL_TD BIGINT 30 | ) ; 31 | 32 | CREATE TABLE PLAYER_SUMMARY ( 33 | ID CHAR(8) NOT NULL, 34 | YEAR_NO BIGINT NOT NULL, 35 | COMPLETES BIGINT NOT NULL , 36 | ATTEMPTS BIGINT NOT NULL , 37 | PASSING_YARDS BIGINT NOT NULL , 38 | PASSING_TD BIGINT NOT NULL , 39 | INTERCEPTIONS BIGINT NOT NULL , 40 | RUSHES BIGINT NOT NULL , 41 | RUSH_YARDS BIGINT NOT NULL , 42 | RECEPTIONS BIGINT NOT NULL , 43 | RECEPTIONS_YARDS BIGINT NOT NULL , 44 | TOTAL_TD BIGINT NOT NULL 45 | ) ; -------------------------------------------------------------------------------- /job-samples/football/src/main/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | org.slf4j.simpleLogger.logFile=System.out -------------------------------------------------------------------------------- /job-samples/hello-world/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | com.microsoft.sample 7 | hello-world-job 8 | 0.0.1-SNAPSHOT 9 | hello-world-job 10 | Hello world of Azure Spring Apps job 11 | 12 | 13 | 17 14 | 17 15 | UTF-8 16 | 17 | 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-dependencies 23 | 3.2.4 24 | pom 25 | import 26 | 27 | 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter 33 | 34 | 35 | org.slf4j 36 | slf4j-simple 37 | 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-maven-plugin 44 | 3.2.4 45 | 46 | com.microsoft.sample.HelloWorldJobApplication 47 | JAR 48 | 49 | 50 | 51 | 52 | repackage 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /job-samples/hello-world/setup-env-variables-template.sh: -------------------------------------------------------------------------------- 1 | export SUBSCRIPTION='subscription-id' # replace it with your subscription-id 2 | export RESOURCE_GROUP='resource-group-name' # existing resource group or one that will be created in next steps 3 | export SPRING_APPS_SERVICE='azure-spring-apps-name' # name of the service that will be created in the next steps 4 | export REGION='region' # region where the resources will be created 5 | 6 | echo "SUBSCRIPTION=$SUBSCRIPTION" 7 | echo "RESOURCE_GROUP=$RESOURCE_GROUP" 8 | echo "SPRING_APPS_SERVICE=$SPRING_APPS_SERVICE" 9 | echo "REGION=$REGION" -------------------------------------------------------------------------------- /job-samples/hello-world/src/main/java/com/microsoft/sample/HelloWorldJobApplication.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.sample; 2 | 3 | import java.util.Map; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.boot.CommandLineRunner; 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | 11 | @SpringBootApplication 12 | public class HelloWorldJobApplication implements CommandLineRunner { 13 | 14 | private final static Logger LOGGER = LoggerFactory.getLogger(HelloWorldJobApplication.class); 15 | 16 | private final static String ARG_NAME_SLEEP = "--sleep="; 17 | 18 | private final static String ENV_PREFIX = "JOB_"; 19 | 20 | public static void main(String[] args) { 21 | LOGGER.info("Starting the job ......"); 22 | 23 | SpringApplication.run(HelloWorldJobApplication.class, args); 24 | 25 | LOGGER.info("Job finished."); 26 | } 27 | 28 | @Override 29 | public void run(String... args) throws Exception { 30 | Map env = System.getenv(); 31 | for(String key : env.keySet()) { 32 | if(key.startsWith(ENV_PREFIX)) { 33 | LOGGER.info("Found environment variable {}={}", key, env.get(key)); 34 | } 35 | } 36 | 37 | LOGGER.info("Input arguments are: {}", String.join(" ", args)); 38 | 39 | int sleep = 30; 40 | for (String arg : args) { 41 | if(arg.startsWith(ARG_NAME_SLEEP)) { 42 | sleep = Integer.parseInt(arg, ARG_NAME_SLEEP.length(), arg.length(), 10); 43 | } 44 | } 45 | 46 | LOGGER.info("Job will sleep for {} seconds", sleep); 47 | Thread.sleep(sleep * 1000); 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /job-samples/hello-world/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.main.web-application-type=NONE -------------------------------------------------------------------------------- /job-samples/hello-world/src/main/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | org.slf4j.simpleLogger.logFile=System.out -------------------------------------------------------------------------------- /k8s-service-registry/.gitignore: -------------------------------------------------------------------------------- 1 | # Maven 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | 5 | # Jenv 6 | .java-version 7 | 8 | # Eclipse 9 | .settings/ 10 | .classpath 11 | .project 12 | 13 | # IntelliJ IDEA 14 | .idea 15 | *.iml 16 | 17 | # Visual Studio Code 18 | .factorypath 19 | 20 | # Branch switching 21 | generated/ 22 | 23 | # Skip scripts 24 | .scripts/ 25 | .vscode/settings.json 26 | -------------------------------------------------------------------------------- /k8s-service-registry/gateway/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.asc 7 | k8s-service-registry 8 | 0.0.1-SNAPSHOT 9 | ../pom.xml 10 | 11 | 12 | gateway 13 | 0.0.1-SNAPSHOT 14 | 15 | 16 | 17 | org.springframework.boot 18 | spring-boot-starter-web 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-dependencies 27 | ${spring-cloud.version} 28 | pom 29 | import 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-maven-plugin 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /k8s-service-registry/gateway/src/main/java/com/microsoft/azure/sample/Application.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.azure.sample; 2 | 3 | 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | public class Application { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(Application.class, args); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /k8s-service-registry/gateway/src/main/java/com/microsoft/azure/sample/controller/Entrance.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.azure.sample.controller; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.RestController; 10 | import org.springframework.web.client.RestTemplate; 11 | import org.springframework.web.servlet.HandlerMapping; 12 | 13 | @RestController 14 | public class Entrance { 15 | 16 | @Value("${spring.application.name}") 17 | private String appName; 18 | 19 | @Bean 20 | RestTemplate getRestTemplate() { 21 | return new RestTemplate(); 22 | } 23 | 24 | @RequestMapping(path = "/", method = RequestMethod.GET) 25 | public String index() { 26 | return appName; 27 | } 28 | 29 | @RequestMapping(path = "/{appName}/**", method = RequestMethod.GET) 30 | public String redirect(@PathVariable String appName, HttpServletRequest request) { 31 | 32 | String requestPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); 33 | String appPath = "/"; 34 | int start = requestPath.indexOf("/", requestPath.indexOf("/") + 1); 35 | if (start > 0) { 36 | appPath = requestPath.substring(start); 37 | } 38 | 39 | RestTemplate restTemplate = new RestTemplate(); 40 | return restTemplate.getForObject(String.format("http://%s%s", appName, appPath), String.class); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /k8s-service-registry/greeting-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.asc 7 | k8s-service-registry 8 | 0.0.1-SNAPSHOT 9 | ../pom.xml 10 | 11 | 12 | greeting-client 13 | 0.0.1-SNAPSHOT 14 | 15 | 16 | 17 | 18 | org.springframework.cloud 19 | spring-cloud-dependencies 20 | ${spring-cloud.version} 21 | pom 22 | import 23 | 24 | 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | org.springframework.cloud 34 | spring-cloud-starter-openfeign 35 | 3.1.4 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-maven-plugin 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /k8s-service-registry/greeting-client/src/main/java/com/microsoft/azure/sample/Application.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.azure.sample; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.openfeign.EnableFeignClients; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @SpringBootApplication 11 | @RestController 12 | @EnableFeignClients 13 | @RequiredArgsConstructor 14 | public class Application { 15 | 16 | private final HelloClient helloClient; 17 | 18 | @RequestMapping("/hello") 19 | public String hello() { 20 | String message = helloClient.hello(); 21 | return String.format("client receive '%s' from server side", message); 22 | } 23 | 24 | public static void main(String [] args) { 25 | SpringApplication.run(Application.class, args); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /k8s-service-registry/greeting-client/src/main/java/com/microsoft/azure/sample/HelloClient.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.azure.sample; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | 7 | @FeignClient(name = "${greeting.server.name}", url = "http://${greeting.server.name}/") 8 | public interface HelloClient { 9 | 10 | @RequestMapping(method = RequestMethod.GET, value = "/hello") 11 | String hello(); 12 | } 13 | -------------------------------------------------------------------------------- /k8s-service-registry/greeting-client/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | greeting.server.name=greeting-server 2 | -------------------------------------------------------------------------------- /k8s-service-registry/greeting-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.asc 7 | k8s-service-registry 8 | 0.0.1-SNAPSHOT 9 | ../pom.xml 10 | 11 | 12 | greeting-server 13 | 0.0.1-SNAPSHOT 14 | 15 | 16 | 17 | 18 | org.springframework.cloud 19 | spring-cloud-dependencies 20 | ${spring-cloud.version} 21 | pom 22 | import 23 | 24 | 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-maven-plugin 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /k8s-service-registry/greeting-server/src/main/java/com/microsoft/azure/sample/Application.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.azure.sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | 9 | @SpringBootApplication 10 | @RestController 11 | public class Application { 12 | 13 | @RequestMapping("/hello") 14 | public String hello() { 15 | return "server says hello"; 16 | } 17 | 18 | public static void main(String [] args) { 19 | SpringApplication.run(Application.class, args); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /k8s-service-registry/media/service-registry-arch.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-spring-apps-samples/30a68f24e61c58e761a5bfabfd2977ae45ee2297/k8s-service-registry/media/service-registry-arch.jpeg -------------------------------------------------------------------------------- /k8s-service-registry/media/service-registry.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-spring-apps-samples/30a68f24e61c58e761a5bfabfd2977ae45ee2297/k8s-service-registry/media/service-registry.jpeg -------------------------------------------------------------------------------- /managed-identity-function/README.md: -------------------------------------------------------------------------------- 1 | # Invoke Azure Function with managed identity 2 | 3 | This sample shows how to invoke an Azure Function securely from Azure Spring Apps using managed identity. 4 | 5 | ## Prerequisite 6 | 7 | * [JDK 8](https://docs.microsoft.com/azure/java/jdk/java-jdk-install) 8 | * [Maven 3.0 and above](http://maven.apache.org/install.html) 9 | * [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/overview) 10 | * An Http triggered [Azure Function](https://docs.microsoft.com/azure/azure-functions/functions-create-first-azure-function-azure-cli?pivots=programming-language-java) with [authentication enabled](https://docs.microsoft.com/azure/app-service/overview-authentication-authorization) 11 | 12 | ## How to run 13 | 14 | 1. Run `mvn clean package` after specifying the URI and trigger name for your function in [application.properties](./src/main/resources/application.properties). 15 | 2. Install Azure CLI extension for Azure Spring Apps by running below command. 16 | ``` 17 | az extension add --name spring-cloud 18 | ``` 19 | 3. Create an instance of Azure Spring Apps. 20 | ``` 21 | az spring-cloud create -n -g 22 | ``` 23 | 4. Create an app with public domain assigned. 24 | ``` 25 | az spring-cloud app create -n -s -g --is-public true 26 | ``` 27 | 5. Enable system-assigned managed identity for your app and take note of the principal id from the command output. 28 | ``` 29 | az spring-cloud app identity assign -n -s -g 30 | ``` 31 | 6. Deploy app with jar. 32 | ``` 33 | az spring-cloud app deploy -n -s -g --jar-path ./target/asc-managed-identity-function-sample-0.1.0.jar 34 | ``` 35 | 7. Verify app is running. Instances should have status `RUNNING` and discoveryStatus `UP`. 36 | ``` 37 | az spring-cloud app show -n -s -g 38 | ``` 39 | 8. Verify sample is working. The url is fetched from previous step. 40 | ``` 41 | # Invoke the function 42 | curl {url}/func/{name} 43 | ``` -------------------------------------------------------------------------------- /managed-identity-function/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.microsoft.azure 7 | asc-managed-identity-function-sample 8 | 0.1.0 9 | 10 | 11 | org.springframework.boot 12 | spring-boot-starter-parent 13 | 2.7.10 14 | 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-web 21 | 22 | 23 | com.azure 24 | azure-identity 25 | 26 | 27 | 28 | 29 | 1.8 30 | 4.7.0 31 | 32 | 33 | 34 | 35 | 36 | com.azure.spring 37 | spring-cloud-azure-dependencies 38 | ${spring-cloud-azure.version} 39 | pom 40 | import 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | org.springframework.boot 49 | spring-boot-maven-plugin 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /managed-identity-function/src/main/java/com/microsoft/azure/ManagedIdentityFunctionApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | 11 | 12 | @SpringBootApplication 13 | public class ManagedIdentityFunctionApplication { 14 | public static void main(String[] args) { 15 | SpringApplication.run(ManagedIdentityFunctionApplication.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /managed-identity-function/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # Specify the base URI of your function app 2 | azure.function.uri=https://.azurewebsites.net 3 | # Specify the name of your function trigger 4 | azure.function.triggerPath=httptrigger 5 | # Specify the Application ID URI of your function app 6 | azure.function.application-id.uri= 7 | -------------------------------------------------------------------------------- /managed-identity-keyvault/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.microsoft.azure 7 | asc-managed-identity-keyvault-sample 8 | 0.1.0 9 | 10 | 11 | org.springframework.cloud 12 | spring-cloud-starter-parent 13 | Hoxton.SR8 14 | 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-starter-web 20 | 21 | 22 | com.azure 23 | azure-identity 24 | 1.0.0 25 | 26 | 27 | com.azure 28 | azure-security-keyvault-secrets 29 | 4.0.0 30 | 31 | 32 | org.projectlombok 33 | lombok 34 | true 35 | 36 | 37 | org.springframework.cloud 38 | spring-cloud-starter-netflix-eureka-client 39 | 40 | 41 | 42 | 43 | 1.8 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-maven-plugin 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /managed-identity-keyvault/src/main/java/com/microsoft/azure/MainController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import com.azure.identity.ManagedIdentityCredential; 9 | import com.azure.identity.ManagedIdentityCredentialBuilder; 10 | import com.azure.security.keyvault.secrets.SecretClient; 11 | import com.azure.security.keyvault.secrets.SecretClientBuilder; 12 | import com.azure.security.keyvault.secrets.models.KeyVaultSecret; 13 | import org.springframework.beans.factory.annotation.Value; 14 | import org.springframework.web.bind.annotation.*; 15 | 16 | import javax.annotation.PostConstruct; 17 | import java.time.Duration; 18 | 19 | @RestController 20 | public class MainController { 21 | private SecretClient secretClient; 22 | 23 | @Value("${azure.keyvault.uri:local}") 24 | private String keyVaultUrl; 25 | 26 | @PostConstruct 27 | private void setupSecretClient() { 28 | ManagedIdentityCredential managedIdentityCredential = new ManagedIdentityCredentialBuilder() 29 | .maxRetry(1) 30 | .retryTimeout(duration -> Duration.ofMinutes(1)) 31 | .build(); 32 | 33 | secretClient = new SecretClientBuilder() 34 | .vaultUrl(keyVaultUrl) 35 | .credential(managedIdentityCredential) 36 | .buildClient(); 37 | } 38 | 39 | @PutMapping("/secrets/{name}") 40 | public String setSecret(@PathVariable String name, @RequestParam String value) { 41 | try { 42 | KeyVaultSecret secret = secretClient.setSecret(name, value); 43 | return String.format("Successfully set secret %s in Key Vault %s", name, keyVaultUrl); 44 | } catch (Exception ex) { 45 | return String.format("Failed to set secret %s in Key Vault %s due to %s", name, 46 | keyVaultUrl, ex.getMessage()); 47 | } 48 | } 49 | 50 | @GetMapping(path="/secrets/{name}") 51 | public String getSecret(@PathVariable String name) { 52 | try { 53 | KeyVaultSecret secret = secretClient.getSecret(name); 54 | return String.format("Successfully got the value of secret %s from Key Vault %s: %s", 55 | name, keyVaultUrl, secret.getValue()); 56 | } catch (Exception ex) { 57 | return String.format("Failed to get secret %s from Key Vault %s due to %s", name, 58 | keyVaultUrl, ex.getMessage()); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /managed-identity-keyvault/src/main/java/com/microsoft/azure/ManagedIdentityKeyVaultApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 11 | 12 | 13 | @EnableDiscoveryClient 14 | @SpringBootApplication 15 | public class ManagedIdentityKeyVaultApplication { 16 | public static void main(String[] args) { 17 | SpringApplication.run(ManagedIdentityKeyVaultApplication.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /managed-identity-keyvault/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # Specify the URI of your Key Vault (e.g.: https://name.vault.azure.net/) 2 | azure.keyvault.uri=https://.vault.azure.net/ -------------------------------------------------------------------------------- /managed-identity-mysql/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.microsoft.azure 7 | asc-managed-identity-mysql-sample 8 | 0.1.0 9 | 10 | 11 | org.springframework.boot 12 | spring-boot-starter-parent 13 | 2.5.4 14 | 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-web 21 | 22 | 23 | com.azure.spring 24 | spring-cloud-azure-starter-keyvault-secrets 25 | 4.0.0-beta.3 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-data-jdbc 30 | 31 | 32 | mysql 33 | mysql-connector-java 34 | runtime 35 | 36 | 37 | 38 | 39 | 1.8 40 | 41 | 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-maven-plugin 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /managed-identity-mysql/src/main/java/com/microsoft/azure/MainController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | @RestController 12 | public class MainController { 13 | private final TodoRepository todoRepository; 14 | 15 | public MainController(TodoRepository todoRepository) { 16 | 17 | this.todoRepository = todoRepository; 18 | } 19 | 20 | @PostMapping("/") 21 | @ResponseStatus(HttpStatus.CREATED) 22 | public Todo createTodo(@RequestBody Todo todo) { 23 | return todoRepository.save(todo); 24 | } 25 | 26 | @GetMapping("/") 27 | public Iterable getTodos() { 28 | return todoRepository.findAll(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /managed-identity-mysql/src/main/java/com/microsoft/azure/ManagedIdentityMysqlApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | 11 | @SpringBootApplication 12 | public class ManagedIdentityMysqlApplication { 13 | public static void main(String[] args) { 14 | SpringApplication.run(ManagedIdentityMysqlApplication.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /managed-identity-mysql/src/main/java/com/microsoft/azure/Todo.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.azure; 2 | 3 | import org.springframework.data.annotation.Id; 4 | 5 | public class Todo { 6 | public Todo() { 7 | } 8 | 9 | public Todo(String description, String details, boolean done) { 10 | this.description = description; 11 | this.details = details; 12 | this.done = done; 13 | } 14 | 15 | @Id 16 | private Long id; 17 | 18 | private String description; 19 | 20 | private String details; 21 | 22 | private boolean done; 23 | 24 | public Long getId() { 25 | return id; 26 | } 27 | 28 | public void setId(Long id) { 29 | this.id = id; 30 | } 31 | 32 | public String getDescription() { 33 | return description; 34 | } 35 | 36 | public void setDescription(String description) { 37 | this.description = description; 38 | } 39 | 40 | public String getDetails() { 41 | return details; 42 | } 43 | 44 | public void setDetails(String details) { 45 | this.details = details; 46 | } 47 | 48 | public boolean isDone() { 49 | return done; 50 | } 51 | 52 | public void setDone(boolean done) { 53 | this.done = done; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /managed-identity-mysql/src/main/java/com/microsoft/azure/TodoRepository.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.azure; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | public interface TodoRepository extends CrudRepository { 6 | } -------------------------------------------------------------------------------- /managed-identity-mysql/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mysql://.mysql.database.azure.com:3306/demo?serverTimezone=UTC 2 | spring.datasource.username=@ 3 | spring.datasource.password=${MYSQL-PASSWORD} 4 | spring.datasource.initialization-mode=always 5 | spring.cloud.azure.keyvault.secret.endpoint=https://.vault.azure.net/ 6 | spring.cloud.azure.keyvault.secret.property-source-enabled=true -------------------------------------------------------------------------------- /managed-identity-mysql/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS todo; 2 | CREATE TABLE todo (id SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN); -------------------------------------------------------------------------------- /managed-identity-storage-blob/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.microsoft.azure 7 | asc-managed-identity-storage-blob-sample 8 | 0.1.0 9 | 10 | 11 | org.springframework.cloud 12 | spring-cloud-starter-parent 13 | Hoxton.SR8 14 | 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-starter-web 20 | 21 | 22 | com.azure 23 | azure-identity 24 | 1.0.5 25 | 26 | 27 | com.azure 28 | azure-storage-blob 29 | 12.6.0 30 | 31 | 32 | org.projectlombok 33 | lombok 34 | true 35 | 36 | 37 | org.springframework.cloud 38 | spring-cloud-starter-netflix-eureka-client 39 | 40 | 41 | org.springframework.cloud 42 | spring-cloud-starter-config 43 | 44 | 45 | 46 | 47 | 1.8 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-maven-plugin 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /managed-identity-storage-blob/src/main/java/com/microsoft/azure/ManagedIdentityStorageBlobApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 11 | 12 | 13 | @EnableDiscoveryClient 14 | @SpringBootApplication 15 | public class ManagedIdentityStorageBlobApplication { 16 | public static void main(String[] args) { 17 | SpringApplication.run(ManagedIdentityStorageBlobApplication.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /managed-identity-storage-blob/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | azure.storage.account= 2 | azure.storage.container= -------------------------------------------------------------------------------- /service-binding-cosmosdb-mongo/README.md: -------------------------------------------------------------------------------- 1 | # Binding your app with Azure COSMOS Mongo API 2 | 3 | This sample shows how to run app with Azure Cosmos DB(Mongo) in Azure Spring Apps. 4 | 5 | ### Prerequisite 6 | 7 | * [JDK 8](https://docs.microsoft.com/azure/java/jdk/java-jdk-install) 8 | * [Maven 3.0 and above](http://maven.apache.org/install.html) 9 | * [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/overview) 10 | 11 | ### How to run 12 | 13 | 1. Run `mvn clean package` to build the project. 14 | 1. Install Azure CLI extension for Azure Spring Apps by running below command. 15 | ``` 16 | az extension add -y --source https://azureclitemp.blob.core.windows.net/spring-cloud/spring_cloud-0.1.0-py2.py3-none-any.whl 17 | ``` 18 | 1. Create an instance of Azure Spring Apps. 19 | ``` 20 | az spring-cloud create -n -g 21 | ``` 22 | 1. Create an app with public domain assigned. 23 | ``` 24 | az spring-cloud app create -n -s -g --is-public true 25 | ``` 26 | 1. Deploy app with jar. 27 | ``` 28 | az spring-cloud app deploy -n -s -g --jar-path ./target/asc-service-binding-cosmosdb-sql-sample-0.1.0.jar 29 | ``` 30 | 1. Add a binding of Azure Cosmos for this app. 31 | ``` 32 | az spring-cloud app binding cosmos add --api-type mongo --app -s -g -n cosmos --resource-id --database-name 33 | ``` 34 | 1. Restart the app. 35 | ``` 36 | az spring-cloud app restart -n -s -g 37 | ``` 38 | 1. Verify app is running. Instances should have status `RUNNING` and discoveryStatus `UP`. 39 | ``` 40 | az spring-cloud app show -n -s -g 41 | ``` 42 | -------------------------------------------------------------------------------- /service-binding-cosmosdb-mongo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.springframework.cloud 8 | spring-cloud-starter-parent 9 | Hoxton.SR8 10 | 11 | 12 | com.microsoft.azure 13 | asc-service-binding-cosmosdb-mongo-sample 14 | 0.1.0 15 | 16 | 17 | 1.8 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-data-mongodb 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-netflix-eureka-client 32 | 33 | 34 | org.springframework.cloud 35 | spring-cloud-starter-config 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-maven-plugin 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /service-binding-cosmosdb-mongo/src/main/java/com/microsoft/azure/MainController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.web.bind.annotation.RestController; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PostMapping; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | 14 | @RestController 15 | public class MainController { 16 | @Autowired 17 | private UserRepository userRepository; 18 | 19 | @PostMapping(path="/add") 20 | public User addNewUser (@RequestParam String name) { 21 | User n = new User(name); 22 | return userRepository.save(n); 23 | } 24 | 25 | @GetMapping(path="/all") 26 | public Iterable getAllUsers() { 27 | return userRepository.findAll(); 28 | } 29 | 30 | @GetMapping(path="/hello") 31 | public String hello() { 32 | return "hello!"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /service-binding-cosmosdb-mongo/src/main/java/com/microsoft/azure/ServiceBindingMongodbApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.azure; 8 | 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.CommandLineRunner; 11 | import org.springframework.boot.SpringApplication; 12 | import org.springframework.boot.autoconfigure.SpringBootApplication; 13 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 14 | 15 | @EnableDiscoveryClient 16 | @SpringBootApplication 17 | public class ServiceBindingMongodbApplication implements CommandLineRunner { 18 | 19 | @Autowired 20 | private UserRepository repository; 21 | 22 | public static void main(String[] args) { 23 | SpringApplication.run(ServiceBindingMongodbApplication.class, args); 24 | } 25 | 26 | @Override 27 | public void run(String... args) throws Exception { 28 | // save a couple of customers 29 | repository.save(new User("Alice")); 30 | repository.save(new User("Bob")); 31 | 32 | // fetch an individual customer 33 | System.out.println("Customer found with findByFirstName('Alice'):"); 34 | System.out.println("--------------------------------"); 35 | System.out.println(repository.findByName("Alice").get(0)); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /service-binding-cosmosdb-mongo/src/main/java/com/microsoft/azure/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.azure; 8 | 9 | import org.springframework.data.annotation.Id; 10 | 11 | public class User { 12 | 13 | @Id 14 | public String id; 15 | 16 | public String name; 17 | 18 | public User(String name) { 19 | this.name = name; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return String.format("User[id=%s, name='%s']", id, name); 25 | } 26 | 27 | } 28 | 29 | -------------------------------------------------------------------------------- /service-binding-cosmosdb-mongo/src/main/java/com/microsoft/azure/UserRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.azure; 8 | 9 | import java.util.List; 10 | import org.springframework.data.mongodb.repository.MongoRepository; 11 | 12 | public interface UserRepository extends MongoRepository { 13 | 14 | List findByName(String name); 15 | } 16 | -------------------------------------------------------------------------------- /service-binding-cosmosdb-sql/README.md: -------------------------------------------------------------------------------- 1 | # Bind your app with Azure COSMOS SQL API 2 | 3 | This sample shows how to run app with Azure Cosmos DB(SQL) in Azure Spring Apps. 4 | 5 | ### Prerequisite 6 | 7 | * [JDK 8](https://docs.microsoft.com/azure/java/jdk/java-jdk-install) 8 | * [Maven 3.0 and above](http://maven.apache.org/install.html) 9 | * [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/overview) 10 | 11 | ### How to run 12 | 13 | 1. Run `mvn clean package`. 14 | 1. Install Azure CLI extension for Azure Spring Apps by running below command. 15 | ``` 16 | az extension add -y --source https://azureclitemp.blob.core.windows.net/spring-cloud/spring_cloud-0.1.0-py2.py3-none-any.whl 17 | ``` 18 | 1. Create an instance of Azure Spring Apps. 19 | ``` 20 | az spring-cloud create -n -g 21 | ``` 22 | 1. Create an app with public domain assigned. 23 | ``` 24 | az spring-cloud app create -n -s -g --is-public true 25 | ``` 26 | 1. Deploy app with jar 27 | ``` 28 | az spring-cloud app deploy -n -s -g --jar-path ./target/asc-service-binding-cosmosdb-sql-sample-0.1.0.jar 29 | ``` 30 | 1. Add a binding for this app 31 | ``` 32 | az spring-cloud app binding cosmos add --api-type sql --app -s -g -n cosmos --resource-id --database-name 33 | ``` 34 | 1. Restart the app 35 | ``` 36 | az spring-cloud app restart -n -s -g 37 | ``` 38 | 1. Verify app is running. Instances should have status `RUNNING` and discoveryStatus `UP`. 39 | ``` 40 | az spring-cloud app show -n -s -g 41 | ``` 42 | -------------------------------------------------------------------------------- /service-binding-cosmosdb-sql/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.springframework.cloud 8 | spring-cloud-starter-parent 9 | Hoxton.SR8 10 | 11 | 12 | com.microsoft.azure 13 | asc-service-binding-cosmosdb-sql-sample 14 | 0.1.0 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-starter-web 20 | 21 | 22 | com.microsoft.azure 23 | azure-cosmosdb-spring-boot-starter 24 | 2.2.5 25 | 26 | 27 | org.projectlombok 28 | lombok 29 | provided 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-netflix-eureka-client 34 | 35 | 36 | org.springframework.cloud 37 | spring-cloud-starter-config 38 | 39 | 40 | 41 | 42 | 43 | nexus-snapshots 44 | https://oss.sonatype.org/content/repositories/snapshots/ 45 | 46 | true 47 | 48 | 49 | 50 | 51 | 52 | 1.8 53 | 54 | 55 | 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-maven-plugin 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /service-binding-cosmosdb-sql/src/main/java/com/microsoft/azure/MainController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.web.bind.annotation.RestController; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | 12 | @RestController 13 | public class MainController { 14 | @Autowired 15 | private UserRepository userRepository; 16 | 17 | @GetMapping(path="/all") 18 | public Iterable getAllUsers() { 19 | return userRepository.findAll(); 20 | } 21 | 22 | @GetMapping(path="/hello") 23 | public String hello() { 24 | return "hello!"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /service-binding-cosmosdb-sql/src/main/java/com/microsoft/azure/ServiceBindingCosmosDbApplication.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.CommandLineRunner; 12 | import org.springframework.boot.SpringApplication; 13 | import org.springframework.boot.autoconfigure.SpringBootApplication; 14 | import org.springframework.util.Assert; 15 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 16 | 17 | import java.util.Optional; 18 | 19 | @EnableDiscoveryClient 20 | @SpringBootApplication 21 | public class ServiceBindingCosmosDbApplication implements CommandLineRunner { 22 | 23 | private static final Logger LOGGER = LoggerFactory.getLogger(ServiceBindingCosmosDbApplication.class); 24 | 25 | @Autowired 26 | private UserRepository repository; 27 | 28 | public static void main(String[] args) { 29 | SpringApplication.run(ServiceBindingCosmosDbApplication.class, args); 30 | } 31 | 32 | public void run(String... var1) throws Exception { 33 | final User testUser = new User("testId", "testFirstName", "testLastName", "test address line one"); 34 | 35 | repository.deleteAll(); 36 | repository.save(testUser); 37 | 38 | final Optional opResult = repository.findById(testUser.getId()); 39 | Assert.isTrue(opResult.isPresent(), "Cannot find user."); 40 | 41 | final User result = opResult.get(); 42 | Assert.state(result.getFirstName().equals(testUser.getFirstName()), "query result firstName doesn't match!"); 43 | Assert.state(result.getLastName().equals(testUser.getLastName()), "query result lastName doesn't match!"); 44 | 45 | LOGGER.info("findOne in User collection get result: {}", result.toString()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /service-binding-cosmosdb-sql/src/main/java/com/microsoft/azure/User.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.azure; 8 | 9 | import com.microsoft.azure.spring.data.cosmosdb.core.mapping.Document; 10 | import com.microsoft.azure.spring.data.cosmosdb.core.mapping.PartitionKey; 11 | import lombok.AllArgsConstructor; 12 | import lombok.Data; 13 | 14 | @Document(collection = "mycollection") 15 | @Data 16 | @AllArgsConstructor 17 | public class User { 18 | @PartitionKey 19 | private String id; 20 | private String firstName; 21 | private String lastName; 22 | private String address; 23 | 24 | public User() { 25 | 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return String.format("%s %s, %s", firstName, lastName, address); 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /service-binding-cosmosdb-sql/src/main/java/com/microsoft/azure/UserRepository.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.azure; 8 | 9 | import com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository; 10 | import org.springframework.stereotype.Repository; 11 | 12 | @Repository 13 | public interface UserRepository extends CosmosRepository { 14 | } 15 | -------------------------------------------------------------------------------- /service-binding-mysql/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.springframework.cloud 8 | spring-cloud-starter-parent 9 | Hoxton.SR8 10 | 11 | 12 | com.microsoft.azure 13 | asc-service-binding-mysql-sample 14 | 0.1.0 15 | 16 | 17 | 1.8 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-data-jpa 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | mysql 31 | mysql-connector-java 32 | runtime 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-starter-netflix-eureka-client 37 | 38 | 39 | org.springframework.cloud 40 | spring-cloud-starter-config 41 | 42 | 43 | 44 | 45 | 46 | nexus-snapshots 47 | https://oss.sonatype.org/content/repositories/snapshots/ 48 | 49 | true 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-maven-plugin 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /service-binding-mysql/readme.md: -------------------------------------------------------------------------------- 1 | ### Service Binding Sample 2 | 3 | This sample shows how to run app with Azure Database for MySQL in Azure Spring Apps. 4 | 5 | ### Prerequisite 6 | 7 | * [JDK 8](https://docs.microsoft.com/azure/java/jdk/java-jdk-install) 8 | * [Maven 3.0 and above](http://maven.apache.org/install.html) 9 | * [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/overview) 10 | 11 | ### How to run 12 | 13 | 1. Run `mvn clean package`. 14 | 1. Install Azure CLI extension for Azure Spring Apps by running below command. 15 | ``` 16 | az extension add -y --source https://azureclitemp.blob.core.windows.net/spring-cloud/spring_cloud-0.1.0-py2.py3-none-any.whl 17 | ``` 18 | 1. Create an instance of Azure Spring Apps. 19 | ``` 20 | az spring-cloud create -n -g 21 | ``` 22 | 1. Create an app with public domain assigned. 23 | ``` 24 | az spring-cloud app create -n -s -g --is-public true 25 | ``` 26 | 1. Deploy app with jar 27 | ``` 28 | az spring-cloud app deploy -n -s -g --jar-path ./target/asc-service-binding-mysql-sample-0.1.0.jar 29 | ``` 30 | 1. Add a binding for this app 31 | ``` 32 | az spring-cloud app binding mysql add --app -s -g -n mysql --resource-id --username --key --database-name 33 | ``` 34 | 1. Restart the app 35 | ``` 36 | az spring-cloud app restart -n -s -g 37 | ``` 38 | 1. Verify app is running. Instances should have status `RUNNING` and discoveryStatus `UP`. 39 | ``` 40 | az spring-cloud app show -n -s -g 41 | ``` 42 | -------------------------------------------------------------------------------- /service-binding-mysql/src/main/java/com/microsoft/azure/MainController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.web.bind.annotation.RestController; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PostMapping; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | 15 | @RestController 16 | public class MainController { 17 | @Autowired 18 | private UserRepository userRepository; 19 | 20 | @PostMapping(path="/add") 21 | public void addNewUser (@RequestParam String name, @RequestParam String email) { 22 | User n = new User(); 23 | n.setName(name); 24 | n.setEmail(email); 25 | userRepository.save(n); 26 | } 27 | 28 | @GetMapping(path="/all") 29 | public @ResponseBody Iterable getAllUsers() { 30 | return userRepository.findAll(); 31 | } 32 | 33 | @GetMapping(path="/hello") 34 | public String hello() { 35 | return "hello!"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /service-binding-mysql/src/main/java/com/microsoft/azure/ServiceBindingMysqlApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 11 | 12 | @EnableDiscoveryClient 13 | @SpringBootApplication 14 | public class ServiceBindingMysqlApplication { 15 | 16 | public static void main(String[] args) { 17 | SpringApplication.run(ServiceBindingMysqlApplication.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /service-binding-mysql/src/main/java/com/microsoft/azure/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import javax.persistence.Entity; 9 | import javax.persistence.GeneratedValue; 10 | import javax.persistence.GenerationType; 11 | import javax.persistence.Id; 12 | 13 | @Entity 14 | public class User { 15 | @Id 16 | @GeneratedValue(strategy=GenerationType.AUTO) 17 | private Integer id; 18 | 19 | private String name; 20 | 21 | private String email; 22 | 23 | public Integer getId() { 24 | return id; 25 | } 26 | 27 | public void setId(Integer id) { 28 | this.id = id; 29 | } 30 | 31 | public String getName() { 32 | return name; 33 | } 34 | 35 | public void setName(String name) { 36 | this.name = name; 37 | } 38 | 39 | public String getEmail() { 40 | return email; 41 | } 42 | 43 | public void setEmail(String email) { 44 | this.email = email; 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /service-binding-mysql/src/main/java/com/microsoft/azure/UserRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.data.repository.CrudRepository; 9 | 10 | public interface UserRepository extends CrudRepository { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /service-binding-mysql/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.jpa.hibernate.ddl-auto=update -------------------------------------------------------------------------------- /service-binding-redis/README.md: -------------------------------------------------------------------------------- 1 | ### Bind your app with Azure Cache for Redis 2 | 3 | This sample shows how to run app with Azure Cache for Redis in Azure Spring Apps. 4 | 5 | ### Prerequisite 6 | 7 | * [JDK 8](https://docs.microsoft.com/azure/java/jdk/java-jdk-install) 8 | * [Maven 3.0 and above](http://maven.apache.org/install.html) 9 | * [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/overview) 10 | 11 | ### How to run 12 | 13 | 1. Run `mvn clean package`. 14 | 1. Install Azure CLI extension for Azure Spring Apps by running below command. 15 | ``` 16 | az extension add -y --source https://azureclitemp.blob.core.windows.net/spring-cloud/spring_cloud-0.1.0-py2.py3-none-any.whl 17 | ``` 18 | 1. Create an instance of Azure Spring Apps. 19 | ``` 20 | az spring-cloud create -n -g 21 | ``` 22 | 1. Create an app with public domain assigned. 23 | ``` 24 | az spring-cloud app create -n -s -g --is-public true 25 | ``` 26 | 1. Deploy app with jar 27 | ``` 28 | az spring-cloud app deploy -n -s -g --jar-path ./target/asc-service-binding-redis-sample-0.1.0.jar 29 | ``` 30 | 1. Add a binding for this app 31 | ``` 32 | az spring-cloud app binding redis add --app -s -g -n redis --resource-id 33 | ``` 34 | 1. Restart the app 35 | ``` 36 | az spring-cloud app restart -n -s -g 37 | ``` 38 | 1. Verify app is running. Instances should have status `RUNNING` and discoveryStatus `UP`. 39 | ``` 40 | az spring-cloud app show -n -s -g 41 | ``` 42 | -------------------------------------------------------------------------------- /service-binding-redis/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.microsoft.azure 7 | asc-service-binding-redis-sample 8 | 0.1.0 9 | 10 | 11 | org.springframework.cloud 12 | spring-cloud-starter-parent 13 | Hoxton.SR8 14 | 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-starter-data-redis 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | org.projectlombok 27 | lombok 28 | true 29 | 30 | 31 | org.springframework.cloud 32 | spring-cloud-starter-netflix-eureka-client 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-config-client 37 | 38 | 39 | 40 | 41 | 42 | nexus-snapshots 43 | https://oss.sonatype.org/content/repositories/snapshots/ 44 | 45 | true 46 | 47 | 48 | 49 | 50 | 51 | 1.8 52 | 53 | 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-maven-plugin 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /service-binding-redis/src/main/java/com/microsoft/azure/MainController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.data.redis.core.StringRedisTemplate; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.util.List; 13 | import java.util.stream.Collectors; 14 | 15 | @RestController 16 | public class MainController { 17 | private final StringRedisTemplate redis; 18 | 19 | public MainController(StringRedisTemplate redis) { 20 | this.redis = redis; 21 | } 22 | 23 | @GetMapping("/all") 24 | public List all() { 25 | return redis.keys("*").stream().sorted().collect(Collectors.toList()); 26 | } 27 | 28 | @GetMapping(path = "/hello") 29 | public String hello() { 30 | return "hello!"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /service-binding-redis/src/main/java/com/microsoft/azure/ServiceBindingRedisApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | package com.microsoft.azure; 7 | 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 11 | import org.springframework.stereotype.Service; 12 | 13 | @EnableDiscoveryClient 14 | @SpringBootApplication 15 | @Service 16 | public class ServiceBindingRedisApplication { 17 | public static void main(String[] args) { 18 | SpringApplication.run(ServiceBindingRedisApplication.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /steeltoe-sample/.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio Projects 2 | .vs/ 3 | .config/ 4 | obj/ 5 | bin/ 6 | PublishProfiles/ 7 | *.csproj.user 8 | -------------------------------------------------------------------------------- /steeltoe-sample/Microsoft.Azure.SpringCloud.Samples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29905.134 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.SpringCloud.Sample.PlanetWeatherProvider", "src\planet-weather-provider\Microsoft.Azure.SpringCloud.Sample.PlanetWeatherProvider.csproj", "{BB317891-B3DD-4F6B-8F1C-D8D77FABEE0E}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.SpringCloud.Sample.SolarSystemWeather", "src\solar-system-weather\Microsoft.Azure.SpringCloud.Sample.SolarSystemWeather.csproj", "{7E608BB8-CE29-4A26-9346-DC972E7E0EC8}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {BB317891-B3DD-4F6B-8F1C-D8D77FABEE0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {BB317891-B3DD-4F6B-8F1C-D8D77FABEE0E}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {BB317891-B3DD-4F6B-8F1C-D8D77FABEE0E}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {BB317891-B3DD-4F6B-8F1C-D8D77FABEE0E}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {7E608BB8-CE29-4A26-9346-DC972E7E0EC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {7E608BB8-CE29-4A26-9346-DC972E7E0EC8}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {7E608BB8-CE29-4A26-9346-DC972E7E0EC8}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {7E608BB8-CE29-4A26-9346-DC972E7E0EC8}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {AB5E4E90-8845-48D4-A974-3321DBA957A5} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /steeltoe-sample/config/planet-weather-provider.yml: -------------------------------------------------------------------------------- 1 | MercuryWeather: very warm 2 | VenusWeather: quite unpleasant 3 | EarthWeather: check your local weather forecast 4 | MarsWeather: very cool 5 | JupiterWeather: I can fly 6 | SaturnWeather: a little bit sandy -------------------------------------------------------------------------------- /steeltoe-sample/config/solar-system-weather.yml: -------------------------------------------------------------------------------- 1 | MercuryWeather: very warm 2 | VenusWeather: quite unpleasant 3 | EarthWeather: check your local weather forecast 4 | MarsWeather: very cool 5 | JupiterWeather: I can fly 6 | SaturnWeather: a little bit sandy -------------------------------------------------------------------------------- /steeltoe-sample/src/planet-weather-provider/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Logging; 4 | 5 | namespace Microsoft.Azure.SpringCloud.Sample.PlanetWeatherProvider.Controllers 6 | { 7 | [ApiController] 8 | [Route("[controller]")] 9 | public class WeatherForecastController : ControllerBase 10 | { 11 | private readonly ILogger logger; 12 | private readonly IConfiguration config; 13 | 14 | public WeatherForecastController(IConfiguration config, ILogger logger) 15 | { 16 | this.config = config; 17 | this.logger = logger; 18 | } 19 | 20 | [HttpGet("{planet}")] 21 | public string Get(string planet) 22 | { 23 | logger.LogDebug("Getting weather data for planet {0}", planet); 24 | 25 | var weatherConfigKey = $"{planet}Weather"; 26 | logger.LogDebug("Getting weather forcast data ({0}) from config server...", weatherConfigKey); 27 | 28 | var weatherFromConfig = config[weatherConfigKey]; 29 | 30 | logger.LogInformation("Weather forcast data retrieved from config: {0}", weatherFromConfig); 31 | return string.IsNullOrEmpty(weatherFromConfig) ? "Unknown" : weatherFromConfig; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /steeltoe-sample/src/planet-weather-provider/Microsoft.Azure.SpringCloud.Sample.PlanetWeatherProvider.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /steeltoe-sample/src/planet-weather-provider/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Azure.SpringCloud.Client; 3 | using Microsoft.Extensions.Hosting; 4 | using Steeltoe.Extensions.Configuration.ConfigServer; 5 | 6 | namespace Microsoft.Azure.SpringCloud.Sample.PlanetWeatherProvider 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) => CreateHostBuilder(args).Build().Run(); 11 | 12 | /// 13 | /// Configure steeltoe and Azure Spring Apps. 14 | /// 15 | /// Please ensure you are using the correct version of Microsoft.Azure.SpringCloud.Client: 16 | /// 17 | /// 1.0.0-preview.1 for Steeltoe library 2.4.4 18 | /// 2.0.0-preview.1 for Steeltoe library 3.0.0 19 | /// 20 | /// 21 | /// Please also notice the sequence of .AddConfigServer() and .UseAzureSpringCloudService(). 22 | /// If you do not follow the correct sequence mentioned below, your app will not run in Azure. 23 | /// 24 | /// For different versions of Microsoft.Azure.SpringCloud.Client: 25 | /// 26 | /// 27 | /// 1.0.0-preview.1 28 | /// .UseAzureSpringCloudService() must be added AFTER .AddConfigServer() 29 | /// 30 | /// 31 | /// 2.0.0-preview.1 32 | /// .UseAzureSpringCloudService() must BEFORE any other Steeltoe configurations 33 | /// 34 | /// 35 | /// 36 | public static IHostBuilder CreateHostBuilder(string[] args) => 37 | Host.CreateDefaultBuilder(args) 38 | .UseAzureSpringCloudService() 39 | .ConfigureWebHostDefaults(webBuilder => 40 | { 41 | webBuilder.UseStartup(); 42 | }) 43 | .AddConfigServer(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /steeltoe-sample/src/planet-weather-provider/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:56339", 7 | "sslPort": 44317 8 | } 9 | }, 10 | "$schema": "http://json.schemastore.org/launchsettings.json", 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast/mars", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "Microsoft.Azure.SpringCloud.Sample.PlanetWeatherProvider": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast/mars", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "applicationUrl": "http://localhost:56339" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /steeltoe-sample/src/planet-weather-provider/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | using Steeltoe.Discovery.Client; 8 | using Steeltoe.Management.Tracing; 9 | 10 | namespace Microsoft.Azure.SpringCloud.Sample.PlanetWeatherProvider 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddLogging(configure => configure.AddConsole()); 25 | 26 | services.AddDiscoveryClient(Configuration); 27 | 28 | services.AddDistributedTracing(Configuration, builder => builder.UseZipkinWithTraceOptions(services)); 29 | 30 | services.AddControllers(); 31 | } 32 | 33 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 34 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 35 | { 36 | if (env.IsDevelopment()) 37 | { 38 | app.UseDeveloperExceptionPage(); 39 | } 40 | 41 | app.UseDiscoveryClient(); 42 | app.UseRouting(); 43 | app.UseEndpoints(endpoints => 44 | { 45 | endpoints.MapControllers(); 46 | }); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /steeltoe-sample/src/planet-weather-provider/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "spring": { 3 | "application": { 4 | "name": "planet-weather-provider" 5 | }, 6 | "cloud": { 7 | "config": { 8 | "uri": "http://localhost:8888", 9 | "validateCertificates": false 10 | } 11 | } 12 | }, 13 | 14 | "eureka": { 15 | "client": { 16 | "serviceUrl": "http://localhost:8761/eureka" 17 | }, 18 | "instance": { 19 | "port": 56339, 20 | "hostName": "localhost" 21 | } 22 | }, 23 | 24 | "management": { 25 | "tracing": { 26 | "alwaysSample": true, 27 | "exporter": { 28 | "zipkin": { 29 | "endpoint": "http://localhost:9411/api/v2/spans", 30 | "validateCertificates": false 31 | } 32 | } 33 | } 34 | }, 35 | 36 | "Logging": { 37 | "LogLevel": { 38 | "Default": "Debug", 39 | "Microsoft": "Debug", 40 | "Microsoft.Hosting.Lifetime": "Debug", 41 | "Steeltoe": "Debug" 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /steeltoe-sample/src/planet-weather-provider/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "spring": { 3 | "application": { 4 | "name": "planet-weather-provider" 5 | } 6 | }, 7 | 8 | "eureka": { 9 | "client": { 10 | "shouldFetchRegistry": false, 11 | "shouldRegisterWithEureka": true 12 | } 13 | }, 14 | 15 | "management": { 16 | "tracing": { 17 | "alwaysSample": true, 18 | "egressIgnorePattern": "/api/v2/spans|/v2/apps/.*/permissions|/eureka/.*|/oauth/.*" 19 | } 20 | }, 21 | 22 | "Logging": { 23 | "LogLevel": { 24 | "Default": "Information", 25 | "Microsoft": "Warning", 26 | "Microsoft.Hosting.Lifetime": "Warning", 27 | "Steeltoe": "Warning" 28 | }, 29 | "Console": { 30 | "IncludeScopes": true, 31 | "LogLevel": { 32 | "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning", 33 | "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug", 34 | "Microsoft.AspNetCore.Mvc.Razor": "Error", 35 | "Default": "Information" 36 | } 37 | } 38 | }, 39 | "AllowedHosts": "*" 40 | } 41 | -------------------------------------------------------------------------------- /steeltoe-sample/src/solar-system-weather/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Net.Http; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | using Steeltoe.Common.Discovery; 8 | using Steeltoe.Discovery; 9 | 10 | namespace Microsoft.Azure.SpringCloud.Sample.SolarSystemWeather.Controllers 11 | { 12 | [ApiController] 13 | [Route("[controller]")] 14 | public class WeatherForecastController : ControllerBase 15 | { 16 | private const string ProviderAppName = "planet-weather-provider"; 17 | 18 | private readonly ILogger logger; 19 | private readonly DiscoveryHttpClientHandler discoveryHandler; 20 | 21 | public WeatherForecastController(IDiscoveryClient discovery, ILogger logger) 22 | { 23 | discoveryHandler = new DiscoveryHttpClientHandler(discovery, logger); 24 | this.logger = logger; 25 | } 26 | 27 | [HttpGet] 28 | public async Task>> Get() 29 | { 30 | logger.LogDebug("Getting weather from solar system planets..."); 31 | using (var client = new HttpClient(discoveryHandler, false)) 32 | { 33 | var responses = await Task.WhenAll( 34 | client.GetAsync($"http://{ProviderAppName}/weatherforecast/Mercury"), 35 | client.GetAsync($"http://{ProviderAppName}/weatherforecast/Venus"), 36 | client.GetAsync($"http://{ProviderAppName}/weatherforecast/Mars"), 37 | client.GetAsync($"http://{ProviderAppName}/weatherforecast/Saturn")); 38 | logger.LogDebug("Weather provider app returned {0} results", responses.Length); 39 | 40 | var weathers = await Task.WhenAll(from res in responses select res.Content.ReadAsStringAsync()); 41 | logger.LogInformation("Retrieved weather data from {0} planets", weathers.Length); 42 | 43 | return new[] 44 | { 45 | new KeyValuePair("Mercury", weathers[0]), 46 | new KeyValuePair("Venus", weathers[1]), 47 | new KeyValuePair("Mars", weathers[2]), 48 | new KeyValuePair("Saturn", weathers[3]), 49 | }; 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /steeltoe-sample/src/solar-system-weather/Microsoft.Azure.SpringCloud.Sample.SolarSystemWeather.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /steeltoe-sample/src/solar-system-weather/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Azure.SpringCloud.Client; 3 | using Microsoft.Extensions.Hosting; 4 | 5 | namespace Microsoft.Azure.SpringCloud.Sample.SolarSystemWeather 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) => CreateHostBuilder(args).Build().Run(); 10 | 11 | /// 12 | /// Configure steeltoe and Azure Spring Apps. 13 | /// 14 | /// Please ensure you are using the correct version of Microsoft.Azure.SpringCloud.Client: 15 | /// 16 | /// 1.0.0-preview.1 for Steeltoe library 2.4.4 17 | /// 2.0.0-preview.1 for Steeltoe library 3.0.0 18 | /// 19 | /// 20 | /// Please also notice the sequence of .AddConfigServer() and .UseAzureSpringCloudService(). 21 | /// If you do not follow the correct sequence mentioned below, your app will not run in Azure. 22 | /// 23 | /// For different versions of Microsoft.Azure.SpringCloud.Client: 24 | /// 25 | /// 26 | /// 1.0.0-preview.1 27 | /// .UseAzureSpringCloudService() must be added AFTER .AddConfigServer() 28 | /// 29 | /// 30 | /// 2.0.0-preview.1 31 | /// .UseAzureSpringCloudService() must BEFORE any other Steeltoe configurations 32 | /// 33 | /// 34 | /// 35 | public static IHostBuilder CreateHostBuilder(string[] args) => 36 | Host.CreateDefaultBuilder(args) 37 | .UseAzureSpringCloudService() 38 | .ConfigureWebHostDefaults(webBuilder => 39 | { 40 | webBuilder.UseStartup(); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /steeltoe-sample/src/solar-system-weather/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:56351", 7 | "sslPort": 44336 8 | } 9 | }, 10 | "$schema": "http://json.schemastore.org/launchsettings.json", 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "Microsoft.Azure.SpringCloud.Sample.SolarSystemWeather": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "applicationUrl": "http://localhost:56351" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /steeltoe-sample/src/solar-system-weather/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | using Steeltoe.Discovery.Client; 8 | using Steeltoe.Management.Tracing; 9 | 10 | namespace Microsoft.Azure.SpringCloud.Sample.SolarSystemWeather 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddLogging(configure => configure.AddConsole()); 25 | 26 | services.AddDiscoveryClient(Configuration); 27 | 28 | services.AddDistributedTracing(Configuration, builder => builder.UseZipkinWithTraceOptions(services)); 29 | 30 | services.AddControllers(); 31 | } 32 | 33 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 34 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 35 | { 36 | if (env.IsDevelopment()) 37 | { 38 | app.UseDeveloperExceptionPage(); 39 | } 40 | 41 | app.UseDiscoveryClient(); 42 | app.UseRouting(); 43 | app.UseEndpoints(endpoints => 44 | { 45 | endpoints.MapControllers(); 46 | }); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /steeltoe-sample/src/solar-system-weather/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "spring": { 3 | "application": { 4 | "name": "solar-system-weather" 5 | } 6 | }, 7 | 8 | "eureka": { 9 | "client": { 10 | "serviceUrl": "http://localhost:8761/eureka" 11 | }, 12 | "instance": { 13 | "port": 56351, 14 | "hostName": "localhost" 15 | } 16 | }, 17 | 18 | "management": { 19 | "tracing": { 20 | "alwaysSample": true, 21 | "exporter": { 22 | "zipkin": { 23 | "endpoint": "http://localhost:9411/api/v2/spans", 24 | "validateCertificates": false 25 | } 26 | } 27 | } 28 | }, 29 | 30 | "Logging": { 31 | "LogLevel": { 32 | "Default": "Debug", 33 | "Microsoft": "Debug", 34 | "Microsoft.Hosting.Lifetime": "Debug", 35 | "Steeltoe": "Debug" 36 | } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /steeltoe-sample/src/solar-system-weather/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "spring": { 3 | "application": { 4 | "name": "solar-system-weather" 5 | } 6 | }, 7 | 8 | "eureka": { 9 | "client": { 10 | "shouldFetchRegistry": true, 11 | "shouldRegisterWithEureka": true 12 | } 13 | }, 14 | "management": { 15 | "tracing": { 16 | "alwaysSample": true, 17 | "egressIgnorePattern": "/api/v2/spans|/v2/apps/.*/permissions|/eureka/.*|/oauth/.*" 18 | } 19 | }, 20 | 21 | "Logging": { 22 | "LogLevel": { 23 | "Default": "Information", 24 | "Microsoft": "Warning", 25 | "Microsoft.Hosting.Lifetime": "Warning", 26 | "Steeltoe": "Warning" 27 | }, 28 | "Console": { 29 | "IncludeScopes": true, 30 | "LogLevel": { 31 | "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning", 32 | "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug", 33 | "Microsoft.AspNetCore.Mvc.Razor": "Error", 34 | "Default": "Information" 35 | } 36 | } 37 | }, 38 | "AllowedHosts": "*" 39 | } 40 | -------------------------------------------------------------------------------- /storage-sample/README.md: -------------------------------------------------------------------------------- 1 | # Temporary and persistent storage in Azure Spring Apps 2 | 3 | This sample shows how to use temporary and persistent storage in Azure Spring Apps. 4 | 5 | ### Prerequisite 6 | 7 | * [JDK 8](https://docs.microsoft.com/azure/java/jdk/java-jdk-install) 8 | * [Maven 3.0 and above](http://maven.apache.org/install.html) 9 | * [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/overview) 10 | 11 | ### How to run 12 | 13 | 1. Run `mvn clean package` under `storage-sample`. 14 | 2. Install Azure CLI extension for Azure Spring Apps by running below command. 15 | ``` 16 | az extension add -y --source https://azureclitemp.blob.core.windows.net/spring-cloud/spring_cloud-0.1.0-py2.py3-none-any.whl 17 | ``` 18 | 3. Create an instance of Azure Spring Apps. 19 | ``` 20 | az spring-cloud create -n -g 21 | ``` 22 | 4. Create an app with public domain assigned and persistent storage enabled. 23 | ``` 24 | az spring-cloud app create -n -s -g --is-public true --enable-persistent-storage true 25 | ``` 26 | 5. Deploy app with jar 27 | ``` 28 | az spring-cloud app deploy -n -s -g --jar-path ./target/storage-sample-1.0-SNAPSHOT.jar 29 | ``` 30 | 6. Verify app is running. Instances should have status `RUNNING` and discoveryStatus `UP`. 31 | ``` 32 | az spring-cloud app show -n -s -g 33 | ``` 34 | 7. Verify sample is working. The url is fetched from previous step. 35 | ``` 36 | # Write content of flie-name under temporary storage 37 | curl -X PUT {url}/tmp/{file-name}?content={content} 38 | 39 | # Get content of file-name 40 | curl {url}/tmp/{file-name} 41 | # return content you wrote before 42 | 43 | # Write content of flie-name under persistent storage 44 | curl -X PUT {url}/persistent/{file-name}?content={content} 45 | 46 | # Get content of file-name 47 | curl {url}/persistent/{file-name} 48 | # return content you wrote before 49 | 50 | ``` 51 | -------------------------------------------------------------------------------- /storage-sample/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.asc 8 | storage-sample 9 | 1.0-SNAPSHOT 10 | 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 2.3.0.RELEASE 15 | 16 | 17 | 18 | 1.8 19 | 1.8 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-netflix-eureka-client 34 | 35 | 36 | 37 | 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-dependencies 42 | Hoxton.SR8 43 | pom 44 | import 45 | 46 | 47 | 48 | 49 | 50 | 51 | nexus-snapshots 52 | https://oss.sonatype.org/content/repositories/snapshots/ 53 | 54 | true 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-maven-plugin 64 | 65 | 66 | org.apache.maven.plugins 67 | maven-compiler-plugin 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /storage-sample/src/main/java/com/microsoft/sample/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample; 8 | 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 12 | 13 | @SpringBootApplication 14 | @EnableDiscoveryClient 15 | public class Application { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(Application.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /storage-sample/src/main/java/com/microsoft/sample/StorageController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE in the project root for 4 | * license information. 5 | */ 6 | 7 | package com.microsoft.sample; 8 | 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import java.io.IOException; 12 | import java.nio.file.Files; 13 | import java.nio.file.Paths; 14 | 15 | @RestController 16 | public class StorageController { 17 | private static final String TEMP = "/tmp"; 18 | private static final String PERSISTENT = "/persistent"; 19 | 20 | @PutMapping(value = "/persistent/{name}") 21 | public void writePersistent(@PathVariable String name, @RequestParam String content) throws IOException { 22 | Files.write(Paths.get(PERSISTENT + "/" + name), content.getBytes()); 23 | } 24 | 25 | @GetMapping(value = "/persistent/{name}") 26 | public String readPersistent(@PathVariable String name) throws IOException { 27 | return new String(Files.readAllBytes(Paths.get(PERSISTENT + "/" + name))); 28 | } 29 | 30 | @PutMapping(value = "/tmp/{name}") 31 | public void writeTemporary(@PathVariable String name, @RequestParam String content) throws IOException { 32 | Files.write(Paths.get(TEMP + "/" + name), content.getBytes()); 33 | } 34 | 35 | @GetMapping(value = "/tmp/{name}") 36 | public String readTemporary(@PathVariable String name) throws IOException { 37 | return new String(Files.readAllBytes(Paths.get(TEMP + "/" + name))); 38 | } 39 | } 40 | --------------------------------------------------------------------------------