General idea
This commit is contained in:
parent
139a1123f2
commit
7a0de46329
16
pom.xml
16
pom.xml
@ -146,8 +146,22 @@
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.28</version>
|
||||
<version>1.18.30</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>32.1.3-jre</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Databases -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-sync</artifactId>
|
||||
<version>4.11.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
20
src/main/java/me/braydon/feather/FeatherThreads.java
Normal file
20
src/main/java/me/braydon/feather/FeatherThreads.java
Normal file
@ -0,0 +1,20 @@
|
||||
package me.braydon.feather;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* The Feather thread pool. This is used by default
|
||||
* when executing tasks in asynchronous pipelines.
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
public final class FeatherThreads {
|
||||
private static final AtomicInteger ID = new AtomicInteger(0); // The thread id
|
||||
public static final ExecutorService THREAD_POOL = Executors.newFixedThreadPool(4, new ThreadFactoryBuilder()
|
||||
.setNameFormat("Feather Thread #" + (ID.incrementAndGet()))
|
||||
.build()); // The thread pool to execute on
|
||||
}
|
64
src/main/java/me/braydon/feather/IDatabase.java
Normal file
64
src/main/java/me/braydon/feather/IDatabase.java
Normal file
@ -0,0 +1,64 @@
|
||||
package me.braydon.feather;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
/**
|
||||
* Represents a database.
|
||||
*
|
||||
* @author Braydon
|
||||
* @param <B> the bootstrap class of this database
|
||||
* @param <A> the type of credentials this database uses
|
||||
* @param <P> the type of pipeline for this database
|
||||
* @param <AP> the type of async pipeline for this database
|
||||
*/
|
||||
public interface IDatabase<B, A, P, AP> extends Closeable {
|
||||
/**
|
||||
* Get the name of this database.
|
||||
*
|
||||
* @return the database name
|
||||
*/
|
||||
@NonNull String getName();
|
||||
|
||||
/**
|
||||
* Initialize a connection to this database.
|
||||
*
|
||||
* @param credentials the optional credentials to use
|
||||
*/
|
||||
void connect(A credentials);
|
||||
|
||||
/**
|
||||
* Check if this database is connected.
|
||||
*
|
||||
* @return the database connection state
|
||||
*/
|
||||
boolean isConnected();
|
||||
|
||||
/**
|
||||
* Get the bootstrap class
|
||||
* instance for this database.
|
||||
*
|
||||
* @return the bootstrap class instance, null if none
|
||||
* @see B for bootstrap class
|
||||
*/
|
||||
B getBootstrap();
|
||||
|
||||
/**
|
||||
* Get the synchronized
|
||||
* pipeline for this database.
|
||||
*
|
||||
* @return the synchronized pipeline
|
||||
* @see P for synchronized pipeline
|
||||
*/
|
||||
@NonNull P sync();
|
||||
|
||||
/**
|
||||
* Get the asynchronous
|
||||
* pipeline for this database.
|
||||
*
|
||||
* @return the asynchronous pipeline
|
||||
* @see AP for asynchronous pipeline
|
||||
*/
|
||||
@NonNull AP async();
|
||||
}
|
26
src/main/java/me/braydon/feather/Playground.java
Normal file
26
src/main/java/me/braydon/feather/Playground.java
Normal file
@ -0,0 +1,26 @@
|
||||
package me.braydon.feather;
|
||||
|
||||
import com.mongodb.ConnectionString;
|
||||
import me.braydon.feather.databases.mongodb.MongoDB;
|
||||
|
||||
/**
|
||||
* @author Braydon
|
||||
*/
|
||||
public final class Playground {
|
||||
public static void main(String[] args) {
|
||||
MongoDB mongoDB = new MongoDB(); // Create the database instance
|
||||
mongoDB.connect(new ConnectionString("mongodb://root:p4$$w0rd@localhost:27017/database")); // Connect to the MongoDB server
|
||||
|
||||
// Get the ping to the database synchronously (blocking)
|
||||
long ping = mongoDB.sync().getPing();
|
||||
System.out.println("ping = " + ping);
|
||||
|
||||
// ...or get the ping to the database asynchronously (another thread)
|
||||
mongoDB.async().getPing().thenAccept(asyncPing -> {
|
||||
System.out.println("asyncPing = " + asyncPing);
|
||||
});
|
||||
|
||||
// Close the connection after our app is done
|
||||
mongoDB.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package me.braydon.feather.databases.mongodb;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import me.braydon.feather.FeatherThreads;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* The pipeline for handling asynchronous {@link MongoDB} operations.
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public final class MongoAsyncPipeline {
|
||||
/**
|
||||
* The database to handle operations for.
|
||||
*/
|
||||
@NonNull private final MongoDB database;
|
||||
|
||||
/**
|
||||
* Get the latency to the database.
|
||||
*
|
||||
* @return the latency
|
||||
*/
|
||||
public CompletableFuture<Long> getPing() {
|
||||
return getPing(FeatherThreads.THREAD_POOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latency to the database.
|
||||
*
|
||||
* @param executor the thread executor to use
|
||||
* @return the latency
|
||||
* @see Executor for executor
|
||||
*/
|
||||
public CompletableFuture<Long> getPing(@NonNull Executor executor) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
if (!database.isConnected()) { // Not connected
|
||||
return -1L;
|
||||
}
|
||||
// Return ping
|
||||
long before = System.currentTimeMillis();
|
||||
database.getDatabase().runCommand(new BasicDBObject("ping", "1"));
|
||||
return System.currentTimeMillis() - before;
|
||||
}, executor);
|
||||
}
|
||||
}
|
125
src/main/java/me/braydon/feather/databases/mongodb/MongoDB.java
Normal file
125
src/main/java/me/braydon/feather/databases/mongodb/MongoDB.java
Normal file
@ -0,0 +1,125 @@
|
||||
package me.braydon.feather.databases.mongodb;
|
||||
|
||||
import com.mongodb.ConnectionString;
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoClients;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import me.braydon.feather.IDatabase;
|
||||
|
||||
/**
|
||||
* The {@link IDatabase} implementation for MongoDB.
|
||||
*
|
||||
* @author Braydon
|
||||
* @see MongoClient for the bootstrap class
|
||||
* @see ConnectionString for the credentials class
|
||||
* @see MongoSyncPipeline for the sync pipeline class
|
||||
* @see MongoAsyncPipeline for the async pipeline class
|
||||
* @see <a href="https://www.mongodb.com/">MongoDB Official Site</a>
|
||||
*/
|
||||
public class MongoDB implements IDatabase<MongoClient, ConnectionString, MongoSyncPipeline, MongoAsyncPipeline> {
|
||||
/**
|
||||
* The current {@link MongoClient} instance.
|
||||
*/
|
||||
private MongoClient client;
|
||||
|
||||
/**
|
||||
* The {@link MongoDatabase} instance.
|
||||
*/
|
||||
@Getter private MongoDatabase database;
|
||||
|
||||
/**
|
||||
* Get the name of this database.
|
||||
*
|
||||
* @return the database name
|
||||
*/
|
||||
@Override @NonNull
|
||||
public String getName() {
|
||||
return "MongoDB";
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a connection to this database.
|
||||
*
|
||||
* @param credentials the optional credentials to use
|
||||
*/
|
||||
@Override
|
||||
public void connect(ConnectionString credentials) {
|
||||
if (credentials == null) { // We need valid credentials
|
||||
throw new IllegalArgumentException("No credentials defined");
|
||||
}
|
||||
if (isConnected()) { // Already connected
|
||||
throw new IllegalStateException("Already connected");
|
||||
}
|
||||
String databaseName = credentials.getDatabase(); // Get the database name
|
||||
if (databaseName == null) {
|
||||
throw new IllegalArgumentException("A database name is required");
|
||||
}
|
||||
if (client != null) { // We have a client, close it first
|
||||
client.close();
|
||||
}
|
||||
client = MongoClients.create(credentials); // Create a new client
|
||||
database = client.getDatabase(databaseName); // Get the database
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this database is connected.
|
||||
*
|
||||
* @return the database connection state
|
||||
*/
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return client != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bootstrap class
|
||||
* instance for this database.
|
||||
*
|
||||
* @return the bootstrap class instance, null if none
|
||||
* @see MongoClients for bootstrap class
|
||||
*/
|
||||
@Override
|
||||
public MongoClient getBootstrap() {
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the synchronized
|
||||
* pipeline for this database.
|
||||
*
|
||||
* @return the synchronized pipeline
|
||||
* @see MongoSyncPipeline for synchronized pipeline
|
||||
*/
|
||||
@Override @NonNull
|
||||
public MongoSyncPipeline sync() {
|
||||
return new MongoSyncPipeline(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the asynchronous
|
||||
* pipeline for this database.
|
||||
*
|
||||
* @return the asynchronous pipeline
|
||||
* @see MongoAsyncPipeline for asynchronous pipeline
|
||||
*/
|
||||
@Override @NonNull
|
||||
public MongoAsyncPipeline async() {
|
||||
return new MongoAsyncPipeline(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this stream and releases any system resources associated
|
||||
* with it. If the stream is already closed then invoking this
|
||||
* method has no effect.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
if (client != null) {
|
||||
client.close();
|
||||
}
|
||||
client = null;
|
||||
database = null;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package me.braydon.feather.databases.mongodb;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
/**
|
||||
* The pipeline for handling {@link MongoDB} operations.
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public final class MongoSyncPipeline {
|
||||
/**
|
||||
* The database to handle operations for.
|
||||
*/
|
||||
@NonNull private final MongoDB database;
|
||||
|
||||
/**
|
||||
* Get the latency to the database.
|
||||
*
|
||||
* @return the latency
|
||||
*/
|
||||
public long getPing() {
|
||||
if (!database.isConnected()) { // Not connected
|
||||
return -1L;
|
||||
}
|
||||
// Return ping
|
||||
long before = System.currentTimeMillis();
|
||||
database.getDatabase().runCommand(new BasicDBObject("ping", "1"));
|
||||
return System.currentTimeMillis() - before;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user