Skip to content

Commit 2dfa43e

Browse files
author
Oracle Public Cloud User
committed
Spring Boot example (work in progress)
1 parent b3fff3f commit 2dfa43e

File tree

11 files changed

+450
-0
lines changed

11 files changed

+450
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target/

MongoExamples/SpringBoot/README.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Microservice Example using Spring Boot and the Autonomous JSON Database
2+
3+
This directory contains an example of how to create a SpringBoot microservice using the Autonomous Database. Spring Boot is a popular Java framework that can be used to create REST services with minimal coding. See [Spring Boot](https://spring.io/projects/spring-boot).
4+
5+
# Prerequisites
6+
7+
This example works best if you run it from an OCI compute node what is in the same data center as the Autonomous Database it is connecting to. Instructions on how to create an Autonomous Database and a compute node can be found here: [Using Oracle Database API for MongoDB](https://oracle.github.io/learning-library/data-management-library/database/json/mongodb-api/workshops/freetier/index.html).
8+
* Lab 1 - shows how to create a compute node. The compute node used in this lab can also be used to run this SpringBoot example.
9+
* Lab 2 - shows how to provision an Autonomous JSON Database.
10+
* Lab 3 - shows how to connect to your database from the compute node using `mongosh`
11+
12+
Note an *always-free* database and compute node are sufficient to run this example.
13+
14+
# Loading Data
15+
16+
This example service accesses real data from a bike sharing company. Oracle is not affiliated with this company. We use their data in this example because they have cleanly exposed JSON data about their bike sharing stations (see [https://github.com/NABSA/gbfs/blob/master/gbfs.md](https://github.com/NABSA/gbfs/blob/master/gbfs.md))
17+
18+
Specifically, this example uses two of their data sets:
19+
20+
* *stations* - JSON data about each bike sharing station including things like its name, location, maximum capacity, etc.
21+
* *status* - JSON data about the current state of a bike sharing station and includes data like the current number of bikes available.
22+
23+
To initially load these data sets, we will use `mongoimport`. You can obtain mongoimport as follows:
24+
25+
```
26+
wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel70-x86_64-100.5.2.tgz
27+
tar -xvf mongodb-database-tools-rhel70-x86_64-100.5.2.tgz
28+
export PATH="`pwd`/mongodb-database-tools-rhel70-x86_64-100.5.2/bin/:$PATH"
29+
```
30+
31+
Run the following commands on your compute node:
32+
33+
```
34+
# substitute the actual URI of your database
35+
export URI=mongodb://XXXYYYZZZ-DEMODB.adb.us-ashburn-1.oraclecloudapps.com:27017/admin?authMechanism=PLAIN&authSource=$external&ssl=true&retryWrites=false&loadBalanced=true
36+
37+
# use jq (https://stedolan.github.io/jq/) to unwrap the nested documents and change
38+
# the station_id field to _id
39+
curl https://gbfs.citibikenyc.com/gbfs/en/station_information.json | \
40+
jq -c '.data.stations[] | .["_id"] = .["station_id"] | del(.station_id)' | \
41+
mongoimport -u ADMIN -p <password> --collection station --uri $URI
42+
43+
curl https://gbfs.citibikenyc.com/gbfs/en/station_status.json | \
44+
jq -c '.data.stations[]' | \
45+
mongoimport -u ADMIN -p <password> --collection status --uri $URI
46+
47+
```
48+
49+
If successful, you should have two collections in your database: station and status. Note, you may want to run the status command a few times over time to get more interesting (varying) data to work with. The data loaded is the state of the stations at the time the command is run.
50+
51+
# Viewing the data
52+
53+
You can view the data you just loaded in a web browser using Database Actions ([Lab 4](https://oracle.github.io/learning-library/data-management-library/database/json/mongodb-api/workshops/freetier/index.html?lab=dbactions)) or from the command line using `mongosh` ([Lab 3](https://oracle.github.io/learning-library/data-management-library/database/json/mongodb-api/workshops/freetier/index.html?lab=mongoshell)). For example:
54+
55+
```
56+
mongosh -u ADMIN -p <password> $URI
57+
admin> show collections
58+
station
59+
status
60+
61+
admin> db.station.find({_id:120})
62+
[
63+
{
64+
_id: '120',
65+
region_id: '71',
66+
lon: -73.95928168,
67+
...
68+
69+
admin> db.station.updateOne({_id:120}, {$set:{capacity:24}});
70+
...
71+
admin> db.station.find({_id:120});
72+
```
73+
74+
# Building the service
75+
76+
[todo]
77+
78+
# Running the service
79+
80+
[todo]
81+
82+
83+

MongoExamples/SpringBoot/pom.xml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<parent>
4+
<groupId>org.springframework.boot</groupId>
5+
<artifactId>spring-boot-starter-parent</artifactId>
6+
<version>2.6.5</version>
7+
<relativePath />
8+
</parent>
9+
<groupId>com.oracle.database.mongo.example</groupId>
10+
<artifactId>SpringBoot</artifactId>
11+
<version>0.0.1</version>
12+
<properties>
13+
<java.version>16</java.version>
14+
</properties>
15+
<dependencies>
16+
<dependency>
17+
<groupId>org.springframework.boot</groupId>
18+
<artifactId>spring-boot-starter-data-mongodb</artifactId>
19+
</dependency>
20+
<dependency>
21+
<groupId>org.springframework.boot</groupId>
22+
<artifactId>spring-boot-starter-web</artifactId>
23+
</dependency>
24+
<dependency>
25+
<groupId>org.springframework.boot</groupId>
26+
<artifactId>spring-boot-starter-data-rest</artifactId>
27+
</dependency>
28+
</dependencies>
29+
<build>
30+
<plugins>
31+
<plugin>
32+
<groupId>org.springframework.boot</groupId>
33+
<artifactId>spring-boot-maven-plugin</artifactId>
34+
</plugin>
35+
</plugins>
36+
</build>
37+
</project>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package example;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
6+
7+
@SpringBootApplication
8+
@EnableMongoRepositories
9+
public class App {
10+
11+
public static void main(String[] args) {
12+
SpringApplication.run(App.class, args);
13+
}
14+
15+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package example;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.data.mongodb.MongoDatabaseFactory;
6+
import org.springframework.data.mongodb.MongoTransactionManager;
7+
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
8+
9+
import com.mongodb.client.MongoClient;
10+
import com.mongodb.client.MongoClients;
11+
12+
@Configuration
13+
public class AppConfig {
14+
15+
public @Bean MongoDatabaseFactory mongoClient() {
16+
String uri = "<connection string>";
17+
MongoClient client = MongoClients.create(uri);
18+
return new SimpleMongoClientDatabaseFactory(client, "admin");
19+
}
20+
21+
@Bean
22+
MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
23+
return new MongoTransactionManager(dbFactory);
24+
}
25+
26+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package example.control;
2+
3+
import static org.springframework.web.bind.annotation.RequestMethod.DELETE;
4+
5+
import org.springframework.data.rest.webmvc.RepositoryRestController;
6+
import org.springframework.transaction.TransactionStatus;
7+
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
8+
import org.springframework.transaction.support.TransactionTemplate;
9+
import org.springframework.web.bind.annotation.PathVariable;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.ResponseBody;
12+
13+
import example.repository.StationRepository;
14+
import example.repository.StatusRepository;
15+
16+
@RepositoryRestController
17+
public class StationController {
18+
19+
private final StationRepository stationRepo;
20+
21+
private final StatusRepository statusRepo;
22+
23+
private final TransactionTemplate transaction;
24+
25+
public StationController(StationRepository stationRepo, StatusRepository statusRepo,
26+
TransactionTemplate transaction) {
27+
this.stationRepo = stationRepo;
28+
this.statusRepo = statusRepo;
29+
this.transaction = transaction;
30+
}
31+
32+
@RequestMapping(method = DELETE, value = "/station/{id}")
33+
public @ResponseBody void getRentalUrls(@PathVariable String id) {
34+
transaction.execute(new TransactionCallbackWithoutResult() {
35+
@Override
36+
protected void doInTransactionWithoutResult(TransactionStatus status) {
37+
stationRepo.deleteById(id);
38+
statusRepo.deleteAllByStationId(id);
39+
}
40+
});
41+
}
42+
43+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package example.model;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
import org.springframework.data.annotation.Id;
7+
import org.springframework.data.mongodb.core.mapping.Document;
8+
9+
/**
10+
* Bike station
11+
*
12+
* @see https://github.com/NABSA/gbfs/blob/master/gbfs.md#station_information
13+
*/
14+
@Document("station")
15+
public class Station {
16+
17+
@Id
18+
String id;
19+
20+
String name;
21+
22+
String region_id;
23+
24+
double lon,lat;
25+
26+
boolean eightd_has_key_dispenser;
27+
28+
String legacy_id;
29+
30+
List<String> rental_methods;
31+
32+
String external_id;
33+
34+
int capacity;
35+
36+
String short_name;
37+
38+
boolean electric_bike_surcharge_waiver;
39+
40+
String station_type;
41+
42+
List<String> eightd_station_services;
43+
44+
boolean has_kiosk;
45+
46+
Map<String, String> rental_uris;
47+
48+
public Station() {
49+
50+
}
51+
52+
public String getId() {
53+
return id;
54+
}
55+
56+
public String getName() {
57+
return name;
58+
}
59+
60+
public String getRegion_id() {
61+
return region_id;
62+
}
63+
64+
public double getLon() {
65+
return lon;
66+
}
67+
68+
public double getLat() {
69+
return lat;
70+
}
71+
72+
public boolean isEightd_has_key_dispenser() {
73+
return eightd_has_key_dispenser;
74+
}
75+
76+
public String getLegacy_id() {
77+
return legacy_id;
78+
}
79+
80+
public List<String> getRental_methods() {
81+
return rental_methods;
82+
}
83+
84+
public String getExternal_id() {
85+
return external_id;
86+
}
87+
88+
public int getCapacity() {
89+
return capacity;
90+
}
91+
92+
public String getShort_name() {
93+
return short_name;
94+
}
95+
96+
public boolean isElectric_bike_surcharge_waiver() {
97+
return electric_bike_surcharge_waiver;
98+
}
99+
100+
public String getStation_type() {
101+
return station_type;
102+
}
103+
104+
public List<String> getEightd_station_services() {
105+
return eightd_station_services;
106+
}
107+
108+
public boolean isHas_kiosk() {
109+
return has_kiosk;
110+
}
111+
112+
public Map<String, String> getRental_uris() {
113+
return rental_uris;
114+
}
115+
116+
}

0 commit comments

Comments
 (0)