Skip to content

Commit 05114e6

Browse files
Feature toggles in sample (#205)
Adds feature toggles for sample. New field ISBN will be visible in "Browse Books" in single tenant mode and will not be visible in multitenant one. There is new template for role `ft_isbn_on` that allows to emulate feature toggle. There is an integration test with embedded sidecar. --------- Co-authored-by: Adrian Görler <[email protected]>
1 parent d4ec603 commit 05114e6

File tree

13 files changed

+265
-8
lines changed

13 files changed

+265
-8
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Framework and Infrastructure related Features:
5757
- [Cloud Foundry Deployment using MTA](https://cap.cloud.sap/docs/advanced/deploy-to-cloud#deploy-using-mta) with XSUAA [Service Bindings](mta-single-tenant.yaml)
5858
- Application Router configuration including authentication via the XSUAA Service. See [package.json](app/package.json), [xs-app.json](app/xs-app.json) and [xs-security.json](xs-security.json)
5959
- [Multitenancy configuration](https://cap.cloud.sap/docs/java/multitenancy) via [mta-multi-tenant.yaml](mta-multi-tenant.yaml), [.cdsrc.json](.cdsrc.json), [sidecar module](mtx-sidecar)
60+
- [Feature toggles](https://cap.cloud.sap/docs/guides/extensibility/feature-toggles?impl-variant=java#limitations). In CF, features can be toggled by assigning the roles `expert` or `premium-customer` to the user.
6061

6162
Domain Model related Features:
6263

app/_i18n/i18n.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,4 @@ AddReview = Add Review
6464
6565
Notes = Notes
6666
Note = Note
67+
ISBN = ISBN

app/_i18n/i18n_de.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,4 @@ AddReview = Rezension hinzufügen
6464

6565
Notes = Notizen
6666
Note = Notiz
67+
ISBN = ISBN

db/data/my.bookshop-Books.csv

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
ID;TITLE;DESCR;AUTHOR_ID;STOCK;PRICE;CURRENCY_CODE;GENRE_ID;RATING
2-
f846b0b9-01d4-4f6d-82a4-d79204f62278;Wuthering Heights;"Wuthering Heights, Emily Brontë's only novel, was published in 1847 under the pseudonym ""Ellis Bell"". It was written between October 1845 and June 1846. Wuthering Heights and Anne Brontë's Agnes Grey were accepted by publisher Thomas Newby before the success of their sister Charlotte's novel Jane Eyre. After Emily's death, Charlotte edited the manuscript of Wuthering Heights and arranged for the edited version to be published as a posthumous second edition in 1850.";335c7bcd-b826-4f14-a788-e0bf6738617a;12;11.11;GBP;11;4.5
3-
9b084139-0b1e-43b6-b12a-7b3669d75f02;Jane Eyre;"Jane Eyre /ɛər/ (originally published as Jane Eyre: An Autobiography) is a novel by English writer Charlotte Brontë, published under the pen name ""Currer Bell"", on 16 October 1847, by Smith, Elder & Co. of London. The first American edition was published the following year by Harper & Brothers of New York. Primarily a bildungsroman, Jane Eyre follows the experiences of its eponymous heroine, including her growth to adulthood and her love for Mr. Rochester, the brooding master of Thornfield Hall. The novel revolutionised prose fiction in that the focus on Jane's moral and spiritual development is told through an intimate, first-person narrative, where actions and events are coloured by a psychological intensity. The book contains elements of social criticism, with a strong sense of Christian morality at its core and is considered by many to be ahead of its time because of Jane's individualistic character and how the novel approaches the topics of class, sexuality, religion and feminism.";e3da2c2e-72ee-45d5-8def-52964c7b252a;11;12.34;GBP;11;3.0
4-
51061ce3-ddde-4d70-a2dc-6314afbcc73e;The Raven;"“The Raven"" is a narrative poem by American writer Edgar Allan Poe. First published in January 1845, the poem is often noted for its musicality, stylized language, and supernatural atmosphere. It tells of a talking raven's mysterious visit to a distraught lover, tracing the man's slow fall into madness. The lover, often identified as being a student, is lamenting the loss of his love, Lenore. Sitting on a bust of Pallas, the raven seems to further distress the protagonist with its constant repetition of the word ""Nevermore"". The poem makes use of folk, mythological, religious, and classical references.";e7643aae-2d2f-4656-bb2d-1328ad3c8045;333;13.13;USD;16;2.5
5-
aebdfc8a-0dfa-4468-bd36-48aabd65e663;Eleonora;"""Eleonora"" is a short story by Edgar Allan Poe, first published in 1842 in Philadelphia in the literary annual The Gift. It is often regarded as somewhat autobiographical and has a relatively ""happy"" ending.";e7643aae-2d2f-4656-bb2d-1328ad3c8045;555;14;USD;16;1.0
6-
4a519e61-3c3a-4bd9-ab12-d7e0c5329933;Catweazle;Catweazle is a British fantasy television series, starring Geoffrey Bayldon in the title role, and created by Richard Carpenter for London Weekend Television. The first series, produced and directed by Quentin Lawrence, was screened in the UK on ITV in 1970. The second series, directed by David Reid and David Lane, was shown in 1971. Each series had thirteen episodes, most but not all written by Carpenter, who also published two books based on the scripts.;3c081d9d-abda-4da9-8b6a-4f4555bb26bc;22;15;EUR;13;4.0
1+
ID;TITLE;DESCR;AUTHOR_ID;STOCK;PRICE;CURRENCY_CODE;GENRE_ID;RATING;ISBN
2+
f846b0b9-01d4-4f6d-82a4-d79204f62278;Wuthering Heights;"Wuthering Heights, Emily Brontë's only novel, was published in 1847 under the pseudonym ""Ellis Bell"". It was written between October 1845 and June 1846. Wuthering Heights and Anne Brontë's Agnes Grey were accepted by publisher Thomas Newby before the success of their sister Charlotte's novel Jane Eyre. After Emily's death, Charlotte edited the manuscript of Wuthering Heights and arranged for the edited version to be published as a posthumous second edition in 1850.";335c7bcd-b826-4f14-a788-e0bf6738617a;12;11.11;GBP;11;4.5;979-8698267973
3+
9b084139-0b1e-43b6-b12a-7b3669d75f02;Jane Eyre;"Jane Eyre /ɛər/ (originally published as Jane Eyre: An Autobiography) is a novel by English writer Charlotte Brontë, published under the pen name ""Currer Bell"", on 16 October 1847, by Smith, Elder & Co. of London. The first American edition was published the following year by Harper & Brothers of New York. Primarily a bildungsroman, Jane Eyre follows the experiences of its eponymous heroine, including her growth to adulthood and her love for Mr. Rochester, the brooding master of Thornfield Hall. The novel revolutionised prose fiction in that the focus on Jane's moral and spiritual development is told through an intimate, first-person narrative, where actions and events are coloured by a psychological intensity. The book contains elements of social criticism, with a strong sense of Christian morality at its core and is considered by many to be ahead of its time because of Jane's individualistic character and how the novel approaches the topics of class, sexuality, religion and feminism.";e3da2c2e-72ee-45d5-8def-52964c7b252a;11;12.34;GBP;11;3.0;979-8598716472
4+
51061ce3-ddde-4d70-a2dc-6314afbcc73e;The Raven;"“The Raven"" is a narrative poem by American writer Edgar Allan Poe. First published in January 1845, the poem is often noted for its musicality, stylized language, and supernatural atmosphere. It tells of a talking raven's mysterious visit to a distraught lover, tracing the man's slow fall into madness. The lover, often identified as being a student, is lamenting the loss of his love, Lenore. Sitting on a bust of Pallas, the raven seems to further distress the protagonist with its constant repetition of the word ""Nevermore"". The poem makes use of folk, mythological, religious, and classical references.";e7643aae-2d2f-4656-bb2d-1328ad3c8045;333;13.13;USD;16;2.5;978-1092909747
5+
aebdfc8a-0dfa-4468-bd36-48aabd65e663;Eleonora;"""Eleonora"" is a short story by Edgar Allan Poe, first published in 1842 in Philadelphia in the literary annual The Gift. It is often regarded as somewhat autobiographical and has a relatively ""happy"" ending.";e7643aae-2d2f-4656-bb2d-1328ad3c8045;555;14;USD;16;1.0;979-8669820985
6+
4a519e61-3c3a-4bd9-ab12-d7e0c5329933;Catweazle;Catweazle is a British fantasy television series, starring Geoffrey Bayldon in the title role, and created by Richard Carpenter for London Weekend Television. The first series, produced and directed by Quentin Lawrence, was screened in the UK on ITV in 1970. The second series, directed by David Reid and David Lane, was shown in 1971. Each series had thirteen episodes, most but not all written by Carpenter, who also published two books based on the scripts.;3c081d9d-abda-4da9-8b6a-4f4555bb26bc;22;15;EUR;13;4.0;978-3473523023

fts/isbn/schema.cds

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using {CatalogService} from '../../app/browse/fiori-service';
2+
using {my.bookshop as my} from '../../db/index';
3+
4+
5+
// domain model
6+
7+
extend my.Books with {
8+
isbn : String(40);
9+
}
10+
11+
// Feature 'isbn' will display ISBN in table and on object page
12+
annotate CatalogService.Books with @(UI: {
13+
FieldGroup #General: {Data: [
14+
...up to
15+
{Value: title},
16+
{
17+
Value: isbn,
18+
Label: '{i18n>ISBN}'
19+
},
20+
...
21+
]},
22+
LineItem: [
23+
...up to
24+
{Value: title},
25+
{
26+
Value: isbn,
27+
Label: '{i18n>ISBN}'
28+
},
29+
...
30+
]
31+
});

mtx/sidecar/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,16 @@
2424
}
2525
},
2626
"devDependencies": {
27-
"sqlite3": "^5"
27+
"sqlite3": "^5",
28+
"forever": "^4"
2829
},
2930
"engines": {
3031
"node": "^16"
3132
},
3233
"scripts": {
3334
"start": "cds run",
34-
"build": "npm install && npx cds build ../.. --for mtx-sidecar && cd gen && npm install"
35+
"build": "npm install && npx cds build ../.. --for mtx-sidecar && cd gen && npm install",
36+
"startAsync": "forever start -o out.log -e err.log -c node node_modules/@sap/cds/bin/cds.js run --profile development",
37+
"stopAsync": "forever stopall"
3538
}
3639
}

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@
101101
</configuration>
102102
</plugin>
103103

104+
<plugin>
105+
<groupId>org.apache.maven.plugins</groupId>
106+
<artifactId>maven-failsafe-plugin</artifactId>
107+
<version>3.0.0-M9</version>
108+
</plugin>
109+
104110
<!-- POM FLATTENING FOR CI FRIENDLY VERSIONS -->
105111
<plugin>
106112
<groupId>org.codehaus.mojo</groupId>

srv/pom.xml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
<name>bookshop</name>
1616

17+
<properties>
18+
<sidecar.dir>../mtx/sidecar</sidecar.dir>
19+
</properties>
20+
1721
<!-- ACTUAL DEPENDENCIES -->
1822
<dependencies>
1923
<!-- CDS DEPENDENCIES -->
@@ -204,8 +208,64 @@
204208
<basePackage>cds.gen</basePackage>
205209
</configuration>
206210
</execution>
211+
212+
<!-- Following steps start and stop MTX sidecar for tests executed by failsafe plugin -->
213+
<execution>
214+
<id>install-sidecar</id>
215+
<goals>
216+
<goal>npm</goal>
217+
</goals>
218+
<phase>pre-integration-test</phase>
219+
<configuration>
220+
<arguments>install</arguments>
221+
<skip>${skipTests}</skip>
222+
<workingDirectory>${sidecar.dir}</workingDirectory>
223+
</configuration>
224+
</execution>
225+
226+
<execution>
227+
<id>start-sidecar</id>
228+
<goals>
229+
<goal>npm</goal>
230+
</goals>
231+
<phase>pre-integration-test</phase>
232+
<configuration>
233+
<arguments>run startAsync</arguments>
234+
<skip>${skipTests}</skip>
235+
<workingDirectory>${sidecar.dir}</workingDirectory>
236+
</configuration>
237+
</execution>
238+
239+
<execution>
240+
<id>stop-sidecar</id>
241+
<goals>
242+
<goal>npm</goal>
243+
</goals>
244+
<phase>post-integration-test</phase>
245+
<configuration>
246+
<arguments>run stopAsync</arguments>
247+
<skip>${skipTests}</skip>
248+
<workingDirectory>${sidecar.dir}</workingDirectory>
249+
</configuration>
250+
</execution>
207251
</executions>
208252
</plugin>
253+
254+
<plugin>
255+
<!-- Tests ending with *IT.java will be executed here -->
256+
<groupId>org.apache.maven.plugins</groupId>
257+
<artifactId>maven-failsafe-plugin</artifactId>
258+
<executions>
259+
<execution>
260+
<id>integration-tests</id>
261+
<phase>integration-test</phase>
262+
<goals>
263+
<goal>integration-test</goal>
264+
</goals>
265+
</execution>
266+
</executions>
267+
</plugin>
268+
209269
</plugins>
210270
</build>
211271

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package my.bookshop;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
import org.springframework.context.annotation.Profile;
7+
import org.springframework.stereotype.Component;
8+
9+
import com.sap.cds.services.request.FeatureTogglesInfo;
10+
import com.sap.cds.services.request.ParameterInfo;
11+
import com.sap.cds.services.request.UserInfo;
12+
import com.sap.cds.services.runtime.FeatureTogglesInfoProvider;
13+
14+
// When application executed locally, the toggles can be switched via application.yaml
15+
@Component
16+
@Profile("cloud")
17+
public class FeatureToggleProvider implements FeatureTogglesInfoProvider {
18+
19+
@Override
20+
public FeatureTogglesInfo get(UserInfo userInfo, ParameterInfo parameterInfo) {
21+
Map<String, Boolean> toggles = new HashMap<>();
22+
toggles.put("isbn", userInfo.hasRole("expert"));
23+
toggles.put("discount", userInfo.hasRole("premium-customer"));
24+
return FeatureTogglesInfo.create(toggles);
25+
}
26+
}

srv/src/main/java/my/bookshop/handlers/CatalogServiceHandler.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import static cds.gen.catalogservice.CatalogService_.BOOKS;
44

5+
import java.math.BigDecimal;
6+
import java.math.RoundingMode;
57
import java.util.List;
68
import java.util.Optional;
79
import java.util.Set;
@@ -186,6 +188,17 @@ public void onSubmitOrder(SubmitOrderContext context) {
186188
}
187189
}
188190

191+
@After
192+
protected void addDiscount(CdsReadEventContext context) {
193+
if (context.getFeatureTogglesInfo().isEnabled("discount")) {
194+
context.getResult().listOf(Books.class).forEach(book -> {
195+
if (book.getPrice() != null) {
196+
book.setPrice(book.getPrice().multiply(BigDecimal.valueOf(0.9)).setScale(2, RoundingMode.FLOOR));
197+
}
198+
});
199+
}
200+
}
201+
189202
private void discountBooksWithMoreThan111Stock(Books b) {
190203
if (b.getStock() != null && b.getStock() > 111) {
191204
b.setTitle(String.format("%s -- 11%% discount", b.getTitle()));

0 commit comments

Comments
 (0)