Skip to content

Commit 72a47b4

Browse files
Merge pull request #17418 from parthiv39731/Bael-6477
Bael 6477
2 parents eeda55d + 50f5aa5 commit 72a47b4

17 files changed

+623
-0
lines changed

spring-cloud-modules/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<module>spring-cloud-open-service-broker</module>
4343
<module>spring-cloud-archaius</module>
4444
<module>spring-cloud-functions</module>
45+
<module>spring-cloud-functions-azure</module>
4546
<module>spring-cloud-vault</module>
4647
<!-- <module>spring-cloud-security</module>-->
4748
<module>spring-cloud-task</module>
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<groupId>com.baeldung.functions</groupId>
6+
<artifactId>spring-cloud-functions-azure</artifactId>
7+
<version>1.0.0-SNAPSHOT</version>
8+
<packaging>jar</packaging>
9+
10+
<name>spring-cloud-functions-azure</name>
11+
<parent>
12+
<groupId>com.baeldung.spring.cloud</groupId>
13+
<artifactId>spring-cloud-modules</artifactId>
14+
<version>1.0.0-SNAPSHOT</version>
15+
</parent>
16+
<!--Ideally, this should be the parent for the spring boot maven plugin to work properly to add the main class in the manifest file-->
17+
<!-- <parent>
18+
<groupId>org.springframework.boot</groupId>
19+
<artifactId>spring-boot-starter-parent</artifactId>
20+
<version>2.7.11</version>
21+
<relativePath/>
22+
</parent>-->
23+
24+
<properties>
25+
<java.version>17</java.version>
26+
27+
<spring-boot-thin-layout.version>1.0.28.RELEASE</spring-boot-thin-layout.version>
28+
29+
<!-- Spring Boot start class! WARING: correct class must be set! -->
30+
<start-class>com.baeldung.azure.functions.AzureSpringCloudFunctionApplication</start-class>
31+
<!-- AZURE FUNCTION CONFIG -->
32+
<azure.functions.maven.plugin.version>1.36.0</azure.functions.maven.plugin.version>
33+
<functionAppName>SCF-baeldung-samples</functionAppName>
34+
<functionAppRegion>westus</functionAppRegion>
35+
<functionResourceGroup>baeldung-resource-group</functionResourceGroup>
36+
<functionAppServicePlanName>sample-service-plan</functionAppServicePlanName>
37+
<functionPricingTier>Consumption</functionPricingTier>
38+
</properties>
39+
<dependencies>
40+
41+
<dependency>
42+
<groupId>com.microsoft.azure.functions</groupId>
43+
<artifactId>azure-functions-java-library</artifactId>
44+
<version>3.1.0</version>
45+
</dependency>
46+
47+
<dependency>
48+
<groupId>org.springframework.cloud</groupId>
49+
<artifactId>spring-cloud-function-adapter-azure</artifactId>
50+
<version>4.0.5</version>
51+
</dependency>
52+
53+
<dependency>
54+
<groupId>org.springframework.boot</groupId>
55+
<artifactId>spring-boot-starter-test</artifactId>
56+
<scope>test</scope>
57+
</dependency>
58+
59+
</dependencies>
60+
61+
62+
<build>
63+
<plugins>
64+
<plugin>
65+
<groupId>org.apache.maven.plugins</groupId>
66+
<artifactId>maven-deploy-plugin</artifactId>
67+
<version>3.1.2</version>
68+
<configuration>
69+
<skip>true</skip>
70+
</configuration>
71+
</plugin>
72+
<plugin>
73+
<groupId>com.microsoft.azure</groupId>
74+
<artifactId>azure-functions-maven-plugin</artifactId>
75+
<version>${azure.functions.maven.plugin.version}</version>
76+
77+
<configuration>
78+
<appName>${functionAppName}</appName>
79+
<resourceGroup>${functionResourceGroup}</resourceGroup>
80+
<region>${functionAppRegion}</region>
81+
<appServicePlanName>${functionAppServicePlanName}</appServicePlanName>
82+
<pricingTier>${functionPricingTier}</pricingTier>
83+
84+
<hostJson>${project.basedir}/src/main/resources/host.json</hostJson>
85+
<localSettingsJson>${project.basedir}/src/main/resources/local.settings.json</localSettingsJson>
86+
87+
<runtime>
88+
<os>linux</os>
89+
<javaVersion>17</javaVersion>
90+
</runtime>
91+
92+
<appSettings>
93+
<property>
94+
<name>FUNCTIONS_EXTENSION_VERSION</name>
95+
<value>~4</value>
96+
</property>
97+
</appSettings>
98+
</configuration>
99+
<executions>
100+
<execution>
101+
<id>package-functions</id>
102+
<goals>
103+
<goal>package</goal>
104+
</goals>
105+
</execution>
106+
</executions>
107+
</plugin>
108+
<!--this is required because we are not using spring-boot-starter-parent-->
109+
<plugin>
110+
<groupId>org.apache.maven.plugins</groupId>
111+
<artifactId>maven-jar-plugin</artifactId>
112+
<version>${maven-jar-plugin.version}</version>
113+
<configuration>
114+
<archive>
115+
<manifest>
116+
<mainClass>${start-class}</mainClass>
117+
</manifest>
118+
</archive>
119+
</configuration>
120+
</plugin>
121+
<!--Don't need spring-boot-thin-layout as it is already part of the parent dependency-->
122+
<!-- <plugin>
123+
<groupId>org.springframework.boot</groupId>
124+
<artifactId>spring-boot-maven-plugin</artifactId>
125+
<version>${spring-boot.version}</version>
126+
&lt;!&ndash;it does not work as we are not using spring-boot-starter-parent&ndash;&gt;
127+
&lt;!&ndash; <configuration>
128+
<mainClass>${start-class}</mainClass>
129+
&lt;!&ndash; this is necessary as we're not using the Boot parent &ndash;&gt;
130+
</configuration>&ndash;&gt;
131+
<dependencies>
132+
<dependency>
133+
<groupId>org.springframework.boot.experimental</groupId>
134+
<artifactId>spring-boot-thin-layout</artifactId>
135+
<version>${thin.version}</version>
136+
</dependency>
137+
</dependencies>
138+
</plugin>-->
139+
</plugins>
140+
</build>
141+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.baeldung.azure.functions;
2+
3+
import java.util.function.Function;
4+
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.Configuration;
7+
8+
import com.baeldung.azure.functions.entity.Employee;
9+
10+
@Configuration
11+
public class ApplicationConfiguration {
12+
13+
@Bean
14+
public Function<Employee, Employee> employeeSalaryFunction() {
15+
return new EmployeeSalaryFunction();
16+
}
17+
18+
@Bean
19+
public Function<Employee, Employee> defaultSalaryCalculatorFn() {
20+
return new DefaultSalaryCalculatorFn();
21+
}
22+
23+
@Bean
24+
public Function<Employee, Employee> californiaSalaryCalculatorFn() {
25+
return new CaliforniaSalaryCalculatorFn();
26+
}
27+
28+
@Bean
29+
public Function<Employee, Employee> chicagoSalaryCalculatorFn() {
30+
return new ChicagoSalaryCalculatorFn();
31+
}
32+
33+
@Bean
34+
public Function<Employee, Employee> newYorkSalaryCalculatorFn() {
35+
return new NewYorkSalaryCalculatorFn();
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.baeldung.azure.functions;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication(scanBasePackages = "com.baeldung.azure.functions")
7+
public class AzureSpringCloudFunctionApplication {
8+
public static void main(String[] args) {
9+
SpringApplication.run(AzureSpringCloudFunctionApplication.class, args);
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.baeldung.azure.functions;
2+
3+
import java.util.function.Function;
4+
5+
import com.baeldung.azure.functions.entity.Employee;
6+
7+
public class CaliforniaSalaryCalculatorFn implements Function<Employee, Employee> {
8+
@Override
9+
public Employee apply(Employee employee) {
10+
Integer finalSalary = employee.getSalary() + 3000;
11+
employee.setSalary(finalSalary);
12+
return employee;
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.baeldung.azure.functions;
2+
3+
import java.util.function.Function;
4+
5+
import com.baeldung.azure.functions.entity.Employee;
6+
7+
public class ChicagoSalaryCalculatorFn implements Function<Employee, Employee> {
8+
@Override
9+
public Employee apply(Employee employee) {
10+
Integer finalSalary = employee.getSalary() + 5000;
11+
employee.setSalary(finalSalary);
12+
return employee;
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.baeldung.azure.functions;
2+
3+
import java.util.function.Function;
4+
5+
import com.baeldung.azure.functions.entity.Employee;
6+
7+
public class DefaultSalaryCalculatorFn implements Function<Employee, Employee> {
8+
9+
@Override
10+
public Employee apply(Employee employee) {
11+
Integer finalSalary = employee.getSalary() + 1000;
12+
employee.setSalary(finalSalary);
13+
return employee;
14+
}
15+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.baeldung.azure.functions;
2+
3+
import java.util.function.Function;
4+
5+
import com.baeldung.azure.functions.entity.Employee;
6+
7+
public class EmployeeSalaryFunction implements Function<Employee, Employee> {
8+
9+
@Override
10+
public Employee apply(Employee employee) {
11+
int allowance;
12+
switch (employee.getCity()) {
13+
case "Chicago" -> allowance = 5000;
14+
case "California" -> allowance = 2000;
15+
case "New York" -> allowance = 2500;
16+
default -> allowance = 1000;
17+
}
18+
int finalSalary = employee.getSalary() + allowance;
19+
employee.setSalary(finalSalary);
20+
return employee;
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.baeldung.azure.functions;
2+
3+
import java.util.function.Function;
4+
5+
import org.springframework.cloud.function.context.FunctionCatalog;
6+
7+
import com.baeldung.azure.functions.entity.Employee;
8+
9+
10+
public class EmployeeSalaryFunctionWrapper {
11+
12+
private FunctionCatalog functionCatalog;
13+
14+
public EmployeeSalaryFunctionWrapper(FunctionCatalog functionCatalog) {
15+
this.functionCatalog = functionCatalog;
16+
}
17+
18+
public Function<Employee, Employee> getCityBasedSalaryFunction(Employee employee) {
19+
Function<Employee, Employee> salaryCalculatorFunction;
20+
switch (employee.getCity()) {
21+
case "Chicago" -> salaryCalculatorFunction = functionCatalog.lookup("chicagoSalaryCalculatorFn");
22+
case "California" -> salaryCalculatorFunction = functionCatalog.lookup("californiaSalaryCalculatorFn|defaultSalaryCalculatorFn");
23+
case "New York" -> salaryCalculatorFunction = functionCatalog.lookup("newYorkSalaryCalculatorFn");
24+
default -> salaryCalculatorFunction = functionCatalog.lookup("defaultSalaryCalculatorFn");
25+
}
26+
return salaryCalculatorFunction;
27+
}
28+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.baeldung.azure.functions;
2+
3+
import java.util.Optional;
4+
import java.util.function.Function;
5+
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.cloud.function.context.FunctionCatalog;
8+
import org.springframework.stereotype.Component;
9+
10+
import com.baeldung.azure.functions.entity.Employee;
11+
import com.microsoft.azure.functions.ExecutionContext;
12+
import com.microsoft.azure.functions.HttpMethod;
13+
import com.microsoft.azure.functions.HttpRequestMessage;
14+
import com.microsoft.azure.functions.HttpResponseMessage;
15+
import com.microsoft.azure.functions.HttpStatus;
16+
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
17+
import com.microsoft.azure.functions.annotation.FunctionName;
18+
import com.microsoft.azure.functions.annotation.HttpTrigger;
19+
20+
@Component
21+
public class EmployeeSalaryHandler {
22+
@Autowired
23+
private Function<Employee, Employee> employeeSalaryFunction;
24+
25+
@Autowired
26+
private FunctionCatalog functionCatalog;
27+
28+
@FunctionName("calculateSalary")
29+
public HttpResponseMessage calculateSalary(
30+
@HttpTrigger(
31+
name="http",
32+
methods = HttpMethod.POST,
33+
authLevel = AuthorizationLevel.ANONYMOUS)HttpRequestMessage<Optional<Employee>> employeeHttpRequestMessage,
34+
ExecutionContext executionContext
35+
) {
36+
Employee employeeRequest = employeeHttpRequestMessage.getBody().get();
37+
executionContext.getLogger().info("Salary of " + employeeRequest.getName() + " is:" + employeeRequest.getSalary());
38+
39+
Employee employee = employeeSalaryFunction.apply(employeeRequest);
40+
executionContext.getLogger().info("Final salary of " + employee.getName() + " is:" + employee.getSalary());
41+
return employeeHttpRequestMessage.createResponseBuilder(HttpStatus.OK)
42+
.body(employee)
43+
.build();
44+
}
45+
46+
@FunctionName("calculateSalaryWithSCF")
47+
public HttpResponseMessage calculateSalaryWithSCF(
48+
@HttpTrigger(
49+
name="http",
50+
methods = HttpMethod.POST,
51+
authLevel = AuthorizationLevel.ANONYMOUS)HttpRequestMessage<Optional<Employee>> employeeHttpRequestMessage,
52+
ExecutionContext executionContext
53+
) {
54+
Employee employeeRequest = employeeHttpRequestMessage.getBody().get();
55+
executionContext.getLogger().info("Salary of " + employeeRequest.getName() + " is:" + employeeRequest.getSalary());
56+
EmployeeSalaryFunctionWrapper employeeSalaryFunctionWrapper = new EmployeeSalaryFunctionWrapper(functionCatalog);
57+
Function<Employee, Employee> cityBasedSalaryFunction = employeeSalaryFunctionWrapper.getCityBasedSalaryFunction(employeeRequest);
58+
executionContext.getLogger().info("The class of the cityBasedSalaryFunction:" + cityBasedSalaryFunction.getClass());
59+
Employee employee = cityBasedSalaryFunction.apply(employeeRequest);
60+
executionContext.getLogger().info("Final salary of " + employee.getName() + " is:" + employee.getSalary());
61+
return employeeHttpRequestMessage.createResponseBuilder(HttpStatus.OK)
62+
.body(employee)
63+
.build();
64+
}
65+
}

0 commit comments

Comments
 (0)