Skip to content
This repository has been archived by the owner on Mar 11, 2024. It is now read-only.

Commit

Permalink
Service Manager
Browse files Browse the repository at this point in the history
  • Loading branch information
BelgianDev committed Dec 2, 2023
1 parent 9047cfb commit f521ae5
Show file tree
Hide file tree
Showing 21 changed files with 765 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import fr.atlasworld.network.api.file.FileManager;
import fr.atlasworld.network.api.networking.Socket;
import fr.atlasworld.network.api.security.SecurityManager;
import fr.atlasworld.network.api.services.ServiceManager;
import fr.atlasworld.network.api.util.NetworkVersion;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
Expand All @@ -34,6 +36,12 @@ public interface AtlasNetworkServer {
*/
CommandManager getCommandManager();

/**
* Get the service manager of the server.
* @see ServiceManager
*/
ServiceManager getServiceManager();

/**
* Get the system security manager.
* @see SecurityManager
Expand All @@ -52,13 +60,23 @@ public interface AtlasNetworkServer {
* @return future action to notify your code when your task finishes, of fails.
*/
@CanIgnoreReturnValue
<V> FutureAction<V> createAsyncTask(Supplier<V> supplier);
<V> FutureAction<V> createAsyncSupplier(Supplier<V> supplier);

/**
* Creates an asynchronous task using the system's Executor Pool.
* @param runnable task
* @param runnable task to run.
* @return future action to notify your code when your task finishes, or fails.
*/
@CanIgnoreReturnValue
FutureAction<Void> createAsyncTask(Runnable runnable);

/**
* Creates an asynchronous task that will run every specified time interval.
* @param runnable task to run.
* @param interval interval before rerunning the task.
* @param intervalUnit time unit of the interval.
* @return future action, this action will never successfully complete, it can only fail or be cancelled.
*/
@CanIgnoreReturnValue
FutureAction<Void> createSequenceTask(Runnable runnable, long interval, TimeUnit intervalUnit);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package fr.atlasworld.network.core.concurrent.action;
package fr.atlasworld.network.api.concurrent.action;

import com.google.common.util.concurrent.UncheckedExecutionException;
import fr.atlasworld.network.api.concurrent.action.FutureAction;
import fr.atlasworld.network.core.diagnostics.environment.Environment;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand All @@ -12,7 +10,6 @@
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

public class SimpleFutureAction<V> implements FutureAction<V> {
private final CountDownLatch latch = new CountDownLatch(1);
Expand Down Expand Up @@ -129,33 +126,4 @@ public void fail(Throwable cause) {
this.latch.countDown();
this.onFailure.accept(this.cause);
}

public static <T> SimpleFutureAction<T> supply(Supplier<T> supplier) {
SimpleFutureAction<T> action = new SimpleFutureAction<>();

Environment.SYSTEM_EXECUTOR.execute(() -> {
try {
action.complete(supplier.get());
} catch (Throwable throwable) {
action.fail(throwable);
}
});

return action;
}

public static SimpleFutureAction<Void> execute(Runnable runnable) {
SimpleFutureAction<Void> action = new SimpleFutureAction<>();

Environment.SYSTEM_EXECUTOR.execute(() -> {
try {
runnable.run();
action.complete(null);
} catch (Throwable throwable) {
action.fail(throwable);
}
});

return action;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package fr.atlasworld.network.api.services;

public interface Service {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package fr.atlasworld.network.api.services;

import org.jetbrains.annotations.Nullable;

/**
* Register and work with services.
*/
public interface ServiceManager {

/**
* Register a service implementation to the service manager.
* @param serviceClass parent service class.
* @param serviceImpl implementation of the service class.
*/
<T extends Service> void registerService(Class<T> serviceClass, T serviceImpl);

/**
* Get a service from the service manager.
* @param serviceClass parent service class.
* @return return the registered service, null if no service we're registered with this class.
*/
@Nullable
<T extends Service> T getService(Class<T> serviceClass);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package fr.atlasworld.network.api.services.database;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import fr.atlasworld.network.api.concurrent.action.FutureAction;
import org.jetbrains.annotations.NotNull;

import java.util.Optional;
import java.util.stream.Stream;

/**
* Database, loads, saves & processes data from/to the database.
* This service <strong>must</strong> be thread safe.
*/
public interface Database<E extends DatabaseEntity> {

/**
* Saves data to the database. If the value already exists, this should override it.
* @param data data to save.
* @return future action of the saving process.
*/
@CanIgnoreReturnValue
FutureAction<Void> save(@NotNull E data);

/**
* Loads data from the database or the cache.
* @param id id to the data.
* @return future action of the loading process.
*/
FutureAction<Optional<E>> load(@NotNull String id);

/**
* Deletes data in the database.
* @param id id of the data.
* @return future action of the deletion process.
*/
FutureAction<Void> delete(@NotNull String id);

/**
* Loads all entries from the database.
* @return future action of the fetch request.
*/
FutureAction<Stream<E>> stream();

/**
* Clear the local cache, executing this may make the system slower.
*/
void clearCache();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package fr.atlasworld.network.api.services.database;

import org.jetbrains.annotations.NotNull;

/**
* A Database entity is a entity that can be uniquely identified by a unique identifier.
*/
public interface DatabaseEntity {

/**
* Get unique instance entity id.
*/
@NotNull String id();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package fr.atlasworld.network.api.services.database;

import fr.atlasworld.network.api.services.database.exceptions.DatabaseDataTransformationException;

/**
* Handles the creation and transformation of data from to the database.
*/
public interface DatabaseEntityFactory<E extends DatabaseEntity> {

/**
* Creates a Java Object from the database store.
* @param store store from the database.
* @param id id of the data.
* @return new DatabaseEntity.
*/
E create(DatabaseStore store, String id) throws DatabaseDataTransformationException;

/**
* Transforms a Java Object into a database store.
* @param store store that gets modified.
* @param obj source java object.
*/
void toDatabase(DatabaseStore store, E obj) throws DatabaseDataTransformationException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package fr.atlasworld.network.api.services.database;

import fr.atlasworld.network.api.services.Service;
import fr.atlasworld.network.api.services.database.exceptions.DatabaseException;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Type;

/**
* Database service, handles the connection and handling of the database.
*/
public interface DatabaseService extends Service {

/**
* Connect to the database.
* @throws DatabaseException if connection could not succeed.
*/
void connect() throws DatabaseException;

/**
* Close connection with the database.
* @throws DatabaseException if the connection could not be closed,
* if it fails closing the connect properly it will just be skipped.
*/
void close() throws DatabaseException;

/**
* Checks if the connections with the database is closed.
* @return true if the connection has been closed.
*/
boolean closed();

/**
* Get a database from the service.
* @param name database name.
* @param type data to DTO from the database.
* @return the specified database.
*/
<E extends DatabaseEntity> Database<E> getDatabase(@NotNull String name, @NotNull DatabaseEntityFactory<E> factory) throws DatabaseException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package fr.atlasworld.network.api.services.database;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.lang.reflect.Type;
import java.util.Map;
import java.util.stream.Stream;

/**
* Stores database entity data in a simpler easier way to save, to any format.
*/
public interface DatabaseStore {

/**
* Put a key and data to the store, if the key already exists value will be overridden.
* @param key data key.
* @param data data.
*/
void put(@NotNull String key, @NotNull Object data);

/**
* Checks if the store has a key.
* @param key key to check for.
*/
boolean has(@NotNull String key);

/**
* Get data from a key.
* @param key key of the data.
* @param type object type.
*/
@Nullable
<T> T get(@NotNull String key, @NotNull Type type);

/**
* Stream data from the store.
*/
Stream<Map.Entry<String, Object>> stream();

/**
* Get the store as a map.
*/
Map<String, Object> asMap();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package fr.atlasworld.network.api.services.database.exceptions;

public class DatabaseConnectionClosedException extends DatabaseException {
public DatabaseConnectionClosedException() {
super();
}

public DatabaseConnectionClosedException(String message) {
super(message);
}

public DatabaseConnectionClosedException(String message, Throwable cause) {
super(message, cause);
}

public DatabaseConnectionClosedException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package fr.atlasworld.network.api.services.database.exceptions;

public class DatabaseDataTransformationException extends DatabaseException {
public DatabaseDataTransformationException() {
}

public DatabaseDataTransformationException(String message) {
super(message);
}

public DatabaseDataTransformationException(String message, Throwable cause) {
super(message, cause);
}

public DatabaseDataTransformationException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package fr.atlasworld.network.api.services.database.exceptions;

import java.io.IOException;

public class DatabaseException extends IOException {
public DatabaseException() {
super();
}

public DatabaseException(String message) {
super(message);
}

public DatabaseException(String message, Throwable cause) {
super(message, cause);
}

public DatabaseException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
import fr.atlasworld.network.api.module.lifecycle.ModuleActivationContext;
import fr.atlasworld.network.api.module.lifecycle.ModuleDeactivationContext;
import fr.atlasworld.network.api.module.lifecycle.ModuleLoadContext;
import fr.atlasworld.network.api.services.database.DatabaseService;
import fr.atlasworld.network.api.test.command.MyTestCommand;
import fr.atlasworld.network.api.test.configuration.TestConfiguration;
import fr.atlasworld.network.api.test.configuration.TestConfigurationSchema;
import fr.atlasworld.network.api.test.services.database.LocalDatabaseService;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;

Expand All @@ -31,6 +33,9 @@ public void onLoad(@NotNull ModuleLoadContext ctx) {
protected void onActivate(@NotNull ModuleActivationContext ctx) {
LOGGER.info("Module activated!");

LOGGER.info("Registering services..");
ctx.getServer().getServiceManager().registerService(DatabaseService.class, new LocalDatabaseService());

ctx.getServer().createAsyncTask(() -> {
while (true) {
LOGGER.info("Hi!");
Expand Down
Loading

0 comments on commit f521ae5

Please sign in to comment.