1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-01-16 05:16:08 +02:00

Invalidate cache for neo deployments (#2209)

* Add additional parameters for invalidating cache

* Fetch bearer token

* Fetch x-csrf token

* Add echo for testing

* Add echo

* Add another echo

* Check status

* Debug

* Clean up

* Throw exception

* Code review changes

* Review changes

* Add test

* Fix tests

* Fetch bearer token

* Fetch x-csrf token

* Add echo for testing

* Add echo

* Add another echo

* Check status

* Debug

* Resolve conflicts

* Resolve conflicts

* Code review changes

* Review changes

* fix conflicts

* Fix indent

* Add new parameter to define portal landscape region

* Add default value for new param

* Fix test

* Remove example

Co-authored-by: Oliver Feldmann <oliver.feldmann@sap.com>

* Check cache invalidation for html5 apps

* Add nesting

Co-authored-by: Oliver Feldmann <oliver.feldmann@sap.com>

* Add docu for invalidating cache for html5 apps (#2306)

* Add docu for invalidating cache for html5 apps

* Improve content

* Docu review changes

* Remove heading

Co-authored-by: Sarah Lendle <44202907+SarahLendle@users.noreply.github.com>

* Update documentation/docs/steps/neoDeploy.md

Co-authored-by: Sarah Lendle <44202907+SarahLendle@users.noreply.github.com>

Co-authored-by: Sarah Lendle <44202907+SarahLendle@users.noreply.github.com>

Co-authored-by: Oliver Feldmann <oliver.feldmann@sap.com>
Co-authored-by: Sarah Lendle <44202907+SarahLendle@users.noreply.github.com>
This commit is contained in:
Srinikitha Kondreddy 2020-11-09 12:15:00 +01:00 committed by GitHub
parent e859ed3375
commit 0234e4908c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 185 additions and 5 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -54,3 +54,46 @@ steps:
account: <myDeployAccount>
host: hana.example.org
```
## Example for invalidating the cache
Set the parameter `invalidateCache` to `true` to clean up the cache of an SAP Fiori launchpad site by refreshing the content of HTML5 applications deployed in it.
**Note:** This section is only applicable for HTML5 applications accessed through an SAP Fiori launchpad site.
Setting this parameter to `true` requires additional configuration:
### Create an OAuth credential
1. In your subaccount, choose **OAuth**.
![OAuth client creation](../images/oauthClientCreation.png)
2. In the **Subscription** field, select the portal landscape to which you would like to subscribe, for example, `portal/nwc` or `portal/sandbox`.
![Portal subscription](../images/portalSubscription.png)
3. From the drop-down menu in the **Authorization Grant** field, choose **Client Credentials**.
4. In the **Secret** field, enter a user-defined password and save your changes.
5. In Jenkins, create new username/password credentials. As username, use the client ID and as password, use the client secret.
### Configure the site ID
When you're logged in to the portal service, you can retrieve the site ID. Either configure it in your configuration file or set the site as default through the **Site Directory** tile.
If you don't set it as default, configure the parameter `siteId` as follows in your configuration file:
```yaml
steps:
<...>
neoDeploy:
neo:
account: <myDeployAccount>
host: hana.example.org
credentialsId: 'my-credentials-id'
invalidateCache: true
portalLandscape: "cloudnwcportal"
oauthCredentialId: <OAUTH_CREDENTIAL_ID>
siteId: <PORTAL_SITE_ID> # not required, if the default site is already set in the portal service (SAP Cloud Platform)
```

View File

@ -333,6 +333,7 @@ steps:
neo:
size: 'lite'
credentialsId: 'CI_CREDENTIALS_ID'
portalLandscape: "cloudnwcportal"
multicloudDeploy:
cfTargets: []
neoTargets: []

View File

@ -3,9 +3,12 @@ import com.sap.piper.Utils
import groovy.lang.Script
import hudson.AbortException
import util.JenkinsReadJsonRule
import static org.hamcrest.Matchers.allOf
import static org.hamcrest.Matchers.contains
import static org.hamcrest.Matchers.containsString
import static org.hamcrest.Matchers.hasItem
import static org.hamcrest.Matchers.not
import static org.junit.Assert.assertThat
@ -52,7 +55,9 @@ class NeoDeployTest extends BasePiperTest {
.around(shellRule)
.around(new JenkinsCredentialsRule(this)
.withCredentials('myCredentialsId', 'anonymous', '********')
.withCredentials('CI_CREDENTIALS_ID', 'defaultUser', '********'))
.withCredentials('CI_CREDENTIALS_ID', 'defaultUser', '********')
.withCredentials('testOauthId', 'clientId', '********'))
.around(new JenkinsReadJsonRule(this))
.around(stepRule)
.around(new JenkinsLockRule(this))
.around(new JenkinsWithEnvRule(this))
@ -417,6 +422,43 @@ class NeoDeployTest extends BasePiperTest {
}
@Test
void invalidateCache_Success_Test() {
nullScript.commonPipelineEnvironment.configuration = [steps: [neoDeploy: [neo: [host: 'test.deploy.host.com', account: 'trialuser123', invalidateCache: true, oauthCredentialId: 'testOauthId', siteId: "12346"]]]]
fileExistsRule.registerExistingFile('./target/artifact.war')
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, "https:\\/\\/oauthasservices-trialuser123\\.test\\.deploy\\.host\\.com\\/oauth2\\/api\\/v1\\/token", "{\"access_token\":\"xxx\"}")
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, "fiori\\/api\\/v1\\/csrf", "X-CSRF-Token=xxx")
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, "fiori\\/v1\\/operations\\/invalidateCache", "{\"statusCode\":\"200\"}")
stepRule.step.neoDeploy(script: nullScript,
source: archiveName,
deployMode: 'mta')
Assert.assertThat(shellRule.shell, hasItem(containsString("curl -X POST -u \"clientId:********\" --fail \"https://oauthasservices-trialuser123.test.deploy.host.com/oauth2/api/v1/token?grant_type=client_credentials&scope=write,read")))
Assert.assertThat(shellRule.shell[3], containsString("#!/bin/bash curl -i -L -c 'cookies.jar' -H 'X-CSRF-Token: Fetch' -H \"Authorization: Bearer xxx\" --fail \"https://cloudnwcportal-trialuser123.test.deploy.host.com/fiori/api/v1/csrf\""))
}
@Test
void invalidateCache_notPerformed_warFiles() {
nullScript.commonPipelineEnvironment.configuration = [steps: [neoDeploy: [neo: [host: 'test.deploy.host.com', account: 'trialuser123', invalidateCache: true]]]]
stepRule.step.neoDeploy(script: nullScript,
neo: [
application: 'testApp',
runtime: 'neo-javaee6-wp',
runtimeVersion: '2.125',
size: 'lite',
],
deployMode: 'warParams',
warAction: 'deploy',
source: warArchiveName)
assertThat(loggingRule.log, containsString("Invalidation of cache is ignored. It is performed only for html5 applications."))
}
@Test
void warFileParamsDeployModeTest() {

View File

@ -41,7 +41,7 @@ import static com.sap.piper.Prerequisites.checkScript
* @mandatory for deployMode=warParams
*/
'host',
/**
/**
* The path to the .properties file in which all necessary deployment properties for the application are defined.
* @parentConfigKey neo
* @mandatory for deployMode=warPropertiesFile
@ -59,16 +59,37 @@ import static com.sap.piper.Prerequisites.checkScript
* @mandatory for deployMode=warParams
*/
'runtimeVersion',
/**
/**
* Compute unit (VM) size. Acceptable values: lite, pro, prem, prem-plus.
* @parentConfigKey neo
*/
'size',
/**
/**
* String of VM arguments passed to the JVM.
* @parentConfigKey neo
*/
'vmArguments'
'vmArguments',
/**
* Boolean to enable/disable invalidating the cache after deployment.
* @possibleValues `true`, `false`
* @parentConfigKey neo
*/
'invalidateCache',
/**
* Portal landscape region subscribed to in SAP Cloud Platform.
* @parentConfigKey neo
*/
'portalLandscape',
/**
* UsernamePassword type credential containing SAP Cloud Platform OAuth client ID and client secret.
* @parentConfigKey neo
*/
'oauthCredentialId',
/**
* Site ID of the SAP Fiori Launchpad containing the SAP Fiori app. If not set, the cache of the default site, as defined in the Portal service, is invalidated.
* @parentConfigKey neo
*/
'siteId'
]
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
@ -216,11 +237,84 @@ void call(parameters = [:]) {
lock("$STEP_NAME:${neoCommandHelper.resourceLock()}") {
deploy(script, configuration, neoCommandHelper, configuration.dockerImage, deployMode)
}
if(configuration.neo.invalidateCache == true) {
if (configuration.deployMode == 'mta') {
echo "Triggering invalidation of cache for html5 applications"
invalidateCache(configuration)
} else {
echo "Invalidation of cache is ignored. It is performed only for html5 applications."
}
}
}
}
}
}
private invalidateCache(configuration){
def account = configuration.neo.account
def host = configuration.neo.host
def portalLandscape = configuration.neo.portalLandscape
withCredentials([usernamePassword(
credentialsId: configuration.neo.oauthCredentialId,
passwordVariable: 'OAUTH_NEO_CLIENT_SECRET',
usernameVariable: 'OAUTH_NEO_CLIENT_ID')]) {
def bearerTokenResponse = sh(
script: """#!/bin/bash
curl -X POST -u "${OAUTH_NEO_CLIENT_ID}:${OAUTH_NEO_CLIENT_SECRET}" \
--fail \
"https://oauthasservices-${account}.${host}/oauth2/api/v1/token?grant_type=client_credentials&scope=write,read"
""",
returnStdout: true)
def bearerToken = readJSON(text: bearerTokenResponse).access_token
echo "Retrieved bearer token."
def fetchXcsrfTokenResponse = sh(
script: """#!/bin/bash
curl -i -L \
-c 'cookies.jar' \
-H 'X-CSRF-Token: Fetch' \
-H "Authorization: Bearer ${bearerToken}" \
--fail \
"https://${portalLandscape}-${account}.${host}/fiori/api/v1/csrf"
""",
returnStdout: true)
def xcsrfToken = readProperties(text: fetchXcsrfTokenResponse)["X-CSRF-Token"]
def siteId = configuration.neo.siteId ?: ""
if(! siteId){
echo "Using the default site defined in Portal service and invalidating the cache."
}
else{
echo "Invalidating the cache for site with Id: ${siteId}."
}
def statusCode = sh(
script: """#!/bin/bash
curl -X POST -L \
-b 'cookies.jar' \
-H "X-CSRF-Token: ${xcsrfToken}" \
-H "Authorization: Bearer ${bearerToken}" \
-d "{\"siteId\":${siteId}}" \
-so /dev/null \
-w '%{response_code}' \
"https://${portalLandscape}-${account}.${host}/fiori/v1/operations/invalidateCache"
""",
returnStdout: true).trim()
if(! siteId && statusCode == "500") {
error "Invalidating the cache failed. " +
"As no siteId is set, the default site defined in the portal UI is used. " +
"Please verify a default site is defined in Portal service. " +
"Alternatively, configure the siteId parameter for this step to invalidate the cache of that specific site."
} else if(! statusCode == "200" || ! statusCode == "201" ){
error "Invalidating the cache failed with response code: ${statusCode}."
}
echo "Successfully invalidated the cache."
}
}
private deploy(script, Map configuration, NeoCommandHelper neoCommandHelper, dockerImage, DeployMode deployMode) {
String logFolder = "logs/neo/${UUID.randomUUID()}"