Skip to content

Commit 6a69d74

Browse files
[AV-68634] Developer Tutorial for Capella Operational (#329)
1 parent 5905e15 commit 6a69d74

36 files changed

+1150
-891
lines changed

antora.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,20 @@ version: ~
33
asciidoc:
44
attributes:
55
ui-name: Capella UI
6-
product-name: Capella
6+
product-name: Capella
7+
ext:
8+
preview:
9+
HEAD:
10+
sources:
11+
docs-capella:
12+
branches: [main]
13+
override:
14+
site:
15+
startPage: cloud:get-started:intro.adoc
16+
AV-68634-tutorial-feature-branch:
17+
sources:
18+
docs-capella:
19+
branches: [AV-68634-dev-tutorial-navigation]
20+
override:
21+
site:
22+
startPage: cloud:get-started:intro.adoc

modules/develop/pages/intro.adoc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@ It also provides links to the documentation for software development kits and ot
2525

2626
include::ROOT:partial$component-signpost.adoc[]
2727

28-
ifdef::flag-devex-tutorial[]
2928
== Developer Tutorial
3029

3130
This tutorial provides an introductory worked example for developers, showing how to use a software development kit with a simple database.
3231

3332
* xref:tutorials:couchbase-tutorial-student-records.adoc[]
34-
endif::flag-devex-tutorial[]
3533

3634
== Connect
3735

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import com.couchbase.client.core.error.CouchbaseException;
2+
import com.couchbase.client.java.Bucket;
3+
import com.couchbase.client.java.Cluster;
4+
import com.couchbase.client.java.Collection;
5+
import com.couchbase.client.java.Scope;
6+
import com.couchbase.client.java.json.JsonArray;
7+
import com.couchbase.client.java.json.JsonObject;
8+
import com.couchbase.client.java.query.QueryOptions;
9+
import com.couchbase.client.java.query.QueryResult;
10+
import com.couchbase.client.java.query.QueryScanConsistency;
11+
import com.couchbase.client.java.ClusterOptions;
12+
13+
import java.time.Duration;
14+
import java.time.LocalDate;
15+
import java.time.format.DateTimeFormatter;
16+
17+
public class AddEnrollments {
18+
19+
public static void main(String[] args) {
20+
21+
String connectionString = "<<connection-string>>"; // Replace this with Connection String
22+
String username = "<<username>>"; // Replace this with username from cluster access credentials
23+
String password = "<<password>>"; // Replace this with password from cluster access credentials
24+
25+
Cluster cluster = Cluster.connect(connectionString, ClusterOptions.clusterOptions(username, password)
26+
.environment(env -> env.applyProfile("wan-development"))
27+
);
28+
29+
// Retrieves the student bucket you set up.
30+
Bucket bucket = cluster.bucket("student-bucket");
31+
32+
// Forces the application to wait until the bucket is ready.
33+
bucket.waitUntilReady(Duration.ofSeconds(10));
34+
35+
// Retrieves the `art-school-scope` collection from the scope.
36+
Scope scope = bucket.scope("art-school-scope");
37+
Collection student_records = scope.collection("student-record-collection");
38+
39+
// Retrieves Hilary's student record, the `graphic design` course record, and the `art history` course record.
40+
// Each method uses a SQL++ call to retrieve a single record from each collection.
41+
JsonObject hilary = retrieveStudent(cluster,"Hilary Smith");
42+
JsonObject graphic_design = retrieveCourse(cluster, "graphic design");
43+
JsonObject art_history = retrieveCourse(cluster, "art history");
44+
45+
// Couchbase does not have a native date type, so the common practice is to store dates as strings.
46+
String currentDate = LocalDate.now().format(DateTimeFormatter.ISO_DATE);
47+
48+
// Stores the `enrollments` inside the student record as an array.
49+
// `JsonArray.create()` creates an empty list structure.
50+
JsonArray enrollments = JsonArray.create();
51+
52+
// Adds two JSON elements to the `enrollments` array: the course that the enrollment relates to, and the date that the student enrolled in the course.
53+
// To avoid repeating data all over the cluster, you store a reference to the course instead of the entire course record itself in this field.
54+
// This means that you do not have to search through every single record if the course details change.
55+
enrollments.add(JsonObject.create()
56+
.put("course-id", graphic_design.getString("id"))
57+
.put("date-enrolled", currentDate));
58+
enrollments.add(JsonObject.create()
59+
.put("course-id", art_history.getString("id"))
60+
.put("date-enrolled", currentDate));
61+
62+
// Adds the `enrollments` array to Hilary's student record.
63+
hilary.put("enrollments", enrollments);
64+
65+
// Commits the changes to the collection.
66+
// The `upsert` function call takes the key of the record you want to insert or update and the record itself as parameters.
67+
// If the `upsert` call finds a document with a matching ID in the collection, it updates the document.
68+
// If there is no matching ID, it creates a new document.
69+
student_records.upsert(hilary.getString("id"), hilary);
70+
71+
cluster.disconnect();
72+
73+
}
74+
75+
private static JsonObject retrieveStudent(Cluster cluster, String name) throws CouchbaseException {
76+
77+
QueryOptions studentQueryOptions = QueryOptions.queryOptions();
78+
studentQueryOptions.parameters(JsonObject.create().put("name", name));
79+
studentQueryOptions.scanConsistency(QueryScanConsistency.REQUEST_PLUS);
80+
81+
final QueryResult result = cluster.query("select META().id, src.* " +
82+
"from `student-bucket`.`art-school-scope`.`student-record-collection` src " +
83+
"where src.`name` = $name", studentQueryOptions);
84+
85+
return result.rowsAsObject().get(0);
86+
87+
}
88+
89+
private static JsonObject retrieveCourse(Cluster cluster, String course) throws CouchbaseException {
90+
91+
QueryOptions courseQueryOptions = QueryOptions.queryOptions();
92+
courseQueryOptions.parameters(JsonObject.create().put("courseName", course));
93+
courseQueryOptions.scanConsistency(QueryScanConsistency.REQUEST_PLUS);
94+
95+
final QueryResult result = cluster.query("select META().id, crc.* " +
96+
"from `student-bucket`.`art-school-scope`.`course-record-collection` crc " +
97+
"where crc.`course-name` = $courseName", courseQueryOptions);
98+
99+
return result.rowsAsObject().get(0);
100+
101+
}
102+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import com.couchbase.client.core.error.CouchbaseException;
2+
import com.couchbase.client.java.Cluster;
3+
import com.couchbase.client.java.json.JsonObject;
4+
import com.couchbase.client.java.query.QueryOptions;
5+
import com.couchbase.client.java.query.QueryResult;
6+
import com.couchbase.client.java.ClusterOptions;
7+
8+
public class ArtSchoolRetrieverParameters {
9+
10+
public static void main(String[] args) {
11+
12+
String connectionString = "<<connection-string>>"; // Replace this with Connection String
13+
String username = "<<username>>"; // Replace this with username from cluster access credentials
14+
String password = "<<password>>"; // Replace this with password from cluster access credentials
15+
16+
Cluster cluster = Cluster.connect(connectionString, ClusterOptions.clusterOptions(username, password)
17+
.environment(env -> env.applyProfile("wan-development"))
18+
);
19+
20+
21+
retrieveCourses(cluster);
22+
23+
cluster.disconnect();
24+
}
25+
26+
private static void retrieveCourses(Cluster cluster) {
27+
28+
try {
29+
30+
// This SQL++ statement takes the parameter `$creditPopints`,
31+
// which is then substituted by the value in the second parameter when the statement is called.
32+
final QueryResult result = cluster.query("select crc.* " +
33+
"from `student-bucket`.`art-school-scope`.`course-record-collection` crc " +
34+
"where crc.`credit-points` < $creditPoints",
35+
36+
// The second parameter in the function call, with a value that replaces `$creditPoints`.
37+
QueryOptions.queryOptions()
38+
.parameters(JsonObject.create().put("creditPoints", 200)));
39+
40+
for (JsonObject row : result.rowsAsObject()) {
41+
System.out.println("Found row: " + row);
42+
}
43+
44+
} catch (CouchbaseException ex) {
45+
ex.printStackTrace();
46+
}
47+
}
48+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import com.couchbase.client.core.error.CouchbaseException;
2+
import com.couchbase.client.java.Cluster;
3+
import com.couchbase.client.java.json.JsonObject;
4+
import com.couchbase.client.java.query.QueryResult;
5+
import com.couchbase.client.java.ClusterOptions;
6+
7+
public class ArtSchoolRetriever {
8+
9+
public static void main(String[] args) {
10+
11+
String connectionString = "<<connection-string>>"; // Replace this with Connection String
12+
String username = "<<username>>"; // Replace this with username from cluster access credentials
13+
String password = "<<password>>"; // Replace this with password from cluster access credentials
14+
15+
Cluster cluster = Cluster.connect(connectionString, ClusterOptions.clusterOptions(username, password)
16+
.environment(env -> env.applyProfile("wan-development"))
17+
);
18+
19+
retrieveCourses(cluster);
20+
21+
cluster.disconnect();
22+
}
23+
24+
private static void retrieveCourses(Cluster cluster) {
25+
26+
try {
27+
final QueryResult result = cluster.query("select crc.* from `student-bucket`.`art-school-scope`.`course-record-collection` crc");
28+
29+
for (JsonObject row : result.rowsAsObject()) {
30+
System.out.println("Found row: " + row);
31+
}
32+
33+
} catch (CouchbaseException ex) {
34+
ex.printStackTrace();
35+
}
36+
}
37+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import com.couchbase.client.java.Bucket;
2+
import com.couchbase.client.java.Cluster;
3+
import com.couchbase.client.java.Collection;
4+
import com.couchbase.client.java.Scope;
5+
import com.couchbase.client.java.ClusterOptions;
6+
import java.time.Duration;
7+
8+
public class ConnectStudent {
9+
10+
public static void main(String[] args) {
11+
12+
String connectionString = "<<connection-string>>"; // Replace this with Connection String
13+
String username = "<<username>>"; // Replace this with username from cluster access credentials
14+
String password = "<<password>>"; // Replace this with password from cluster access credentials
15+
16+
//Connecting to the cluster
17+
Cluster cluster = Cluster.connect(connectionString, ClusterOptions.clusterOptions(username, password)
18+
// Use the pre-configured profile below to avoid latency issues with your connection.
19+
.environment(env -> env.applyProfile("wan-development"))
20+
);
21+
22+
// The `cluster.bucket` retrieves the bucket you set up for the student cluster.
23+
Bucket bucket = cluster.bucket("student-bucket");
24+
25+
// Most of the Couchbase APIs are non-blocking.
26+
// When you call one of them, your application carries on and continues to perform other actions while the function you called executes.
27+
// When the function has finished executing, it sends a notification to the caller and the output of the call is processed.
28+
// While this usually works, in this code sample the application carries on without waiting for the bucket retrieval to complete after you make the call to `cluster.bucket`.
29+
// This means that you now have to try to retrieve the scope from a bucket object that has not been fully initialized yet.
30+
// To fix this, you can use the `waitUntilReady` call.
31+
// This call forces the application to wait until the bucket object is ready.
32+
bucket.waitUntilReady(Duration.ofSeconds(10));
33+
34+
// The `bucket.scope` retrieves the `art-school-scope` from the bucket.
35+
Scope scope = bucket.scope("art-school-scope");
36+
37+
// The `scope.collection` retrieves the student collection from the scope.
38+
Collection student_records = scope.collection("student-record-collection");
39+
40+
// A check to make sure the collection is connected and retrieved when you run the application.
41+
// You can see the output using maven.
42+
System.out.println("The name of this collection is " + student_records.name());
43+
44+
// Like with all database systems, it's good practice to disconnect from the Couchbase cluster after you have finished working with it.
45+
cluster.disconnect();
46+
}
47+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import com.couchbase.client.java.Bucket;
2+
import com.couchbase.client.java.Cluster;
3+
import com.couchbase.client.java.Collection;
4+
import com.couchbase.client.java.Scope;
5+
import com.couchbase.client.java.json.JsonObject;
6+
import com.couchbase.client.java.ClusterOptions;
7+
8+
import java.time.Duration;
9+
10+
public class InsertCourses {
11+
12+
public static void main(String[] args) {
13+
14+
String connectionString = "<<connection-string>>"; // Replace this with Connection String
15+
String username = "<<username>>"; // Replace this with username from cluster access credentials
16+
String password = "<<password>>"; // Replace this with password from cluster access credentials
17+
18+
Cluster cluster = Cluster.connect(connectionString, ClusterOptions.clusterOptions(username, password)
19+
.environment(env -> env.applyProfile("wan-development"))
20+
);
21+
22+
Bucket bucket = cluster.bucket("student-bucket");
23+
bucket.waitUntilReady(Duration.ofSeconds(10));
24+
Scope scope = bucket.scope("art-school-scope");
25+
26+
// The code here is similar to creating a student record, but it writes to a different collection.
27+
Collection course_records = scope.collection("course-record-collection");
28+
29+
addCourse(course_records, "ART-HISTORY-000001", "art history", "fine art", 100);
30+
addCourse(course_records, "FINE-ART-000002", "fine art", "fine art", 50);
31+
addCourse(course_records, "GRAPHIC-DESIGN-000003", "graphic design", "media and communication", 200);
32+
33+
cluster.disconnect();
34+
}
35+
36+
private static void addCourse(Collection collection, String id, String name,
37+
String faculty, int creditPoints) {
38+
39+
JsonObject course = JsonObject.create()
40+
.put("course-name", name)
41+
.put("faculty", faculty)
42+
.put("credit-points", creditPoints);
43+
44+
collection.upsert(id, course);
45+
46+
}
47+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import com.couchbase.client.java.Bucket;
2+
import com.couchbase.client.java.Cluster;
3+
import com.couchbase.client.java.Collection;
4+
import com.couchbase.client.java.Scope;
5+
import com.couchbase.client.java.json.JsonObject;
6+
import com.couchbase.client.java.ClusterOptions;
7+
8+
import java.time.Duration;
9+
import java.time.LocalDate;
10+
import java.time.format.DateTimeFormatter;
11+
12+
public class InsertStudent {
13+
14+
public static void main(String[] args) {
15+
16+
String connectionString = "<<connection-string>>"; // Replace this with Connection String
17+
String username = "<<username>>"; // Replace this with username from cluster access credentials
18+
String password = "<<password>>"; // Replace this with password from cluster access credentials
19+
20+
Cluster cluster = Cluster.connect(connectionString, ClusterOptions.clusterOptions(username, password)
21+
.environment(env -> env.applyProfile("wan-development"))
22+
);
23+
24+
Bucket bucket = cluster.bucket("student-bucket");
25+
bucket.waitUntilReady(Duration.ofSeconds(10));
26+
Scope scope = bucket.scope("art-school-scope");
27+
Collection student_records = scope.collection("student-record-collection");
28+
29+
// This `JsonObject` class creates and populates the student record.
30+
JsonObject hilary = JsonObject.create()
31+
.put("name", "Hilary Smith")
32+
.put("date-of-birth",
33+
LocalDate.of(1980, 12, 21)
34+
.format(DateTimeFormatter.ISO_DATE));
35+
36+
// The `upsert` function inserts or updates documents in a collection.
37+
// The first parameter is a unique ID for the document, similar to a primary key used in a relational database system.
38+
// If the `upsert` call finds a document with a matching ID in the collection, it updates the document.
39+
// If there is no matching ID, it creates a new document.
40+
student_records.upsert("000001", hilary);
41+
42+
cluster.disconnect();
43+
}
44+
}

0 commit comments

Comments
 (0)