diff --git a/api/pom.xml b/api/pom.xml
new file mode 100644
index 0000000..afe8d2c
--- /dev/null
+++ b/api/pom.xml
@@ -0,0 +1,27 @@
+
+
+ 4.0.0
+
+ ru.kirillius
+ XCP
+ 1.0.0.0
+
+
+ api
+
+
+
+ ru.kirillius
+ java-events
+ 1.1.0.0
+
+
+
+ tools.jackson.core
+ jackson-databind
+ 3.0.3
+
+
+
\ No newline at end of file
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Commons/Config.java b/api/src/main/java/ru/kirillius/XCP/api/Commons/Config.java
new file mode 100644
index 0000000..5618bb0
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Commons/Config.java
@@ -0,0 +1,21 @@
+package ru.kirillius.XCP.api.Commons;
+
+import java.io.File;
+
+public interface Config {
+
+ File getLoadedConfigFile();
+
+ String getHost();
+
+ void setHost(String host);
+
+ File getDatabaseFile();
+
+ void setDatabaseFile(File databaseFile);
+
+ int getHttpPort();
+
+ void setHttpPort(int httpPort);
+
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Commons/ConfigManager.java b/api/src/main/java/ru/kirillius/XCP/api/Commons/ConfigManager.java
new file mode 100644
index 0000000..43bebbd
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Commons/ConfigManager.java
@@ -0,0 +1,14 @@
+package ru.kirillius.XCP.api.Commons;
+
+import java.io.IOException;
+
+public interface ConfigManager {
+
+ boolean isExist();
+
+ Config load();
+
+ Config create();
+
+ void save(Config config) throws IOException;
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Commons/Context.java b/api/src/main/java/ru/kirillius/XCP/api/Commons/Context.java
new file mode 100644
index 0000000..51e475c
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Commons/Context.java
@@ -0,0 +1,11 @@
+package ru.kirillius.XCP.api.Commons;
+
+public interface Context {
+ Config getConfig();
+
+ ConfigManager getConfigManager();
+
+ S getService(Class serviceClass);
+
+ void shutdown();
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Commons/ResourceHandler.java b/api/src/main/java/ru/kirillius/XCP/api/Commons/ResourceHandler.java
new file mode 100644
index 0000000..4c5ebd3
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Commons/ResourceHandler.java
@@ -0,0 +1,7 @@
+package ru.kirillius.XCP.api.Commons;
+
+import java.io.Closeable;
+
+public interface ResourceHandler extends Closeable {
+ T get();
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Commons/Service.java b/api/src/main/java/ru/kirillius/XCP/api/Commons/Service.java
new file mode 100644
index 0000000..27a8803
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Commons/Service.java
@@ -0,0 +1,7 @@
+package ru.kirillius.XCP.api.Commons;
+
+import java.io.Closeable;
+
+public interface Service extends Closeable {
+ void initialize(Context context);
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Commons/StreamHandler.java b/api/src/main/java/ru/kirillius/XCP/api/Commons/StreamHandler.java
new file mode 100644
index 0000000..fde73df
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Commons/StreamHandler.java
@@ -0,0 +1,7 @@
+package ru.kirillius.XCP.api.Commons;
+
+import java.util.stream.Stream;
+
+public interface StreamHandler extends ResourceHandler> {
+
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Data/DataTransferProtocol.java b/api/src/main/java/ru/kirillius/XCP/api/Data/DataTransferProtocol.java
new file mode 100644
index 0000000..05a8817
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Data/DataTransferProtocol.java
@@ -0,0 +1,6 @@
+package ru.kirillius.XCP.api.Data;
+
+@Deprecated
+public interface DataTransferProtocol {
+ //TODO
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Data/PollSettings.java b/api/src/main/java/ru/kirillius/XCP/api/Data/PollSettings.java
new file mode 100644
index 0000000..a9beb62
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Data/PollSettings.java
@@ -0,0 +1,20 @@
+package ru.kirillius.XCP.api.Data;
+
+public interface PollSettings {
+ int getMaxValueCount();
+
+ void setMaxValueCount(int maxValueCount);
+
+ long getPollInterval();
+
+ void setPollInterval(long pollInterval);
+
+ boolean isInterruptIfBusy();
+
+ void setInterruptIfBusy(boolean interruptIfBusy);
+
+ boolean setEnabled();
+
+ boolean isEnabled();
+
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Data/ValueModifier.java b/api/src/main/java/ru/kirillius/XCP/api/Data/ValueModifier.java
new file mode 100644
index 0000000..fd578ac
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Data/ValueModifier.java
@@ -0,0 +1,6 @@
+package ru.kirillius.XCP.api.Data;
+
+@Deprecated
+public interface ValueModifier {
+ //TODO
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Data/ValueModifierSettings.java b/api/src/main/java/ru/kirillius/XCP/api/Data/ValueModifierSettings.java
new file mode 100644
index 0000000..533d548
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Data/ValueModifierSettings.java
@@ -0,0 +1,14 @@
+package ru.kirillius.XCP.api.Data;
+
+import tools.jackson.databind.node.ObjectNode;
+
+public interface ValueModifierSettings {
+
+ Class extends ValueModifier> getModifierClass();
+
+ void setModifierClass(Class extends ValueModifier> modifierClass);
+
+ ObjectNode getParameters();
+
+ void setParameters(ObjectNode parameters);
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/Group.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/Group.java
new file mode 100644
index 0000000..82a9f69
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/Group.java
@@ -0,0 +1,8 @@
+package ru.kirillius.XCP.api.Persistence.Entities;
+
+import ru.kirillius.XCP.api.Persistence.NodeEntity;
+
+public interface Group extends NodeEntity {
+ String getIcon();
+ void setIcon(String icon);
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/Input.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/Input.java
new file mode 100644
index 0000000..11a4430
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/Input.java
@@ -0,0 +1,13 @@
+package ru.kirillius.XCP.api.Persistence.Entities;
+
+import ru.kirillius.XCP.api.Data.PollSettings;
+import ru.kirillius.XCP.api.Persistence.IOEntity;
+import ru.kirillius.XCP.api.Persistence.NodeEntity;
+
+public interface Input extends IOEntity, NodeEntity {
+
+ PollSettings getPollSettings();
+
+ void setPollSettings(PollSettings pollSettings);
+
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/Output.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/Output.java
new file mode 100644
index 0000000..cc6ed5f
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/Output.java
@@ -0,0 +1,7 @@
+package ru.kirillius.XCP.api.Persistence.Entities;
+
+import ru.kirillius.XCP.api.Persistence.IOEntity;
+import ru.kirillius.XCP.api.Persistence.NodeEntity;
+
+public interface Output extends IOEntity, NodeEntity {
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/User.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/User.java
new file mode 100644
index 0000000..87de17f
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Entities/User.java
@@ -0,0 +1,25 @@
+package ru.kirillius.XCP.api.Persistence.Entities;
+
+import ru.kirillius.XCP.api.Persistence.PersistenceEntity;
+import ru.kirillius.XCP.api.Security.UserRole;
+import tools.jackson.databind.node.ObjectNode;
+
+public interface User extends PersistenceEntity {
+ void changePassword(String newPass);
+
+ String getLogin();
+
+ void setLogin(String login);
+
+ UserRole getRole();
+
+ void setRole(UserRole role);
+
+ ObjectNode getValues();
+
+ void setValues(ObjectNode values);
+
+ String getName();
+
+ void setName(String name);
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/IOEntity.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/IOEntity.java
new file mode 100644
index 0000000..65123a2
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/IOEntity.java
@@ -0,0 +1,16 @@
+package ru.kirillius.XCP.api.Persistence;
+
+import ru.kirillius.XCP.api.Data.DataTransferProtocol;
+import ru.kirillius.XCP.api.Data.ValueModifierSettings;
+
+import java.util.List;
+
+public interface IOEntity extends NodeEntity {
+ List getModifiers();
+
+ void setModifiers(List modifiers);
+
+ Class extends DataTransferProtocol> getProtocol();
+
+ void setProtocol(Class extends DataTransferProtocol> protocol);
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/NodeEntity.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/NodeEntity.java
new file mode 100644
index 0000000..f1402ca
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/NodeEntity.java
@@ -0,0 +1,32 @@
+package ru.kirillius.XCP.api.Persistence;
+
+import ru.kirillius.XCP.api.Persistence.Entities.Group;
+import tools.jackson.databind.node.ObjectNode;
+
+import java.util.Set;
+
+public interface NodeEntity extends PersistenceEntity {
+ String getName();
+
+ void setName(String name);
+
+ boolean isEssential();
+
+ void setEssential(boolean essential);
+
+ boolean isEnabled();
+
+ void setEnabled(boolean enabled);
+
+ Group getParent();
+
+ void setParent(Group parent);
+
+ ObjectNode getProperties();
+
+ void setProperties(ObjectNode properties);
+
+ Set getTags();
+
+ void setTags(Set tags);
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/NodeRepository.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/NodeRepository.java
new file mode 100644
index 0000000..30737e1
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/NodeRepository.java
@@ -0,0 +1,18 @@
+package ru.kirillius.XCP.api.Persistence;
+
+import ru.kirillius.XCP.api.Commons.StreamHandler;
+import ru.kirillius.XCP.api.Persistence.Entities.Group;
+
+import java.util.Collection;
+
+public interface NodeRepository extends Repository {
+ StreamHandler getByGroup(Group group);
+
+ StreamHandler getByTags(Collection tags, TagSearchMode searchMode);
+
+ enum TagSearchMode {
+ MatchAnyTag,
+ MatchAllTags,
+ MatchExactTags
+ }
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/PersistenceEntity.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/PersistenceEntity.java
new file mode 100644
index 0000000..0d52384
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/PersistenceEntity.java
@@ -0,0 +1,11 @@
+package ru.kirillius.XCP.api.Persistence;
+
+import java.util.UUID;
+
+public interface PersistenceEntity {
+ long getId();
+
+ UUID getUUID();
+
+ Class extends PersistenceEntity> getBaseType();
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/GroupRepository.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/GroupRepository.java
new file mode 100644
index 0000000..e68def2
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/GroupRepository.java
@@ -0,0 +1,14 @@
+package ru.kirillius.XCP.api.Persistence.Repositories;
+
+import ru.kirillius.XCP.api.Commons.StreamHandler;
+import ru.kirillius.XCP.api.Persistence.Entities.Group;
+import ru.kirillius.XCP.api.Persistence.Entities.Input;
+import ru.kirillius.XCP.api.Persistence.NodeRepository;
+
+public interface GroupRepository extends NodeRepository {
+ StreamHandler getChildrenOf(Group dataGroup);
+
+ StreamHandler getChildrenRecursiveOf(Group dataGroup);
+
+ Group getRoot();
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/InputRepository.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/InputRepository.java
new file mode 100644
index 0000000..2fc0d6e
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/InputRepository.java
@@ -0,0 +1,8 @@
+package ru.kirillius.XCP.api.Persistence.Repositories;
+
+import ru.kirillius.XCP.api.Persistence.Entities.Input;
+import ru.kirillius.XCP.api.Persistence.NodeRepository;
+
+public interface InputRepository extends NodeRepository {
+
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/OutputRepository.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/OutputRepository.java
new file mode 100644
index 0000000..ed541e3
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/OutputRepository.java
@@ -0,0 +1,8 @@
+package ru.kirillius.XCP.api.Persistence.Repositories;
+
+import ru.kirillius.XCP.api.Persistence.Entities.Input;
+import ru.kirillius.XCP.api.Persistence.NodeRepository;
+
+public interface OutputRepository extends NodeRepository {
+
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/UserRepository.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/UserRepository.java
new file mode 100644
index 0000000..dede83b
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repositories/UserRepository.java
@@ -0,0 +1,10 @@
+package ru.kirillius.XCP.api.Persistence.Repositories;
+
+import ru.kirillius.XCP.api.Persistence.Entities.User;
+import ru.kirillius.XCP.api.Persistence.Repository;
+
+public interface UserRepository extends Repository {
+ User getByLoginAndPassword(String login, String password);
+
+ User getByLogin(String login);
+}
diff --git a/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repository.java b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repository.java
new file mode 100644
index 0000000..c45a68b
--- /dev/null
+++ b/api/src/main/java/ru/kirillius/XCP/api/Persistence/Repository.java
@@ -0,0 +1,49 @@
+package ru.kirillius.XCP.api.Persistence;
+
+import ru.kirillius.XCP.api.Commons.StreamHandler;
+import ru.kirillius.java.utils.events.EventHandler;
+import tools.jackson.databind.node.ArrayNode;
+import tools.jackson.databind.node.ObjectNode;
+
+import java.util.Collection;
+import java.util.UUID;
+
+public interface Repository {
+ E create();
+
+ E load(long id);
+
+ E load(UUID uuid);
+
+ StreamHandler load(Collection ids);
+
+ StreamHandler search(String query, Collection