You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2021/02/17 15:54:02 UTC

[ignite-3] 01/01: IGNITE-14198 Client interface for metastorage.

This is an automated email from the ASF dual-hosted git repository.

agura pushed a commit to branch ignite-14198
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit cf15dba2a9206d05246a58a563100126ee23eeca
Author: Andrey Gura <ag...@apache.org>
AuthorDate: Wed Feb 17 18:53:22 2021 +0300

    IGNITE-14198 Client interface for metastorage.
---
 modules/metastorage-client/pom.xml                 |  42 ++++++
 .../metastorage/client/MetaStorageService.java     | 155 ++++++++++++++++++++
 .../ignite/metastorage/client/package-info.java    |  21 +++
 modules/metastorage-common/pom.xml                 |  41 ++++++
 .../metastorage/common/AbstractCondition.java      |  77 ++++++++++
 .../ignite/metastorage/common/Condition.java       |  31 ++++
 .../ignite/metastorage/common/ConditionType.java   |  35 +++++
 .../apache/ignite/metastorage/common/Entry.java    | 162 +++++++++++++++++++++
 .../common/LexicographicComparator.java            |  46 ++++++
 .../ignite/metastorage/common/PutUpdate.java       |  47 ++++++
 .../ignite/metastorage/common/RemoveUpdate.java    |  38 +++++
 .../metastorage/common/RevisionCondition.java      |  48 ++++++
 .../apache/ignite/metastorage/common/Update.java   |  24 +++
 .../ignite/metastorage/common/ValueCondition.java  |  49 +++++++
 .../ignite/metastorage/common/package-info.java    |  21 +++
 pom.xml                                            |   2 +
 16 files changed, 839 insertions(+)

diff --git a/modules/metastorage-client/pom.xml b/modules/metastorage-client/pom.xml
new file mode 100644
index 0000000..0d21c81
--- /dev/null
+++ b/modules/metastorage-client/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+  -->
+
+<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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>metastorage-client</artifactId>
+    <version>3.0.0-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>metastorage-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/MetaStorageService.java b/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/MetaStorageService.java
new file mode 100644
index 0000000..178f633
--- /dev/null
+++ b/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/MetaStorageService.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.client;
+
+
+import org.apache.ignite.metastorage.common.Condition;
+import org.apache.ignite.metastorage.common.Entry;
+import org.apache.ignite.metastorage.common.Update;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * Defines interface for access to a metastorage service.
+ */
+public interface MetaStorageService {
+    /**
+     * Returns metastorage revision.
+     *
+     * @return Metastorage revision.
+     */
+    @NotNull
+    Future<Long> revision();
+
+    /**
+     * Updates entry with given key and value.
+     *
+     * @param key Key. Couldn't be {@code null}.
+     * @param value Value.Couldn't be {@code null}.
+     * @return A previous entry which could be regular, empty or tombstone. Couldn't be {@code null}.
+     * @see Entry
+     */
+    @NotNull
+    Future<Entry> put(@NotNull byte[] key, @NotNull byte[] value);
+
+    /**
+     * Retrieves entry with a given key.
+     *
+     * @param key Key. Couldn't be {@code null}.
+     * @return An entry for given key or an empty/tombstone entry. Couldn't be {@code null}.
+     * @see Entry
+     */
+    @NotNull
+    Future<Entry> get(@NotNull byte[] key);
+
+    /**
+     * Retrieves entry with a given key and a revision.
+     *
+     * @param key Key. Couldn't be {@code null}.
+     * @param rev Revision. Must be positive.
+     * @return An entry for given key and a revision or an empty/tombstone entry. Couldn't be {@code null}.
+     * @see Entry
+     */
+    //TODO: Is it really needed???
+    @NotNull
+    Future<Entry> get(@NotNull byte[] key, long rev);
+
+    /**
+     * Removes an entry with a given key.
+     *
+     * @param key Key. Couldn't be {@code null}.
+     * @return A previous entry which could be regular, empty or tombstone. Couldn't be {@code null}.
+     * @see Entry
+     */
+    @NotNull
+    Future<Entry> remove(@NotNull byte[] key);
+
+    /**
+     * Updates entry conditionally.
+     *
+     * @param key Key. Couldn't be {@code null}.
+     * @param condition Condition.
+     * @param success Update which will be applied in case of condition success.
+     * @param failure Update which will be applied in case of condition failure.
+     * @return A previous entry which could be regular, empty or tombstone. Couldn't be {@code null}.
+     * @see Entry
+     */
+    Future<Entry> update(@NotNull byte[] key, Condition condition, Update success, Update failure);
+
+    /**
+     * Updates multiple entries conditionally.
+     *
+     * @param keys List of keys.
+     * @param condition List of conditions corresponding to keys list.
+     * @param success List of updates which will be applied to corresponding key in case of condition success.
+     * @param failure List of updates which will be applied to corresponding key in case of condition failure.
+     * @return A List of previous entries corresponding to list of keys, where each entry could be regular,
+     * empty or tombstone. Couldn't be {@code null}.
+     * @see Entry
+     */
+    // TODO: If I understand correctly, we always use one success and one failure condition for each key in transaction. May be I'm wrong.
+    // TODO: Probably, we should provide no-op conditions also (e.g. for implementation if-then only logic).
+    Future<List<Entry>> update(List<byte[]> keys, List<Condition> condition, List<Update> success, List<Update> failure);
+
+    /**
+     * Retrieves entries for a given key range in lexicographic order.
+     * Only entries with the latest revisions will be returned.
+     *
+     * @param keyFrom Start key of range (inclusive). Couldn't be {@code null}.
+     * @param keyTo End key of range (exclusive). Could be {@code null}.
+     * @param consumer Entry consumer which will be invoked for each entry. Entry couldn't be {@code null}.
+     * @return Future which will be completed when iteration will be finished. Couldn't be {@code null}.
+     */
+    @NotNull
+    Future<Void> iterate(@NotNull byte[] keyFrom, @Nullable byte[] keyTo, @NotNull Consumer<Entry> consumer);
+
+    /**
+     * Creates watcher on metastorage updates with given parameters.
+     *
+     * @param keyFrom Start key of range (inclusive). Could be {@code null}.
+     * @param keyTo End key of range (exclusive). Could be {@code null}.
+     * @param revision Start revision.
+     * @param consumer Entry consumer which will be invoked for each update. Entry couldn't be {@code null}.
+     * @return Watch identifier.
+     */
+    @NotNull
+    Future<Long> watch(@Nullable byte[] keyFrom, @Nullable byte[] keyTo, long revision,
+                       @NotNull BiConsumer<Entry, Entry> consumer);
+
+    /**
+     * Stops watch with a given identifier.
+     *
+     * @param watchId Watch identifier.
+     * @return Completed future in case of operation success. Couldn't be {@code null}.
+     */
+    @NotNull
+    Future<Void> stopWatch(long watchId);
+
+    /**
+     * Compacts metastorage (removes all tombstone entries and old entries except of entries with latest revision).
+     *
+     * @return Completed future. Couldn't be {@code null}.
+     */
+    Future<Void> compact();
+}
+
diff --git a/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/package-info.java b/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/package-info.java
new file mode 100644
index 0000000..b790384
--- /dev/null
+++ b/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Defines client interface for access to a metastorage server.
+ */
+package org.apache.ignite.metastorage.client;
\ No newline at end of file
diff --git a/modules/metastorage-common/pom.xml b/modules/metastorage-common/pom.xml
new file mode 100644
index 0000000..cd9e1c6
--- /dev/null
+++ b/modules/metastorage-common/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+  -->
+
+<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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>metastorage-common</artifactId>
+    <version>3.0.0-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jetbrains</groupId>
+            <artifactId>annotations</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/AbstractCondition.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/AbstractCondition.java
new file mode 100644
index 0000000..9bfb570
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/AbstractCondition.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+import static org.apache.ignite.metastorage.common.ConditionType.EQUAL;
+import static org.apache.ignite.metastorage.common.ConditionType.GREATER;
+import static org.apache.ignite.metastorage.common.ConditionType.LESS;
+import static org.apache.ignite.metastorage.common.ConditionType.NOT_EQUAL;
+
+/**
+ * Abstract condition which is designed for a comparison based conditions.
+ *
+ * <p>The comparison type is defined by {@link ConditionType} enumeration. Only {@link #compare(Entry)} method
+ * should be implemented for getting correct comparison based condition evaluation.</p>
+ */
+public abstract class AbstractCondition implements Condition {
+    /** Condition type. */
+    private final ConditionType type;
+
+    /**
+     * Constructor.
+     *
+     * @param type Condition type.
+     */
+    public AbstractCondition(ConditionType type) {
+        this.type = type;
+    }
+
+    /**
+     * Returns condition type for this condition.
+     *
+     * @return Condition type.
+     */
+    protected ConditionType conditionType() {
+        return type;
+    }
+
+    /**
+     * Evaluates comparison based condition.
+     *
+     * @param e Entry which is a subject of conditional update.
+     * @return {@code True} if condition is successful, otherwise - {@code false}.
+     */
+    @Override public boolean eval(Entry e) {
+        int res = compare(e);
+
+        ConditionType type = conditionType();
+
+        return (type == EQUAL && res == 0) ||
+                (type == NOT_EQUAL && res != 0) ||
+                (type == LESS && res < 0) ||
+                (type == GREATER && res > 0);
+    }
+
+    /**
+     * This abstract method should implement comparison logic based on {@link java.util.Comparator} contract.
+     *
+     * @param e Entry.
+     * @return Comparison result as defined {@link java.util.Comparator} contract.
+     */
+    abstract protected int compare(Entry e);
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Condition.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Condition.java
new file mode 100644
index 0000000..e1a81ed
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Condition.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+/**
+ * Defines condition interface for metastorage conditional update.
+ */
+public interface Condition {
+    /**
+     * Should implements logic for condition evaluation.
+     *
+     * @param e Entry which is a subject of conditional update.
+     * @return {@code True} if condition is successful, otherwise - {@code false}.
+     */
+    boolean eval(Entry e);
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ConditionType.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ConditionType.java
new file mode 100644
index 0000000..16383d2
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ConditionType.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+/**
+ * Defines available condition types.
+ */
+enum ConditionType {
+    /** Equal to smth. */
+    EQUAL,
+
+    /** Not equal to smth. */
+    NOT_EQUAL,
+
+    /** Greater than smth. */
+    GREATER,
+
+    /** Less than smth. */
+    LESS
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Entry.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Entry.java
new file mode 100644
index 0000000..719809f
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Entry.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Represents a storage unit as entry with key, value and revision, where
+ * <ul>
+ *     <li>key - an unique entry's key represented by an array of bytes. Keys are comparable in lexicographic manner.</li>
+ *     <ul>value - a data which is associated with a key and represented as an array of bytes.</ul>
+ *     <ul>revision - a number which denotes a version of whole meta storage. Each change increments the revision.</ul>
+ * </ul>
+ *
+ * Instance of {@link #Entry} could represents:
+ * <ul>
+ *     <li>A regular entry which stores a particular key, a value and a revision number.</li>
+ *     <li>An empty entry which denotes absence a regular entry in the meta storage for a given key.
+ *     A revision is 0 for such kind of entry.</li>
+ *     <li>A tombstone entry which denotes that a regular entry for a given key was removed from storage on some revision.</li>
+ * </ul>
+ */
+public class Entry {
+    /** Entry key. Couldn't be {@code null}. */
+    @NotNull
+    final private byte[] key;
+
+    /**
+     * Entry value.
+     * <p>
+     *     {@code val == null} only for {@link #empty()} and {@link #tombstone()} entries.
+     * </p>
+     */
+    @Nullable
+    final private byte[] val;
+
+    /**
+     * Revision number corresponding to this particular entry.
+     * <p>
+     *     {@code rev == 0} for {@link #empty()} entry,
+     *     {@code rev > 0} for regular and {@link #tombstone()} entries.
+     * </p>
+     */
+    final private long rev;
+
+    /**
+     * Constructor.
+     *
+     * @param key Key bytes. Couldn't be {@code null}.
+     * @param val Value bytes. Couldn't be {@code null}.
+     * @param rev Revision.
+     */
+    // TODO: It seems user will never create Entry, so we can reduce constructor scope to protected or package-private and reuse it from two-place private constructor.
+    public Entry(@NotNull byte[] key, @NotNull byte[] val, long rev) {
+        assert key != null : "key can't be null";
+        assert val != null : "value can't be null";
+
+        this.key = key;
+        this.val = val;
+        this.rev = rev;
+    }
+
+    /**
+     * Constructor for empty and tombstone entries.
+     *
+     * @param key Key bytes. Couldn't be {@code null}.
+     * @param rev Revision.
+     */
+    private Entry(@NotNull byte[] key, long rev) {
+        assert key != null : "key can't be null";
+
+        this.key = key;
+        this.val = null;
+        this.rev = rev;
+    }
+
+    /**
+     * Creates an instance of empty entry for a given key.
+     *
+     * @param key Key bytes. Couldn't be {@code null}.
+     * @return Empty entry.
+     */
+    @NotNull
+    public static Entry empty(byte[] key) {
+        return new Entry(key, 0);
+    }
+
+    /**
+     * Creates an instance of tombstone entry for a given key and a revision.
+     *
+     * @param key Key bytes. Couldn't be {@code null}.
+     * @return Empty entry.
+     */
+    @NotNull
+    public static Entry tombstone(byte[] key, long rev) {
+        assert rev > 0 : "rev must be positive for tombstone entry.";
+
+        return new Entry(key, rev);
+    }
+
+    /**
+     * Returns a key.
+     *
+     * @return Key.
+     */
+    @NotNull
+    public byte[] key() {
+        return key;
+    }
+
+    /**
+     * Returns a value.
+     *
+     * @return Value.
+     */
+    @Nullable
+    public byte[] value() {
+        return val;
+    }
+
+    /**
+     * Returns a revision.
+     * @return Revision.
+     */
+    public long revision() {
+        return rev;
+    }
+
+    /**
+     * Returns value which denotes whether entry is tombstone or not.
+     *
+     * @return {@code True} if entry is tombstone, otherwise - {@code false}.
+     */
+    public boolean tombstone() {
+        return val == null && rev > 0;
+    }
+
+    /**
+     * Returns value which denotes whether entry is empty or not.
+     *
+     * @return {@code True} if entry is empty, otherwise - {@code false}.
+     */
+    public boolean empty() {
+        return val == null && rev == 0;
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/LexicographicComparator.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/LexicographicComparator.java
new file mode 100644
index 0000000..c0e5f9d
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/LexicographicComparator.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+import java.util.Comparator;
+
+/**
+ * Byte array lexicographic comparator.
+ */
+public class LexicographicComparator implements Comparator<byte[]> {
+    /** Comparator instance. */
+    public static final Comparator<byte[]> INSTANCE = new LexicographicComparator();
+
+    /** {@inheritDoc} */
+    @Override public int compare(byte[] o1, byte[] o2) {
+        int minLength = Math.min(o1.length, o2.length);
+
+        for (int i = 0; i < minLength; ++i) {
+            int res = toInt(o1[i]) - toInt(o2[i]);
+
+            if (res != 0)
+                return res;
+        }
+
+        return o1.length - o2.length;
+    }
+
+    private static int toInt(byte val) {
+        return val & 0xFF;
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/PutUpdate.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/PutUpdate.java
new file mode 100644
index 0000000..d1012df
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/PutUpdate.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Put (write) update.
+ */
+public class PutUpdate implements Update {
+    /** Key. */
+    @NotNull
+    private final byte[] key;
+
+    /** Value. */
+    @NotNull
+    private final byte[] val;
+
+    /**
+     * Constructor.
+     *
+     * @param key A target key which will be updated.
+     * @param val A target value which will be written for a given key.
+     */
+    public PutUpdate(@NotNull byte[] key, @NotNull byte[] val) {
+        assert key != null : "key can't be null";
+        assert val != null : "value can't be null";
+
+        this.key = key;
+        this.val = val;
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RemoveUpdate.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RemoveUpdate.java
new file mode 100644
index 0000000..09e227c
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RemoveUpdate.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Remove update.
+ */
+public class RemoveUpdate implements Update {
+    /** Key. */
+    @NotNull
+    private final byte[] key;
+
+    /**
+     * Constructor.
+     *
+     * @param key A target key which will be removed.
+     */
+    public RemoveUpdate(@NotNull byte[] key) {
+        this.key = key;
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RevisionCondition.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RevisionCondition.java
new file mode 100644
index 0000000..cd08c9c
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RevisionCondition.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+/**
+ * Condition, intended for revision evaluation.
+ */
+public class RevisionCondition extends AbstractCondition {
+    /** Revision. */
+    private final long rev;
+
+    /**
+     * Constructor.
+     *
+     * @param type Condition type.
+     * @param rev Revision for comparison.
+     */
+    public RevisionCondition(ConditionType type, long rev) {
+        super(type);
+
+        this.rev = rev;
+    }
+
+    /**
+     * Compares a given revision with a target one.
+     *
+     * @param e A target entry.
+     * @return Comparison result as defined {@link java.util.Comparator} contract.
+     */
+    @Override protected int compare(Entry e) {
+        return Long.compare(e.revision(), rev);
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Update.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Update.java
new file mode 100644
index 0000000..58b211c
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Update.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+/**
+ * Defines update command for metastorage conditional update.
+ */
+public interface Update {
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ValueCondition.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ValueCondition.java
new file mode 100644
index 0000000..d437c87
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ValueCondition.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+/**
+ * Condition, intended for value evaluation.
+ */
+public class ValueCondition extends AbstractCondition {
+    /** Value. */
+    private final byte[] val;
+
+    /**
+     * Constructor.
+     *
+     * @param type Condition type.
+     * @param val Value for comparison.
+     */
+    public ValueCondition(ConditionType type, byte[] val) {
+        super(type);
+
+        this.val = val;
+    }
+
+    /**
+     * Compares a given value with a target one in lexicographical manner.
+     *
+     * @param e A target entry.
+     * @return Comparison result as defined {@link java.util.Comparator} contract.
+     */
+    // TODO: Actually, value could be compared in different manners. So we should have possibility to define comparison logic.
+    @Override protected int compare(Entry e) {
+        return LexicographicComparator.INSTANCE.compare(e.value(), val);
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/package-info.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/package-info.java
new file mode 100644
index 0000000..fab9cc7
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Contains entities required by both metastorage client and server implementations.
+ */
+package org.apache.ignite.metastorage.common;
diff --git a/pom.xml b/pom.xml
index abf5ce6..f0c5f2e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,6 +38,8 @@
         <module>modules/cli-common</module>
         <module>modules/configuration</module>
         <module>modules/configuration-annotation-processor</module>
+        <module>modules/metastorage-common</module>
+        <module>modules/metastorage-client</module>
         <module>modules/rest</module>
         <module>modules/runner</module>
     </modules>