Skip to content

Commit 0b0a041

Browse files
committed
upgraded spring boot and swagger from 2 to 3, fixed readme and added images, changed javax to jakarta. Used environment variables instead of hardcoding
1 parent e2b6a7c commit 0b0a041

23 files changed

+146
-195
lines changed

.github/workflows/tests.yaml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ jobs:
1212
run_tests:
1313
name: Run Tests
1414
runs-on: ubuntu-latest
15+
env:
16+
DB_CONN_STR: ${{ vars.DB_CONN_STR }}
17+
DB_USERNAME: ${{ vars.DB_USERNAME }}
18+
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
1519
strategy:
1620
matrix:
17-
java-version: ["8", "11", "17"]
21+
java-version: ["17", "21"]
1822
steps:
1923
- name: Update repositories
2024
run: |
@@ -30,15 +34,6 @@ jobs:
3034
distribution: "adopt"
3135
cache: "gradle"
3236

33-
- name: Replace secrets in application.properties
34-
run: |
35-
sed -i "s#DB_CONN_STR#${{ vars.DB_CONN_STR }}#g" src/main/resources/application.properties
36-
sed -i "s#DB_USERNAME#${{ vars.DB_USERNAME }}#g" src/main/resources/application.properties
37-
sed -i "s#DB_PASSWORD#${{ secrets.DB_PASSWORD }}#g" src/main/resources/application.properties
38-
39-
# Print the updated file for verification
40-
cat ./src/main/resources/application.properties
41-
4237
- name: Run Gradle Tests
4338
id: run
4439
run: |

Dockerfile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,8 @@ EXPOSE 8080
2222
# Run the application
2323
ENTRYPOINT ["java","-jar","/app/build/libs/java-springdata-quickstart-0.0.1-SNAPSHOT.jar"]
2424

25-
# docker build -t java-springdata-quickstart .
26-
# docker run -d --name springdata-container -p 9440:8080 java-springdata-quickstart
25+
# Build the image
26+
# docker build -t java-springdata-quickstart .
27+
28+
# Run the container
29+
# docker run -d --name springdata-container -p 9440:8080 java-springdata-quickstart -e DB_CONN_STR=<connection_string> -e DB_USERNAME=<username> -e DB_PASSWORD=<password>

README.md

Lines changed: 56 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ To run this prebuilt project, you will need:
1515

1616
- [Couchbase Capella](https://www.couchbase.com/products/capella/) cluster with [travel-sample](https://docs.couchbase.com/java-sdk/current/ref/travel-app-data-model.html) bucket loaded.
1717
- To run this tutorial using a self-managed Couchbase cluster, please refer to the [appendix](#running-self-managed-couchbase-cluster).
18-
- [Java 1.8 or higher](https://www.oracle.com/java/technologies/javase-downloads.html)
18+
- [Java 17 or higher](https://www.oracle.com/java/technologies/javase-downloads.html)
1919
- Ensure that the Java version is compatible with the Couchbase SDK.
2020
- Loading Travel Sample Bucket
2121
If travel-sample is not loaded in your Capella cluster, you can load it by following the instructions for your Capella Cluster:
@@ -65,116 +65,90 @@ spring.couchbase.bucket.password=DB_PASSWORD
6565
spring.couchbase.scope.name=inventory
6666
spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER
6767
```
68-
69-
Instead of the hash symbols, you need to add the values for the Couchbase connection.
68+
Instead of DB_CONN_STR, DB_USERNAME, and DB_PASSWORD, you should replace these with the connection string, username, and password for your Couchbase cluster. The connection string is the URL of your cluster. For example, if you are using Capella, the connection string will look like `couchbases://cb.jnym5s9gv4ealbe.cloud.couchbase.com`. If you are using a local cluster, the connection string will be `localhost`.
7069

7170
> Note: The connection string expects the `couchbases://` or `couchbase://` part.
7271
7372

7473
## Cluster Connection Configuration
7574
Spring Data couchbase connector can be configured by providing a `@Configuration` [bean](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-definition) that extends [`AbstractCouchbaseConfiguration`](https://docs.spring.io/spring-data/couchbase/docs/current/api/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.html).
76-
The sample application provides a configuration bean that uses default couchbase login and password:
75+
7776
```java
77+
@Slf4j
7878
@Configuration
79+
@EnableCouchbaseRepositories
7980
public class CouchbaseConfiguration extends AbstractCouchbaseConfiguration {
8081

82+
@Value("#{systemEnvironment['DB_CONN_STR'] ?: '${spring.couchbase.bootstrap-hosts:localhost}'}")
83+
private String host;
84+
85+
@Value("#{systemEnvironment['DB_USERNAME'] ?: '${spring.couchbase.bucket.user:Administrator}'}")
86+
private String username;
87+
88+
@Value("#{systemEnvironment['DB_PASSWORD'] ?: '${spring.couchbase.bucket.password:password}'}")
89+
private String password;
90+
91+
@Value("${spring.couchbase.bucket.name:travel-sample}")
92+
private String bucketName;
93+
8194
@Override
8295
public String getConnectionString() {
83-
// capella
84-
// return "couchbases://cb.jnym5s9gv4ealbe.cloud.couchbase.com";
85-
86-
// localhost
87-
return "127.0.0.1"
96+
return host;
8897
}
8998

9099
@Override
91100
public String getUserName() {
92-
return "Administrator";
101+
return username;
93102
}
94103

95104
@Override
96105
public String getPassword() {
97-
return "password";
106+
return password;
98107
}
99108

100109
@Override
101110
public String getBucketName() {
102-
return "springdata_quickstart";
111+
return bucketName;
103112
}
104113

105-
...
106-
```
107-
> *from config/CouchbaseConfiguration.java*
108-
109-
This default configuration assumes that you have a locally running Couchbae server and uses standard administrative login and password for demonstration purpose.
110-
Applications deployed to production or staging environments should use less privileged credentials created using [Role-Based Access Control](https://docs.couchbase.com/go-sdk/current/concept-docs/rbac.html).
111-
Please refer to [Managing Connections using the Java SDK with Couchbase Server](https://docs.couchbase.com/java-sdk/current/howtos/managing-connections.html) for more information on Capella and local cluster connections.
112-
113-
## Let's Review the Code
114-
115-
### Airline Model
116-
117-
The `Airline` model is a simple POJO (Plain Old Java Object) that is used to represent the airline document in the travel-sample bucket. The `@Id` annotation is used to specify the document ID in the bucket. The `@Field` annotation is used to specify the field name in the document. The `@TypeAlias` annotation is used to specify the type of the document in the bucket.
118-
119-
```java
120-
@Document
121-
@Scope("inventory")
122-
@Collection("airline")
123-
public class Airline {
124-
125-
@Id
126-
private String id;
127-
128-
@Field("callsign")
129-
private String callsign;
130-
131-
@Field("country")
132-
private String country;
133-
134-
@Field("iata")
135-
private String iata;
136-
137-
@Field("icao")
138-
private String icao;
139-
140-
@Field("name")
141-
private String name;
142-
143-
@Field("type")
144-
private String type;
145-
146-
@Field("active")
147-
private boolean active;
148-
149-
...
150-
```
151-
> *from model/Airline.java*
152-
153-
The `@Document` annotation is used to specify that this class is a document in the bucket. The `@Scope` annotation is used to specify the scope of the document. The `@Collection` annotation is used to specify the collection of the document.
154-
155-
The `@Id` annotation is used to specify the document ID in the bucket. The `@Field` annotation is used to specify the field name in the document. The `@TypeAlias` annotation is used to specify the type of the document in the bucket.
156-
157-
You can find more information on key generation in the [Connector Documentation](https://docs.spring.io/spring-data/couchbase/docs/current/reference/html/#couchbase.autokeygeneration).
158-
159-
Couchbase Spring Data connector will automatically serialize model instances into JSON when storing them on the cluster.
114+
@Override
115+
public String typeKey() {
116+
return "type";
117+
}
160118

161-
## Document Structure
119+
@Override
120+
@Bean(destroyMethod = "disconnect")
121+
public Cluster couchbaseCluster(ClusterEnvironment couchbaseClusterEnvironment) {
122+
try {
123+
log.debug("Connecting to Couchbase cluster at " + host);
124+
return Cluster.connect(getConnectionString(), getUserName(), getPassword());
125+
} catch (Exception e) {
126+
log.error("Error connecting to Couchbase cluster", e);
127+
throw e;
128+
}
129+
}
162130

163-
The `Airline` document is stored in the `airline` collection in the `travel-sample` bucket. The document has the following structure:
131+
@Bean
132+
public Bucket getCouchbaseBucket(Cluster cluster) {
133+
try {
134+
if (!cluster.buckets().getAllBuckets().containsKey(getBucketName())) {
135+
log.error("Bucket with name {} does not exist. Creating it now", getBucketName());
136+
throw new BucketNotFoundException(bucketName);
137+
}
138+
return cluster.bucket(getBucketName());
139+
} catch (Exception e) {
140+
log.error("Error getting bucket", e);
141+
throw e;
142+
}
143+
}
164144

165-
```json
166-
{
167-
"callsign": "AMERICAN",
168-
"country": "United States",
169-
"iata": "AA",
170-
"icao": "AAL",
171-
"id": 10,
172-
"name": "American Airlines",
173-
"type": "airline",
174-
"active": true
175145
}
176146
```
147+
> *from config/CouchbaseConfiguration.java*
177148
149+
This default configuration assumes that you have a locally running Couchbae server and uses standard administrative login and password for demonstration purpose.
150+
Applications deployed to production or staging environments should use less privileged credentials created using [Role-Based Access Control](https://docs.couchbase.com/go-sdk/current/concept-docs/rbac.html).
151+
Please refer to [Managing Connections using the Java SDK with Couchbase Server](https://docs.couchbase.com/java-sdk/current/howtos/managing-connections.html) for more information on Capella and local cluster connections.
178152

179153
## Running The Application
180154

@@ -212,11 +186,11 @@ Note: The `application.properties` file has the connection information to connec
212186

213187
Once the application starts, you can see the details of the application on the logs.
214188

215-
![Application Startup](app_startup.png)
189+
![Application Startup](./assets/images/app-startup-spring-data.png)
216190

217191
The application will run on port 8080 of your local machine (http://localhost:8080). You will find the interactive Swagger documentation of the API if you go to the URL in your browser. Swagger documentation is used in this demo to showcase the different API endpoints and how they can be invoked. More details on the Swagger documentation can be found in the [appendix](#swagger-documentation).
218192

219-
![Swagger Documentation](swagger_documentation.png)
193+
![Swagger Documentation](./assets/images/swagger-documentation-spring-data.png)
220194

221195
## Running Tests
222196

@@ -232,7 +206,7 @@ gradle test
232206

233207
For this quickstart, we use three collections, `airport`, `airline` and `routes` that contain sample airports, airlines and airline routes respectively. The routes collection connects the airports and airlines as seen in the figure below. We use these connections in the quickstart to generate airports that are directly connected and airlines connecting to a destination airport. Note that these are just examples to highlight how you can use SQL++ queries to join the collections.
234208

235-
![travel-sample data model](travel_sample_data_model.png)
209+
![travel-sample data model](./assets/images/travel_sample_data_model.png)
236210

237211
### Extending API by Adding New Entity
238212

@@ -268,6 +242,3 @@ You can try out an API by clicking on the "Try it out" button next to the endpoi
268242
#### Models
269243

270244
Swagger documents the structure of request and response bodies using models. These models define the expected data structure using JSON schema and are extremely helpful in understanding what data to send and expect.
271-
272-
## Conclusion
273-
Setting up a basic REST API in Spring Data with Couchbase is fairly simple. This project, when run with Couchbase Server 7 installed creates a collection in Couchbase, an index for our parameterized [N1QL query](https://docs.couchbase.com/java-sdk/current/howtos/n1ql-queries-with-sdk.html), and showcases basic CRUD operations needed in most applications.
724 KB
Loading
603 KB
Loading
66.7 KB
Loading

build.gradle

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
plugins {
2-
id 'org.springframework.boot' version '2.7.18'
3-
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
2+
id 'org.springframework.boot' version '3.2.2'
3+
id 'io.spring.dependency-management' version '1.1.0'
44
id 'java'
55
}
66

77
group = 'org.couchbase.quickstart.springdata'
88
version = '0.0.1-SNAPSHOT'
9-
sourceCompatibility = '1.8'
10-
targetCompatibility = '1.8'
119
archivesBaseName = 'java-springdata-quickstart'
1210

1311
repositories {
@@ -24,22 +22,20 @@ dependencies {
2422
implementation 'org.springframework.boot:spring-boot-starter-data-couchbase'
2523
implementation 'org.springframework.boot:spring-boot-starter-web'
2624
implementation 'org.springframework.data:spring-data-couchbase'
27-
2825
implementation 'org.springframework.boot:spring-boot-devtools'
26+
27+
implementation 'jakarta.persistence:jakarta.persistence-api'
28+
implementation 'jakarta.servlet:jakarta.servlet-api'
29+
2930
// lombok
3031
compileOnly 'org.projectlombok:lombok'
3132
annotationProcessor 'org.projectlombok:lombok'
3233
testCompileOnly 'org.projectlombok:lombok:'
3334
testAnnotationProcessor 'org.projectlombok:lombok'
3435

35-
// swagger
36-
implementation 'io.swagger.core.v3:swagger-annotations'
37-
implementation 'org.springdoc:springdoc-openapi-ui:1.6.15'
36+
// swagger 3 springdoc openapi 2
37+
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
3838

39-
// implementation "io.springfox:springfox-boot-starter:${swaggerVersion}"
40-
// implementation "io.springfox:springfox-spring-web:${springWebVersion}"
41-
// implementation "io.springfox:springfox-swagger2:${swaggerVersion}"
42-
// implementation "io.springfox:springfox-swagger-ui:${swaggerVersion}"
4339

4440
testImplementation 'org.springframework.boot:spring-boot-starter-test'
4541
}

src/main/java/org/couchbase/quickstart/springdata/Application.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package org.couchbase.quickstart.springdata;
22

3+
import static org.couchbase.quickstart.springdata.config.SpringDocConstants.DESCRIPTION;
4+
import static org.couchbase.quickstart.springdata.config.SpringDocConstants.TITLE;
5+
import static org.couchbase.quickstart.springdata.config.SpringDocConstants.VERSION;
6+
37
import org.springframework.boot.CommandLineRunner;
48
import org.springframework.boot.SpringApplication;
59
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -13,27 +17,26 @@
1317

1418
/**
1519
* This example application demonstrates using
16-
* Spring Data with Couchbase.
20+
* Spring Data with Couchbase.
1721
**/
1822

1923
@Slf4j
2024
@SpringBootApplication(exclude = SecurityAutoConfiguration.class, proxyBeanMethods = false)
21-
@OpenAPIDefinition(info = @Info(title = "Quickstart in Couchbase with Spring Data", version = "2.0", description = "<html><body><h2>A quickstart API using Java and Spring Data with Couchbase and travel-sample data</h2><p>We have a visual representation of the API documentation using Swagger which allows you to interact with the API's endpoints directly through the browser. It provides a clear view of the API including endpoints, HTTP methods, request parameters, and response objects.</p><p>Click on an individual endpoint to expand it and see detailed information. This includes the endpoint's description, possible response status codes, and the request parameters it accepts.</p><p><strong>Trying Out the API</strong></p><p>You can try out an API by clicking on the \"Try it out\" button next to the endpoints.</p><ul><li><strong>Parameters:</strong> If an endpoint requires parameters, Swagger UI provides input boxes for you to fill in. This could include path parameters, query strings, headers, or the body of a POST/PUT request.</li><li><strong>Execution:</strong> Once you've inputted all the necessary parameters, you can click the \"Execute\" button to make a live API call. Swagger UI will send the request to the API and display the response directly in the documentation. This includes the response code, response headers, and response body.</li></ul><p><strong>Models</strong></p><p>Swagger documents the structure of request and response bodies using models. These models define the expected data structure using JSON schema and are extremely helpful in understanding what data to send and expect.</p><p>For details on the API, please check the tutorial on the Couchbase Developer Portal: <a href=\"https://developer.couchbase.com/tutorial-quickstart-java-spring-boot\">https://developer.couchbase.com/tutorial-quickstart-java-spring-boot</a></p></body></html>"))
25+
@OpenAPIDefinition(info = @Info(title = TITLE, version = VERSION, description = DESCRIPTION))
2226
public class Application implements CommandLineRunner {
23-
27+
2428
@Override
2529
public void run(String... args) throws Exception {
2630
log.info("Application started successfully");
2731
}
32+
2833
public static void main(String[] args) {
2934
SpringApplication.run(Application.class, args);
3035
}
3136

32-
3337
@Bean
3438
ForwardedHeaderFilter forwardedHeaderFilter() {
3539
return new ForwardedHeaderFilter();
3640
}
3741

38-
3942
}

0 commit comments

Comments
 (0)