Skip to content

Commit 2f10ce2

Browse files
committed
integration test
1 parent ccdd983 commit 2f10ce2

File tree

5 files changed

+171
-2
lines changed

5 files changed

+171
-2
lines changed

documentation/ADDITIONAL-RESOURCES.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
* [SAP Cloud SDK documentation for JavaScript](https://sap.github.io/cloud-sdk/docs/js/tutorials/getting-started/introduction)
66

7+
* [Access SAP Business Application Studio as a remote from Visual Studio Code / Codespaces](https://blogs.sap.com/2023/04/28/access-sap-business-application-studio-as-a-remote-from-visual-studio-code)
8+
79
* [SAP Cloud SDK repos for JavaScript](https://github.com/SAP/cloud-sdk-js)
810

911
* [SAP Cloud SDK for JavaScript API documentation](https://sap.github.io/cloud-sdk/api/v2/index.html)

infra/app/apim-api-policy.xml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!-- Policy configuration for the API. Explore other sample policies at https://learn.microsoft.com/azure/api-management/policies/ -->
2+
<policies>
3+
<inbound>
4+
<base />
5+
<!-- The rate-limit policy prevents API usage spikes on a per subscription basis by limiting the call rate
6+
to a specified number per a specified time period. When the call rate is exceeded, the caller receives
7+
a 429 Too Many Requests response status code.
8+
-->
9+
<rate-limit calls="20" renewal-period="90" remaining-calls-variable-name="remainingCallsPerSubscription"/>
10+
</inbound>
11+
<backend>
12+
</backend>
13+
<outbound>
14+
<base />
15+
</outbound>
16+
<on-error>
17+
<base />
18+
</on-error>
19+
</policies> <!-- Optional policy to handle errors. Learn more at https://learn.microsoft.com/azure/api-management/api-management-error-handling-policies -->

infra/app/apim-api.bicep

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
param name string
2+
3+
@description('Resource name to uniquely identify this API within the API Management service instance')
4+
@minLength(1)
5+
param apiName string
6+
7+
@description('The Display Name of the API')
8+
@minLength(1)
9+
@maxLength(300)
10+
param apiDisplayName string
11+
12+
@description('Description of the API. May include HTML formatting tags.')
13+
@minLength(1)
14+
param apiDescription string
15+
16+
@description('Relative URL uniquely identifying this API and all of its resource paths within the API Management service instance. It is appended to the API endpoint base URL specified during the service instance creation to form a public URL for this API.')
17+
@minLength(1)
18+
param apiPath string
19+
20+
//@description('Absolute URL of the web frontend')
21+
//param webFrontendUrl string
22+
23+
@description('Absolute URL of the backend service implementing this API.')
24+
param apiBackendUrl string
25+
26+
@description('Resource name for backend Web App or Function App')
27+
param apiAppName string = ''
28+
29+
//var apiPolicyContent = replace(loadTextContent('apim-api-policy.xml'), '{origin}', webFrontendUrl)
30+
31+
resource restApi 'Microsoft.ApiManagement/service/apis@2021-12-01-preview' = {
32+
name: apiName
33+
parent: apimService
34+
properties: {
35+
description: apiDescription
36+
displayName: apiDisplayName
37+
path: apiPath
38+
protocols: [ 'https' ]
39+
subscriptionRequired: false
40+
type: 'http'
41+
format: 'openapi'
42+
serviceUrl: apiBackendUrl
43+
value: string(loadJsonContent('../../src/api/API_BUSINESS_PARTNER.openapi.json'))
44+
}
45+
}
46+
47+
/*resource apiPolicy 'Microsoft.ApiManagement/service/apis/policies@2021-12-01-preview' = {
48+
name: 'policy'
49+
parent: restApi
50+
properties: {
51+
format: 'rawxml'
52+
value: apiPolicyContent
53+
}
54+
}
55+
56+
resource apiDiagnostics 'Microsoft.ApiManagement/service/apis/diagnostics@2021-12-01-preview' = {
57+
name: 'applicationinsights'
58+
parent: restApi
59+
properties: {
60+
alwaysLog: 'allErrors'
61+
backend: {
62+
request: {
63+
body: {
64+
bytes: 1024
65+
}
66+
}
67+
response: {
68+
body: {
69+
bytes: 1024
70+
}
71+
}
72+
}
73+
frontend: {
74+
request: {
75+
body: {
76+
bytes: 1024
77+
}
78+
}
79+
response: {
80+
body: {
81+
bytes: 1024
82+
}
83+
}
84+
}
85+
httpCorrelationProtocol: 'W3C'
86+
logClientIp: true
87+
loggerId: apimLogger.id
88+
metrics: true
89+
sampling: {
90+
percentage: 100
91+
samplingType: 'fixed'
92+
}
93+
verbosity: 'verbose'
94+
}
95+
}*/
96+
97+
resource apimService 'Microsoft.ApiManagement/service@2021-08-01' existing = {
98+
name: name
99+
}
100+
101+
// Necessary due to https://github.com/Azure/bicep/issues/9594
102+
// placeholderName is never deployed, it is merely used to make the child name validation pass
103+
var appNameForBicep = !empty(apiAppName) ? apiAppName : 'placeholderName'
104+
105+
resource apiAppProperties 'Microsoft.Web/sites/config@2022-03-01' = if (!empty(apiAppName)) {
106+
name: '${appNameForBicep}/web'
107+
kind: 'string'
108+
properties: {
109+
apiManagementConfig: {
110+
id: '${apimService.id}/apis/${apiName}'
111+
}
112+
}
113+
}
114+
115+
/*resource apimLogger 'Microsoft.ApiManagement/service/loggers@2021-12-01-preview' existing = {
116+
name: 'app-insights-logger'
117+
parent: apimService
118+
}*/
119+
120+
output SERVICE_API_URI string = '${apimService.properties.gatewayUrl}/${apiPath}'

infra/main.bicep

+29-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@ param appServicePlanName string = ''
2020
param keyVaultName string = ''
2121
param logAnalyticsName string = ''
2222
param resourceGroupName string = ''
23+
param apimResourceGroupName string = 'DEMO-NEU-SAP-PM1'
24+
param apimServiceName string = 'demo-sap-apim'
25+
26+
@description('Flag to use Azure API Management to mediate the calls between the Web frontend and the SAP backend API')
27+
param useAPIM bool = true
2328

2429
// Name of the SKU; default is F1 (Free), use B1 (Basic) for features like health checks and S1 (Standard) for production
2530
@description('Name of the SKU of the App Service Plan')
26-
param skuName string = 'F1'
31+
param skuName string = 'B1'
2732

2833
@description('Id of the user or app to assign application roles')
2934
param principalId string = ''
@@ -57,6 +62,12 @@ resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
5762
tags: tags
5863
}
5964

65+
//Reference the existing API Management instance from another resource group but same subscription
66+
resource apimrg 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
67+
name: apimResourceGroupName
68+
scope: subscription()
69+
}
70+
6071
// The application backend
6172
module api './app/api.bicep' = {
6273
name: 'api'
@@ -153,11 +164,27 @@ module monitoring './core/monitor/monitoring.bicep' = {
153164
}
154165
}
155166

167+
// Configures the API in the Azure API Management (APIM) service
168+
module apimApi './app/apim-api.bicep' = if (useAPIM) {
169+
name: 'apim-api-deployment'
170+
scope: apimrg
171+
params: {
172+
name: useAPIM ? apimServiceName : ''
173+
apiName: 'api-business-partner'
174+
apiDisplayName: 'API_BUSINESS_PARTNER'
175+
apiDescription: 'Business Partner residing on SAP ERP exposed via OData'
176+
apiPath: 'sdk/sap/opu/odata/sap/API_BUSINESS_PARTNER'
177+
apiBackendUrl: api.outputs.SERVICE_API_URI
178+
apiAppName: api.outputs.SERVICE_API_NAME
179+
}
180+
}
181+
156182
// App outputs
157183
output APPLICATIONINSIGHTS_CONNECTION_STRING string = monitoring.outputs.applicationInsightsConnectionString
158184
output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.endpoint
159185
output AZURE_KEY_VAULT_NAME string = keyVault.outputs.name
160186
output AZURE_LOCATION string = location
161187
output AZURE_TENANT_ID string = tenant().tenantId
162-
output SAP_CLOUD_SDK_API_URL string = api.outputs.SERVICE_API_URI
188+
output USE_APIM bool = useAPIM
189+
output SAP_CLOUD_SDK_API_URL array = useAPIM ? [ apimApi.outputs.SERVICE_API_URI, api.outputs.SERVICE_API_URI ]: []
163190
output SAP_CLOUD_SDK_API_APPLICATIONINSIGHTS_CONNECTION_STRING string = monitoring.outputs.applicationInsightsConnectionString

src/api/API_BUSINESS_PARTNER.openapi.json

+1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)