Skip to content

Commit 5414cb6

Browse files
Merge branch 'develop' into RefactoringStaticClass
2 parents 2739ee2 + e9cc167 commit 5414cb6

12 files changed

Lines changed: 1650 additions & 630 deletions

File tree

.github/workflows/deploy_and_Integration_test.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,17 @@ jobs:
176176
clientSecret="${{ env.CLIENT_SECRET }}"
177177
username="${{ secrets.CF_USER }}"
178178
password="${{ secrets.CF_PASSWORD }}"
179+
noSDMRoleUsername="${{ secrets.NOSDMROLEUSERNAME }}"
180+
noSDMRoleUserPassword="${{ secrets.NOSDMROLEUSERPASSWORD }}"
179181
# Ensure all required variables are set
180182
if [ -z "$appUrl" ]; then echo "Error: appUrl is not set"; exit 1; fi
181183
if [ -z "$authUrl" ]; then echo "Error: authUrl is not set"; exit 1; fi
182184
if [ -z "$clientID" ]; then echo "Error: clientID is not set"; exit 1; fi
183185
if [ -z "$clientSecret" ]; then echo "Error: clientSecret is not set"; exit 1; fi
184186
if [ -z "$username" ]; then echo "Error: username is not set"; exit 1; fi
185187
if [ -z "$password" ]; then echo "Error: password is not set"; exit 1; fi
188+
if [ -z "$noSDMRoleUsername" ]; then echo "Error: noSDMRoleUsername is not set"; exit 1; fi
189+
if [ -z "$noSDMRoleUserPassword" ]; then echo "Error: noSDMRoleUserPassword is not set"; exit 1; fi
186190
# Function to partially mask sensitive information for logging
187191
mask() {
188192
local value="$1"
@@ -200,10 +204,12 @@ jobs:
200204
clientSecret=$clientSecret
201205
username=$username
202206
password=$password
207+
noSDMRoleUsername=$noSDMRoleUsername
208+
noSDMRoleUserPassword=$noSDMRoleUserPassword
203209
EOL
204210
# Run Maven integration tests
205-
mvn clean verify -P integration-tests -DtokenFlow=technicalUser -DskipUnitTests || { echo "Maven tests failed for Technical User Flow"; exit 1; }
206-
mvn clean verify -P integration-tests -DtokenFlow=namedUser -DskipUnitTests || { echo "Maven tests failed for Named User Flow"; exit 1; }
211+
mvn clean verify -P integration-tests -DtokenFlow=namedUser -DtenancyModel=single -DskipUnitTests || { echo "Maven tests failed for Technical User Flow"; exit 1; }
212+
mvn clean verify -P integration-tests -DtokenFlow=technicalUser -DtenancyModel=single -DskipUnitTests || { echo "Maven tests failed for Named User Flow"; exit 1; }
207213
208214

209215

.github/workflows/integration_test.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,16 @@ jobs:
9191
clientSecret="${{ env.CLIENT_SECRET }}"
9292
username="${{ secrets.CF_USER }}"
9393
password="${{ secrets.CF_PASSWORD }}"
94-
94+
noSDMRoleUsername="${{ secrets.NOSDMROLEUSERNAME }}"
95+
noSDMRoleUserPassword="${{ secrets.NOSDMROLEUSERPASSWORD }}"
9596
if [ -z "$appUrl" ]; then echo "Error: appUrl is not set"; exit 1; fi
9697
if [ -z "$authUrl" ]; then echo "Error: authUrl is not set"; exit 1; fi
9798
if [ -z "$clientID" ]; then echo "Error: clientID is not set"; exit 1; fi
9899
if [ -z "$clientSecret" ]; then echo "Error: clientSecret is not set"; exit 1; fi
99100
if [ -z "$username" ]; then echo "Error: username is not set"; exit 1; fi
100101
if [ -z "$password" ]; then echo "Error: password is not set"; exit 1; fi
102+
if [ -z "$noSDMRoleUsername" ]; then echo "Error: noSDMRoleUsername is not set"; exit 1; fi
103+
if [ -z "$noSDMRoleUserPassword" ]; then echo "Error: noSDMRoleUserPassword is not set"; exit 1; fi
101104
102105
mask() {
103106
local value="$1"
@@ -115,8 +118,10 @@ jobs:
115118
clientSecret=$clientSecret
116119
username=$username
117120
password=$password
121+
noSDMRoleUsername=$noSDMRoleUsername
122+
noSDMRoleUserPassword=$noSDMRoleUserPassword
118123
EOL
119124
120125
# Run Maven integration tests
121-
mvn clean verify -P integration-tests -DtokenFlow=technicalUser -DskipUnitTests || { echo "Maven tests failed for Technical User Flow"; exit 1; }
122-
mvn clean verify -P integration-tests -DtokenFlow=namedUser -DskipUnitTests || { echo "Maven tests failed for Named User Flow"; exit 1; }
126+
mvn clean verify -P integration-tests -DtokenFlow=namedUser -DtenancyModel=single -DskipUnitTests || { echo "Maven tests failed for Technical User Flow"; exit 1; }
127+
mvn clean verify -P integration-tests -DtokenFlow=technicalUser -DtenancyModel=single -DskipUnitTests || { echo "Maven tests failed for Named User Flow"; exit 1; }

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
44
This project adheres to [Semantic Versioning](http://semver.org/).
55
The format is based on [Keep a Changelog](http://keepachangelog.com/).
66

7+
## Version 1.4.0
8+
9+
### Added
10+
- Support technical user flow.
11+
- Support codelist for custom properties.
12+
13+
### Fixed
14+
- An issue where attachments uploaded with one repository was visible when application is redeployed with another repository.
15+
716
## Version 1.3.1
817

918
### Fixed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ This plugin can be consumed by the CAP application deployed on BTP to store thei
1515
- Display attachments specific to repository: Lists attachments contained in the repository that is configured with the CAP application.
1616
- Maximum allowed uploads: Provides the capability to define the maximum number of uploads allowed for the user.
1717
- Multiple attachment facets: Provides the capability to define multiple attachment facets/sections in the CAP Entity.
18+
- Technical user support: Provides the capability to consume the plugin using technical user.
1819

1920
## Table of Contents
2021

@@ -26,6 +27,7 @@ This plugin can be consumed by the CAP application deployed on BTP to store thei
2627
- [Support for Custom Properties](#support-for-custom-properties)
2728
- [Support for Maximum allowed uploads](#support-for-maximum-allowed-uploads)
2829
- [Support for Multiple attachment facets](#support-for-multiple-attachment-facets)
30+
- [Support for Technical user](#support-for-technical-user)
2931
- [Known Restrictions](#known-restrictions)
3032
- [Support, Feedback, Contributing](#support-feedback-contributing)
3133
- [Code of Conduct](#code-of-conduct)
@@ -465,6 +467,24 @@ Add the following facet in _fiori-service.cds_ in the _app_ folder. Refer the fo
465467
>
466468
> Once a facet or section name is defined in the CDS file, it is strongly recommended not to modify it. For instance, in the example provided, section names such as attachments, references, and footnotes should remain unchanged after initial configuration. Renaming these sections will result in the creation of new tables, causing any data associated with the original sections to become inaccessible in the UI.
467469
470+
## Support for technical user
471+
The CAP OData operations can be performed on attachments using a technical user. This flow can be used for machine-to-machine (M2M) interactions, where user involvement is not necessary.
472+
473+
A leading CAP application's service should add the requires with annotation "system-user". For more detailed information on "system-user" within the SAP CAP framework, refer to the [Capire documentation](https://cap.cloud.sap/docs/guides/security/authorization#pseudo-roles). Here is an [example](https://github.com/cap-java/sdm/blob/develop_deploy/cap-notebook/demoapp/srv/admin-service.cds) from a sample Bookshop app demonstrating the implementation.
474+
```cds
475+
service AdminService @(requires: ['admin', 'system-user'])
476+
```
477+
478+
The plugin supports technical users using oAuth 2.0 client credentials flow. Refer the following [example](https://github.com/cap-java/sdm/blob/a1bd1a0d829e6f25e4db349143b621757e0274d1/sdm/src/test/java/integration/com/sap/cds/sdm/IntegrationTest_SingleFacet.java#L80) of an OData call.
479+
```java
480+
request =
481+
new Request.Builder()
482+
.url(authUrl + "/oauth/token?grant_type=client_credentials")
483+
.method("POST", body)
484+
.addHeader("Authorization", basicAuth)
485+
.build();
486+
```
487+
468488
## Known Restrictions
469489

470490
- UI5 Version 1.135.0: This version causes error in upload of attachments.

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
</developers>
2424

2525
<properties>
26-
<revision>1.3.2-SNAPSHOT</revision>
26+
<revision>1.4.1-SNAPSHOT</revision>
2727
<java.version>17</java.version>
2828
<maven.compiler.source>${java.version}</maven.compiler.source>
2929
<maven.compiler.target>${java.version}</maven.compiler.target>

sdm/pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
<test-generation-folder>src/test/gen</test-generation-folder>
3535
<maven.compiler.source>17</maven.compiler.source>
3636
<maven.compiler.target>17</maven.compiler.target>
37-
<attachments_version>1.0.7</attachments_version>
37+
<attachments_version>1.0.9</attachments_version>
3838
<lombok.version>1.18.36</lombok.version>
3939
<jacoco.version>0.8.7</jacoco.version>
4040
<ehcache-version>3.10.8</ehcache-version>
@@ -114,6 +114,12 @@
114114
<groupId>org.apache.httpcomponents</groupId>
115115
<artifactId>httpasyncclient</artifactId>
116116
<version>${httpasyncclient-version}</version>
117+
<exclusions>
118+
<exclusion>
119+
<groupId>commons-logging</groupId>
120+
<artifactId>commons-logging</artifactId>
121+
</exclusion>
122+
</exclusions>
117123
</dependency>
118124
<!-- Log4j dependencies -->
119125
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->

sdm/src/test/java/integration/com/sap/cds/sdm/Api.java

Lines changed: 19 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,22 @@
66
import okhttp3.*;
77
import okio.ByteString;
88

9-
public class Api {
9+
public class Api implements ApiInterface {
1010
private final Map<String, String> config;
1111
private final OkHttpClient httpClient;
1212
private static final ObjectMapper objectMapper = new ObjectMapper();
1313
private final String token;
14+
private final String serviceName;
1415

1516
public Api(Map<String, String> config) {
1617
this.config = new HashMap<>(config);
1718
this.httpClient = new OkHttpClient();
1819
this.token = this.config.get("Authorization");
20+
this.serviceName = this.config.get("serviceName");
1921
}
2022

2123
public String createEntityDraft(
22-
String appUrl, String serviceName, String entityName, String entityName2, String srvpath) {
24+
String appUrl, String entityName, String entityName2, String srvpath) {
2325
MediaType mediaType = MediaType.parse("application/json");
2426

2527
// Creating the Entity (draft)
@@ -55,8 +57,7 @@ public String createEntityDraft(
5557
return ("Could not create entity");
5658
}
5759

58-
public String editEntityDraft(
59-
String appUrl, String serviceName, String entityName, String srvpath, String entityID) {
60+
public String editEntityDraft(String appUrl, String entityName, String srvpath, String entityID) {
6061
MediaType mediaType = MediaType.parse("application/json");
6162
Request request =
6263
new Request.Builder()
@@ -88,8 +89,7 @@ public String editEntityDraft(
8889
return "Could not edit entity";
8990
}
9091

91-
public String saveEntityDraft(
92-
String appUrl, String serviceName, String entityName, String srvpath, String entityID) {
92+
public String saveEntityDraft(String appUrl, String entityName, String srvpath, String entityID) {
9393
Request request =
9494
new Request.Builder()
9595
.url(
@@ -139,6 +139,10 @@ public String saveEntityDraft(
139139
System.out.println("Save entity failed. Error : " + draftResponseBodyString);
140140
return (draftResponseBodyString);
141141
}
142+
String sapMessages = draftResponse.header("sap-messages");
143+
if (sapMessages != null && !sapMessages.isEmpty()) {
144+
return sapMessages;
145+
}
142146
return "Saved";
143147
} catch (IOException e) {
144148
System.out.println("Could not save entity : " + e);
@@ -151,8 +155,7 @@ public String saveEntityDraft(
151155
return "Could not save entity";
152156
}
153157

154-
public String deleteEntity(
155-
String appUrl, String serviceName, String entityName, String entityID) {
158+
public String deleteEntity(String appUrl, String entityName, String entityID) {
156159
Request request =
157160
new Request.Builder()
158161
.url(
@@ -181,7 +184,7 @@ public String deleteEntity(
181184
return ("Could not delete entity");
182185
}
183186

184-
public String checkEntity(String appUrl, String serviceName, String entityName, String entityID) {
187+
public String checkEntity(String appUrl, String entityName, String entityID) {
185188
Request request =
186189
new Request.Builder()
187190
.url(
@@ -212,7 +215,6 @@ public String checkEntity(String appUrl, String serviceName, String entityName,
212215

213216
public List<String> createAttachment(
214217
String appUrl,
215-
String serviceName,
216218
String entityName,
217219
String facetName,
218220
String entityID,
@@ -354,12 +356,7 @@ public List<String> createAttachment(
354356
}
355357

356358
public String readAttachment(
357-
String appUrl,
358-
String serviceName,
359-
String entityName,
360-
String facetName,
361-
String entityID,
362-
String ID)
359+
String appUrl, String entityName, String facetName, String entityID, String ID)
363360
throws IOException {
364361
Request request =
365362
new Request.Builder()
@@ -387,11 +384,11 @@ public String readAttachment(
387384
Response response = httpClient.newCall(request).execute();
388385
if (!response.isSuccessful()) {
389386
System.out.println(
390-
"Read Attachnent failed in the"
387+
"Read Attachment failed in the"
391388
+ facetName
392389
+ " section. Error :"
393390
+ response.body().string());
394-
throw new IOException("Read Attachnent failed in the" + facetName + " section");
391+
throw new IOException("Read Attachment failed in the" + facetName + " section");
395392
}
396393
return "OK";
397394
} catch (IOException e) {
@@ -401,12 +398,7 @@ public String readAttachment(
401398
}
402399

403400
public String readAttachmentDraft(
404-
String appUrl,
405-
String serviceName,
406-
String entityName,
407-
String facetName,
408-
String entityID,
409-
String ID)
401+
String appUrl, String entityName, String facetName, String entityID, String ID)
410402
throws IOException {
411403
Request request =
412404
new Request.Builder()
@@ -444,12 +436,7 @@ public String readAttachmentDraft(
444436
}
445437

446438
public String deleteAttachment(
447-
String appUrl,
448-
String serviceName,
449-
String entityName,
450-
String facetName,
451-
String entityID,
452-
String ID) {
439+
String appUrl, String entityName, String facetName, String entityID, String ID) {
453440
Request request =
454441
new Request.Builder()
455442
.url(
@@ -487,13 +474,7 @@ public String deleteAttachment(
487474
}
488475

489476
public String renameAttachment(
490-
String appUrl,
491-
String serviceName,
492-
String entityName,
493-
String facetName,
494-
String entityID,
495-
String ID,
496-
String name) {
477+
String appUrl, String entityName, String facetName, String entityID, String ID, String name) {
497478
MediaType mediaType = MediaType.parse("application/json");
498479
RequestBody body =
499480
RequestBody.create(
@@ -537,7 +518,6 @@ public String renameAttachment(
537518

538519
public String updateSecondaryProperty(
539520
String appUrl,
540-
String serviceName,
541521
String entityName,
542522
String facetName,
543523
String entityID,
@@ -580,7 +560,6 @@ public String updateSecondaryProperty(
580560

581561
public String updateInvalidSecondaryProperty(
582562
String appUrl,
583-
String serviceName,
584563
String entityName,
585564
String facetName,
586565
String entityID,
@@ -624,12 +603,7 @@ public String updateInvalidSecondaryProperty(
624603
}
625604

626605
public Map<String, Object> fetchMetadata(
627-
String appUrl,
628-
String serviceName,
629-
String entityName,
630-
String facetName,
631-
String entityID,
632-
String ID)
606+
String appUrl, String entityName, String facetName, String entityID, String ID)
633607
throws IOException {
634608
// Construct the URL for fetching attachment metadata
635609
String url =

0 commit comments

Comments
 (0)