├── .gitignore
├── .gitpod.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE.md
├── README.md
├── astra.json
├── hero.png
├── img
├── 01.png
├── 02.png
├── 03.png
├── 04.png
├── 05.png
└── 06.png
├── pom.xml
├── setup.sh
└── src
└── main
├── java
└── com
│ └── datastax
│ └── examples
│ ├── DataStaxAstraProperties.java
│ ├── SpringDataCassandraApplication.java
│ └── order
│ ├── Order.java
│ ├── OrderController.java
│ ├── OrderPrimaryKey.java
│ ├── OrderRepository.java
│ └── ProductNameAndPrice.java
└── resources
├── META-INF
└── additional-spring-configuration-metadata.json
├── application.yml
└── logback.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # eclipse conf file
2 | .settings
3 | .classpath
4 | .project
5 | .cache
6 |
7 | # idea conf files
8 | .idea
9 | *.ipr
10 | *.iws
11 | *.iml
12 |
13 | # building
14 | target
15 | build
16 | tmp
17 | dist
18 |
19 | # misc
20 | .DS_Store
21 | .factorypath
22 |
--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 | image: gitpod/workspace-full
2 | tasks:
3 | - init: mvn package
4 | command: . setup.sh && java -jar target/spring-data-example-1.0.0-SNAPSHOT.jar
5 | ports:
6 | - port: 8081
7 | onOpen: open-browser
8 | github:
9 | prebuilds:
10 | master: true
11 | branches: false
12 | pullRequests: false
13 | pullRequestsFromForks: false
14 | addCheck: false
15 | addComment: false
16 | addBadge: false
17 | addLabel: false
18 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at . All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | When contributing to this repository, please first discuss the change you wish to make via issue,
4 | email, or any other method with the owners of this repository before making a change.
5 |
6 | Please note we have a [Code of Conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project.
7 |
8 | ## Found an Issue?
9 | If you find a bug in the source code or a mistake in the documentation, you can help us by
10 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can
11 | [submit a Pull Request](#submit-pr) with a fix.
12 |
13 | ## Want a Feature?
14 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub
15 | Repository. If you would like to *implement* a new feature, please submit an issue with
16 | a proposal for your work first, to be sure that we can use it.
17 |
18 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
19 |
20 | ## Contribution Guidelines
21 |
22 | ### Submitting an Issue
23 | Before you submit an issue, search the archive, maybe your question was already answered.
24 |
25 | If your issue appears to be a bug, and hasn't been reported, open a new issue.
26 | Help us to maximize the effort we can spend fixing issues and adding new
27 | features, by not reporting duplicate issues. Providing the following information will increase the
28 | chances of your issue being dealt with quickly:
29 |
30 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
31 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you
32 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps
33 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
34 | causing the problem (line of code or commit)
35 |
36 | ### Submitting a Pull Request (PR)
37 | Before you submit your Pull Request (PR) consider the following guidelines:
38 |
39 | * Search the repository (https://github.com/bechbd/[repository-name]/pulls) for an open or closed PR that relates to your submission. You don't want to duplicate effort.
40 |
41 | * Create a fork of the repo
42 | * Navigate to the repo you want to fork
43 | * In the top right corner of the page click **Fork**:
44 | 
45 |
46 | * Make your changes in the forked repo
47 | * Commit your changes using a descriptive commit message
48 | * In GitHub, create a pull request: https://help.github.com/en/articles/creating-a-pull-request-from-a-fork
49 | * If we suggest changes then:
50 | * Make the required updates.
51 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request):
52 |
53 | ```shell
54 | git rebase master -i
55 | git push -f
56 | ```
57 |
58 | That's it! Thank you for your contribution!
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM openjdk:11.0.7-jre-slim-buster
2 | EXPOSE 8081
3 | EXPOSE 8082
4 |
5 | WORKDIR /app
6 | ARG JAR=spring-data-example-1.0.0-SNAPSHOT.jar
7 |
8 | COPY /target/$JAR /app.jar
9 | ENTRYPOINT ["java","-jar","/app.jar"]
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Spring Data Cassandra REST API
3 | *10 minutes, Beginner, [Start Building](https://github.com/DataStax-Examples/spring-data-starter#prerequisites)*
4 |
5 | This application uses Spring Data Cassandra and DataStax Astra DB to build a REST API for a backend service that interacts with products and orders.
6 |
7 |
8 | 
9 |
10 | ## Objectives
11 | * Run a REST API that connects to DataStax Astra DB
12 |
13 | ## How this works
14 | We're using Spring Data Cassandra and Datastax Astra DB to build a REST API that stores Products and Orders.
15 |
16 | ## Get Started
17 | To build and play with this app, follow the build instructions that are located here: [https://github.com/DataStax-Examples/spring-data-starter](https://github.com/DataStax-Examples/spring-data-starter#prerequisites)
18 |
19 |
20 | # Running Spring Data Cassandra REST API
21 | Follow the instructions below to get started.
22 |
23 | ## Prerequisites
24 | Let's do some initial setup by creating a serverless(!) database.
25 |
26 | ### DataStax Astra
27 | 1. Create a [DataStax Astra account](https://dtsx.io/38HWu73) if you don't already have one:
28 | 
29 |
30 | 2. On the home page. Locate the button **`Create Database`** both vector and non-vector support the Cassandra CQL
31 | 
32 |
33 | 3. Populate the fields and click create database
34 | 
35 |
36 | 4. After your database is provisioned, we need to generate an Application Token for our App. Go to the `Settings` tab in the database home screen.
37 | 
38 |
39 | 5. Generate a token by clicking `Generate Token` and give it a name.
40 | 
41 |
42 | 6. After you have your Application Token, head to the database connect screen and select the driver connection that we need. Go ahead and download the `Secure Bundle` for the driver.
43 | 
44 |
45 | ### Github
46 | 1. Click `Use this template` at the top of the [GitHub Repository](https://github.com/DataStax-Examples/spring-data-starter):
47 | 
48 |
49 | 2. Enter a repository name and click 'Create repository from template':
50 | 
51 |
52 | 3. Clone the repository:
53 | 
54 |
55 | ## 🚀 Getting Started Paths:
56 | *Make sure you've completed the [prerequisites](#prerequisites) before starting this step*
57 | - [Running on Gitpod](#running-on-gitpod)
58 |
59 | ### Running on Gitpod
60 | 1. Click the 'Open in Gitpod' link:
61 | [](https://dtsx.io/2QjoULs)
62 |
63 | 2. Once your Gitpod workspace has loaded, you'll be asked to paste your service account credentials in the Gitpod terminal at the bottom of the screen:
64 | 
65 |
66 | 3. When the app is finished building, click the 'Open Browser' button on the bottom right of the screen:
67 | 
68 |
69 | 4. You've successfully build a Spring Data Cassandra application!
70 | 
71 |
72 |
--------------------------------------------------------------------------------
/astra.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Spring Data Astra DB REST API",
3 | "description": "This application uses Spring Data Cassandra and DataStax Astra DB to build a REST API for a backend service that interacts with products and orders.",
4 | "duration": "10 minutes",
5 | "skillLevel": "Beginner",
6 | "gitpodUrl": "https://dtsx.io/2QjoULs",
7 | "githubUrl": "https://github.com/DataStax-Examples/spring-data-starter",
8 | "tags": [{ "name": "java" }, { "name": "java driver" }],
9 | "category": "starters",
10 | "priority": 1,
11 | "heroImage": "https://raw.githubusercontent.com/DataStax-Examples/spring-data-starter/master/hero.png"
12 | }
13 |
--------------------------------------------------------------------------------
/hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataStax-Examples/spring-data-starter/331017bb6cc6c6a3ad4ea088c08f3800a57c13ba/hero.png
--------------------------------------------------------------------------------
/img/01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataStax-Examples/spring-data-starter/331017bb6cc6c6a3ad4ea088c08f3800a57c13ba/img/01.png
--------------------------------------------------------------------------------
/img/02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataStax-Examples/spring-data-starter/331017bb6cc6c6a3ad4ea088c08f3800a57c13ba/img/02.png
--------------------------------------------------------------------------------
/img/03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataStax-Examples/spring-data-starter/331017bb6cc6c6a3ad4ea088c08f3800a57c13ba/img/03.png
--------------------------------------------------------------------------------
/img/04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataStax-Examples/spring-data-starter/331017bb6cc6c6a3ad4ea088c08f3800a57c13ba/img/04.png
--------------------------------------------------------------------------------
/img/05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataStax-Examples/spring-data-starter/331017bb6cc6c6a3ad4ea088c08f3800a57c13ba/img/05.png
--------------------------------------------------------------------------------
/img/06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataStax-Examples/spring-data-starter/331017bb6cc6c6a3ad4ea088c08f3800a57c13ba/img/06.png
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.datastax.examples
8 | spring-data-example
9 | 1.0.0-SNAPSHOT
10 | Spring Boot & Spring Data Example
11 | Demo project for using Spring Boot, Spring Data Cassandra with DataStax Astra
12 |
13 |
14 | org.springframework.boot
15 | spring-boot-starter-parent
16 | 3.3.0
17 |
18 |
19 |
20 |
21 |
22 | UTF-8
23 | 21
24 |
25 |
26 | 4.17.0
27 | 1.4.11
28 | 1.8.0
29 |
30 |
31 | 3.0.0
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter-data-cassandra
41 |
42 |
43 | org.springframework.boot
44 | spring-boot-starter-data-rest
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-web
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-configuration-processor
53 | true
54 |
55 |
56 | org.springdoc
57 | springdoc-openapi-starter-webmvc-ui
58 | 2.5.0
59 |
60 |
61 | org.projectlombok
62 | lombok
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | org.apache.maven.plugins
71 | maven-compiler-plugin
72 |
73 | ${java.version}
74 | ${java.version}
75 | ${java.version}
76 | false
77 |
78 |
79 |
80 | org.springframework.boot
81 | spring-boot-maven-plugin
82 |
83 |
84 |
85 | org.springframework.boot
86 | spring-boot-configuration-processor
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/setup.sh:
--------------------------------------------------------------------------------
1 | echo "🚀 Go to https://astra.datastax.com/org/?create_service_account
2 | If you have not created a service account for your org click Actions -> Add Service Account. Then, click the copy icon and paste your service account credentials here: "
3 | read -r SERVICE_ACCOUNT
4 | export SERVICE_ACCOUNT="${SERVICE_ACCOUNT}"
5 |
6 | echo "Getting your Astra DevOps API token..."
7 | DEVOPS_TOKEN=$(curl -s --request POST \
8 | --url "https://api.astra.datastax.com/v2/authenticateServiceAccount" \
9 | --header 'content-type: application/json' \
10 | --data "$SERVICE_ACCOUNT" | jq -r '.token')
11 |
12 | echo "Getting databases..."
13 | DBS=$(curl -s --request GET \
14 | --url "https://api.astra.datastax.com/v2/databases?include=nonterminated&provider=all&limit=25" \
15 | --header "authorization: Bearer ${DEVOPS_TOKEN}" \
16 | --header 'content-type: application/json')
17 |
18 | # TODO: Allow the user to select the DB
19 | NUM_DBS=$(echo "${DBS}" | jq -c 'length')
20 | FIRST_DB_ID=$(echo "${DBS}" | jq -c '.[0].id')
21 | FIRST_DB_REGION=$(echo "${DBS}" | jq -c '.[0].info.region')
22 | FIRST_DB_USER=$(echo "${DBS}" | jq -c '.[0].info.user')
23 |
24 | # TODO: Allow the user to select a keyspace
25 | FIRST_DB_KEYSPACE=$(echo "${DBS}" | jq -c '.[0].info.keyspaces[0]')
26 | FIRST_DB_SECURE_BUNDLE_URL=$(echo "${DBS}" | jq -c '.[0].info.datacenters[0].secureBundleUrl')
27 |
28 | export ASTRA_SECURE_BUNDLE_URL=${FIRST_DB_SECURE_BUNDLE_URL}
29 | gp env ASTRA_SECURE_BUNDLE_URL=${FIRST_DB_SECURE_BUNDLE_URL} &>/dev/null
30 |
31 | # Download the secure connect bundle
32 | curl -s -L $(echo $FIRST_DB_SECURE_BUNDLE_URL | sed "s/\"//g") -o astra-creds.zip
33 |
34 | export ASTRA_DB_BUNDLE="astra-creds.zip"
35 | gp env ASTRA_DB_BUNDLE="astra-creds.zip" &>/dev/null
36 |
37 | export ASTRA_DB_USERNAME=$(echo ${FIRST_DB_USER} | sed "s/\"//g")
38 | gp env ASTRA_DB_USERNAME=$(echo ${FIRST_DB_USER} | sed "s/\"//g") &>/dev/null
39 |
40 | export ASTRA_DB_KEYSPACE=$(echo ${FIRST_DB_KEYSPACE} | sed "s/\"//g")
41 | gp env ASTRA_DB_KEYSPACE=$(echo ${FIRST_DB_KEYSPACE} | sed "s/\"//g") &>/dev/null
42 |
43 | export ASTRA_DB_ID=$(echo ${FIRST_DB_ID} | sed "s/\"//g")
44 | gp env ASTRA_DB_ID=$(echo ${FIRST_DB_ID} | sed "s/\"//g") &>/dev/null
45 |
46 | export ASTRA_DB_REGION=$(echo ${FIRST_DB_REGION} | sed "s/\"//g")
47 | gp env ASTRA_DB_REGION=$(echo ${FIRST_DB_REGION} | sed "s/\"//g") &>/dev/null
48 |
49 |
50 | echo "What is your Astra DB password? 🔒"
51 | read -s ASTRA_DB_PASSWORD
52 | export ASTRA_DB_PASSWORD=${ASTRA_DB_PASSWORD}
53 | gp env ASTRA_DB_PASSWORD=${ASTRA_DB_PASSWORD} &>/dev/null
54 |
55 | echo "You're all set 👌"
56 |
--------------------------------------------------------------------------------
/src/main/java/com/datastax/examples/DataStaxAstraProperties.java:
--------------------------------------------------------------------------------
1 | package com.datastax.examples;
2 |
3 | import java.io.File;
4 | import lombok.Getter;
5 | import lombok.Setter;
6 | import org.springframework.boot.context.properties.ConfigurationProperties;
7 |
8 | @ConfigurationProperties(prefix = "datastax.astra")
9 | @Getter
10 | @Setter
11 | public class DataStaxAstraProperties {
12 |
13 | private File secureConnectBundle;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/datastax/examples/SpringDataCassandraApplication.java:
--------------------------------------------------------------------------------
1 | package com.datastax.examples;
2 |
3 | import java.nio.file.Path;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.boot.autoconfigure.cassandra.CqlSessionBuilderCustomizer;
7 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
8 | import org.springframework.context.annotation.Bean;
9 |
10 | @SpringBootApplication
11 | @EnableConfigurationProperties(DataStaxAstraProperties.class)
12 | public class SpringDataCassandraApplication {
13 |
14 | public static void main(String[] args) {
15 | SpringApplication.run(SpringDataCassandraApplication.class, args);
16 | }
17 |
18 | @Bean
19 | public CqlSessionBuilderCustomizer sessionBuilderCustomizer(DataStaxAstraProperties astraProperties) {
20 | Path bundle = astraProperties.getSecureConnectBundle().toPath();
21 | return builder -> builder.withCloudSecureConnectBundle(bundle);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/datastax/examples/order/Order.java:
--------------------------------------------------------------------------------
1 | package com.datastax.examples.order;
2 |
3 | import lombok.Data;
4 | import org.springframework.data.cassandra.core.mapping.*;
5 |
6 | import java.io.Serializable;
7 | import java.time.Instant;
8 |
9 | @Table(value = "starter_orders")
10 | @Data
11 | public class Order implements Serializable {
12 |
13 | @PrimaryKey
14 | private OrderPrimaryKey key;
15 |
16 | @Column("product_quantity")
17 | @CassandraType(type = CassandraType.Name.INT)
18 | private Integer productQuantity;
19 |
20 | @Column("product_name")
21 | @CassandraType(type = CassandraType.Name.TEXT)
22 | private String productName;
23 |
24 | @CassandraType(type = CassandraType.Name.DECIMAL)
25 | @Column("product_price")
26 | private Float productPrice;
27 |
28 | @CassandraType(type = CassandraType.Name.TIMESTAMP)
29 | @Column("added_to_order_at")
30 | private Instant addedToOrderTimestamp;
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/datastax/examples/order/OrderController.java:
--------------------------------------------------------------------------------
1 | package com.datastax.examples.order;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.data.rest.webmvc.BasePathAwareController;
5 | import org.springframework.web.bind.annotation.*;
6 | import org.springframework.web.servlet.ModelAndView;
7 |
8 | import java.util.List;
9 | import java.util.UUID;
10 |
11 | @RestController
12 | public class OrderController {
13 |
14 | @Autowired
15 | private OrderRepository orderRepository;
16 |
17 | @RequestMapping(value = "/", method = RequestMethod.GET)
18 | public ModelAndView root() {
19 | return new ModelAndView("redirect:/swagger-ui.html");
20 | }
21 |
22 | // CREATE
23 |
24 | @PostMapping("orders")
25 | public Order createOrder(@RequestBody Order order) {
26 | return orderRepository.save(order);
27 | }
28 |
29 | // UPDATE
30 |
31 | @PutMapping("orders/{oid}/{pid}")
32 | public Order updateOrder(@PathVariable("oid") UUID oid, @PathVariable("pid") UUID pid, @RequestBody Order order) {
33 | order.getKey().setOrderId(oid);
34 | order.getKey().setProductId(pid);
35 | return orderRepository.save(order);
36 | }
37 |
38 | // DELETE
39 |
40 | @DeleteMapping("orders/{oid}/{pid}")
41 | public void deleteOrder(@PathVariable("oid") UUID oid, @PathVariable("pid") UUID pid) {
42 | orderRepository.deleteByKeyOrderIdAndKeyProductId(oid, pid);
43 | }
44 |
45 | @DeleteMapping("orders/{oid}")
46 | public void deleteOrders(@PathVariable("oid") UUID oid) {
47 | orderRepository.deleteByKeyOrderId(oid);
48 | }
49 |
50 | // FIND
51 |
52 | @GetMapping("orders/{oid}/{pid}")
53 | public ProductNameAndPrice findOrder(@PathVariable("oid") UUID oid, @PathVariable("pid") UUID pid) {
54 | return orderRepository.findByKeyOrderIdAndKeyProductId(oid, pid);
55 | }
56 |
57 | @GetMapping("orders/{oid}")
58 | public List findOrders(@PathVariable("oid") UUID oid) {
59 | return orderRepository.findByKeyOrderId(oid);
60 | }
61 |
62 | @GetMapping("orders")
63 | public List findAll() {
64 | return orderRepository.findAllProjectedBy();
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/com/datastax/examples/order/OrderPrimaryKey.java:
--------------------------------------------------------------------------------
1 | package com.datastax.examples.order;
2 |
3 | import lombok.Data;
4 | import org.springframework.data.cassandra.core.cql.PrimaryKeyType;
5 | import org.springframework.data.cassandra.core.mapping.PrimaryKeyClass;
6 | import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn;
7 |
8 | import java.io.Serializable;
9 | import java.util.UUID;
10 |
11 | @PrimaryKeyClass
12 | @Data
13 | public class OrderPrimaryKey implements Serializable {
14 |
15 | @PrimaryKeyColumn(name = "order_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
16 | private UUID orderId;
17 |
18 | @PrimaryKeyColumn(name = "product_id", ordinal = 1, type = PrimaryKeyType.CLUSTERED)
19 | private UUID productId;
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/datastax/examples/order/OrderRepository.java:
--------------------------------------------------------------------------------
1 | package com.datastax.examples.order;
2 |
3 | import org.springframework.data.cassandra.repository.CassandraRepository;
4 | import org.springframework.data.rest.core.annotation.RestResource;
5 | import org.springframework.stereotype.Repository;
6 |
7 | import java.util.List;
8 | import java.util.UUID;
9 |
10 | @Repository
11 | @RestResource(exported = false)
12 | public interface OrderRepository extends CassandraRepository {
13 |
14 | // DELETE
15 |
16 | void deleteByKeyOrderId(UUID orderId);
17 |
18 | void deleteByKeyOrderIdAndKeyProductId(UUID orderId, UUID productId);
19 |
20 | // FIND (all projected)
21 |
22 | ProductNameAndPrice findByKeyOrderIdAndKeyProductId(UUID orderId, UUID productId);
23 |
24 | List findByKeyOrderId(UUID orderId);
25 |
26 | List findAllProjectedBy();
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/src/main/java/com/datastax/examples/order/ProductNameAndPrice.java:
--------------------------------------------------------------------------------
1 | package com.datastax.examples.order;
2 |
3 | import org.springframework.data.rest.core.config.Projection;
4 |
5 | @Projection(name = "product-name-and-price", types = { Order.class })
6 | public interface ProductNameAndPrice {
7 | String getProductName();
8 | Float getProductPrice();
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/additional-spring-configuration-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "properties": [
3 | {
4 | "name": "datastax.astra.secure-connect-bundle",
5 | "type": "java.lang.String",
6 | "description": "An absolute path to the Astra secure connect bundle to use."
7 | }
8 | ] }
--------------------------------------------------------------------------------
/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: spring-data-service
4 | cassandra:
5 | username: token
6 | password: ${ASTRA_DB_PASSWORD}
7 | keyspace-name: ${ASTRA_DB_KEYSPACE}
8 | schema-action: CREATE_IF_NOT_EXISTS
9 | request:
10 | timeout: 10s
11 | connection:
12 | connect-timeout: 10s
13 | init-query-timeout: 10s
14 |
15 | server.port: 8081
16 |
17 | springdoc.swagger-ui.path: /swagger-ui.html
18 |
19 | datastax.astra:
20 | secure-connect-bundle: ${ASTRA_DB_BUNDLE}
--------------------------------------------------------------------------------
/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | %d{HH:mm:ss.SSS} %magenta(%-5level) %cyan(%-50logger) : %msg%n
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------