diff --git a/accsoft-nxcals-ansible/inventory/dev-timartin/vars.yml b/accsoft-nxcals-ansible/inventory/dev-timartin/vars.yml
index 7177efd2c0863657c09394196aafcb1a57c5eea6..75fe3c83e3e461cfd1711a3d20cbca7372481f25 100644
--- a/accsoft-nxcals-ansible/inventory/dev-timartin/vars.yml
+++ b/accsoft-nxcals-ansible/inventory/dev-timartin/vars.yml
@@ -94,7 +94,7 @@ monitoring_reader_memory: "-Xms100m -Xmx512m"
 monitoring_reader_spark_executor_instances: 1
 monitoring_reader_spark_executor_cores: 1
 monitoring_reader_spark_executor_memory: 512m
-monitoring_reader_extract_since: 2017-12-11 18:00:00
+monitoring_reader_extract_since: 2018-02-20 18:20:00
 
 monitoring_reader_checks: [
     {
diff --git a/accsoft-nxcals-client-inttest/src/test/java/cern/accsoft/nxcals/inttests/datamodel/Message.java b/accsoft-nxcals-client-inttest/src/test/java/cern/accsoft/nxcals/inttests/datamodel/Message.java
index cfdc3cbb4095cac1520a39136fe0ab7e036f8bfa..c0c0b770d5cc26748567dfbeef8fafc549614fad 100644
--- a/accsoft-nxcals-client-inttest/src/test/java/cern/accsoft/nxcals/inttests/datamodel/Message.java
+++ b/accsoft-nxcals-client-inttest/src/test/java/cern/accsoft/nxcals/inttests/datamodel/Message.java
@@ -15,7 +15,7 @@ public final class Message {
 
     public Message(/* @Nonnnull */ String key,
                    /* @Nonnnull */ String partition,
-	               /* @Nonnnull */ String timestamp,
+                   /* @Nonnnull */ String timestamp,
 	               /* @Nonnnull */ String data) {
         this.key = key;
         this.partition = partition;
diff --git a/accsoft-nxcals-client-inttest/src/test/java/cern/accsoft/nxcals/inttests/kafka/InttestKafkaClient.java b/accsoft-nxcals-client-inttest/src/test/java/cern/accsoft/nxcals/inttests/kafka/InttestKafkaClient.java
index 94c3ba25c1b4e0f722798e35a538d2d2b60cf348..7c641221b71d369285d937d596a7fe6332c7ec44 100644
--- a/accsoft-nxcals-client-inttest/src/test/java/cern/accsoft/nxcals/inttests/kafka/InttestKafkaClient.java
+++ b/accsoft-nxcals-client-inttest/src/test/java/cern/accsoft/nxcals/inttests/kafka/InttestKafkaClient.java
@@ -35,7 +35,7 @@ public class InttestKafkaClient implements Closeable {
         LOGGER.debug("Marking offset");
         /* with empty list as argument should seek for all parititons that we subscribed to */
         consumer.seekToEnd(Collections.emptyList());
-		/* but seeking is lazy, so we need to call poll */
+        /* but seeking is lazy, so we need to call poll */
         consumer.poll(200);
 		/* we don't use autocommit, so I think this is required */
         consumer.commitSync();
diff --git a/accsoft-nxcals-client/build.gradle b/accsoft-nxcals-client/build.gradle
index 41e0613def3a43923e8a95a9110151ea16f9ddc0..8a4e84bbdb5f5f4f4cc2c51eb974eac0c600d5c5 100644
--- a/accsoft-nxcals-client/build.gradle
+++ b/accsoft-nxcals-client/build.gradle
@@ -13,5 +13,5 @@ dependencies {
     testCompile group: 'junit', name: 'junit', version: junitVersion
     testCompile group: 'org.mockito', name: 'mockito-core', version: mockitoVersion
     testCompile group: 'org.aspectj', name: 'aspectjrt', version: aspectjVersion
-
+    testCompile group: 'pl.pragmatists', name: 'JUnitParams', version: jUnitParamsVersion
 }
diff --git a/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataToServiceEncoder.java b/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataServiceEncoder.java
similarity index 95%
rename from accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataToServiceEncoder.java
rename to accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataServiceEncoder.java
index 99061f8110c53e1c618eb31cfcf77b127936de04..54b8e9abb41639e6c18aff97628be0af72279dd3 100644
--- a/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataToServiceEncoder.java
+++ b/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataServiceEncoder.java
@@ -14,7 +14,7 @@ import cern.cmw.datax.ImmutableData;
  *
  * @author jwozniak
  */
-interface DataToServiceEncoder<K, P, S, T> {
+public interface DataServiceEncoder<K, P, S, T> {
 
     /**
      * @param record
diff --git a/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataToAvroServiceEncoder.java b/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataServiceEncoderImpl.java
similarity index 76%
rename from accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataToAvroServiceEncoder.java
rename to accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataServiceEncoderImpl.java
index 16613a2e335c78681b847303ca8602955e130ba4..2209054698a85b4fa8eeb1a02698a036db6056b5 100644
--- a/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataToAvroServiceEncoder.java
+++ b/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/DataServiceEncoderImpl.java
@@ -10,10 +10,15 @@ import cern.accsoft.nxcals.common.converters.TimeConverter;
 import cern.accsoft.nxcals.common.domain.SchemaData;
 import cern.accsoft.nxcals.common.utils.AvroUtils;
 import cern.accsoft.nxcals.common.utils.IllegalCharacterConverter;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+import cern.accsoft.nxcals.service.client.domain.impl.GenericRecordKeyValues;
+import cern.accsoft.nxcals.service.client.domain.impl.SimpleKeyValues;
 import cern.cmw.data.DiscreteFunction;
 import cern.cmw.datax.EntryType;
 import cern.cmw.datax.ImmutableData;
 import cern.cmw.datax.ImmutableEntry;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
 import com.google.common.primitives.Doubles;
 import com.google.common.primitives.Floats;
 import com.google.common.primitives.Ints;
@@ -26,15 +31,55 @@ import org.apache.avro.generic.GenericData;
 import org.apache.avro.generic.GenericRecord;
 
 import java.text.MessageFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import static cern.accsoft.nxcals.common.Schemas.*;
-import static cern.accsoft.nxcals.common.avro.SchemaConstants.*;
-import static cern.cmw.datax.EntryType.*;
+import static cern.accsoft.nxcals.common.Schemas.ENTITY_ID;
+import static cern.accsoft.nxcals.common.Schemas.PARTITION_ID;
+import static cern.accsoft.nxcals.common.Schemas.SCHEMA_ID;
+import static cern.accsoft.nxcals.common.Schemas.SYSTEM_ID;
+import static cern.accsoft.nxcals.common.Schemas.TIMESTAMP;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.ARRAY_DIMENSIONS_FIELD_NAME;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.ARRAY_ELEMENTS_FIELD_NAME;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.BOOLEAN_MULTI_ARRAY_SCHEMA_NAME;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.DDF_X_ARRAY_FIELD_NAME;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.DDF_Y_ARRAY_FIELD_NAME;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.DF_MULTI_ARRAY_SCHEMA_NAME;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.DOUBLE_MULTI_ARRAY_SCHEMA_NAME;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.FLOAT_MULTI_ARRAY_SCHEMA_NAME;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.INT_MULTI_ARRAY_SCHEMA_NAME;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.LONG_MULTI_ARRAY_SCHEMA_NAME;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.RECORD_NAMESPACE;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.RECORD_NAME_PREFIX;
+import static cern.accsoft.nxcals.common.avro.SchemaConstants.STRING_MULTI_ARRAY_SCHEMA_NAME;
+import static cern.cmw.datax.EntryType.BOOL;
+import static cern.cmw.datax.EntryType.BOOL_ARRAY;
+import static cern.cmw.datax.EntryType.DATA;
+import static cern.cmw.datax.EntryType.DATA_ARRAY;
+import static cern.cmw.datax.EntryType.DISCRETE_FUNCTION;
+import static cern.cmw.datax.EntryType.DISCRETE_FUNCTION_ARRAY;
+import static cern.cmw.datax.EntryType.DOUBLE;
+import static cern.cmw.datax.EntryType.DOUBLE_ARRAY;
+import static cern.cmw.datax.EntryType.FLOAT;
+import static cern.cmw.datax.EntryType.FLOAT_ARRAY;
+import static cern.cmw.datax.EntryType.INT16;
+import static cern.cmw.datax.EntryType.INT16_ARRAY;
+import static cern.cmw.datax.EntryType.INT32;
+import static cern.cmw.datax.EntryType.INT32_ARRAY;
+import static cern.cmw.datax.EntryType.INT64;
+import static cern.cmw.datax.EntryType.INT64_ARRAY;
+import static cern.cmw.datax.EntryType.INT8;
+import static cern.cmw.datax.EntryType.INT8_ARRAY;
+import static cern.cmw.datax.EntryType.STRING;
+import static cern.cmw.datax.EntryType.STRING_ARRAY;
 import static java.util.Arrays.asList;
 import static java.util.Comparator.comparing;
 
@@ -42,11 +87,10 @@ import static java.util.Comparator.comparing;
  * Understands the specific interpretation of the dynamic keys stored in the service and converts Avro records & schemas
  * to strings. It also converts from RecordData to avro bytes. It is crazily ugly code, left like that for the moment,
  * maybe somebody will be brave enough to make it a bit more clear... (jwozniak)
- *
- * @author jwozniak
  */
-public class DataToAvroServiceEncoder
-        implements DataToServiceEncoder<String, String, String, Long>, Function<RecordData, byte[]> {
+public class DataServiceEncoderImpl
+        implements DataServiceEncoder<KeyValues, KeyValues, String, Long>,
+        Function<RecordData, byte[]> {
     /**
      * All Data related possible schema types definitions.
      */
@@ -103,6 +147,27 @@ public class DataToAvroServiceEncoder
     private static final Schema ddfMultiArrayFieldSchemaNullable = SchemaBuilder.nullable()
             .type(ddfMultiArrayFieldSchema);
 
+    private static final Map<EntryType<?>, Schema> TYPE_TO_SCHEMA_MAP = new ImmutableMap.Builder<EntryType<?>, Schema>()
+            .put(BOOL, booleanFieldSchemaNullable)
+            .put(BOOL_ARRAY, booleanMultiArrayFieldSchemaNullable)
+            .put(INT8, intFieldSchemaNullable)
+            .put(INT16, intFieldSchemaNullable)
+            .put(INT32, intFieldSchemaNullable)
+            .put(INT8_ARRAY, intMultiArrayFieldSchemaNullable)
+            .put(INT16_ARRAY, intMultiArrayFieldSchemaNullable)
+            .put(INT32_ARRAY, intMultiArrayFieldSchemaNullable)
+            .put(INT64, longFieldSchemaNullable)
+            .put(INT64_ARRAY, longMultiArrayFieldSchemaNullable)
+            .put(FLOAT, floatFieldSchemaNullable)
+            .put(FLOAT_ARRAY, floatMultiArrayFieldSchemaNullable)
+            .put(DOUBLE, doubleFieldSchemaNullable)
+            .put(DOUBLE_ARRAY, doubleMultiArrayFieldSchemaNullable)
+            .put(STRING, stringFieldSchemaNullable)
+            .put(STRING_ARRAY, stringMultiArrayFieldSchemaNullable)
+            .put(DISCRETE_FUNCTION, ddfFieldSchemaNullable)
+            .put(DISCRETE_FUNCTION_ARRAY, ddfMultiArrayFieldSchemaNullable)
+            .build();
+
     private final ConcurrentHashMap<Long, Schema> schemaCache = new ConcurrentHashMap<>();
 
     //@formatter:on
@@ -114,8 +179,8 @@ public class DataToAvroServiceEncoder
     private TimeConverter timeConverter;
 
     @SuppressWarnings("WeakerAccess")
-    public DataToAvroServiceEncoder(Schema entityKeyDefs, Schema partitionKeyDefs, Schema timeKeyDefs,
-            Schema recordVersionDefs, TimeConverter timeConverter) {
+    public DataServiceEncoderImpl(Schema entityKeyDefs, Schema partitionKeyDefs, Schema timeKeyDefs,
+            Schema recordVersionKeySchema, TimeConverter timeConverter) {
         this.timeConverter = timeConverter;
         this.entityKeySchema = Objects.requireNonNull(entityKeyDefs);
         this.partitionKeySchema = Objects.requireNonNull(partitionKeyDefs);
@@ -124,7 +189,7 @@ public class DataToAvroServiceEncoder
         // this schema is a merge of all special fields and its fields override the field from the record (for
         // non-nullability)
         this.specialFieldsSchemaMap = Collections.unmodifiableMap(
-                Stream.of(this.entityKeySchema, this.partitionKeySchema, recordVersionDefs,
+                Stream.of(this.entityKeySchema, this.partitionKeySchema, recordVersionKeySchema,
                         this.timeKeyRecordSchema).reduce(AvroUtils::mergeSchemas)
                         .orElseThrow(() -> new IllegalStateException("Schema is empty?")).getFields().stream()
                         .collect(Collectors.toMap(Schema.Field::name, Function.identity())));
@@ -159,6 +224,11 @@ public class DataToAvroServiceEncoder
         }
     }
 
+    @Override
+    public Long encodeTimeKeyValues(ImmutableData record) {
+        return this.timeConverter.convert(encodeKeyValuesOrThrow(this.timeKeyRecordSchema, record));
+    }
+
     /*
      * It has to iterate over the fields from the Data record as the schema contains here more fields (our system
      * fields) that are not present in the record.
@@ -296,21 +366,21 @@ public class DataToAvroServiceEncoder
         return record;
     }
 
-    private static GenericRecord encodeKeyValues(Schema schema, ImmutableData record) {
+    private static GenericRecord encodeKeyValuesOrThrow(Schema schema, ImmutableData data) {
         GenericRecord genericRecord = new GenericData.Record(schema);
         for (Schema.Field field : schema.getFields()) {
             String cmwDataFieldName = field.name(); // I assume that we won't allow illegal characters in the names of
             // the system def keys.
-            ImmutableEntry entry = record.getEntry(cmwDataFieldName);
+            ImmutableEntry entry = data.getEntry(cmwDataFieldName);
             if (entry != null) {
                 genericRecord.put(cmwDataFieldName, createGenericRecordFieldValue(entry, cmwDataFieldName, schema));
             } else {
                 throw new IllegalRecordRuntimeException(
-                        "Record [" + record + "] does not contain expected field [" + cmwDataFieldName + "]");
+                        "Record [" + data + "] does not contain expected field [" + cmwDataFieldName + "]");
             }
         }
-        return genericRecord;
 
+        return genericRecord;
     }
 
     private static Schema createMultiArraySchemaType(String typeName, Schema elementType) {
@@ -325,11 +395,6 @@ public class DataToAvroServiceEncoder
                 .name(DDF_Y_ARRAY_FIELD_NAME).type(doubleArrayFieldSchemaNullable).noDefault().endRecord();
     }
 
-    @Override
-    public Long encodeTimeKeyValues(ImmutableData record) {
-        return this.timeConverter.convert(encodeKeyValues(this.timeKeyRecordSchema, record));
-    }
-
     @Override
     public byte[] apply(RecordData record) {
         GenericRecord genericRecord = this.convert(record);
@@ -337,13 +402,27 @@ public class DataToAvroServiceEncoder
     }
 
     @Override
-    public String encodeEntityKeyValues(ImmutableData record) {
-        return encodeKeyValues(this.entityKeySchema, record).toString();
+    public KeyValues encodeEntityKeyValues(ImmutableData data) {
+        return new GenericRecordKeyValues(encodeKeyValuesOrThrow(entityKeySchema, data));
     }
 
     @Override
-    public String encodePartitionKeyValues(ImmutableData record) {
-        return encodeKeyValues(this.partitionKeySchema, record).toString();
+    public KeyValues encodePartitionKeyValues(ImmutableData data) {
+        GenericRecord genericRecord = encodeKeyValuesOrThrow(partitionKeySchema, data);
+        Map<String, Object> keyValuesBasedOnGenericRecord = getKeyValuesBasedOnGenericRecord(genericRecord);
+        return new SimpleKeyValues(null, keyValuesBasedOnGenericRecord);
+    }
+
+    private static Map<String, Object> getKeyValuesBasedOnGenericRecord(GenericRecord record) {
+        Map<String, Object> keyValues = Maps.newHashMap();
+        Schema schema = record.getSchema();
+
+        for (Schema.Field field : schema.getFields()) {
+            String fieldName = field.name();
+            keyValues.put(fieldName, record.get(fieldName));
+        }
+
+        return keyValues;
     }
 
     /**
@@ -424,7 +503,6 @@ public class DataToAvroServiceEncoder
             }
 
             fieldAssembler.name(fieldName).type(fieldSchema).noDefault();
-
         }
 
         if (recordLevel == 0 && fieldsCount != this.specialFieldsCount) {
@@ -438,52 +516,24 @@ public class DataToAvroServiceEncoder
     /**
      * Creates the schema for a given @see {@link ImmutableEntry} object with all the fields nullable by default.
      */
-    @SuppressWarnings({ "squid:S3776", "squid:S1698" })//== instead of equals, method complexity
     private Schema getSchemaForEntry(ImmutableEntry cmwDataEntry, int recordLevel) {
         EntryType<?> type = cmwDataEntry.getType();
-        if (type == BOOL) {
-            return booleanFieldSchemaNullable;
-        } else if (type == BOOL_ARRAY) {
-            return booleanMultiArrayFieldSchemaNullable;
-        } else if (type == INT8 || type == INT16 || type == INT32) {
-            return intFieldSchemaNullable;
-        } else if (type == INT8_ARRAY || type == INT16_ARRAY || type == INT32_ARRAY) {
-            return intMultiArrayFieldSchemaNullable;
-        } else if (type == INT64) {
-            return longFieldSchemaNullable;
-        } else if (type == INT64_ARRAY) {
-            return longMultiArrayFieldSchemaNullable;
-        } else if (type == FLOAT) {
-            return floatFieldSchemaNullable;
-        } else if (type == FLOAT_ARRAY) {
-            return floatMultiArrayFieldSchemaNullable;
-        } else if (type == DOUBLE) {
-            return doubleFieldSchemaNullable;
-        } else if (type == DOUBLE_ARRAY) {
-            return doubleMultiArrayFieldSchemaNullable;
-        } else if (type == STRING) {
-            return stringFieldSchemaNullable;
-        } else if (type == STRING_ARRAY) {
-            return stringMultiArrayFieldSchemaNullable;
-        } else if (type == DATA) {
-            return getSchemaForDataType(cmwDataEntry, recordLevel);
-        } else if (type == DISCRETE_FUNCTION) {
-            return ddfFieldSchemaNullable;
-        } else if (type == DISCRETE_FUNCTION_ARRAY) {
-            return ddfMultiArrayFieldSchemaNullable;
+        Schema schema;
+        if (type == DATA) {
+            int nestedRecordLevel = recordLevel + 1;
+            FieldAssembler<Schema> fieldAssembler = SchemaBuilder.nullable()
+                    .record(RECORD_NAME_PREFIX + nestedRecordLevel).namespace(RECORD_NAMESPACE).fields();
+            // this is built dynamically
+            this.addFieldsFromData(fieldAssembler, cmwDataEntry.getAs(DATA), nestedRecordLevel);
+            schema = fieldAssembler.endRecord();
+        } else {
+            schema = TYPE_TO_SCHEMA_MAP.get(type);
         }
 
-        // normally this should not happen...unless DataType is extended with new types...
-        throw new UnsupportedOperationException("Unknown DataType: " + type);
-
-    }
+        if (schema == null) {
+            throw new UnsupportedOperationException("Unknown DataType: " + type);
+        }
 
-    private Schema getSchemaForDataType(ImmutableEntry cmwDataEntry, int recordLevel) {
-        int nestedRecordLevel = recordLevel + 1;
-        FieldAssembler<Schema> fieldAssembler = SchemaBuilder.nullable()
-                .record(RECORD_NAME_PREFIX + nestedRecordLevel).namespace(RECORD_NAMESPACE).fields();
-        // this is built dynamically
-        this.addFieldsFromData(fieldAssembler, cmwDataEntry.getAs(DATA), nestedRecordLevel);
-        return fieldAssembler.endRecord();
+        return schema;
     }
 }
diff --git a/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/PublisherFactory.java b/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/PublisherFactory.java
index 2128629ea6f7f27e9a5b8d9ee0955efadd595f29..f22bd401ea805dc67fbf2e43d09a563639d392b5 100644
--- a/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/PublisherFactory.java
+++ b/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/PublisherFactory.java
@@ -76,18 +76,18 @@ public final class PublisherFactory {
         if (systemData == null) {
             throw new IllegalArgumentException("Unknown system: " + systemName);
         }
-        DataToAvroServiceEncoder serviceEncoder = createDataToAvroServiceEncoder(systemData);
+        DataServiceEncoderImpl serviceEncoder = createDataToAvroServiceEncoder(systemData);
         DataSink<RecordData, DefaultCallback> dataSink = createInternalDataSink(systemData, serviceEncoder);
-        return new PublisherImpl<>(systemData.getId(), convertingFunction, entityService, serviceEncoder, dataSink);
+        return new PublisherImpl<V>(systemData.getId(), convertingFunction, entityService, serviceEncoder, dataSink);
     }
 
-    private DataToAvroServiceEncoder createDataToAvroServiceEncoder(SystemData systemData) {
+    private DataServiceEncoderImpl createDataToAvroServiceEncoder(SystemData systemData) {
         String recordVersionSchemaStr = systemData.getRecordVersionKeyDefinitions();
         Schema recordVersionSchema = null;
         if (recordVersionSchemaStr != null) {
             recordVersionSchema = new Schema.Parser().parse(recordVersionSchemaStr);
         }
-        return new DataToAvroServiceEncoder(new Schema.Parser().parse(systemData.getEntityKeyDefinitions()),
+        return new DataServiceEncoderImpl(new Schema.Parser().parse(systemData.getEntityKeyDefinitions()),
                 new Schema.Parser().parse(systemData.getPartitionKeyDefinitions()),
                 new Schema.Parser().parse(systemData.getTimeKeyDefinitions()), recordVersionSchema,
                 new TimeConverterImpl());
diff --git a/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/PublisherImpl.java b/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/PublisherImpl.java
index 5c757fde1617c0f73c2eb8853d9ca0439f1aa35f..d3af3ba004396c90d75e27c20863dae7724c7ad4 100644
--- a/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/PublisherImpl.java
+++ b/accsoft-nxcals-client/src/main/java/cern/accsoft/nxcals/client/PublisherImpl.java
@@ -7,6 +7,7 @@ import cern.accsoft.nxcals.common.SystemFields;
 import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.common.utils.Tuple2;
 import cern.accsoft.nxcals.service.client.api.internal.InternalEntityService;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
 import cern.cmw.data.Data;
 import cern.cmw.datax.EntryType;
 import cern.cmw.datax.ImmutableData;
@@ -14,12 +15,12 @@ import cern.cmw.datax.ImmutableEntry;
 import lombok.extern.slf4j.Slf4j;
 
 import java.io.IOException;
+import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ForkJoinPool;
 import java.util.function.Function;
 
-
 import static java.util.Objects.requireNonNull;
 
 /**
@@ -35,10 +36,10 @@ class PublisherImpl<V> implements Publisher<V> {
     private final InternalEntityService entityService;
     private final DataSink<RecordData, DefaultCallback> sink;
     private final long systemId;
-    private final DataToServiceEncoder<String, String, String, Long> encoder;
+    private final DataServiceEncoder<KeyValues, KeyValues, String, Long> encoder;
 
     PublisherImpl(long systemId, Function<V, ImmutableData> converter, InternalEntityService entityService,
-            DataToServiceEncoder<String, String, String, Long> encoder, DataSink<RecordData, DefaultCallback> dataSink) {
+            DataServiceEncoder<KeyValues, KeyValues, String, Long> encoder, DataSink<RecordData, DefaultCallback> dataSink) {
         this.systemId = systemId;
         this.entityService = requireNonNull(entityService);
         this.converter = requireNonNull(converter);
@@ -102,21 +103,21 @@ class PublisherImpl<V> implements Publisher<V> {
                             + "re-model your data."));
 
         }
-        //Encoding will check for the all needed fields as well, so validity with the system definition is ok
-        String entityKeyValues = this.encoder.encodeEntityKeyValues(record);
+
+        KeyValues cachedRequest = encoder.encodeEntityKeyValues(record);
+
         Long timestamp = this.encoder.encodeTimeKeyValues(record);
         if (timestamp == null || timestamp <= 0) {
             return new Tuple2<>(null, new IllegalRecordRuntimeException(
-                    "Illegal record timestamp for entityKey=" + entityKeyValues + " system=" + this.systemId
+                    "Illegal record timestamp for entityKey=" + cachedRequest + " system=" + this.systemId
                             + " timestamp=" + timestamp));
         }
 
-
-        EntityData entityData = findEntityData(record, entityKeyValues, timestamp);
+        EntityData entityData = findEntityData(record, cachedRequest, timestamp);
         return new Tuple2<>(new RecordData(entityData, record), null);
     }
 
-    private EntityData findEntityData(ImmutableData record, String entityKeyValues, Long timestamp) {
+    private EntityData findEntityData(ImmutableData record, KeyValues entityCachedRequest, Long timestamp) {
         Long entityId;
         Long partitionId = null;
         //This is like that on purpose to avoid getting both ids when the entityId == null already.
@@ -129,10 +130,10 @@ class PublisherImpl<V> implements Publisher<V> {
             //Encoding schema here to check if the required partition fields are ok
             return entityService.findOrCreateEntityFor(this.systemId, entityId, partitionId, this.encoder.encodeRecordFieldDefinitions(record), timestamp);
         } else if( entityId == null ){
-            return entityService.findOrCreateEntityFor(this.systemId, entityKeyValues, this.encoder.encodePartitionKeyValues(record), this.encoder.encodeRecordFieldDefinitions(record), timestamp);
+            return entityService.findOrCreateEntityFor(this.systemId, entityCachedRequest, this.encoder.encodePartitionKeyValues(record), this.encoder.encodeRecordFieldDefinitions(record), timestamp);
         } else {
             throw new IllegalRecordRuntimeException("Must have both entityId and partitionId set in a record for " +
-                    "entityKey=" +  entityKeyValues + " system=" + this.systemId  + " timestamp=" + timestamp);
+                    "entityKey=" +  entityCachedRequest.getKeyValues() + " system=" + this.systemId  + " timestamp=" + timestamp);
         }
     }
 
diff --git a/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/DataToAvroServiceEncoderTest.java b/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/DataServiceEncoderImplTest.java
similarity index 87%
rename from accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/DataToAvroServiceEncoderTest.java
rename to accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/DataServiceEncoderImplTest.java
index 62fb267087c200773dbd019dd752cd6aec4dbd2f..ef5960f9a2c93eaa84a26c6f846822f091ee32e0 100644
--- a/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/DataToAvroServiceEncoderTest.java
+++ b/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/DataServiceEncoderImplTest.java
@@ -8,10 +8,15 @@ import cern.accsoft.nxcals.common.SystemFields;
 import cern.accsoft.nxcals.common.avro.BytesToGenericRecordDecoder;
 import cern.accsoft.nxcals.common.converters.TimeConverter;
 import cern.accsoft.nxcals.common.converters.TimeConverterImpl;
-import cern.accsoft.nxcals.common.domain.*;
+import cern.accsoft.nxcals.common.domain.EntityData;
+import cern.accsoft.nxcals.common.domain.EntityHistoryData;
+import cern.accsoft.nxcals.common.domain.PartitionData;
+import cern.accsoft.nxcals.common.domain.SchemaData;
+import cern.accsoft.nxcals.common.domain.SystemData;
 import cern.accsoft.nxcals.common.domain.impl.EntityHistoryDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.SchemaDataImpl;
 import cern.accsoft.nxcals.service.client.api.internal.InternalSchemaService;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
 import cern.cmw.data.DataFactory;
 import cern.cmw.data.DiscreteFunction;
 import cern.cmw.datax.DataBuilder;
@@ -30,12 +35,15 @@ import java.util.SortedSet;
 import static cern.accsoft.nxcals.common.Schemas.ENTITY_ID;
 import static cern.accsoft.nxcals.common.Schemas.PARTITION_ID;
 import static cern.cmw.datax.EntryType.STRING;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
-public class DataToAvroServiceEncoderTest extends Base {
+public class DataServiceEncoderImplTest extends Base {
     @Mock
     private InternalSchemaService schemaProvider;
     @Mock
@@ -57,40 +65,43 @@ public class DataToAvroServiceEncoderTest extends Base {
     @Test
     public void testEncodeEntityKeyValues() {
         // given
-        DataToAvroServiceEncoder serializer = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl serializer = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, recordVersionKeyDefSchemaNullable, timeConverter);
         ImmutableData data = createTestCmwData(10);
 
         // when
-        String entityKeyValues = serializer.encodeEntityKeyValues(data);
+        KeyValues cachedRequest = serializer.encodeEntityKeyValues(data);
 
         // then
-        assertNotNull(entityKeyValues);
+        assertNotNull(cachedRequest);
+        assertNotNull(cachedRequest.getId());
+        assertNotNull(cachedRequest.getKeyValues());
 
     }
 
     @Test
     public void testEncodePartitionKeyValues() {
         // given
-        DataToAvroServiceEncoder serializer = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl serializer = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, recordVersionKeyDefSchemaNullable, timeConverter);
         ImmutableData data = createTestCmwData(10);
 
         // when
-        String partitionKeyValues = serializer.encodePartitionKeyValues(data);
+        KeyValues partitionKeyValues = serializer.encodePartitionKeyValues(data);
 
         // then
         assertNotNull(partitionKeyValues);
-
+        assertNull(partitionKeyValues.getId());
+        assertNotNull(partitionKeyValues.getKeyValues());
     }
 
     /**
-     * Test method for {@link DataToAvroServiceEncoder#apply(RecordData)} .
+     * Test method for {@link DataServiceEncoderImpl#apply(RecordData)} .
      */
     @Test
     public void testEncodeSchemaAndSerialize() {
         // given
-        DataToAvroServiceEncoder serializer = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl serializer = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, recordVersionKeyDefSchema, timeConverter);
         ImmutableData data = createTestCmwData(10);
         String recordSchemaStr = serializer.encodeRecordFieldDefinitions(data);
@@ -148,7 +159,7 @@ public class DataToAvroServiceEncoderTest extends Base {
     @Test
     public void testEncodeSchemaWithNullRecordVersion() {
         // given
-        DataToAvroServiceEncoder encoder = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl encoder = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, null, timeConverter);
         ImmutableData data = createTestCmwData(null);
 
@@ -176,7 +187,7 @@ public class DataToAvroServiceEncoderTest extends Base {
     @Test
     public void testEncodeSchemaWithNullableRecordVersion() {
         // given
-        DataToAvroServiceEncoder encoder = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl encoder = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, recordVersionKeyDefSchemaNullable, timeConverter);
         ImmutableData data = createTestCmwData(1);
         DataBuilder builder = ImmutableData.builder();
@@ -208,7 +219,7 @@ public class DataToAvroServiceEncoderTest extends Base {
     @Test(expected = IllegalRecordRuntimeException.class)
     public void testEncodeSchemaWithMissingRecordVersionField() {
         // given
-        DataToAvroServiceEncoder encoder = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl encoder = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, recordVersionKeyDefSchemaNullable, timeConverter);
         ImmutableData data = createTestCmwData(null);
 
@@ -220,7 +231,7 @@ public class DataToAvroServiceEncoderTest extends Base {
     @Test
     public void testEncodeSchemaWithRecordVersion() {
         // given
-        DataToAvroServiceEncoder encoder = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl encoder = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, recordVersionKeyDefSchemaNullable, timeConverter);
         ImmutableData data = createTestCmwData(20);
 
@@ -246,7 +257,7 @@ public class DataToAvroServiceEncoderTest extends Base {
     @Test(expected = UnsupportedOperationException.class)
     public void testUnsupportedMultiArrayOfDifferentData() {
         // given
-        DataToAvroServiceEncoder encoder = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl encoder = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, recordVersionKeyDefSchemaNullable, timeConverter);
         DataBuilder builder1 = ImmutableData.builder();
         builder1.add("field1", true);
@@ -267,7 +278,7 @@ public class DataToAvroServiceEncoderTest extends Base {
     @Test
     public void testEncodeSchemaWithNoRecordVersionSchema() {
         // given
-        DataToAvroServiceEncoder encoder = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl encoder = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, null, timeConverter);
         ImmutableData data = createTestCmwData(null);
 
@@ -290,7 +301,7 @@ public class DataToAvroServiceEncoderTest extends Base {
     @Test
     public void testEntityIdAndPartitionIdPassedFromRecord() {
         // given
-        DataToAvroServiceEncoder encoder = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl encoder = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, null, timeConverter);
         ImmutableData data = createTestCmwData(null, 1L, 2L);
 
@@ -310,7 +321,7 @@ public class DataToAvroServiceEncoderTest extends Base {
     @Test(expected = IllegalRecordRuntimeException.class)
     public void testNoFieldsInNestedRecord() {
         // given
-        DataToAvroServiceEncoder encoder = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl encoder = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, null, timeConverter);
         ImmutableData data = createTestCmwData(null, null, null, false);
 
@@ -327,7 +338,7 @@ public class DataToAvroServiceEncoderTest extends Base {
     @Test(expected = UnsupportedOperationException.class)
     public void testUnsupportedArrayOfDifferentData() {
         // given
-        DataToAvroServiceEncoder encoder = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl encoder = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, recordVersionKeyDefSchemaNullable, timeConverter);
         DataBuilder builder1 = ImmutableData.builder();
         builder1.add("field1", true);
@@ -349,7 +360,7 @@ public class DataToAvroServiceEncoderTest extends Base {
     @Test(expected = UnsupportedOperationException.class)
     public void testUnsupportedArray2DOfDifferentData() {
         // given
-        DataToAvroServiceEncoder encoder = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl encoder = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, recordVersionKeyDefSchemaNullable, timeConverter);
         DataBuilder builder1 = ImmutableData.builder();
         builder1.add("field1", true);
@@ -370,24 +381,17 @@ public class DataToAvroServiceEncoderTest extends Base {
 
     @Test(expected = RuntimeException.class)
     public void testSerializeNoSystemFields() {
-        // given
-
-        DataToAvroServiceEncoder serializer = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl serializer = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, recordVersionKeyDefSchema, timeConverter);
         DataBuilder builder = ImmutableData.builder();
         builder.add("field", 1);
-        String recordSchemaStr = serializer.encodeEntityKeyValues(builder.build());
-        System.out.println(recordSchemaStr);
-
-        // then
-        // exception
-
+        serializer.encodeEntityKeyValues(builder.build());
     }
 
     @Test
     public void testEncodeTimeValue() {
         // given
-        DataToAvroServiceEncoder serializer = new DataToAvroServiceEncoder(entityKeyDefSchema, partitionKeyDefSchema,
+        DataServiceEncoderImpl serializer = new DataServiceEncoderImpl(entityKeyDefSchema, partitionKeyDefSchema,
                 timeKeyDefSchema, recordVersionKeyDefSchemaNullable, timeConverter);
         ImmutableData data = createTestCmwData(10);
         // when
diff --git a/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/KafkaDataSinkTest.java b/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/KafkaDataSinkTest.java
index 10872de568c4c22fb9d85ff2b494f8dfd6db5c82..b34145661d8daf667aeefe1e30f714a9719218a8 100644
--- a/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/KafkaDataSinkTest.java
+++ b/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/KafkaDataSinkTest.java
@@ -7,6 +7,7 @@ import cern.accsoft.nxcals.common.domain.impl.EntityDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.PartitionDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.SchemaDataImpl;
 import cern.cmw.datax.ImmutableData;
+import com.google.common.collect.ImmutableMap;
 import org.apache.kafka.clients.producer.Callback;
 import org.apache.kafka.clients.producer.Producer;
 import org.apache.kafka.clients.producer.ProducerRecord;
@@ -69,8 +70,8 @@ public class KafkaDataSinkTest {
         this.kafkaSink = new KafkaDataSink(topicName, producer, (RecordData data) -> new byte[MAX_RECORD_SIZE + 1],
                 MAX_RECORD_SIZE);
         EntityData entityData = mock(EntityDataImpl.class);
-        when(entityData.getId()).thenReturn(Long.valueOf(1L));
-        when(entityData.getEntityKeyValues()).thenReturn("entityKey");
+        when(entityData.getId()).thenReturn(1L);
+        when(entityData.getEntityKeyValues()).thenReturn(ImmutableMap.of("entityKeyValues", "entityKeyValues"));
         ImmutableData data = mock(ImmutableData.class);
         RecordData recordData = new RecordData(entityData, data);
 
@@ -86,7 +87,7 @@ public class KafkaDataSinkTest {
         RecordData data = mock(RecordData.class);
         EntityData entityData = mock(EntityDataImpl.class);
         SchemaData schemaData = mock(SchemaDataImpl.class);
-        PartitionData partitionData = mock(PartitionDataImpl.class);
+        PartitionData partitionData = mock(PartitionData.class);
 
         when(data.getEntityData()).thenReturn(entityData);
         when(entityData.getSchemaData()).thenReturn(schemaData);
diff --git a/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/PublisherImplTest.java b/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/PublisherImplTest.java
index 1916f31baeedb948b3e43a8c1b5e4ae1155749e7..99ae36fc7eed9bbc98a3ffbfc8c9c3ac3f3414b1 100644
--- a/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/PublisherImplTest.java
+++ b/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/PublisherImplTest.java
@@ -4,13 +4,14 @@ import cern.accsoft.nxcals.common.SystemFields;
 import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.common.domain.impl.EntityDataImpl;
 import cern.accsoft.nxcals.service.client.api.internal.InternalEntityService;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
 import cern.cmw.datax.EntryType;
 import cern.cmw.datax.ImmutableData;
 import cern.cmw.datax.ImmutableEntry;
+import com.google.common.collect.ImmutableMap;
 import org.junit.Before;
 import org.junit.Test;
 
-
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
@@ -18,10 +19,10 @@ import java.util.concurrent.Executor;
 import java.util.function.Function;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.*;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyMap;
 import static org.mockito.Mockito.doThrow;
@@ -35,9 +36,14 @@ import static org.mockito.Mockito.when;
  */
 public class PublisherImplTest {
     private static final Executor CURRENT_THREAD_EXECUTOR = Runnable::run;
+    private static final Map<String, Object> ENTITY_KEY_VALUES = ImmutableMap.of("entity", "value1");
+    private static final Map<String, Object> PARTITION_KEY_VALUES = ImmutableMap.of("partition", "value");
+    private static final String SCHEMA = "SCHEMA";
+    private static KeyValues entityKeyValues;
+    private static KeyValues partitionKeyValues;
     private Function<Map<String, Object>, ImmutableData> converter;
     private InternalEntityService entityService;
-    private DataToServiceEncoder<String, String, String, Long> encoder;
+    private DataServiceEncoderImpl encoder;
     private DataSink<RecordData, DefaultCallback> dataSink;
     private Publisher<Map<String, Object>> publisher;
     private ImmutableData cmwData;
@@ -53,13 +59,22 @@ public class PublisherImplTest {
 
     @Before
     public void setUp() throws Exception {
+
+        entityKeyValues = mock(KeyValues.class);
+        when(entityKeyValues.getId()).thenReturn("");
+        when(entityKeyValues.getKeyValues()).thenReturn(ENTITY_KEY_VALUES);
+
+        partitionKeyValues = mock(KeyValues.class);
+        when(partitionKeyValues.getId()).thenReturn(null);
+        when(partitionKeyValues.getKeyValues()).thenReturn(PARTITION_KEY_VALUES);
+
         data = new HashMap<>();
         data.put("field1", 1L);
         data.put("field2", 2L);
 
         converter = mock(Function.class);
         entityService = mock(InternalEntityService.class);
-        encoder = mock(DataToAvroServiceEncoder.class);
+        encoder = mock(DataServiceEncoderImpl.class);
         dataSink = mock(DataSink.class);
         cmwData = mock(ImmutableData.class);
         entityData = mock(EntityDataImpl.class);
@@ -68,16 +83,13 @@ public class PublisherImplTest {
         when(converter.apply(anyMap())).thenReturn(cmwData);
         when(cmwData.getEntryCount()).thenReturn(10);
 
-        when(encoder.encodeEntityKeyValues(cmwData)).thenReturn("entityKeyValues");
-        when(encoder.encodePartitionKeyValues(cmwData)).thenReturn("partitionKeyValues");
-        when(encoder.encodeRecordFieldDefinitions(cmwData)).thenReturn("recordSchema");
+        when(encoder.encodeEntityKeyValues(cmwData)).thenReturn(entityKeyValues);
+        when(encoder.encodePartitionKeyValues(cmwData)).thenReturn(partitionKeyValues);
+        when(encoder.encodeRecordFieldDefinitions(cmwData)).thenReturn(SCHEMA);
         when(encoder.encodeTimeKeyValues(cmwData)).thenReturn(Long.valueOf(100L));
-        when(entityService.findOrCreateEntityFor(1L, "entityKeyValues", "partitionKeyValues", "recordSchema", 100L))
+        when(entityService.findOrCreateEntityFor(1L, entityKeyValues, partitionKeyValues, SCHEMA, 100L))
                 .thenReturn(entityData);
         publisher = new PublisherImpl<>(1, converter, entityService, encoder, dataSink);
-//        when(sink.publish(any(RecordData.class))).thenReturn(new CompletableFuture<Void>());
-//        publisher = new PublisherImpl<>(SYSTEM_ID, converter, entityService, encoder, sink, Runnable::run);
-
     }
 
     @Test
@@ -112,9 +124,10 @@ public class PublisherImplTest {
         when(cmwData.getEntry(SystemFields.NXC_PARTITION_ID.getValue())).thenReturn(partitionIdEntry);
         when(entityIdEntry.getAs(EntryType.INT64)).thenReturn(ENTITY_ID);
         when(partitionIdEntry.getAs(EntryType.INT64)).thenReturn(PARTITION_ID);
-        when(entityService.findOrCreateEntityFor(SYSTEM_ID, ENTITY_ID, PARTITION_ID, "recordSchema", RECORD_TIMESTAMP))
+        when(entityService.findOrCreateEntityFor(SYSTEM_ID, ENTITY_ID, PARTITION_ID, SCHEMA, RECORD_TIMESTAMP))
                 .thenReturn(entityData);
 
+
         CompletableFuture<Result> future = publisher.publishAsync(data,CURRENT_THREAD_EXECUTOR);
 
         assertNotNull(future);
@@ -125,15 +138,12 @@ public class PublisherImplTest {
 
     }
 
-
-
-
     @Test
     public void shouldFailToPublishWithEntityIdAndMissingPartitionId() throws Exception {
         data.put(SystemFields.NXC_ENTITY_ID.getValue(), ENTITY_ID);
         when(cmwData.getEntry(SystemFields.NXC_ENTITY_ID.getValue())).thenReturn(entityIdEntry);
         when(entityIdEntry.getAs(EntryType.INT64)).thenReturn(ENTITY_ID);
-        when(entityService.findOrCreateEntityFor(SYSTEM_ID, ENTITY_ID, PARTITION_ID, "recordSchema", RECORD_TIMESTAMP))
+        when(entityService.findOrCreateEntityFor(SYSTEM_ID, ENTITY_ID, PARTITION_ID, SCHEMA, RECORD_TIMESTAMP))
                 .thenReturn(entityData);
 
         CompletableFuture<Result> future = publisher.publishAsync(data,CURRENT_THREAD_EXECUTOR);
@@ -144,13 +154,8 @@ public class PublisherImplTest {
             return null;
         });
         assertTrue(future.isCompletedExceptionally());
-
-
-
     }
 
-
-
     @Test(expected = NullPointerException.class)
     public void shouldThrowOnPublishNull() throws Exception {
         Map<String, Object> data = null;
@@ -218,7 +223,7 @@ public class PublisherImplTest {
     @Test
     public void shouldReturnExceptionFutureOnInternalEntityServiceException() throws Exception {
 
-        when(entityService.findOrCreateEntityFor(SYSTEM_ID, "entityKeyValues", "partitionKeyValues", "recordSchema", 100L))
+        when(entityService.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues, SCHEMA, 100L))
                 .thenThrow(new NullPointerException());
         CompletableFuture<Result> future = publisher.publishAsync(data, CURRENT_THREAD_EXECUTOR);
         assertNotNull(future);
@@ -239,5 +244,4 @@ public class PublisherImplTest {
         assertTrue(future.isCompletedExceptionally());
         verify(dataSink, times(1)).send(any(RecordData.class), any(DefaultCallback.class));
     }
-
 }
\ No newline at end of file
diff --git a/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/aspect/TimeMeasureAspects.java b/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/aspect/TimeMeasureAspects.java
index 6ca3a88356505992c4c86cf8d769453ff981a72d..ac77c6d37cd9108ed9d963f9a8c6bec74d47d0ba 100644
--- a/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/aspect/TimeMeasureAspects.java
+++ b/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/aspect/TimeMeasureAspects.java
@@ -10,19 +10,16 @@ import org.aspectj.lang.annotation.Aspect;
 
 /**
  * In order to time measure the calls please enable AspectJ on a project.
- *
- * @author jwozniak
  */
 @Aspect
 public class TimeMeasureAspects extends TimeMeasure {
     //@Around(
     //"execution(* cern.accsoft.nxcals.client.KafkaDataSink.*(..)) ||"
     //"execution(* cern.accsoft.nxcals.client.PublisherImpl.*(..))"
-    //+ "execution(* cern.accsoft.nxcals.client.DataToAvroServiceEncoder.encode*(..)) ||"
-    //+ "execution(* cern.accsoft.nxcals.client.DataToAvroServiceEncoder.apply(..))"
+    //+ "execution(* cern.accsoft.nxcals.client.DataServiceEncoderImpl.encode*(..)) ||"
+    //+ "execution(* cern.accsoft.nxcals.client.DataServiceEncoderImpl.apply(..))"
     //)
     public Object timeMeasure(ProceedingJoinPoint pjp) throws Throwable {
-        return super.doTimeMeasure(pjp);
+        return doTimeMeasure(pjp);
     }
-
 }
diff --git a/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/aspect/package-info.java b/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/aspect/package-info.java
index 337fdc3d4a10a8c03726c2d5613f74410612d772..8e13b7947bdef9d20f5c1539fd353f9ee2acb132 100644
--- a/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/aspect/package-info.java
+++ b/accsoft-nxcals-client/src/test/java/cern/accsoft/nxcals/client/aspect/package-info.java
@@ -3,6 +3,7 @@
  *
  * @author jwozniak
  * @author jwozniak
+ * @author jwozniak
  */
 /**
  *
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/EntitiesResourcesData.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/EntitiesResourcesData.java
deleted file mode 100644
index 77676f1af1dd02ebcec6095526bb2c86eaa993eb..0000000000000000000000000000000000000000
--- a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/EntitiesResourcesData.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package cern.accsoft.nxcals.common.domain;
-
-import cern.accsoft.nxcals.common.domain.impl.EntitiesResourcesDataImpl;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-
-import java.util.Set;
-
-@JsonDeserialize(as = EntitiesResourcesDataImpl.class)
-public interface EntitiesResourcesData {
-    Set<EntityResources> getEntityResources();
-}
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/EntityData.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/EntityData.java
index 31a15f6ad6f1e36580c55f73bdb06191d496c608..e4d1818173f2e9ee09ab134dde41dbd3f5e3d07c 100644
--- a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/EntityData.java
+++ b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/EntityData.java
@@ -4,6 +4,7 @@ import cern.accsoft.nxcals.common.domain.impl.EntityDataImpl;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 
+import java.util.Map;
 import java.util.SortedSet;
 
 @JsonDeserialize(as = EntityDataImpl.class)
@@ -12,7 +13,7 @@ public interface EntityData {
 
     long getRecVersion();
 
-    String getEntityKeyValues();
+    Map<String, Object> getEntityKeyValues();
 
     SchemaData getSchemaData();
 
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/FindOrCreateEntityRequest.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/FindOrCreateEntityRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2127dba5b516959715323f68b1e657fa59d5f7f0
--- /dev/null
+++ b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/FindOrCreateEntityRequest.java
@@ -0,0 +1,31 @@
+package cern.accsoft.nxcals.common.domain;
+
+import cern.accsoft.nxcals.common.domain.impl.FindOrCreateEntityRequestImpl;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+
+import java.util.Map;
+
+/**
+ * DTO for the findOrCreateEntity request endpoint
+ */
+@JsonDeserialize(as = FindOrCreateEntityRequestImpl.class)
+public interface FindOrCreateEntityRequest {
+
+    /**
+     * Gets the key values that identify the entity.
+     * @return a {@link Map} of {@link String}s to {@link Object}s.
+     */
+    Map<String, Object> getEntityKeyValues();
+
+    /**
+     * Gets the key values that identify the partition of the entity.
+     * @return a {@link Map} of {@link String}s to {@link Object}s.
+     */
+    Map<String, Object> getPartitionKeyValues();
+
+    /**
+     * Gets the string json representation of the full schema of the data sent.
+     * @return a json formatted {@link String}.
+     */
+    String getSchema();
+}
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/PartitionData.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/PartitionData.java
index 204db450559109e2204ba5a9b6e916e841fd0a4a..f76c9034e6dc07bb07830ec887162ad9f945322e 100644
--- a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/PartitionData.java
+++ b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/PartitionData.java
@@ -3,9 +3,11 @@ package cern.accsoft.nxcals.common.domain;
 import cern.accsoft.nxcals.common.domain.impl.PartitionDataImpl;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 
+import java.util.Map;
+
 @JsonDeserialize(as = PartitionDataImpl.class)
 public interface PartitionData {
     long getId();
 
-    String getKeyValues();
+    Map<String, Object> getKeyValues();
 }
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/EntitiesResourcesDataImpl.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/EntitiesResourcesDataImpl.java
deleted file mode 100644
index 4719fca4ad3a071afecff8a42a6e9631a5dba2dd..0000000000000000000000000000000000000000
--- a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/EntitiesResourcesDataImpl.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Copyright (c) 2017 European Organisation for Nuclear Research (CERN), All Rights Reserved.
- */
-package cern.accsoft.nxcals.common.domain.impl;
-
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
-import cern.accsoft.nxcals.common.domain.EntityResources;
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonManagedReference;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Getter;
-
-import java.util.Set;
-
-/**
- * Created by ntsvetko on 4/27/17.
- */
-public class EntitiesResourcesDataImpl implements EntitiesResourcesData {
-
-    @Getter
-    @JsonManagedReference
-    private final Set<EntityResources> entityResources;
-
-    @JsonCreator
-    public EntitiesResourcesDataImpl(@JsonProperty("entityResources") Set<EntityResources> entityResources) {
-        this.entityResources = entityResources;
-    }
-
-    @Override
-    public String toString() {
-        return "EntitiesResourcesData{" + "entityResources=" + entityResources + '}';
-    }
-}
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/EntityDataImpl.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/EntityDataImpl.java
index b3d1972bb9b7f2f8a7f8958245fc9a4854dcde1c..226365cefb1f5056457a33b528298de99b990c3c 100644
--- a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/EntityDataImpl.java
+++ b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/EntityDataImpl.java
@@ -16,6 +16,7 @@ import lombok.EqualsAndHashCode;
 import lombok.NonNull;
 
 import java.util.Collections;
+import java.util.Map;
 import java.util.Objects;
 import java.util.SortedSet;
 
@@ -29,7 +30,7 @@ public class EntityDataImpl implements EntityData {
     private final long recVersion;
     private final long id;
     @NonNull
-    private final String entityKeyValues;
+    private final Map<String, Object> entityKeyValues;
     @NonNull
     private final SchemaData schemaData;
     @NonNull
@@ -42,7 +43,8 @@ public class EntityDataImpl implements EntityData {
     @JsonManagedReference
     private final SortedSet<EntityHistoryData> entityHistoryData;
 
-    public EntityDataImpl(@JsonProperty("id") long id, @JsonProperty("entityKeyValues") String entityKeyValues,
+    public EntityDataImpl(@JsonProperty("id") long id,
+            @JsonProperty("entityKeyValues") Map<String, Object> entityKeyValues,
             @JsonProperty("systemData") SystemData systemData,
             @JsonProperty("partitionData") PartitionData partitionData,
             @JsonProperty("schemaData") SchemaData schemaData,
@@ -50,13 +52,12 @@ public class EntityDataImpl implements EntityData {
             @JsonProperty(value = "lockUntilEpochNanos") Long lockUntilEpochNanos,
             @JsonProperty("version") long recVersion) {
         this.id = id;
-        this.entityKeyValues = entityKeyValues;
-        this.systemData = systemData;
-        this.partitionData = partitionData;
-        this.schemaData = schemaData;
+        this.entityKeyValues = Objects.requireNonNull(entityKeyValues);
+        this.systemData = Objects.requireNonNull(systemData);
+        this.partitionData = Objects.requireNonNull(partitionData);
+        this.schemaData = Objects.requireNonNull(schemaData);
         this.entityHistoryData = entityHistoryData;
         this.lockUntilEpochNanos = lockUntilEpochNanos;
-
         this.recVersion = recVersion;
     }
 
@@ -75,7 +76,7 @@ public class EntityDataImpl implements EntityData {
         @NonNull
         private final EntityData entityData;
 
-        private String entityKeyValues;
+        private Map<String, Object> entityKeyValues;
 
         private Long lockUntilEpochNanos;
 
@@ -90,7 +91,7 @@ public class EntityDataImpl implements EntityData {
          * @param entityKeyValues
          * @return
          */
-        public Builder withNewEntityKeyValues(String entityKeyValues) {
+        public Builder withNewEntityKeyValues(Map<String, Object> entityKeyValues) {
             this.entityKeyValues = entityKeyValues;
             return this;
         }
@@ -123,6 +124,5 @@ public class EntityDataImpl implements EntityData {
                     entityData.getPartitionData(), entityData.getSchemaData(), entityData.getEntityHistoryData(),
                     lockUntilEpochNanos, entityData.getRecVersion());
         }
-
     }
 }
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/FindOrCreateEntityRequestImpl.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/FindOrCreateEntityRequestImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..65d4d886d98419fd848955383930198030f60831
--- /dev/null
+++ b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/FindOrCreateEntityRequestImpl.java
@@ -0,0 +1,51 @@
+package cern.accsoft.nxcals.common.domain.impl;
+
+import cern.accsoft.nxcals.common.domain.FindOrCreateEntityRequest;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import com.google.common.collect.ImmutableMap;
+import lombok.Builder;
+import lombok.Value;
+
+import javax.validation.constraints.NotEmpty;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * DTO for the findOrCreateEntity request endpoint
+ */
+@JsonDeserialize(builder = FindOrCreateEntityRequestImpl.Builder.class)
+@Builder(builderClassName = "Builder")
+@Value
+public final class FindOrCreateEntityRequestImpl implements FindOrCreateEntityRequest{
+    @NotEmpty
+    private final Map<String, Object> entityKeyValues;
+    @NotEmpty
+    private final Map<String, Object> partitionKeyValues;
+    @NotEmpty
+    private final String schema;
+
+    public Map<String, Object> getEntityKeyValues() {
+        return new HashMap<>(entityKeyValues);
+    }
+
+    public Map<String, Object> getPartitionKeyValues() {
+        return new HashMap<>(partitionKeyValues);
+    }
+
+    @JsonPOJOBuilder(withPrefix = "")
+    public static final class Builder {
+
+        /* Collection setters are manual written to provide immutability */
+
+        public Builder entityKeyValues(Map<String, Object> entityKeyValues) {
+            this.entityKeyValues = ImmutableMap.copyOf(entityKeyValues);
+            return this;
+        }
+
+        public Builder partitionKeyValues(Map<String, Object> partitionKeyValues) {
+            this.partitionKeyValues = ImmutableMap.copyOf(partitionKeyValues);
+            return this;
+        }
+    }
+}
\ No newline at end of file
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/PartitionDataImpl.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/PartitionDataImpl.java
index 62d3fbba87b4e81f9016c388b75cc04d8f132ec5..5736df86bd5a55e68459f06c3252af0e71dd142d 100644
--- a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/PartitionDataImpl.java
+++ b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/domain/impl/PartitionDataImpl.java
@@ -4,24 +4,35 @@
 package cern.accsoft.nxcals.common.domain.impl;
 
 import cern.accsoft.nxcals.common.domain.PartitionData;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-import lombok.NonNull;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import com.google.common.collect.ImmutableMap;
+import lombok.Builder;
+import lombok.Value;
 
-/**
- * @author Marcin Sobieszek
- * @date Jul 21, 2016 12:26:31 PM
- */
+import javax.validation.constraints.NotEmpty;
+import java.util.HashMap;
+import java.util.Map;
 
-@Data
+@JsonDeserialize(builder = PartitionDataImpl.Builder.class)
+@Builder(builderClassName = "Builder")
+@Value
 public class PartitionDataImpl implements PartitionData {
 
     private final long id;
-    private final String keyValues;
+    @NotEmpty
+    private final Map<String, Object> keyValues;
 
-    public PartitionDataImpl(@JsonProperty("id") long id, @NonNull @JsonProperty("keyValues") String keyValues) {
-        this.id = id;
-        this.keyValues = keyValues;
+    public Map<String, Object> getKeyValues() {
+        return new HashMap<>(keyValues);
     }
 
+    @JsonPOJOBuilder(withPrefix = "")
+    public static final class Builder {
+
+        public Builder keyValues(Map<String, Object> keyValues) {
+            this.keyValues = ImmutableMap.copyOf(keyValues);
+            return this;
+        }
+    }
 }
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/utils/KeyValuesUtils.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/utils/KeyValuesUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..c00811909e7bb1c525bb0d782fa084a489b64d8e
--- /dev/null
+++ b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/utils/KeyValuesUtils.java
@@ -0,0 +1,55 @@
+package cern.accsoft.nxcals.common.utils;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.avro.Schema;
+import org.apache.avro.generic.GenericRecordBuilder;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.List;
+import java.util.Map;
+
+import static java.lang.String.format;
+
+public class KeyValuesUtils {
+
+    private KeyValuesUtils() {
+        //Should not be initialized
+    }
+
+    private static final String ERROR_MISSING_KEY_IN_KEY_VALUES = "There is not field %s in key values but it was defined in key values definition";
+    private static final String ERROR_MISMATCHED_NUMBER_OF_KEYS = "Number of fields in key values definition must match key values";
+    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+    public static String convertMapIntoAvroSchemaString(Map<String, Object> entityKeyValuesMap,
+            String keyValuesSchema) {
+        Schema avroSchema = new Schema.Parser().parse(keyValuesSchema);
+        GenericRecordBuilder genericRecordBuilder = new GenericRecordBuilder(avroSchema);
+        List<Schema.Field> fields = avroSchema.getFields();
+        if (fields.size() != entityKeyValuesMap.size()) {
+            throw new IllegalArgumentException(ERROR_MISMATCHED_NUMBER_OF_KEYS);
+        }
+
+        for (Schema.Field field : fields) {
+            String fieldName = field.name();
+            if (!entityKeyValuesMap.containsKey(fieldName)) {
+                throw new IllegalArgumentException(format(ERROR_MISSING_KEY_IN_KEY_VALUES, fieldName));
+            }
+            genericRecordBuilder.set(field, entityKeyValuesMap.get(fieldName));
+        }
+
+        return genericRecordBuilder.build().toString();
+    }
+
+    public static Map<String, Object> convertKeyValuesStringIntoMap(String keyValues) {
+        Map<String, Object> parsedKeyValues;
+        try {
+            parsedKeyValues = OBJECT_MAPPER.readValue(keyValues, new TypeReference<Map<String, Object>>() {
+            });
+        } catch (IOException exception) {
+            throw new UncheckedIOException("Cannot deserialize from json", exception);
+        }
+        return parsedKeyValues;
+    }
+}
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/web/Endpoints.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/web/Endpoints.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9791aa2907f7702cf0d1ba229223b2a75cc7b02
--- /dev/null
+++ b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/web/Endpoints.java
@@ -0,0 +1,37 @@
+package cern.accsoft.nxcals.common.web;
+
+/**
+ * This class is to provide constants that corresponds to service endpoints.
+ */
+public final class Endpoints {
+
+    private Endpoints() {
+        //Nothing to do here
+    }
+
+    public static final String ENTITIES = "/entities";
+
+    public static final String ENTITY_EXTEND_FIRST_HISTORY = ENTITIES + "extendFirstHistoryData";
+
+    public static final String ENTITY_UPDATE = ENTITIES + "/update";
+
+    public static final String COMPACTION = "/compaction";
+
+    public static final String COMPACTION_SHOULD_COMPACT = COMPACTION + "/shouldCompact";
+
+    public static final String RESOURCES = "/resources";
+
+    public static final String PARTITIONS = "/partitions";
+
+    public static final String SCHEMAS = "/schemas";
+
+    public static final String SCHEMA_WITH_ID = SCHEMAS + "/{schemaId}";
+
+    public static final String SYSTEMS = "/systems";
+
+    public static final String SYSTEM_WITH_ID = SYSTEMS + "/{id}";
+
+    public static final String VARIABLES = "/variables";
+
+    public static final String VARIABLE_REGISTER_OR_UPDATE = VARIABLES + "/registerOrUpdateVariableFor";
+}
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/web/HttpHeaders.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/web/HttpHeaders.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f6d4e4063dd21909f7e1e2a72bab3644d58d6f4
--- /dev/null
+++ b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/web/HttpHeaders.java
@@ -0,0 +1,10 @@
+package cern.accsoft.nxcals.common.web;
+
+/**
+ * Constants with the HTTP headers.
+ */
+public class HttpHeaders {
+    public static final String APPLICATION_JSON_DATA_FORMAT = "application/json";
+    public static final String ACCEPT_APPLICATION_JSON = "Accept: " + APPLICATION_JSON_DATA_FORMAT;
+    public static final String CONTENT_TYPE_APPLICATION_JSON = "Content-Type: " + APPLICATION_JSON_DATA_FORMAT;
+}
diff --git a/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/web/HttpVerbs.java b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/web/HttpVerbs.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8470d1f76f55dd851a08b9d5d8e9805bbaa0ff3
--- /dev/null
+++ b/accsoft-nxcals-common/src/main/java/cern/accsoft/nxcals/common/web/HttpVerbs.java
@@ -0,0 +1,21 @@
+package cern.accsoft.nxcals.common.web;
+
+/**
+ * Constants with the HTTP verbs.
+ */
+public final class HttpVerbs {
+
+    private HttpVerbs() {
+        // Nothing to do here
+    }
+
+    public static final String GET = "GET ";
+    public static final String POST = "POST ";
+    public static final String PUT = "PUT ";
+    public static final String PATCH = "PATCH ";
+    public static final String DELETE = "DELETE ";
+    public static final String HEAD = "HEAD ";
+    public static final String CONNECT = "CONNECT ";
+    public static final String OPTIONS = "OPTIONS ";
+    public static final String TRACE = "TRACE ";
+}
diff --git a/accsoft-nxcals-compaction/src/main/java/cern/accsoft/nxcals/compaction/package-info.java b/accsoft-nxcals-compaction/src/main/java/cern/accsoft/nxcals/compaction/package-info.java
index b7f3e19606f564f8d27a9370b9bd2d96d71906af..731a481b355da8e99c756b23d4bf9ca2805d5dfb 100644
--- a/accsoft-nxcals-compaction/src/main/java/cern/accsoft/nxcals/compaction/package-info.java
+++ b/accsoft-nxcals-compaction/src/main/java/cern/accsoft/nxcals/compaction/package-info.java
@@ -1,9 +1,4 @@
 /**
  * Copyright (c) 2016 European Organisation for Nuclear Research (CERN), All Rights Reserved.
- *
- * @author jwozniak
- */
-/**
- * @author jwozniak
  */
 package cern.accsoft.nxcals.compaction;
\ No newline at end of file
diff --git a/accsoft-nxcals-data-access/src/main/java/cern/accsoft/nxcals/data/access/api/QueryDataServiceImpl.java b/accsoft-nxcals-data-access/src/main/java/cern/accsoft/nxcals/data/access/api/QueryDataServiceImpl.java
index e434e01386f1d85e7e857e6db024bd6229e84cf2..a2fb8c4dbd5e3aa1f5046c59e24141be06e4cc96 100644
--- a/accsoft-nxcals-data-access/src/main/java/cern/accsoft/nxcals/data/access/api/QueryDataServiceImpl.java
+++ b/accsoft-nxcals-data-access/src/main/java/cern/accsoft/nxcals/data/access/api/QueryDataServiceImpl.java
@@ -4,7 +4,6 @@
 
 package cern.accsoft.nxcals.data.access.api;
 
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
 import cern.accsoft.nxcals.common.domain.EntityResources;
 import cern.accsoft.nxcals.common.domain.SchemaData;
 import cern.accsoft.nxcals.common.domain.SystemData;
@@ -18,6 +17,8 @@ import com.google.common.annotations.VisibleForTesting;
 import org.apache.avro.Schema;
 import org.apache.avro.generic.GenericData;
 import org.apache.avro.generic.GenericRecord;
+import org.apache.avro.generic.GenericRecordBuilder;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.spark.sql.types.DataTypes;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.slf4j.Logger;
@@ -117,22 +118,22 @@ class QueryDataServiceImpl implements QueryDataService {
         Set<InternalQueryData> queries = new HashSet<>();
         SystemData systemData = systemService.findByName(query.get(SYSTEM_KEY));
 
-        String entityKeyValues = getCustomKeysQueryDataFor(query, systemData);
+        Map<String, Object> entityKeyValues = getCustomKeysQueryDataFor(query, systemData);
         LOGGER.debug("Get entityKeyValues={}", entityKeyValues);
 
-        EntitiesResourcesData entities = entitiesResourcesService
+        Set<EntityResources> entityResources = entitiesResourcesService
                 .findBySystemIdKeyValuesAndTimeWindow(systemData.getId(), entityKeyValues, startTime, endTime);
-        if (entities == null || entities.getEntityResources().isEmpty()) {
+        if (CollectionUtils.isEmpty(entityResources)) {
             throw new IllegalArgumentException(
                     "There is no entity registered for systemId=" + systemData.getId() + " and keyValues="
                             + entityKeyValues);
         }
-        LOGGER.debug("Build query for Set<entityResourceData>={}, startTime={}, endTime={}", entities, startTime,
+        LOGGER.debug("Build query for Set<entityResourceData>={}, startTime={}, endTime={}", entityResources, startTime,
                 endTime);
 
         Instant start = TimeUtils.getInstantFromNanos(startTime);
         Instant stop = TimeUtils.getInstantFromNanos(endTime);
-        return entities.getEntityResources().stream().map(e -> new InternalQueryData(e, start, stop,
+        return entityResources.stream().map(e -> new InternalQueryData(e, start, stop,
                 getRequestedEntityFields(query, e.getSystemData(), e.getSchemaData()), null))
                 .collect(Collectors.toSet());
     }
@@ -230,9 +231,9 @@ class QueryDataServiceImpl implements QueryDataService {
     private Set<InternalQueryData> createInternalQueryData(String variableName, long startTime, long endTime,
             VariableConfigData conf) {
         LOGGER.debug("Add query data for variableConfig={}", conf);
-        EntitiesResourcesData entities = this.entitiesResourcesService
+        Set<EntityResources> entityResources = this.entitiesResourcesService
                 .findByEntityIdAndTimeWindow(conf.getEntityId(), startTime, endTime);
-        if (entities == null) {
+        if (CollectionUtils.isEmpty(entityResources)) {
             throw new IllegalStateException(
                     "There are no registered resources in NXCALS for the requested entity=" + conf.getEntityId()
                             + " in time window startTime=" + startTime + " endTime=" + endTime);
@@ -243,9 +244,9 @@ class QueryDataServiceImpl implements QueryDataService {
         Instant stop = TimeUtils.getInstantFromNanos(
                 Long.min(conf.getValidToStamp() == null ? endTime : conf.getValidToStamp(), endTime));
         Set<InternalQueryData> ret = new HashSet<>();
-        for (EntityResources entityResources : entities.getEntityResources()) {
-            ret.add(new InternalQueryData(entityResources, start, stop,
-                    getVariableFields(conf, entityResources.getSystemData(), entityResources.getSchemaData()),
+        for (EntityResources entityResource : entityResources) {
+            ret.add(new InternalQueryData(entityResource, start, stop,
+                    getVariableFields(conf, entityResource.getSystemData(), entityResource.getSchemaData()),
                     variableName));
         }
         return ret;
@@ -274,10 +275,11 @@ class QueryDataServiceImpl implements QueryDataService {
                 .fieldSchema(stringSchema).alias(NXC_EXTR_VARIABLE_NAME.getValue()).build();
     }
 
-    private String getCustomKeysQueryDataFor(Map<String, String> query, SystemData systemData) {
-        KeyValueBuilder kvBuilder = new KeyValueBuilder(systemData);
+    private Map<String, Object> getCustomKeysQueryDataFor(Map<String, String> query, SystemData systemData) {
+        Schema schema = new Schema.Parser().parse(systemData.getEntityKeyDefinitions());
+
+        Map<String, Object> keyValues;
         String serializedKeyValues = query.get(KEY_VALUES_KEY);
-        Map<String, String> keyValues;
         try {
             keyValues = mapper.readValue(serializedKeyValues, KEY_VALUES_TYPE);
         } catch (IOException exception) {
@@ -285,8 +287,19 @@ class QueryDataServiceImpl implements QueryDataService {
             throw createDeserializationException(serializedKeyValues, exception);
         }
 
-        keyValues.entrySet().stream().forEach(entry -> kvBuilder.setField(entry.getKey(), entry.getValue()));
-        return kvBuilder.build();
+        GenericRecordBuilder genericRecordBuilder = new GenericRecordBuilder(schema);
+        for (Map.Entry<String, Object> entry : keyValues.entrySet()) {
+            String fieldName = entry.getKey();
+            Object value = entry.getValue();
+            try {
+                genericRecordBuilder.set(fieldName, value);
+            } catch (Exception exception) {
+                throw new IllegalArgumentException(String.format(SCHEMA_MISMATCH_ERROR_MESSAGE_FORMAT, fieldName, value,
+                        systemData.getName()), exception);
+            }
+        }
+        genericRecordBuilder.build();
+        return keyValues;
     }
 
     private long getTimeFieldFromQueryMap(String key, Map<String, String> query) {
diff --git a/accsoft-nxcals-data-access/src/test/java/cern/accsoft/nxcals/data/access/BaseTest.java b/accsoft-nxcals-data-access/src/test/java/cern/accsoft/nxcals/data/access/BaseTest.java
index 50eee809e3b2e7c13b92561bca5bfcacac87cd25..1a137484e949ac6558676deb4b8789892e47d2a1 100644
--- a/accsoft-nxcals-data-access/src/test/java/cern/accsoft/nxcals/data/access/BaseTest.java
+++ b/accsoft-nxcals-data-access/src/test/java/cern/accsoft/nxcals/data/access/BaseTest.java
@@ -4,8 +4,6 @@
 
 package cern.accsoft.nxcals.data.access;
 
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
-import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.common.domain.EntityHistoryData;
 import cern.accsoft.nxcals.common.domain.EntityResources;
 import cern.accsoft.nxcals.common.domain.PartitionData;
@@ -13,8 +11,6 @@ import cern.accsoft.nxcals.common.domain.SchemaData;
 import cern.accsoft.nxcals.common.domain.SystemData;
 import cern.accsoft.nxcals.common.domain.VariableConfigData;
 import cern.accsoft.nxcals.common.domain.VariableData;
-import cern.accsoft.nxcals.common.domain.impl.EntitiesResourcesDataImpl;
-import cern.accsoft.nxcals.common.domain.impl.EntityDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.EntityHistoryDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.EntityResourcesImpl;
 import cern.accsoft.nxcals.common.domain.impl.PartitionDataImpl;
@@ -24,6 +20,7 @@ import cern.accsoft.nxcals.common.domain.impl.SystemDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.VariableConfigDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.VariableDataImpl;
 import cern.accsoft.nxcals.common.utils.TimeUtils;
+import com.google.common.collect.Sets;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.junit.Ignore;
 
@@ -32,14 +29,13 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.time.Instant;
 import java.time.temporal.ChronoUnit;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
+
+import static cern.accsoft.nxcals.common.utils.KeyValuesUtils.convertKeyValuesStringIntoMap;
 
 @Ignore
 public class BaseTest {
@@ -86,8 +82,10 @@ public class BaseTest {
                 + "\"fields\":[{\"name\":\"elements\",\"type\":[{\"type\":\"array\",\"items\":[\"float\",\"null\"]},\"null\"]},{\"name\":\"rowCount\",\"type\":[\"int\",\"null\"]},{\"name\":\"columnCount\",\"type\":[\"int\",\"null\"]}]},\"null\"]}"
                 + "]}";
 
-        PartitionDataImpl partitionData = new PartitionDataImpl(2L,
-                "{\"class\": \"ClassName\", \"property\": \"Acquisition\"}");
+        PartitionData partitionData = PartitionDataImpl.builder()
+                .id(2L)
+                .keyValues(convertKeyValuesStringIntoMap("{\"class\": \"ClassName\", \"property\": \"Acquisition\"}"))
+                .build();
         SchemaData schemaData1 = new SchemaDataImpl(3L, schema1);
         SchemaDataImpl schemaData2 = new SchemaDataImpl(4L, schema2);
         EntityHistoryData ehData1 = new EntityHistoryDataImpl(1L, schemaData1, partitionData,
@@ -108,36 +106,8 @@ public class BaseTest {
         }
     }
 
-    protected EntitiesResourcesData getTestEntitiesResources(SystemData systemData) {
-        return new EntitiesResourcesDataImpl(Stream.of(this.getTestEntityData(systemData)).collect(Collectors.toSet()));
-    }
-
-    protected EntityData getTestEntityDataWitoutHistory(SystemData systemData) {
-        String schema = "{\"type\":\"record\",\"name\":\"data0\",\"namespace\":\"cern.nxcals\",\"fields\":"
-                + "[{\"name\":\"__sys_nxcals_system_id__\",\"type\":\"long\"},"
-                + "{\"name\":\"__sys_nxcals_entity_id__\",\"type\":\"long\"},"
-                + "{\"name\":\"__sys_nxcals_partition_id__\",\"type\":\"long\"},"
-                + "{\"name\":\"__sys_nxcals_schema_id__\",\"type\":\"long\"},"
-                + "{\"name\":\"__sys_nxcals_timestamp__\",\"type\":\"long\"},"
-                + "{\"name\":\"__record_timestamp__\",\"type\":\"long\"},"
-                + "{\"name\":\"__record_version__\",\"type\":\"long\"},"
-                + "{\"name\":\"acqStamp\",\"type\":[\"long\",\"null\"]}," + "{\"name\":\"class\",\"type\":\"string\"},"
-                + "{\"name\":\"int_field\",\"type\":[\"int\"]},"
-                + "{\"name\":\"long_field\",\"type\":[\"long\",\"null\"]},"
-                + "{\"name\":\"float_field\",\"type\":[\"float\",\"null\"]},"
-                + "{\"name\":\"double_field\",\"type\":[\"double\",\"null\"]},"
-                + "{\"name\":\"string_field\",\"type\":[\"string\",\"null\"]},"
-                + "{\"name\":\"array_field\",\"type\":[{\"type\":\"array\",\"items\":[\"float\",\"null\"]},\"null\"]},"
-                + "{\"name\":\"array2D_field\",\"type\":[{\"type\":\"record\",\"name\":\"float_array_2d\","
-                + "\"fields\":[{\"name\":\"elements\",\"type\":[{\"type\":\"array\",\"items\":[\"float\",\"null\"]},\"null\"]},{\"name\":\"rowCount\",\"type\":[\"int\",\"null\"]},{\"name\":\"columnCount\",\"type\":[\"int\",\"null\"]}]},\"null\"]}"
-                + "]}";
-
-        PartitionData partitionData = new PartitionDataImpl(2L,
-                "{\"class\": \"ClassName\", \"property\": \"Acquisition\"}");
-        SchemaData schemaData = new SchemaDataImpl(3L, schema);
-
-        return new EntityDataImpl(1L, "{\"device\": \"Test_Device\", \"property\": \"Acquisition\"}", systemData,
-                partitionData, schemaData, Collections.emptySortedSet(), null, VERSION);
+    protected Set<EntityResources> getTestEntitiesResources(SystemData systemData) {
+        return Sets.newHashSet(getTestEntityData(systemData));
     }
 
     protected SystemDataImpl getTestDevPropSystemData() {
diff --git a/accsoft-nxcals-data-access/src/test/java/cern/accsoft/nxcals/data/access/api/QueryDataServiceImplTest.java b/accsoft-nxcals-data-access/src/test/java/cern/accsoft/nxcals/data/access/api/QueryDataServiceImplTest.java
index 1346c330989d1b3b790c03af15abaeb5262f348f..fcd7c533445c3130d5f137dbcf07f654acb3ae01 100644
--- a/accsoft-nxcals-data-access/src/test/java/cern/accsoft/nxcals/data/access/api/QueryDataServiceImplTest.java
+++ b/accsoft-nxcals-data-access/src/test/java/cern/accsoft/nxcals/data/access/api/QueryDataServiceImplTest.java
@@ -3,7 +3,7 @@
  */
 package cern.accsoft.nxcals.data.access.api;
 
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
+import cern.accsoft.nxcals.common.domain.EntityResources;
 import cern.accsoft.nxcals.common.domain.SystemData;
 import cern.accsoft.nxcals.common.utils.TimeUtils;
 import cern.accsoft.nxcals.data.access.BaseTest;
@@ -44,14 +44,10 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyMap;
 import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 
-/**
- * Created by ntsvetko on 12/1/16.
- */
-//@RunWith(MockitoJUnitRunner.class)
 public class QueryDataServiceImplTest extends BaseTest {
 
     private static final String FIELD_NAME = "newField";
@@ -81,7 +77,7 @@ public class QueryDataServiceImplTest extends BaseTest {
     public void shouldCreateQueryDataFromDevPropKeyValueBuilder() throws IOException {
         //given
         SystemData systemData = getTestDevPropSystemData();
-        EntitiesResourcesData entityData = getTestEntitiesResources(systemData);
+        Set<EntityResources> entityResources = getTestEntitiesResources(systemData);
 
         String deviceName = "DEVICE";
         String propertyName = "PROPERTY";
@@ -97,8 +93,8 @@ public class QueryDataServiceImplTest extends BaseTest {
 
         //when
         Mockito.when(systemServiceMock.findByName(systemData.getName())).thenReturn(systemData);
-        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyString(), anyLong(), anyLong()))
-                .thenReturn(entityData);
+        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyMap(), anyLong(), anyLong()))
+                .thenReturn(entityResources);
 
         Set<InternalQueryData> queryData = queryDataService.loadQueryData(query);
 
@@ -106,7 +102,7 @@ public class QueryDataServiceImplTest extends BaseTest {
         Assert.assertNotNull(queryData);
         assertEquals(1, queryData.size());
         InternalQueryData internalQueryData = queryData.iterator().next();
-        assertEquals(internalQueryData.getEntityData(), entityData.getEntityResources().stream().findFirst().get());
+        assertEquals(internalQueryData.getEntityData(), entityResources.stream().findFirst().get());
         assertEquals(internalQueryData.getEntityData().getSystemData(), systemData);
         assertEquals(internalQueryData.getStartTime(), TIME_1);
         assertEquals(internalQueryData.getEndTime(), TIME_2);
@@ -119,7 +115,7 @@ public class QueryDataServiceImplTest extends BaseTest {
     public void shouldCreateQueryDataWithAliasesFromDevPropKeyValueBuilder() throws IOException {
         //given
         SystemData systemData = getTestDevPropSystemData();
-        EntitiesResourcesData entityData = getTestEntitiesResources(systemData);
+        Set<EntityResources> entityResources = getTestEntitiesResources(systemData);
 
         String deviceName = "DEVICE";
         String propertyName = "PROPERTY";
@@ -137,8 +133,8 @@ public class QueryDataServiceImplTest extends BaseTest {
 
         //when
         Mockito.when(systemServiceMock.findByName(systemData.getName())).thenReturn(systemData);
-        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyString(), anyLong(), anyLong()))
-                .thenReturn(entityData);
+        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyMap(), anyLong(), anyLong()))
+                .thenReturn(entityResources);
 
         Set<InternalQueryData> queryData = queryDataService.loadQueryData(query);
 
@@ -146,7 +142,7 @@ public class QueryDataServiceImplTest extends BaseTest {
         Assert.assertNotNull(queryData);
         assertEquals(1, queryData.size());
         InternalQueryData internalQueryData = queryData.iterator().next();
-        assertEquals(internalQueryData.getEntityData(), entityData.getEntityResources().stream().findFirst().get());
+        assertEquals(internalQueryData.getEntityData(), entityResources.stream().findFirst().get());
         assertEquals(internalQueryData.getEntityData().getSystemData(), systemData);
         assertEquals(internalQueryData.getStartTime(), TIME_1);
         assertEquals(internalQueryData.getEndTime(), TIME_2);
@@ -170,7 +166,7 @@ public class QueryDataServiceImplTest extends BaseTest {
     public void shouldCreateQueryDataFromVariablesBuilder() {
         //given
         SystemData systemData = getTestDevPropSystemData();
-        EntitiesResourcesData entityData = getTestEntitiesResources(systemData);
+        Set<EntityResources> entityResources = getTestEntitiesResources(systemData);
 
         String variableName = "VARIABLE";
         String startTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_1));
@@ -185,7 +181,7 @@ public class QueryDataServiceImplTest extends BaseTest {
         //then
         Mockito.when(systemServiceMock.findByName(systemData.getName())).thenReturn(systemData);
         Mockito.when(entityService.findByEntityIdAndTimeWindow(eq(1L), eq(Long.valueOf(startTime)),
-                eq(Long.valueOf(endTime)))).thenReturn(entityData);
+                eq(Long.valueOf(endTime)))).thenReturn(entityResources);
         Mockito.when(variableService.findByVariableNameAndTimeWindow(eq(variableName), eq(Long.valueOf(startTime)),
                 eq(Long.valueOf(endTime)))).thenReturn(getTestVariableDataFullEntity());
         Set<InternalQueryData> queryData = queryDataService.loadQueryData(query);
@@ -194,7 +190,7 @@ public class QueryDataServiceImplTest extends BaseTest {
         Assert.assertNotNull(queryData);
         assertEquals(1, queryData.size());
         InternalQueryData internalQueryData = queryData.iterator().next();
-        assertEquals(internalQueryData.getEntityData(), entityData.getEntityResources().stream().findFirst().get());
+        assertEquals(internalQueryData.getEntityData(), entityResources.stream().findFirst().get());
         assertEquals(internalQueryData.getEntityData().getSystemData(), systemData);
         assertEquals(internalQueryData.getStartTime(), TIME_1);
         assertEquals(internalQueryData.getEndTime(), TIME_2);
@@ -205,7 +201,7 @@ public class QueryDataServiceImplTest extends BaseTest {
     public void shouldCreateQueryDataFromVariablesBuilderWithField() {
         //given
         SystemData systemData = getTestDevPropSystemData();
-        EntitiesResourcesData entityData = getTestEntitiesResources(systemData);
+        Set<EntityResources> entityResources = getTestEntitiesResources(systemData);
 
         String variableName = "VARIABLE";
         String startTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_1));
@@ -220,7 +216,7 @@ public class QueryDataServiceImplTest extends BaseTest {
         //then
         Mockito.when(systemServiceMock.findByName(systemData.getName())).thenReturn(systemData);
         Mockito.when(entityService.findByEntityIdAndTimeWindow(eq(1L), eq(Long.valueOf(startTime)),
-                eq(Long.valueOf(endTime)))).thenReturn(entityData);
+                eq(Long.valueOf(endTime)))).thenReturn(entityResources);
         Mockito.when(variableService.findByVariableNameAndTimeWindow(eq(variableName), eq(Long.valueOf(startTime)),
                 eq(Long.valueOf(endTime)))).thenReturn(getTestVariableDataWithField());
         Set<InternalQueryData> queryData = queryDataService.loadQueryData(query);
@@ -229,7 +225,7 @@ public class QueryDataServiceImplTest extends BaseTest {
         Assert.assertNotNull(queryData);
         assertEquals(1, queryData.size());
         InternalQueryData internalQueryData = queryData.iterator().next();
-        assertEquals(internalQueryData.getEntityData(), entityData.getEntityResources().stream().findFirst().get());
+        assertEquals(internalQueryData.getEntityData(), entityResources.stream().findFirst().get());
         assertEquals(internalQueryData.getEntityData().getSystemData(), systemData);
         assertEquals(internalQueryData.getStartTime(), TIME_1);
         assertEquals(internalQueryData.getEndTime(), TIME_2);
@@ -242,7 +238,7 @@ public class QueryDataServiceImplTest extends BaseTest {
     public void shouldCreateQueryDataFromKeyValueBuilder() throws IOException {
         //given
         SystemData systemData = getTestElementSystemData();
-        EntitiesResourcesData entityData = getTestEntitiesResources(systemData);
+        Set<EntityResources> entityResources = getTestEntitiesResources(systemData);
 
         String elementName = "element";
         String startTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_1));
@@ -257,8 +253,8 @@ public class QueryDataServiceImplTest extends BaseTest {
 
         //when
         Mockito.when(systemServiceMock.findByName(systemData.getName())).thenReturn(systemData);
-        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyString(), anyLong(), anyLong()))
-                .thenReturn(entityData);
+        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyMap(), anyLong(), anyLong()))
+                .thenReturn(entityResources);
 
         Set<InternalQueryData> queryData = queryDataService.loadQueryData(query);
 
@@ -266,7 +262,7 @@ public class QueryDataServiceImplTest extends BaseTest {
         Assert.assertNotNull(queryData);
         assertEquals(1, queryData.size());
         InternalQueryData internalQueryData = queryData.iterator().next();
-        assertEquals(internalQueryData.getEntityData(), entityData.getEntityResources().stream().findFirst().get());
+        assertEquals(internalQueryData.getEntityData(), entityResources.stream().findFirst().get());
         assertEquals(internalQueryData.getEntityData().getSystemData(), systemData);
         assertEquals(internalQueryData.getStartTime(), TIME_1);
         assertEquals(internalQueryData.getEndTime(), TIME_2);
@@ -279,7 +275,7 @@ public class QueryDataServiceImplTest extends BaseTest {
     public void shouldNotCreateQueryDataFromNonEpochTimestampInNanos() {
         //given
         SystemData systemData = getTestElementSystemData();
-        EntitiesResourcesData entityData = getTestEntitiesResources(systemData);
+        Set<EntityResources> entityResources = getTestEntitiesResources(systemData);
 
         String startTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_BEFORE_YEAR_2000));
         String endTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_1));
@@ -295,8 +291,8 @@ public class QueryDataServiceImplTest extends BaseTest {
 
         //when
         Mockito.when(systemServiceMock.findByName(systemData.getName())).thenReturn(systemData);
-        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyString(), anyLong(), anyLong()))
-                .thenReturn(entityData);
+        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyMap(), anyLong(), anyLong()))
+                .thenReturn(entityResources);
 
         Set<InternalQueryData> queryData = queryDataService.loadQueryData(query);
     }
@@ -305,7 +301,7 @@ public class QueryDataServiceImplTest extends BaseTest {
     public void shouldNotCreateQueryDataFromValueNotConvertableToLong() {
         //given
         SystemData systemData = getTestElementSystemData();
-        EntitiesResourcesData entityData = getTestEntitiesResources(systemData);
+        Set<EntityResources> entityResources = getTestEntitiesResources(systemData);
 
         String startTime = "timestamp";
         String endTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_1));
@@ -320,8 +316,8 @@ public class QueryDataServiceImplTest extends BaseTest {
 
         //when
         Mockito.when(systemServiceMock.findByName(systemData.getName())).thenReturn(systemData);
-        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyString(), anyLong(), anyLong()))
-                .thenReturn(entityData);
+        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyMap(), anyLong(), anyLong()))
+                .thenReturn(entityResources);
 
         Set<InternalQueryData> queryData = queryDataService.loadQueryData(query);
     }
@@ -330,7 +326,7 @@ public class QueryDataServiceImplTest extends BaseTest {
     public void shouldNotCreateQueryDataFromNonMatchingSystem() throws IOException {
         //given
         SystemData systemData = getTestElementSystemData();
-        EntitiesResourcesData entityData = getTestEntitiesResources(systemData);
+        Set<EntityResources> entityResources = getTestEntitiesResources(systemData);
 
         String startTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_1));
         String endTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_2));
@@ -347,8 +343,8 @@ public class QueryDataServiceImplTest extends BaseTest {
 
         //when
         Mockito.when(systemServiceMock.findByName(systemData.getName())).thenReturn(systemData);
-        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyString(), anyLong(), anyLong()))
-                .thenReturn(entityData);
+        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyMap(), anyLong(), anyLong()))
+                .thenReturn(entityResources);
 
         Set<InternalQueryData> queryData = queryDataService.loadQueryData(query);
 
@@ -358,7 +354,7 @@ public class QueryDataServiceImplTest extends BaseTest {
     public void shouldNotCreateQueryDataWithoutSystemName() throws IOException {
         //given
         SystemData systemData = getTestElementSystemData();
-        EntitiesResourcesData entityData = getTestEntitiesResources(systemData);
+        Set<EntityResources> entityResources = getTestEntitiesResources(systemData);
 
         String startTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_1));
         String endTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_2));
@@ -372,8 +368,8 @@ public class QueryDataServiceImplTest extends BaseTest {
 
         //when
         Mockito.when(systemServiceMock.findByName(systemData.getName())).thenReturn(systemData);
-        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyString(), anyLong(), anyLong()))
-                .thenReturn(entityData);
+        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyMap(), anyLong(), anyLong()))
+                .thenReturn(entityResources);
 
         Set<InternalQueryData> queryData = queryDataService.loadQueryData(query);
     }
@@ -382,7 +378,7 @@ public class QueryDataServiceImplTest extends BaseTest {
     public void shouldNotCreateQueryDataWithoutStartTime() throws IOException {
         //given
         SystemData systemData = getTestElementSystemData();
-        EntitiesResourcesData entityData = getTestEntitiesResources(systemData);
+        Set<EntityResources> entityResources = getTestEntitiesResources(systemData);
 
         String endTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_1));
 
@@ -395,8 +391,8 @@ public class QueryDataServiceImplTest extends BaseTest {
 
         //when
         Mockito.when(systemServiceMock.findByName(systemData.getName())).thenReturn(systemData);
-        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyString(), anyLong(), anyLong()))
-                .thenReturn(entityData);
+        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyMap(), anyLong(), anyLong()))
+                .thenReturn(entityResources);
 
         Set<InternalQueryData> queryData = queryDataService.loadQueryData(query);
     }
@@ -405,7 +401,7 @@ public class QueryDataServiceImplTest extends BaseTest {
     public void shouldNotCreateQueryDataWithoutEndTime() throws IOException {
         //given
         SystemData systemData = getTestElementSystemData();
-        EntitiesResourcesData entityData = getTestEntitiesResources(systemData);
+        Set<EntityResources> entityResources = getTestEntitiesResources(systemData);
         String startTime = String.valueOf(TimeUtils.getNanosFromInstant(TIME_1));
 
         Map<String, String> query = new HashMap<>();
@@ -417,8 +413,8 @@ public class QueryDataServiceImplTest extends BaseTest {
 
         //when
         Mockito.when(systemServiceMock.findByName(systemData.getName())).thenReturn(systemData);
-        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyString(), anyLong(), anyLong()))
-                .thenReturn(entityData);
+        Mockito.when(entityService.findBySystemIdKeyValuesAndTimeWindow(anyLong(), anyMap(), anyLong(), anyLong()))
+                .thenReturn(entityResources);
 
         Set<InternalQueryData> queryData = queryDataService.loadQueryData(query);
     }
diff --git a/accsoft-nxcals-etl/src/main/java/cern/accsoft/nxcals/kerberos/package-info.java b/accsoft-nxcals-etl/src/main/java/cern/accsoft/nxcals/kerberos/package-info.java
index d4f56bf80e80cf2ebe640e5d5df5d8fa1af6a6c9..b15024baca0049b0df71b40be9e89861f052827c 100644
--- a/accsoft-nxcals-etl/src/main/java/cern/accsoft/nxcals/kerberos/package-info.java
+++ b/accsoft-nxcals-etl/src/main/java/cern/accsoft/nxcals/kerberos/package-info.java
@@ -1,9 +1,4 @@
 /**
  * Copyright (c) 2016 European Organisation for Nuclear Research (CERN), All Rights Reserved.
- *
- * @author jwozniak
- */
-/**
- * @author jwozniak
  */
 package cern.accsoft.nxcals.kerberos;
\ No newline at end of file
diff --git a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/CorruptionDemo.java b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/CorruptionDemo.java
index 1b2be8802f1910ce41402c66a221d7eeb6d26430..5f828d539cbd7e5403781bc2544618299519a0a6 100644
--- a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/CorruptionDemo.java
+++ b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/CorruptionDemo.java
@@ -5,11 +5,17 @@ import cern.accsoft.nxcals.common.domain.SystemData;
 import cern.accsoft.nxcals.service.client.api.EntityService;
 import cern.accsoft.nxcals.service.client.api.SystemService;
 import cern.accsoft.nxcals.service.client.api.internal.InternalEntityService;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+import cern.accsoft.nxcals.service.client.domain.impl.SimpleKeyValues;
 import cern.accsoft.nxcals.service.client.providers.InternalServiceClientFactory;
 import cern.accsoft.nxcals.service.client.providers.ServiceClientFactory;
+import com.google.common.collect.ImmutableMap;
 
+import java.util.Map;
 import java.util.Random;
 
+import static org.mockito.Mockito.mock;
+
 /**
  * This test can be launched against a service to check if it does not have corrupted records.
  * We used to have them in the sense of entities that had incorrect partitions assigned.
@@ -66,13 +72,16 @@ public class CorruptionDemo {
 
     private void saveEntity(int devId, int classId) {
         String property = "\"property\": \"prop" + classId + "\"";
-        String entityKey = "{\"device\": \"corr_dev" + devId + "\", " + property + "}";
-        String partitionKey = "{\"class\": \"corr_devClass\", " + property + "}";
+        Map<String, Object> entityKey = ImmutableMap.of("device", "corr_dev" + devId + "\", " + property);
+        Map<String, Object> partitionKey = ImmutableMap.of("class", "corr_devClass\", " + property);
+
+        KeyValues entityKeyValues = new SimpleKeyValues("", entityKey);
+        KeyValues partitionKeyValues = new SimpleKeyValues(null, partitionKey);
 
         EntityData entityData1 = internalEntityService.findOrCreateEntityFor(
                 systemData.getId(),
-                entityKey,
-                partitionKey,
+                entityKeyValues,
+                partitionKeyValues,
                 "corr_brokenSchema1", //this does not matter
                 System.currentTimeMillis() * 1_000_000L);
 
@@ -116,7 +125,8 @@ public class CorruptionDemo {
     }
 
     private void test() {
-        EntityData entityData2 = entityService.findBySystemIdAndKeyValues(systemData.getId(), "not existent");
+        Map<String, Object> keyValues = ImmutableMap.of("not_existent", "not_existent");
+        EntityData entityData2 = entityService.findBySystemIdAndKeyValues(systemData.getId(), keyValues);
         System.err.println(entityData2);
     }
 }
diff --git a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/AbstractTest.java b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/AbstractTest.java
index 69937f31987bb298405161d496f91e271be68721..30ec0256e8d07aed9cf27a63c7deb0b044222039 100644
--- a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/AbstractTest.java
+++ b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/AbstractTest.java
@@ -2,28 +2,37 @@ package cern.accsoft.nxcals.integrationtests.service;
 
 import cern.accsoft.nxcals.common.domain.SystemData;
 import cern.accsoft.nxcals.integrationtests.ServiceProvider;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang.RandomStringUtils;
 
-import java.util.UUID;
+import java.util.Map;
 
 /**
  * Those tests need variable that will point to the service location -Dservice.url=xxx.
- * Created by jwozniak on 02/07/17.
  */
 class AbstractTest extends ServiceProvider {
-    private static final String DEVICE = "{\"device\"=\"";
-    private static final String PROPERTY = "\",\"property\"=\"prop1\"}";
-    static final String ENTITY_KEY_VALUES = DEVICE + UUID.randomUUID().toString() + PROPERTY;
-    static final String ENTITY_KEY_VALUES_FOR_VARIABLE = DEVICE + UUID.randomUUID().toString() + PROPERTY;
-    static final String ENTITY_KEY_VALUES_FOR_SCHEMA = DEVICE + UUID.randomUUID().toString() + PROPERTY;
-    static final String ENTITY_KEY_VALUES_FOR_RESOURCES = DEVICE + UUID.randomUUID().toString() + PROPERTY;
-    static final String SCHEMA = "{\"schema\"=\"" + UUID.randomUUID().toString() + PROPERTY;
+    //fixme think about this random things here, are they for 100% necesserry?
+    private static final String RANDOM_STRING = RandomStringUtils.randomAscii(64);
+
+    static final Map<String, Object> ENTITY_KEY_VALUES = ImmutableMap
+            .of("device", "device_value" + RANDOM_STRING);
+    static final Map<String, Object> ENTITY_KEY_VALUES_RESOURCES_TEST = ImmutableMap
+            .of("device", "device_value_resources_test" + RANDOM_STRING);
+    static final Map<String, Object> ENTITY_KEY_VALUES_SCHEMA_TEST = ImmutableMap
+            .of("device", "device_value_schema_test" + RANDOM_STRING);
+    static final Map<String, Object> ENTITY_KEY_VALUES_VARIABLE_TEST = ImmutableMap
+            .of("device", "device_value_variable_test" + RANDOM_STRING);
+    static final Map<String, Object> PARTITION_KEY_VALUES = ImmutableMap
+            .of("specification", "devClass1" + RANDOM_STRING);
+
     static final SystemData mockSystemData = systemService.findByName("MOCK-SYSTEM");
 
-    static final long RECORD_TIMESTAMP = 1476789831111222334L;
-    static final String PARTITION_KEY_VALUES = "{\"class\"=\"devClass1\",\"property\"=\"prop1\"}";
-    static final long MOCK_SYSTEM_ID = 0;
+    static final String SCHEMA = "TEST_SCHEMA" + RANDOM_STRING;
     static final String MOCK_SYSTEM_NAME = "MOCK-SYSTEM";
+    static final SystemData systemData = systemService.findByName(MOCK_SYSTEM_NAME);
+
+    static final long RECORD_TIMESTAMP = 1476789831111222334L;
+    static final long MOCK_SYSTEM_ID = -100;
 
-    static String variableName = UUID.randomUUID().toString();
-    static String entityKey = System.getProperty("entity.key");
+    static String variableName = "VARIABLE_NAME" + RANDOM_STRING;
 }
diff --git a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/EntitiesResourcesServiceTest.java b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/EntitiesResourcesServiceTest.java
index 2e8b28715f69da9df4da2c1fd11774ba7eb4483b..7350c9aa4c766f462721aaa9a319bc1400730fb4 100644
--- a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/EntitiesResourcesServiceTest.java
+++ b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/EntitiesResourcesServiceTest.java
@@ -1,40 +1,42 @@
 package cern.accsoft.nxcals.integrationtests.service;
 
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
 import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.common.domain.EntityResources;
 import cern.accsoft.nxcals.common.utils.TimeUtils;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+import cern.accsoft.nxcals.service.client.domain.impl.SimpleKeyValues;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
 import java.time.Instant;
 import java.time.temporal.ChronoUnit;
+import java.util.Set;
 
 import static org.junit.Assert.assertEquals;
 
-/**
- * Created by jwozniak on 02/07/17.
- */
 @RunWith(JUnit4.class)
 public class EntitiesResourcesServiceTest extends AbstractTest {
 
     @Test
     public void shouldFindEntitiesResources() {
-        EntityData entityData1 = internalEntityService
-                .findOrCreateEntityFor(mockSystemData.getId(), ENTITY_KEY_VALUES_FOR_RESOURCES,
-                        PARTITION_KEY_VALUES, SCHEMA, RECORD_TIMESTAMP);
+        KeyValues entityKeyValues = new SimpleKeyValues("", ENTITY_KEY_VALUES_RESOURCES_TEST);
+        KeyValues partitionKeyValues = new SimpleKeyValues("", PARTITION_KEY_VALUES);
 
-        EntitiesResourcesData resourceData = entitiesResourcesService
-                .findBySystemIdKeyValuesAndTimeWindow(mockSystemData.getId(), entityData1.getEntityKeyValues(),
+        EntityData entityData1 = internalEntityService.findOrCreateEntityFor(systemData.getId(), entityKeyValues,
+                        partitionKeyValues, SCHEMA, RECORD_TIMESTAMP);
+
+        Set<EntityResources> resourceData = entitiesResourcesService
+                .findBySystemIdKeyValuesAndTimeWindow(systemData.getId(), entityData1.getEntityKeyValues(),
                         TimeUtils.getNanosFromInstant(Instant.now().minus(10, ChronoUnit.DAYS)),
                         TimeUtils.getNanosFromInstant(Instant.now()));
-        assertEquals(1, resourceData.getEntityResources().size());
-        EntityResources[] entityResources = resourceData.getEntityResources().toArray(new EntityResources[0]);
-        assertEquals(1, entityResources[0].getResourcesData().getHbaseTableNames().size());
-        System.err.println(entityResources[0].getResourcesData().getHdfsPaths());
-        //FIXME - why this return 11 paths for HDFS while the current date should not be there but in HBASE -jwozniak
-        assertEquals(11, entityResources[0].getResourcesData().getHdfsPaths().size());
+        assertEquals(1, resourceData.size());
 
+        //FIXME: Use assertJ (timartin 27/11/2017)
+        EntityResources entityResources = resourceData.iterator().next();
+        assertEquals(1, entityResources.getResourcesData().getHbaseTableNames().size());
+        System.err.println(entityResources.getResourcesData().getHdfsPaths());
+        //        FIXME - why this return 11 paths for HDFS while the current date should not be there but in HBASE -jwozniak
+        assertEquals(11, entityResources.getResourcesData().getHdfsPaths().size());
     }
 }
diff --git a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/EntityServiceTest.java b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/EntityServiceTest.java
index 4f26579886f551f92ae30207d7c1c8651bd9023c..20fa186f3e0ac4fa6ad349450ddb5ad5b97b3300 100644
--- a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/EntityServiceTest.java
+++ b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/EntityServiceTest.java
@@ -1,12 +1,19 @@
 package cern.accsoft.nxcals.integrationtests.service;
 
 import cern.accsoft.nxcals.common.domain.EntityData;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+import cern.accsoft.nxcals.service.client.domain.impl.SimpleKeyValues;
+import com.google.common.collect.ImmutableMap;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
-import static org.junit.Assert.*;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
 /**
  * Created by jwozniak on 02/07/17.
@@ -18,17 +25,20 @@ public class EntityServiceTest extends AbstractTest {
     @Test
     public void shouldCreateAndFindEntity() {
 
-        EntityData entityData1 = internalEntityService.findOrCreateEntityFor(mockSystemData.getId(), ENTITY_KEY_VALUES,
-                PARTITION_KEY_VALUES, "brokenSchema1", RECORD_TIMESTAMP);
+        KeyValues entityKeyValues = new SimpleKeyValues("", ENTITY_KEY_VALUES);
+        KeyValues partitionKeyValues = new SimpleKeyValues("", PARTITION_KEY_VALUES);
+
+        EntityData entityData1 = internalEntityService.findOrCreateEntityFor(systemData.getId(), entityKeyValues,
+                partitionKeyValues, "brokenSchema1", RECORD_TIMESTAMP);
 
-        EntityData entityData2 = internalEntityService.findOrCreateEntityFor(mockSystemData.getId(), ENTITY_KEY_VALUES,
-                PARTITION_KEY_VALUES, "brokenSchema1", RECORD_TIMESTAMP);
+        EntityData entityData2 = internalEntityService.findOrCreateEntityFor(systemData.getId(), entityKeyValues,
+                partitionKeyValues, "brokenSchema1", RECORD_TIMESTAMP);
 
         Assert.assertEquals(1, entityData1.getEntityHistoryData().size());
         Assert.assertEquals(1, entityData2.getEntityHistoryData().size());
 
         EntityData entityData4 = internalEntityService
-                .findBySystemIdAndKeyValues(mockSystemData.getId(), ENTITY_KEY_VALUES);
+                .findBySystemIdAndKeyValues(systemData.getId(), ENTITY_KEY_VALUES);
         assertNotNull(entityData4);
 
         assertEquals(entityData1.getEntityKeyValues(), entityData4.getEntityKeyValues());
@@ -37,15 +47,18 @@ public class EntityServiceTest extends AbstractTest {
                 .findByEntityIdAndTimeWindow(entityData4.getId(), 0, RECORD_TIMESTAMP);
 
         assertNotNull(entityData5);
-
     }
 
     @Test
     public void shouldCreateAndFindEntityUsingIds() {
+
+        KeyValues entityKeyValues = new SimpleKeyValues("", ENTITY_KEY_VALUES);
+        KeyValues partitionKeyValues = new SimpleKeyValues("", PARTITION_KEY_VALUES);
+
         Long nextTimestamp  = RECORD_TIMESTAMP + 100;
         String nextSchema ="brokenSchema2";
-        EntityData entityData1 = internalEntityService.findOrCreateEntityFor(mockSystemData.getId(), ENTITY_KEY_VALUES,
-                PARTITION_KEY_VALUES, "brokenSchema1", RECORD_TIMESTAMP);
+        EntityData entityData1 = internalEntityService.findOrCreateEntityFor(mockSystemData.getId(), entityKeyValues,
+                partitionKeyValues, "brokenSchema1", RECORD_TIMESTAMP);
 
         Assert.assertEquals(1, entityData1.getEntityHistoryData().size());
         assertEquals(Long.valueOf(RECORD_TIMESTAMP), entityData1.getFirstEntityHistoryData().getValidFromStamp());
@@ -59,13 +72,10 @@ public class EntityServiceTest extends AbstractTest {
 
     }
 
-
-
-
     @Test
     public void shouldNotFindEntity() {
-        EntityData entityData3 = entityService.findBySystemIdAndKeyValues(mockSystemData.getId(), "aaaa");
+        Map<String, Object> keyValues = ImmutableMap.of("device", "%$#SHOULD_NOT_BE_FOUND");
+        EntityData entityData3 = entityService.findBySystemIdAndKeyValues(systemData.getId(), keyValues);
         assertNull(entityData3);
     }
-
 }
diff --git a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/PartitionServiceTest.java b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/PartitionServiceTest.java
index 496ae24cc2379e4c2a4e90a8f5b7decd46f5c971..e6a57a1bf0049c62d9876d2ed1efff896e157491 100644
--- a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/PartitionServiceTest.java
+++ b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/PartitionServiceTest.java
@@ -1,12 +1,15 @@
 package cern.accsoft.nxcals.integrationtests.service;
 
 import cern.accsoft.nxcals.common.domain.PartitionData;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+import cern.accsoft.nxcals.service.client.domain.impl.SimpleKeyValues;
+import com.google.common.collect.ImmutableMap;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+import static junit.framework.TestCase.assertNotNull;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
 /**
@@ -17,12 +20,14 @@ public class PartitionServiceTest extends AbstractTest {
 
     @Test
     public void shouldFindPartition() {
+        KeyValues entityKeyValues = new SimpleKeyValues("", ENTITY_KEY_VALUES);
+        KeyValues partitionKeyValues = new SimpleKeyValues("", PARTITION_KEY_VALUES);
         internalEntityService
-                .findOrCreateEntityFor(mockSystemData.getId(), ENTITY_KEY_VALUES, PARTITION_KEY_VALUES, "brokenSchema1",
+                .findOrCreateEntityFor(systemData.getId(), entityKeyValues, partitionKeyValues, "brokenSchema1",
                         RECORD_TIMESTAMP);
 
         PartitionData partitionData = internalPartitionService
-                .findBySystemIdAndKeyValues(mockSystemData.getId(), PARTITION_KEY_VALUES);
+                .findBySystemIdAndKeyValues(systemData.getId(), PARTITION_KEY_VALUES);
         assertNotNull(partitionData);
 
         assertEquals(PARTITION_KEY_VALUES, partitionData.getKeyValues());
@@ -31,7 +36,8 @@ public class PartitionServiceTest extends AbstractTest {
     @Test
     public void shouldNotFindPartition() {
         PartitionData partitionData = internalPartitionService
-                .findBySystemIdAndKeyValues(mockSystemData.getId(), PARTITION_KEY_VALUES + System.currentTimeMillis());
+                .findBySystemIdAndKeyValues(systemData.getId(),
+                        ImmutableMap.of("specification", "SHOULD_NOT_BE_FOUND_PARTITION_KEY_VALUES"));
         assertNull(partitionData);
     }
 
diff --git a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/SchemaServiceTest.java b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/SchemaServiceTest.java
index 50de7fe2e53b31becbd14f40be1f24cb357e9bb9..afd096ef54f9d87f47465b0af2305784e09d73a8 100644
--- a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/SchemaServiceTest.java
+++ b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/SchemaServiceTest.java
@@ -2,20 +2,20 @@ package cern.accsoft.nxcals.integrationtests.service;
 
 import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.common.domain.SchemaData;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+import cern.accsoft.nxcals.service.client.domain.impl.SimpleKeyValues;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
-/**
- * Created by jwozniak on 02/07/17.
- */
 public class SchemaServiceTest extends AbstractTest {
     @Test
     public void shouldFindSchema() {
-        EntityData entityData = internalEntityService
-                .findOrCreateEntityFor(mockSystemData.getId(), ENTITY_KEY_VALUES_FOR_SCHEMA,
-                        PARTITION_KEY_VALUES, SCHEMA, RECORD_TIMESTAMP);
+        KeyValues entityKeyValues = new SimpleKeyValues("", ENTITY_KEY_VALUES_SCHEMA_TEST);
+        KeyValues partitionKeyValues = new SimpleKeyValues(null, PARTITION_KEY_VALUES);
+        EntityData entityData = internalEntityService.findOrCreateEntityFor(systemData.getId(),
+                entityKeyValues, partitionKeyValues, SCHEMA, RECORD_TIMESTAMP);
         assertNotNull(entityData);
         SchemaData schemaData = internalSchemaService.findById(entityData.getSchemaData().getId());
         assertNotNull(schemaData);
diff --git a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/VariableServiceTest.java b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/VariableServiceTest.java
index 23ab1610ea25c83cd235153b34a26bd28dd0c0d0..c7405b120a687d794a6d214e9c3a8b8b5ded480e 100644
--- a/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/VariableServiceTest.java
+++ b/accsoft-nxcals-integration-tests/src/integration-test/java/cern/accsoft/nxcals/integrationtests/service/VariableServiceTest.java
@@ -6,6 +6,8 @@ import cern.accsoft.nxcals.common.domain.VariableData;
 import cern.accsoft.nxcals.common.domain.impl.VariableConfigDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.VariableDataImpl;
 import cern.accsoft.nxcals.common.utils.TimeUtils;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+import cern.accsoft.nxcals.service.client.domain.impl.SimpleKeyValues;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -18,22 +20,17 @@ import static junit.framework.TestCase.assertNull;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
-/**
- * Created by jwozniak on 02/07/17.
- */
-
-/**
- *
- */
 @RunWith(JUnit4.class)
 public class VariableServiceTest extends AbstractTest {
 
     @Test
     public void shouldCreateAndFindVariable() {
         //lets first find some existing entity for which we will create variable
+        KeyValues entityKeyValues = new SimpleKeyValues("", ENTITY_KEY_VALUES_VARIABLE_TEST);
+        KeyValues partitionKeyValues = new SimpleKeyValues("", PARTITION_KEY_VALUES);
         EntityData entityData = internalEntityService
-                .findOrCreateEntityFor(mockSystemData.getId(), ENTITY_KEY_VALUES_FOR_VARIABLE,
-                        PARTITION_KEY_VALUES, "brokenSchema1", RECORD_TIMESTAMP);
+                .findOrCreateEntityFor(systemData.getId(), entityKeyValues,
+                        partitionKeyValues, "brokenSchema1", RECORD_TIMESTAMP);
 
         assertNotNull(entityData);
 
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/AbstractClientFactory.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/AbstractClientFactory.java
index 2c837538fa16e0bd86235d00316ba293be31a7b1..e0346d92a70fba52505380c707705ad8553f12f7 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/AbstractClientFactory.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/AbstractClientFactory.java
@@ -1,9 +1,9 @@
 package cern.accsoft.nxcals.service.client;
 
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
 import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.common.domain.EntityHistoryData;
 import cern.accsoft.nxcals.common.domain.EntityResources;
+import cern.accsoft.nxcals.common.domain.FindOrCreateEntityRequest;
 import cern.accsoft.nxcals.common.domain.PartitionData;
 import cern.accsoft.nxcals.common.domain.ResourceData;
 import cern.accsoft.nxcals.common.domain.SchemaData;
@@ -11,10 +11,10 @@ import cern.accsoft.nxcals.common.domain.SystemData;
 import cern.accsoft.nxcals.common.domain.TimeWindow;
 import cern.accsoft.nxcals.common.domain.VariableConfigData;
 import cern.accsoft.nxcals.common.domain.VariableData;
-import cern.accsoft.nxcals.common.domain.impl.EntitiesResourcesDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.EntityDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.EntityHistoryDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.EntityResourcesImpl;
+import cern.accsoft.nxcals.common.domain.impl.FindOrCreateEntityRequestImpl;
 import cern.accsoft.nxcals.common.domain.impl.PartitionDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.ResourceDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.SchemaDataImpl;
@@ -53,8 +53,12 @@ import java.util.stream.Collectors;
 import static cern.accsoft.nxcals.common.utils.ConfigHolder.getConfig;
 import static cern.accsoft.nxcals.common.utils.ConfigHolder.getConfigIfPresent;
 
+/**
+ * Abstract base class for Feign clients. Knows how to configure the whole chain of serialization and security.
+ */
 @Slf4j
 public class AbstractClientFactory {
+    //FIXME: No need to store the servive url or passing around the SERVICE_URL_CONFIG as now things are based on system property.
     private final String serviceUrl;
     private static final String SERVICE_URL_CONFIG = "service.url";
 
@@ -62,7 +66,9 @@ public class AbstractClientFactory {
         serviceUrl = createServiceURL(SERVICE_URL_CONFIG);
     }
 
-    protected <T> T createServiceFor(Class<T> clazz, boolean useEncoder) {
+    protected <T> T createServiceFor(Class<T> clazz) {
+
+        //FIXME: Can we remove all of these comments? (timartin 27/11/2017)
         //This might be used for Jackson customization. Please don't remove, let it be here for simplicity in the future - jwozniak
         //This mapper is the default that feign-jenskins creates when no mapper is passed.
         ObjectMapper mapper = new ObjectMapper()
@@ -73,7 +79,6 @@ public class AbstractClientFactory {
 
         SimpleModule module = new SimpleModule("CustomDomainModel", Version.unknownVersion());
         SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver();
-        resolver.addMapping(EntitiesResourcesData.class, EntitiesResourcesDataImpl.class);
         resolver.addMapping(EntityData.class, EntityDataImpl.class);
         resolver.addMapping(EntityHistoryData.class, EntityHistoryDataImpl.class);
         resolver.addMapping(EntityResources.class, EntityResourcesImpl.class);
@@ -84,23 +89,16 @@ public class AbstractClientFactory {
         resolver.addMapping(TimeWindow.class, TimeWindowImpl.class);
         resolver.addMapping(VariableConfigData.class, VariableConfigDataImpl.class);
         resolver.addMapping(VariableData.class, VariableDataImpl.class);
+        resolver.addMapping(FindOrCreateEntityRequest.class, FindOrCreateEntityRequestImpl.class);
         module.setAbstractTypes(resolver);
         mapper.registerModule(module);
 
         Feign.Builder builder = Feign.builder();
-        if (useEncoder) {
-            builder = builder.encoder(new JacksonEncoder(mapper));
-        }
+
         return builder
+                .encoder(new JacksonEncoder(mapper))
                 .decoder(new JacksonDecoder(mapper))
-                .client(RibbonClient.builder()
-                        .delegate(KerberosAwareClient.builder()
-                                .setKeytabLocation(ConfigHolder.getProperty(PropertiesKeys.USER_KEYTAB_PATH_CONFIG.getPathInProperties(),(String)null))
-                                .setUserPrincipal(ConfigHolder.getProperty(PropertiesKeys.USER_PRINCIPAL_PATH.getPathInProperties(),(String)null))
-                                .setLoginOptions(getKerberosLoginOptions())
-                                .setServiceType("HTTPS")
-                                .build())
-                        .build())
+                .client(RibbonClient.builder().delegate(createKerberosClientDelegate()).build())
                 .logger(new Slf4jLogger())
                 .logLevel(Logger.Level.BASIC)
                 .errorDecoder(new ServiceClientErrorDecoder())
@@ -108,15 +106,26 @@ public class AbstractClientFactory {
                 .target(clazz, serviceUrl);
     }
 
+    private KerberosAwareClient createKerberosClientDelegate() {
+        return KerberosAwareClient.builder()
+                .setKeytabLocation(ConfigHolder
+                        .getProperty(PropertiesKeys.USER_KEYTAB_PATH_CONFIG.getPathInProperties(), (String) null))
+                .setUserPrincipal(ConfigHolder
+                        .getProperty(PropertiesKeys.USER_PRINCIPAL_PATH.getPathInProperties(), (String) null))
+                .setLoginOptions(getKerberosLoginOptions())
+                .setServiceType("HTTPS")
+                .build();
+    }
+
     private static class ServiceClientErrorDecoder implements ErrorDecoder {
         @Override
         public Exception decode(String methodKey, Response response) {
-            String body = null;
+            String body;
             try (InputStreamReader reader = new InputStreamReader(response.body().asInputStream(),
                     StandardCharsets.UTF_8.name())) {
                 body = CharStreams.toString(reader);
-            } catch (IOException e) {
-                log.warn("Cannot read response body for {}", methodKey, e);
+            } catch (IOException exception) {
+                log.warn("Cannot read response body for {}", methodKey, exception);
                 body = "Cannot read response body for " + methodKey;
             }
             if (response.status() == HttpStatus.SC_CONFLICT) {
@@ -143,10 +152,8 @@ public class AbstractClientFactory {
             throw new IllegalStateException("Cannot find schema service url for " + variableName);
         }
         String url = config.getString(variableName);
-        //FIXME - could not find other way of doing it, ugly system property - jwozniak
         System.setProperty("nxcals-service.ribbon.listOfServers", url);
-        return "https://nxcals-service"; //this is for Ribbon, must be like the prefix of the property with listOfServers
-        //return url; //this would be without Ribbon, kept for testing only - jwozniak
+        return "https://nxcals-service";
     }
 
     private static Map<String, Object> getKerberosLoginOptions() {
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/EntitiesResourcesService.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/EntitiesResourcesService.java
index 901294e284693498006aae0daf47b7cefb34c81d..74756059635b0fe46eb945e1ada6047dce0c3e16 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/EntitiesResourcesService.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/EntitiesResourcesService.java
@@ -3,16 +3,16 @@
  */
 package cern.accsoft.nxcals.service.client.api;
 
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
+import cern.accsoft.nxcals.common.domain.EntityResources;
+
+import java.util.Map;
+import java.util.Set;
 
-/**
- * Created by ntsvetko on 4/25/17.
- */
 public interface EntitiesResourcesService {
-    EntitiesResourcesData findBySystemIdKeyValuesAndTimeWindow(long systemId, String entityKeyValues,
+    Set<EntityResources> findBySystemIdKeyValuesAndTimeWindow(long systemId, Map<String, Object> entityKeyValues,
             long startTime, long endTime);
 
-    EntitiesResourcesData findByEntityIdAndTimeWindow(long entityId, long startTime, long endTime);
+    Set<EntityResources> findByEntityIdAndTimeWindow(long entityId, long startTime, long endTime);
 }
 
 
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/EntityService.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/EntityService.java
index 89bc7a644977b7072dcd0050448fe02e07590c70..5f914fec851516734092ad7f03b22247680fba04 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/EntityService.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/EntityService.java
@@ -6,17 +6,17 @@ package cern.accsoft.nxcals.service.client.api;
 import cern.accsoft.nxcals.common.domain.EntityData;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * Public access to NXCALS entities.
- *
- * @author jwozniak
  */
-
+//FIXME: VERY IMPORTANT, this class is the public entry for the service, MUST BE DOCUMENTED (timartin 27/11/2017)
 public interface EntityService {
-    EntityData findBySystemIdAndKeyValues(long systemId, String entityKeyValues);
 
-    EntityData findBySystemIdKeyValuesAndTimeWindow(long systemId, String entityKeyValues, long startTime,
+    EntityData findBySystemIdAndKeyValues(long systemId, Map<String, Object> entityKeyValues);
+
+    EntityData findBySystemIdKeyValuesAndTimeWindow(long systemId, Map<String, Object> entityKeyValues, long startTime,
             long endTime);
 
     List<EntityData> findByKeyValuesLike(String keyValuesExpression);
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/internal/InternalEntityService.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/internal/InternalEntityService.java
index 2505b708dcc9b00ce5874d0f55ef6b5d33ed5e67..64a44adb6c73066a9bb0f90dde81648be4bbfaff 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/internal/InternalEntityService.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/internal/InternalEntityService.java
@@ -2,11 +2,11 @@ package cern.accsoft.nxcals.service.client.api.internal;
 
 import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.service.client.api.EntityService;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
 
 import java.util.List;
 
 public interface InternalEntityService extends EntityService {
-
     /**
      * Finds or creates an entity for given ids. In this case only the history is sometimes created (depending on the passed timestamp).
      * @param systemId
@@ -18,12 +18,8 @@ public interface InternalEntityService extends EntityService {
      */
     EntityData findOrCreateEntityFor(long systemId, Long entityId, Long partitionId, String schema, Long timestamp);
 
-    /**
-     * Remarks (msobiesz): This I don't like - you can put whatever you want here as Strings and ... the service will
-     * happily accept it. Apart from that, what is the format of the String parameters?
-     */
-    EntityData findOrCreateEntityFor(long systemId, String entityKeyValues, String partitionKeyValues,
-            String recordFieldDefinitions, long recordTimestamp);
+    EntityData findOrCreateEntityFor(long systemId, KeyValues entityCachedRequest,
+            KeyValues partitionKeyValues, String recordFieldDefinitions, long recordTimestamp);
 
     /**
      * Extends entity's history for a given schema in a given time window
@@ -66,5 +62,4 @@ public interface InternalEntityService extends EntityService {
      */
     List<EntityData> findAllByIdIn(List<Long> entityIds);
 
-
 }
\ No newline at end of file
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/internal/InternalPartitionService.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/internal/InternalPartitionService.java
index 341e78c36ead286af9e012841968053884d1bce1..551e79c7e46e30fc196bd924646c59a8574dcc8f 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/internal/InternalPartitionService.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/api/internal/InternalPartitionService.java
@@ -3,6 +3,8 @@ package cern.accsoft.nxcals.service.client.api.internal;
 import cern.accsoft.nxcals.common.domain.PartitionData;
 import cern.accsoft.nxcals.service.client.api.PartitionService;
 
+import java.util.Map;
+
 public interface InternalPartitionService extends PartitionService {
-    PartitionData findBySystemIdAndKeyValues(long systemId, String partitionKeyValues);
+    PartitionData findBySystemIdAndKeyValues(long systemId, Map<String, Object> partitionKeyValues);
 }
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/KeyValues.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/KeyValues.java
new file mode 100644
index 0000000000000000000000000000000000000000..ad13f2b89b101a0e372a6b239266f6a91a188aa3
--- /dev/null
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/KeyValues.java
@@ -0,0 +1,23 @@
+package cern.accsoft.nxcals.service.client.domain;
+
+import java.util.Map;
+
+/**
+ * Wrapper that provides a way to identify quickly if the key values are identical or not.
+ */
+public interface KeyValues {
+
+    /**
+     * A unique identifier of that represents the provided key values. For the same key values the same identifier must be generated.
+     *
+     * @return a {@link String}
+     */
+    String getId();
+
+    /**
+     * The key values that identify the entity.
+     *
+     * @return a {@link Map} of with the key values.
+     */
+    Map<String, Object> getKeyValues();
+}
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/impl/AbstractKeyValues.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/impl/AbstractKeyValues.java
new file mode 100644
index 0000000000000000000000000000000000000000..741b2aff8e10efcc65909e712edc346bfc5e198d
--- /dev/null
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/impl/AbstractKeyValues.java
@@ -0,0 +1,39 @@
+package cern.accsoft.nxcals.service.client.domain.impl;
+
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Abstract implementation of {@link KeyValues} that enforces the correct behaviour.
+ */
+public abstract class AbstractKeyValues implements KeyValues {
+
+    private Integer hashcode;
+
+    @Override
+    public final boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        AbstractKeyValues that = (AbstractKeyValues) o;
+
+        if(getId() == null) {
+            return that.getId() == null;
+        }
+
+        return getId().equals(that.getId());
+    }
+
+    @Override
+    public final int hashCode() {
+        if (hashcode == null) {
+            hashcode = new HashCodeBuilder(17, 37)
+                    .append(getId())
+                    .toHashCode();
+        }
+        return hashcode;
+    }
+}
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/impl/GenericRecordKeyValues.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/impl/GenericRecordKeyValues.java
new file mode 100644
index 0000000000000000000000000000000000000000..36ff2ad070f4bdc04acc0eedfe03dfe981655f63
--- /dev/null
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/impl/GenericRecordKeyValues.java
@@ -0,0 +1,48 @@
+package cern.accsoft.nxcals.service.client.domain.impl;
+
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+import org.apache.avro.Schema;
+import org.apache.avro.generic.GenericRecord;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Implementation of {@link KeyValues} based on the Avro API.
+ */
+public class GenericRecordKeyValues extends AbstractKeyValues {
+
+    private final String id;
+    private final Map<String, Object> keyValues;
+
+    /**
+     * Creates an id and {@link Map} of keyValues from a {@link GenericRecord}.
+     *
+     * @param genericRecord the source of the key values.
+     */
+    public GenericRecordKeyValues(GenericRecord genericRecord) {
+        Map<String, Object> keyValues = new HashMap<>();
+        Schema schema = genericRecord.getSchema();
+        StringBuilder idStringBuilder = new StringBuilder();
+
+        for (Schema.Field field : schema.getFields()) {
+            String fieldName = field.name();
+            Object fieldValue = genericRecord.get(fieldName);
+            keyValues.put(fieldName, fieldValue);
+            idStringBuilder.append(field).append(fieldValue);
+        }
+
+        id = idStringBuilder.toString();
+        this.keyValues = keyValues;
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public Map<String, Object> getKeyValues() {
+        return new HashMap<>(keyValues);
+    }
+}
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/impl/SimpleKeyValues.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/impl/SimpleKeyValues.java
new file mode 100644
index 0000000000000000000000000000000000000000..97d9f0a01e7c239e4d1fe5dbb377be017aec5829
--- /dev/null
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/domain/impl/SimpleKeyValues.java
@@ -0,0 +1,30 @@
+package cern.accsoft.nxcals.service.client.domain.impl;
+
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Simple implementation of {@link KeyValues} that received both the id and key values as parameters.
+ */
+public class SimpleKeyValues extends AbstractKeyValues {
+
+    private final String id;
+    private final Map<String, Object> keyValues;
+
+    public SimpleKeyValues(String id, Map<String, Object> keyValues) {
+        this.id = id;
+        this.keyValues = new HashMap<>(keyValues);
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public Map<String, Object> getKeyValues() {
+        return new HashMap<>(keyValues);
+    }
+}
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/ClientFactory.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/ClientFactory.java
index e5a788393e8e1643fb41b745dea3bb96a6ad370c..d5d1e4a697c34a70fbe01ea7ab90be10fbb1640a 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/ClientFactory.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/ClientFactory.java
@@ -6,7 +6,7 @@ package cern.accsoft.nxcals.service.client.providers;
 
 import cern.accsoft.nxcals.service.client.AbstractClientFactory;
 import cern.accsoft.nxcals.service.client.providers.feign.CompactionClient;
-import cern.accsoft.nxcals.service.client.providers.feign.EntitiesResourcesClient;
+import cern.accsoft.nxcals.service.client.providers.feign.EntitiyResourcesClient;
 import cern.accsoft.nxcals.service.client.providers.feign.EntityClient;
 import cern.accsoft.nxcals.service.client.providers.feign.PartitionClient;
 import cern.accsoft.nxcals.service.client.providers.feign.SchemaClient;
@@ -24,28 +24,28 @@ class ClientFactory extends AbstractClientFactory {
     private final SystemClient systemClient;
     private final SchemaClient schemaClient;
     private final EntityClient entityClient;
-    private final EntitiesResourcesClient resourceClient;
+    private final EntitiyResourcesClient resourceClient;
     private final VariableClient variableService;
     private final CompactionClient compactionService;
 
     private ClientFactory() {
         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-        this.partitionClient = createNotFoundRuntimeExceptionProxy(PartitionClient.class, classLoader, false);
-        this.systemClient = createNotFoundRuntimeExceptionProxy(SystemClient.class, classLoader, false);
-        this.schemaClient = createNotFoundRuntimeExceptionProxy(SchemaClient.class, classLoader, false);
-        this.entityClient = createNotFoundRuntimeExceptionProxy(EntityClient.class, classLoader, false);
-        this.resourceClient = createNotFoundRuntimeExceptionProxy(EntitiesResourcesClient.class, classLoader, false);
-        this.variableService = createNotFoundRuntimeExceptionProxy(VariableClient.class, classLoader, true);
-        this.compactionService = createNotFoundRuntimeExceptionProxy(CompactionClient.class, classLoader, false);
+        this.partitionClient = createNotFoundRuntimeExceptionProxy(PartitionClient.class, classLoader);
+        this.systemClient = createNotFoundRuntimeExceptionProxy(SystemClient.class, classLoader);
+        this.schemaClient = createNotFoundRuntimeExceptionProxy(SchemaClient.class, classLoader);
+        this.entityClient = createNotFoundRuntimeExceptionProxy(EntityClient.class, classLoader);
+        this.resourceClient = createNotFoundRuntimeExceptionProxy(EntitiyResourcesClient.class, classLoader);
+        this.variableService = createNotFoundRuntimeExceptionProxy(VariableClient.class, classLoader);
+        this.compactionService = createNotFoundRuntimeExceptionProxy(CompactionClient.class, classLoader);
     }
 
     /**
      * Suppressing because for our use cases it will always succeed
      */
     @SuppressWarnings("unchecked")
-    private <T> T createNotFoundRuntimeExceptionProxy(Class<T> clazz, ClassLoader classLoader, boolean useEncoder) {
+    private <T> T createNotFoundRuntimeExceptionProxy(Class<T> clazz, ClassLoader classLoader) {
         return (T) Proxy.newProxyInstance(classLoader, new Class[] { clazz },
-                new NotFoundRuntimeExceptionInterceptor<>(createServiceFor(clazz, useEncoder)));
+                new NotFoundRuntimeExceptionInterceptor<>(createServiceFor(clazz)));
     }
 
     static SchemaClient createSchemaSerivce() {
@@ -64,7 +64,7 @@ class ClientFactory extends AbstractClientFactory {
         return INSTANCE.systemClient;
     }
 
-    static EntitiesResourcesClient createResourceService() {
+    static EntitiyResourcesClient createResourceService() {
         return INSTANCE.resourceClient;
     }
 
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/EntitiesResourcesProvider.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/EntitiesResourcesProvider.java
index a90dc7059e6be4c7239093549f055b0fb5a92d82..20a2d6b067e30973a5aebcbaf44ee16df136828b 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/EntitiesResourcesProvider.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/EntitiesResourcesProvider.java
@@ -4,23 +4,26 @@
 
 package cern.accsoft.nxcals.service.client.providers;
 
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
+import cern.accsoft.nxcals.common.domain.EntityResources;
 import cern.accsoft.nxcals.service.client.api.internal.InternalEntitiesResourcesService;
-import cern.accsoft.nxcals.service.client.providers.feign.EntitiesResourcesClient;
+import cern.accsoft.nxcals.service.client.providers.feign.EntitiyResourcesClient;
 import lombok.RequiredArgsConstructor;
 
+import java.util.Map;
+import java.util.Set;
+
 @RequiredArgsConstructor
 class EntitiesResourcesProvider implements InternalEntitiesResourcesService {
-    private final EntitiesResourcesClient httpService;
+    private final EntitiyResourcesClient httpService;
 
     @Override
-    public EntitiesResourcesData findBySystemIdKeyValuesAndTimeWindow(long systemId, String entityKeyValues,
-            long startTime, long endTime) {
+    public Set<EntityResources> findBySystemIdKeyValuesAndTimeWindow(long systemId,
+            Map<String, Object> entityKeyValues, long startTime, long endTime) {
         return httpService.findBySystemIdKeyValuesAndTimeWindow(systemId, entityKeyValues, startTime, endTime);
     }
 
     @Override
-    public EntitiesResourcesData findByEntityIdAndTimeWindow(long entityId, long startTime, long endTime) {
+    public Set<EntityResources> findByEntityIdAndTimeWindow(long entityId, long startTime, long endTime) {
         return httpService.findByEntityIdAndTimeWindow(entityId, startTime, endTime);
     }
 }
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/EntityProvider.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/EntityProvider.java
index f4e5255822d7c9e34df2161ee8ea9b374334f1d8..c1cd0923b408d29d020e0aeec3f0d0d25a0d6d03 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/EntityProvider.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/EntityProvider.java
@@ -5,20 +5,22 @@ package cern.accsoft.nxcals.service.client.providers;
 
 import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.common.domain.EntityHistoryData;
+import cern.accsoft.nxcals.common.domain.FindOrCreateEntityRequest;
 import cern.accsoft.nxcals.common.domain.PartitionData;
 import cern.accsoft.nxcals.common.domain.impl.EntityDataImpl;
+import cern.accsoft.nxcals.common.domain.impl.FindOrCreateEntityRequestImpl;
 import cern.accsoft.nxcals.common.utils.TimeUtils;
 import cern.accsoft.nxcals.service.client.AbstractProvider;
 import cern.accsoft.nxcals.service.client.DataConflictRuntimeException;
 import cern.accsoft.nxcals.service.client.api.internal.InternalEntityService;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
 import cern.accsoft.nxcals.service.client.providers.feign.EntityClient;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.text.MessageFormat;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.BiFunction;
@@ -31,25 +33,26 @@ import java.util.function.Supplier;
  * @author jwozniak
  * @date Jul 21, 2016 4:40:15 PM
  */
-class EntityProvider extends AbstractProvider<Long, String, EntityData, EntityClient> implements InternalEntityService {
-    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+class EntityProvider extends AbstractProvider<Long, Map<String, Object>, EntityData, EntityClient> implements InternalEntityService {
+
+    private static final BiFunction<Map<String, Object>, PartitionData,Boolean> KEY_VALUE_MATCHER =
+            (partitionKeyValues, partitionData) -> partitionData.getKeyValues().equals(partitionKeyValues);
     private static final Logger LOGGER = LoggerFactory.getLogger(EntityProvider.class);
     private final ConcurrentHashMap<String, EntityData> entityCacheByKeyValues = new ConcurrentHashMap<>();
     private final ConcurrentHashMap<Long, EntityData> entityCacheById = new ConcurrentHashMap<>();
-    private BiFunction<String,PartitionData,Boolean> keyValueMatcher = (partitionKeyValues, partitionData) -> partitionData.getKeyValues().equals(partitionKeyValues);
-    private BiFunction<Long,PartitionData,Boolean> idMatcher = (partitionId, partitionData) -> partitionData.getId() == partitionId;
+    private BiFunction<Long, PartitionData, Boolean> idMatcher = (partitionId, partitionData) -> partitionData.getId() == partitionId;
 
     EntityProvider(EntityClient httpService) {
         super(httpService);
     }
 
     @Override
-    public EntityData findBySystemIdAndKeyValues(long system, String entityKeyValues) {
+    public EntityData findBySystemIdAndKeyValues(long system, Map<String, Object> entityKeyValues) {
         return serviceFindEntityFor(system, entityKeyValues);
     }
 
     @Override
-    protected EntityData createDataForCache(Long systemId, String entityKeyValues) {
+    protected EntityData createDataForCache(Long systemId, Map<String, Object> entityKeyValues) {
         return getHttpClient().findBySystemIdAndKeyValues(systemId, entityKeyValues);
     }
 
@@ -96,7 +99,7 @@ class EntityProvider extends AbstractProvider<Long, String, EntityData, EntityCl
 
 
     @Override
-    public EntityData findOrCreateEntityFor(long systemId, String entityKeyValues, String partitionKeyValues,
+    public EntityData findOrCreateEntityFor(long systemId, KeyValues entityKeyValues, KeyValues partitionKeyValues,
             String schema, long recordTimestamp) {
         try {
             return internalFindOrCreateEntityFor(systemId, entityKeyValues, partitionKeyValues, schema,
@@ -109,14 +112,14 @@ class EntityProvider extends AbstractProvider<Long, String, EntityData, EntityCl
             //History rewrite failure will always fail for the second time so we should not retry.
             LOGGER.warn(
                     "Retrying - another client has already created an entity for system {} entity {}  partition {} schema {}",
-                    systemId, entityKeyValues, partitionKeyValues, schema, ex);
+                    systemId, entityKeyValues.getKeyValues(), partitionKeyValues, schema, ex);
             return internalFindOrCreateEntityFor(systemId, entityKeyValues, partitionKeyValues, schema,
                     recordTimestamp);
         }
 
     }
 
-    private EntityData internalFindOrCreateEntityFor(long systemId, String entityKeyValues, String partitionKeyValues,
+    private EntityData internalFindOrCreateEntityFor(long systemId, KeyValues entityKeyValues, KeyValues partitionKeyValues,
             String schema, long recordTimestamp) {
         //We only cache by entityKeyValues as this code is always for the same system.
         //If the cache does not contain the entity this first call always hits the remote service in order to put the entity into the cache.
@@ -129,33 +132,34 @@ class EntityProvider extends AbstractProvider<Long, String, EntityData, EntityCl
         // THIS IS A TRY WITH LESS LOCKING IMPLEMENTATION. BEWARE THAT put ALSO SYNCHRONIZES...
 
         //this is only finding
-        EntityData entityData = getEntityData(entityKeyValues, entityCacheByKeyValues, () -> serviceFindEntityFor(systemId, entityKeyValues),false);
+        EntityData entityData = getEntityData(entityKeyValues.getId(), entityCacheByKeyValues,
+                () -> serviceFindEntityFor(systemId, entityKeyValues.getKeyValues()), false);
 
-        if (entityData == null || !isRecordDefinitionFoundInCachedHistory(entityData, partitionKeyValues, keyValueMatcher, schema,recordTimestamp)) {
+        if (entityData == null || !isRecordDefinitionFoundInCachedHistory(entityData, partitionKeyValues.getKeyValues(),
+                KEY_VALUE_MATCHER, schema,recordTimestamp)) {
             //This is a new record (null) or data is ok as isRecordDefinitionFoundInCachedHistory will throw an exception for history rewrite.
             //This call is synchronized on the key by the ConcurrentHashMap on the key but it has to go the remote service to add data to history.
             try {
                 //this is finding or creating
-                return getEntityData(entityKeyValues, entityCacheByKeyValues,
-                        () -> serviceFindOrCreateEntityFor(systemId, entityKeyValues, partitionKeyValues, schema,
+                return getEntityData(entityKeyValues.getId(), entityCacheByKeyValues,
+                        () -> serviceFindOrCreateEntityFor(systemId, entityKeyValues.getKeyValues(), partitionKeyValues.getKeyValues(), schema,
                                 recordTimestamp), true);
 
             } catch (DataConflictRuntimeException e) {
                 //We have a data conflict for this entity. The cache needs to be updated with the recent state of this entity to avoid hitting the service.
                 LOGGER.warn("Data conflict for system={}, entity={}, partition={}, schema={}, timestamp={}", systemId,
-                        entityKeyValues, partitionKeyValues, schema, recordTimestamp);
+                        entityKeyValues.getKeyValues(), partitionKeyValues, schema, recordTimestamp);
 
                 //this is only finding
-                getEntityData(entityKeyValues, entityCacheByKeyValues, () -> serviceFindEntityFor(systemId,
-                        entityKeyValues), true);
+                getEntityData(entityKeyValues.getId(), entityCacheByKeyValues, () -> serviceFindEntityFor(systemId,
+                        entityKeyValues.getKeyValues()),true);
 
                 throw new IllegalStateException(MessageFormat
                         .format(("Data conflict detected, schema or partition history rewrite error, for systemId={0," +
                                         "number,#}, entityKey={1}, partitionKey={2},recordTimestamp={3}, schema={4}")
                                         ,
-                                systemId, entityKeyValues, partitionKeyValues,
+                                systemId, entityKeyValues.getKeyValues(), partitionKeyValues,
                                 TimeUtils.getInstantFromNanos(recordTimestamp), schema), e);
-
             }
         } else {
             return entityData;
@@ -168,7 +172,7 @@ class EntityProvider extends AbstractProvider<Long, String, EntityData, EntityCl
     }
 
     @Override
-    public EntityData findBySystemIdKeyValuesAndTimeWindow(long systemId, String entityKeyValues, long startTime,
+    public EntityData findBySystemIdKeyValuesAndTimeWindow(long systemId, Map<String, Object> entityKeyValues, long startTime,
             long endTime) {
         LOGGER.debug("Calling a remote service to findEntityFor system={}, entityKey={} startTime={} endTime={}",
                 systemId, entityKeyValues, TimeUtils.getInstantFromNanos(startTime),
@@ -190,12 +194,7 @@ class EntityProvider extends AbstractProvider<Long, String, EntityData, EntityCl
 
     @Override
     public List<EntityData> updateEntities(List<EntityData> entityDataList) {
-        try {
-            return getHttpClient()
-                    .updateEntities(OBJECT_MAPPER.writeValueAsString(entityDataList));
-        } catch (JsonProcessingException exception) {
-            throw new RuntimeException(exception);
-        }
+        return getHttpClient().updateEntities(entityDataList);
     }
 
     @Override
@@ -211,8 +210,6 @@ class EntityProvider extends AbstractProvider<Long, String, EntityData, EntityCl
         return getHttpClient().findAllByIdIn(entityIds);
     }
 
-
-
     /**
      * Uses supplier to fill in the cache.
      *
@@ -243,27 +240,30 @@ class EntityProvider extends AbstractProvider<Long, String, EntityData, EntityCl
         }
     }
 
-    private EntityData serviceFindEntityFor(long systemId, String entityKeyValues) {
+    private EntityData serviceFindEntityFor(long systemId, Map<String, Object> entityKeyValues) {
         LOGGER.debug("Calling a remote service to findEntityFor system={}, entityKey={}", systemId, entityKeyValues);
         return getHttpClient().findBySystemIdAndKeyValues(systemId, entityKeyValues);
-
     }
 
     private EntityData serviceFindEntityFor(long id, long timestamp) {
         LOGGER.debug("Calling a remote service to findEntityFor entityId={} timestamp={}", id,timestamp);
         return getHttpClient().findByEntityIdAndTimeWindow(id, timestamp, timestamp);
-
     }
 
 
 
-    protected EntityData serviceFindOrCreateEntityFor(long systemId, String entityKeyValues, String partitionKeyValues,
-            String schema, long recordTimestamp) {
+    protected EntityData serviceFindOrCreateEntityFor(long systemId, Map<String, Object> entityKeyValues,
+            Map<String, Object> partitionKeyValues, String schema, long recordTimestamp) {
         LOGGER.debug(
                 "Calling a remote service to findOrCreateEntityFor system={}, entityKey={}, partitionKey={}, schema={}, timestamp={}",
                 systemId, entityKeyValues, partitionKeyValues, schema, recordTimestamp);
+        FindOrCreateEntityRequest findOrCreateEntityRequest = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(entityKeyValues)
+                .partitionKeyValues(partitionKeyValues)
+                .schema(schema.toString())
+                .build();
         return getHttpClient()
-                .findOrCreateEntityFor(systemId, entityKeyValues, partitionKeyValues, recordTimestamp, schema);
+                .findOrCreateEntityFor(systemId, recordTimestamp, findOrCreateEntityRequest);
     }
 
     private EntityData serviceExtendEntityHistoryDataFor(long entityId, String schema, long from) {
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/PartitionProvider.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/PartitionProvider.java
index 0c2b434334fbb90669fab5c9a16ef0184c74195f..5a8a87e9c32bff8358681eaa56bf3bf303d9b2db 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/PartitionProvider.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/PartitionProvider.java
@@ -8,11 +8,13 @@ import cern.accsoft.nxcals.service.client.AbstractProvider;
 import cern.accsoft.nxcals.service.client.api.internal.InternalPartitionService;
 import cern.accsoft.nxcals.service.client.providers.feign.PartitionClient;
 
+import java.util.Map;
+
 /**
  * @author Marcin Sobieszek
  * @date Jul 21, 2016 4:46:52 PM
  */
-class PartitionProvider extends AbstractProvider<Long, String, PartitionData, PartitionClient>
+class PartitionProvider extends AbstractProvider<Long, Map<String, Object>, PartitionData, PartitionClient>
         implements InternalPartitionService {
 
     PartitionProvider(PartitionClient httpClient) {
@@ -26,12 +28,12 @@ class PartitionProvider extends AbstractProvider<Long, String, PartitionData, Pa
      * have to override the method) but could be in a future.
      */
     @Override
-    protected PartitionData createDataForCache(Long systemId, String partitionKeyValues) {
+    protected PartitionData createDataForCache(Long systemId, Map<String, Object> partitionKeyValues) {
         return this.getHttpClient().findBySystemIdAndKeyValues(systemId, partitionKeyValues);
     }
 
     @Override
-    public PartitionData findBySystemIdAndKeyValues(long systemId, String partitionKeyValues) {
+    public PartitionData findBySystemIdAndKeyValues(long systemId, Map<String, Object> partitionKeyValues) {
         return super.getDataFromCache(systemId, partitionKeyValues);
     }
 }
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/CompactionClient.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/CompactionClient.java
index 7f3e54ea4ced6c10275a5550df0053c6a493dbc1..cc8ad9f190fd40095216a5bba4a326def2dad9d1 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/CompactionClient.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/CompactionClient.java
@@ -5,15 +5,16 @@ import feign.Headers;
 import feign.Param;
 import feign.RequestLine;
 
+import static cern.accsoft.nxcals.common.web.Endpoints.COMPACTION_SHOULD_COMPACT;
+import static cern.accsoft.nxcals.common.web.HttpVerbs.POST;
+
 /**
- * Interface using Feign as implementation
- *
- * @author ntsvetko
+ * Feing declarative service interface for consuming Compaction service..
  */
 public interface CompactionClient {
 
     @Headers({ "Content-Type: application/json" })
-    @RequestLine("POST /compaction/shouldCompact")
+    @RequestLine(POST + COMPACTION_SHOULD_COMPACT)
     @Body("{path}")
     boolean shouldCompact(@Param("path") String path);
 }
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/EntitiesResourcesClient.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/EntitiesResourcesClient.java
deleted file mode 100644
index 353ba47365ecc681901c27bc952f4656857b662c..0000000000000000000000000000000000000000
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/EntitiesResourcesClient.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Copyright (c) 2017 European Organisation for Nuclear Research (CERN), All Rights Reserved.
- */
-package cern.accsoft.nxcals.service.client.providers.feign;
-
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
-import feign.Param;
-import feign.RequestLine;
-
-public interface EntitiesResourcesClient {
-
-    @RequestLine(
-            "GET /resources/search/findBySystemIdKeyValuesAndTimeWindow?systemId={systemId}&entityKeyValues={entityKeyValues}&startTime={startTime}&endTime={endTime}")
-    EntitiesResourcesData findBySystemIdKeyValuesAndTimeWindow(
-            @Param("systemId") long systemId,
-            @Param("entityKeyValues") String entityKeyValues,
-            @Param("startTime") long startTime,
-            @Param("endTime") long endTime);
-
-    @RequestLine(
-            "GET /resources/search/findByEntityIdAndTimeWindow?entityId={entityId}&startTime={startTime}&endTime={endTime}")
-    EntitiesResourcesData findByEntityIdAndTimeWindow(
-            @Param("entityId") long entityId,
-            @Param("startTime") long startTime,
-            @Param("endTime") long endTime);
-}
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/EntitiyResourcesClient.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/EntitiyResourcesClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..fb072c3e9f5f38a8ac46654a67a78ee3141c3cf9
--- /dev/null
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/EntitiyResourcesClient.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2017 European Organisation for Nuclear Research (CERN), All Rights Reserved.
+ */
+package cern.accsoft.nxcals.service.client.providers.feign;
+
+import cern.accsoft.nxcals.common.domain.EntityResources;
+import feign.Headers;
+import feign.Param;
+import feign.RequestLine;
+
+import java.util.Map;
+import java.util.Set;
+
+import static cern.accsoft.nxcals.common.web.Endpoints.RESOURCES;
+import static cern.accsoft.nxcals.common.web.HttpVerbs.GET;
+import static cern.accsoft.nxcals.common.web.HttpVerbs.POST;
+
+/**
+ * Feing declarative service interface for consuming Entity Resources service.
+ */
+public interface EntitiyResourcesClient {
+    @Headers("Content-Type: application/json")
+    @RequestLine(POST + RESOURCES
+            + "?systemId={systemId}"
+            + "&startTime={startTime}"
+            + "&endTime={endTime}")
+    Set<EntityResources> findBySystemIdKeyValuesAndTimeWindow(
+            @Param("systemId") long systemId,
+            Map<String, Object> entityKeyValues,
+            @Param("startTime") long startTime,
+            @Param("endTime") long endTime);
+
+    @RequestLine(GET + RESOURCES
+            + "?entityId={entityId}"
+            + "&startTime={startTime}"
+            + "&endTime={endTime}")
+    Set<EntityResources> findByEntityIdAndTimeWindow(
+            @Param("entityId") long entityId,
+            @Param("startTime") long startTime,
+            @Param("endTime") long endTime);
+}
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/EntityClient.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/EntityClient.java
index c15c5547c92983489e5744c456433801966dee39..1121bb92ac5a9c431b35ade4622e5bdef14c22ef 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/EntityClient.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/EntityClient.java
@@ -3,93 +3,117 @@
  */
 package cern.accsoft.nxcals.service.client.providers.feign;
 
+import cern.accsoft.nxcals.common.domain.FindOrCreateEntityRequest;
 import cern.accsoft.nxcals.common.domain.EntityData;
+import feign.Body;
 import feign.Headers;
 import feign.Param;
 import feign.RequestLine;
 
 import java.util.List;
+import java.util.Map;
 
-import static cern.accsoft.nxcals.service.client.providers.feign.EntityClient.HttpHeaders.ACCEPT_APPLICATION_JSON;
-import static cern.accsoft.nxcals.service.client.providers.feign.EntityClient.HttpHeaders.CONTENT_TYPE_APPLICATION_JSON;
-import static cern.accsoft.nxcals.service.client.providers.feign.EntityClient.Paths.BASE_PATH;
-import static cern.accsoft.nxcals.service.client.providers.feign.EntityClient.Paths.SEARCH_PATH;
-import static cern.accsoft.nxcals.service.client.providers.feign.EntityClient.Paths.UPDATE;
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITIES;
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITY_EXTEND_FIRST_HISTORY;
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITY_UPDATE;
+import static cern.accsoft.nxcals.common.web.HttpHeaders.ACCEPT_APPLICATION_JSON;
+import static cern.accsoft.nxcals.common.web.HttpHeaders.CONTENT_TYPE_APPLICATION_JSON;
+import static cern.accsoft.nxcals.common.web.HttpVerbs.GET;
+import static cern.accsoft.nxcals.common.web.HttpVerbs.POST;
+import static cern.accsoft.nxcals.common.web.HttpVerbs.PUT;
 
 /**
  * Feign declarative service interface for consuming EntityService.
  */
 public interface EntityClient {
-
-
-    interface Paths {
-        String BASE_PATH = "/entities";
-
-        String SEARCH_PATH = BASE_PATH + "/search";
-        String UPDATE = BASE_PATH + "/update";
-    }
-
-    interface HttpHeaders {
-        String APPLICATION_JSON_DATA_FORMAT = "application/json";
-
-        String ACCEPT_APPLICATION_JSON = "Accept: " + APPLICATION_JSON_DATA_FORMAT;
-        String CONTENT_TYPE_APPLICATION_JSON = "Content-Type: " + APPLICATION_JSON_DATA_FORMAT;
-    }
+    @Headers({ACCEPT_APPLICATION_JSON, CONTENT_TYPE_APPLICATION_JSON})
+    @RequestLine(POST + ENTITIES
+            + "?systemId={systemId}")
+    EntityData findBySystemIdAndKeyValues(
+            @Param("systemId") long systemId,
+            Map<String, Object> entityKeyValues
+    );
+
+    @Headers({ACCEPT_APPLICATION_JSON, CONTENT_TYPE_APPLICATION_JSON})
+    @RequestLine(POST + ENTITIES
+            + "?systemId={systemId}&"
+            + "startTime={startTime}&"
+            + "endTime={endTime}")
+    EntityData findBySystemIdKeyValuesAndTimeWindow(
+            @Param("systemId") long systemId,
+            Map<String, Object> entityKeyValues,
+            @Param("startTime") long startTime,
+            @Param("endTime") long endTime
+    );
 
     @Headers(ACCEPT_APPLICATION_JSON)
-    @RequestLine("GET " + SEARCH_PATH +
-            "/findBySystemIdAndKeyValues?systemId={systemId}&entityKeyValues={entityKeyValues}")
-    EntityData findBySystemIdAndKeyValues(@Param("systemId") long systemId,
-            @Param("entityKeyValues") String entityKeyValues);
+    @RequestLine(GET + ENTITIES
+            + "?keyValuesExpression={keyValuesExpression}")
+    List<EntityData> findByKeyValuesLike(
+            @Param("keyValuesExpression") String keyValuesExpression
+    );
+
+    @Headers({ACCEPT_APPLICATION_JSON, CONTENT_TYPE_APPLICATION_JSON})
+    @RequestLine(PUT + ENTITIES
+            + "?systemId={systemId}&"
+            + "recordTimestamp={recordTimestamp}")
+    EntityData findOrCreateEntityFor(
+            @Param("systemId") long systemId,
+            @Param("recordTimestamp") long recordTimestamp,
+            FindOrCreateEntityRequest findOrCreateEntityRequest
+    );
+
+    @Headers({ACCEPT_APPLICATION_JSON, CONTENT_TYPE_APPLICATION_JSON})
+    @RequestLine(PUT + ENTITY_EXTEND_FIRST_HISTORY
+            + "?entityId={entityId}&"
+            + "from={from}")
+    EntityData extendEntityFirstHistoryDataFor(
+            @Param("entityId") long entityId,
+            @Param("from") long from,
+            String schema
+    );
+
+    @Headers({ACCEPT_APPLICATION_JSON})
+    @Body("{schema}")
+    @RequestLine(PUT + ENTITIES
+            + "?systemId={systemId}"
+            + "&entityId={entityId}"
+            + "&partitionId={partitionId}"
+            + "&recordTimestamp={recordTimestamp}")
+    EntityData findOrCreateEntityFor(
+            @Param("systemId") long systemId,
+            @Param("entityId") long entityId,
+            @Param("partitionId") long partitionId,
+            @Param("recordTimestamp") long recordTimestamp,
+            @Param("schema") String schema);
 
     @Headers(ACCEPT_APPLICATION_JSON)
-    @RequestLine("GET " + SEARCH_PATH
-            + "/findBySystemIdKeyValuesAndTimeWindow?systemId={systemId}&entityKeyValues={entityKeyValues}&partitionKeyValues={partitionKeyValues}&startTime={startTime}&endTime={endTime}")
-    EntityData findBySystemIdKeyValuesAndTimeWindow(@Param("systemId") long systemId,
-            @Param("entityKeyValues") String entityKeyValues, @Param("startTime") long startTime,
-            @Param("endTime") long endTime);
+    @RequestLine(GET + ENTITIES
+            + "?entityId={entityId}&"
+            + "startTime={startTime}&"
+            + "endTime={endTime}")
+    EntityData findByEntityIdAndTimeWindow(
+            @Param("entityId") long entityId,
+            @Param("startTime") long startTime,
+            @Param("endTime") long endTime
+    );
+
+    @Headers({CONTENT_TYPE_APPLICATION_JSON,ACCEPT_APPLICATION_JSON})
+    @RequestLine(PUT + ENTITY_UPDATE)
+    List<EntityData> updateEntities(
+            List<EntityData> entityDataList
+    );
 
     @Headers(ACCEPT_APPLICATION_JSON)
-    @RequestLine("GET " + SEARCH_PATH + "/findByExpression/keyValues?expression={keyValuesExpression}")
-    List<EntityData> findByKeyValuesLike(@Param("keyValuesExpression") String keyValuesExpression);
+    @RequestLine(GET + ENTITIES + "/{entityId}")
+    EntityData findById(
+            @Param("entityId") long entityId
+    );
 
     @Headers(ACCEPT_APPLICATION_JSON)
-    @RequestLine("PUT " + SEARCH_PATH
-            + "/findOrCreateEntityFor?systemId={systemId}&entityKeyValues={entityKeyValues}&partitionKeyValues={partitionKeyValues}&recordTimestamp={recordTimestamp}")
-    EntityData findOrCreateEntityFor(@Param("systemId") long systemId, @Param("entityKeyValues") String entityKeyValues,
-            @Param("partitionKeyValues") String partitionKeyValues, @Param("recordTimestamp") long recordTimestamp,
-            String recordFieldDefinitions);
-
-    @Headers(ACCEPT_APPLICATION_JSON)
-    @RequestLine("PUT " + SEARCH_PATH + "/extendEntityFirstHistoryDataFor?entityId={entityId}&from={from}")
-    EntityData extendEntityFirstHistoryDataFor(@Param("entityId") long entityId, @Param("from") long from,
-            String schema);
-
-    @Headers(ACCEPT_APPLICATION_JSON)
-    @RequestLine("PUT " + SEARCH_PATH + "/findOrCreateEntityForIds?systemId={systemId}&entityId={entityId}&partitionId={partitionId}&recordTimestamp={recordTimestamp}")
-    EntityData findOrCreateEntityFor(@Param("systemId") long systemId, @Param("entityId") long entityId, @Param("partitionId") long partitionId, @Param("recordTimestamp") long recordTimestamp, String schema);
-
-
-
-    @Headers(ACCEPT_APPLICATION_JSON)
-    @RequestLine("GET " + SEARCH_PATH
-            + "/findByEntityIdAndTimeWindow?entityId={entityId}&startTime={startTime}&endTime={endTime}")
-    EntityData findByEntityIdAndTimeWindow(@Param("entityId") long entityId, @Param("startTime") long startTime,
-            @Param("endTime") long endTime);
-
-    @Headers({
-            CONTENT_TYPE_APPLICATION_JSON,
-            ACCEPT_APPLICATION_JSON
-    })
-    @RequestLine("PUT " + UPDATE)
-    List<EntityData> updateEntities(String idToNameMap);
-
-    @Headers(ACCEPT_APPLICATION_JSON)
-    @RequestLine("GET " + BASE_PATH + "/{entityId}")
-    EntityData findById(@Param("entityId") long entityId);
-
-    @Headers(ACCEPT_APPLICATION_JSON)
-    @RequestLine("GET " + BASE_PATH + "?ids={entityIds}")
-    List<EntityData> findAllByIdIn(@Param("entityIds") List<Long> entityIds);
-
+    @RequestLine(GET + ENTITIES
+            + "?ids={entityIds}")
+    List<EntityData> findAllByIdIn(
+            @Param("entityIds") List<Long> entityIds
+    );
 }
\ No newline at end of file
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/PartitionClient.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/PartitionClient.java
index dd07892761f9d6e5af82ffc168dbea1f8a8f85a2..ee64a3ed8c32b074bf5452a7765f88d6fdf4bd63 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/PartitionClient.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/PartitionClient.java
@@ -4,16 +4,22 @@
 package cern.accsoft.nxcals.service.client.providers.feign;
 
 import cern.accsoft.nxcals.common.domain.PartitionData;
+import feign.Headers;
 import feign.Param;
 import feign.RequestLine;
 
+import java.util.Map;
+
+import static cern.accsoft.nxcals.common.web.Endpoints.PARTITIONS;
+import static cern.accsoft.nxcals.common.web.HttpHeaders.CONTENT_TYPE_APPLICATION_JSON;
+import static cern.accsoft.nxcals.common.web.HttpVerbs.POST;
+
 /**
- * @author Marcin Sobieszek
- * @date Jul 21, 2016 1:56:37 PM
+ * Feing declarative service interface for consuming Partition service.
  */
 public interface PartitionClient {
-    @RequestLine(
-            "GET /partitions/search/findBySystemIdAndKeyValues?systemId={systemId}&partitionKeyValues={partitionKeyValues}")
-    PartitionData findBySystemIdAndKeyValues(
-            @Param("systemId") long systemId, @Param("partitionKeyValues") String partitionKeyValues);
+    @Headers(CONTENT_TYPE_APPLICATION_JSON)
+    @RequestLine(POST + PARTITIONS
+            + "?systemId={systemId}")
+    PartitionData findBySystemIdAndKeyValues(@Param("systemId") long systemId, Map<String, Object> partitionKeyValues);
 }
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/SchemaClient.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/SchemaClient.java
index 7e60c4425992c02fc4aa5acb5ec4f424482d050d..4193aedb737c90f8853023a397cc1b9d940787eb 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/SchemaClient.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/SchemaClient.java
@@ -7,12 +7,13 @@ import cern.accsoft.nxcals.common.domain.SchemaData;
 import feign.Param;
 import feign.RequestLine;
 
+import static cern.accsoft.nxcals.common.web.Endpoints.SCHEMA_WITH_ID;
+import static cern.accsoft.nxcals.common.web.HttpVerbs.GET;
+
 /**
- * @author Marcin Sobieszek
- * @date Jul 21, 2016 1:56:09 PM
+ * Feing declarative service interface for consuming Schema service.
  */
-// @Headers({"Accept: application/json", "Content-Type: application/json"})
 public interface SchemaClient {
-    @RequestLine("GET /schemas/{schemaId}")
+    @RequestLine(GET + SCHEMA_WITH_ID)
     SchemaData findById(@Param("schemaId") long schemaId);
 }
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/SystemClient.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/SystemClient.java
index 0ba4ee484420976d04aa146dcc36fba11eaa9e33..b3bb5faf8baf32da14467e4304bca94908a572e7 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/SystemClient.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/SystemClient.java
@@ -7,15 +7,17 @@ import cern.accsoft.nxcals.common.domain.SystemData;
 import feign.Param;
 import feign.RequestLine;
 
+import static cern.accsoft.nxcals.common.web.Endpoints.SYSTEMS;
+import static cern.accsoft.nxcals.common.web.Endpoints.SYSTEM_WITH_ID;
+import static cern.accsoft.nxcals.common.web.HttpVerbs.GET;
+
 /**
- * @author Marcin Sobieszek
- * @author jwozniak
- * @date Jul 21, 2016 3:27:44 PM
+ * Feing declarative service interface for consuming System service..
  */
 public interface SystemClient {
-    @RequestLine("GET /systems/search/findById?id={id}")
+    @RequestLine(GET + SYSTEM_WITH_ID)
     SystemData findById(@Param("id") long systemId);
 
-    @RequestLine("GET /systems/search/findByName?name={name}")
+    @RequestLine(GET + SYSTEMS + "?name={name}")
     SystemData findByName(@Param("name") String name);
 }
diff --git a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/VariableClient.java b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/VariableClient.java
index 2c624643a533cc3a80881e159be1a8cf6f815d99..e924ab295e25d1c4b4848f658c1bee092a333bc2 100644
--- a/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/VariableClient.java
+++ b/accsoft-nxcals-service-client/src/main/java/cern/accsoft/nxcals/service/client/providers/feign/VariableClient.java
@@ -7,34 +7,42 @@ import feign.RequestLine;
 
 import java.util.List;
 
+import static cern.accsoft.nxcals.common.web.Endpoints.VARIABLES;
+import static cern.accsoft.nxcals.common.web.Endpoints.VARIABLE_REGISTER_OR_UPDATE;
+import static cern.accsoft.nxcals.common.web.HttpHeaders.ACCEPT_APPLICATION_JSON;
+import static cern.accsoft.nxcals.common.web.HttpHeaders.CONTENT_TYPE_APPLICATION_JSON;
+import static cern.accsoft.nxcals.common.web.HttpVerbs.GET;
+import static cern.accsoft.nxcals.common.web.HttpVerbs.PUT;
+
 /**
- * Interface using Feign as implementation Created by jwozniak on 01/07/17.
+ * Feing declarative service interface for consuming Variable service.
  */
 public interface VariableClient {
-    String VARIABLES_SEARCH_PATH = "/variables/search/";
 
-    @RequestLine("GET " + VARIABLES_SEARCH_PATH + "findByVariableName?variableName={variableName}")
-    VariableData findByVariableName(@Param("variableName") String variableName);
+    @RequestLine(GET + VARIABLES
+            + "?name={name}")
+    VariableData findByVariableName(@Param("name") String name);
 
-    @RequestLine("GET " + VARIABLES_SEARCH_PATH + "findByExpression/name?expression={nameExpression}")
+    @RequestLine(GET + VARIABLES
+            + "?nameExpression={nameExpression}")
     List<VariableData> findByNameLike(@Param("nameExpression") String nameExpression);
 
-    @RequestLine(
-            "GET " + VARIABLES_SEARCH_PATH + "findByExpression/desc?expression={descriptionExpression}")
+    @RequestLine(GET + VARIABLES
+            + "?descriptionExpression={descriptionExpression}")
     List<VariableData> findByDescriptionLike(
             @Param("descriptionExpression") String descriptionExpression);
 
-    @RequestLine(
-            "GET "
-                    + VARIABLES_SEARCH_PATH
-                    + "findByVariableNameAndTimeWindow?variableName={variableName}&startTime={startTime}&endTime={endTime}")
+    @RequestLine(GET + VARIABLES
+            + "?name={name}"
+            + "&startTime={startTime}"
+            + "&endTime={endTime}")
     VariableData findByVariableNameAndTimeWindow(
-            @Param("variableName") String variableName,
+            @Param("name") String variableName,
             @Param("startTime") long startTime,
             @Param("endTime") long endTime);
 
     // fixme should be private (may be public in future)
-    @Headers({ "Accept: application/json", "Content-Type: application/json" })
-    @RequestLine("PUT /variables/registerOrUpdateVariableFor")
+    @Headers({ ACCEPT_APPLICATION_JSON, CONTENT_TYPE_APPLICATION_JSON})
+    @RequestLine(PUT + VARIABLE_REGISTER_OR_UPDATE)
     VariableData registerOrUpdateVariableFor(VariableData variableData);
 }
diff --git a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/ClientDemoVariables.java b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/ClientDemoVariables.java
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..011fc3f1808e046564048fb380207a0cc559140b 100644
--- a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/ClientDemoVariables.java
+++ b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/ClientDemoVariables.java
@@ -0,0 +1,73 @@
+package cern.accsoft.nxcals.service.client;
+
+import cern.accsoft.nxcals.common.domain.VariableConfigData;
+import cern.accsoft.nxcals.common.domain.VariableData;
+import cern.accsoft.nxcals.common.domain.impl.VariableConfigDataImpl;
+import cern.accsoft.nxcals.common.domain.impl.VariableDataImpl;
+import cern.accsoft.nxcals.common.utils.TimeUtils;
+import cern.accsoft.nxcals.service.client.api.internal.InternalVariableService;
+import cern.accsoft.nxcals.service.client.providers.InternalServiceClientFactory;
+
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Created by ntsvetko on 3/10/17.
+ */
+public class ClientDemoVariables {
+    static {
+        String user = System.getProperty("user.name");
+        System.setProperty("service.url", "http://nxcals-" + user + "1:19093");
+    }
+
+    public static void main(String[] args) {
+
+        InternalVariableService variableService = InternalServiceClientFactory.createVariableService();
+        VariableData variableData = variableService.findByVariableName("TestVariable");
+        System.out.println("FOUND variable: " + variableData.toString());
+
+        long t1 = TimeUtils.getNanosFromInstant(Instant.now().minus(5, ChronoUnit.DAYS));
+        long t2 = TimeUtils.getNanosFromInstant(Instant.now().minus(2, ChronoUnit.DAYS));
+
+        VariableConfigData varConfData1 = new VariableConfigDataImpl(500011, "field3", null, t1);
+        VariableConfigData varConfData2 = new VariableConfigDataImpl(500011, "field2", t1, t2);
+        VariableConfigData varConfData3 = new VariableConfigDataImpl(500011, "field4", t2, null);
+
+        SortedSet<VariableConfigData> varConfSet = new TreeSet<>();
+        varConfSet.add(varConfData1);
+        varConfSet.add(varConfData2);
+        varConfSet.add(varConfData3);
+
+        VariableData varData = new VariableDataImpl("TestVariable4", "Description",
+                TimeUtils.getNanosFromInstant(Instant.now()),
+                varConfSet);
+        VariableData var1 = variableService.registerOrUpdateVariableFor(varData);
+        System.out.println("Updated variable data: " + var1);
+
+        long tNow = TimeUtils.getNanosFromInstant(Instant.now());
+
+        VariableData var2 = variableService
+                .findByVariableNameAndTimeWindow("TestVariable4", t2, TimeUtils.getNanosFromInstant(Instant.now()));
+        System.err.println("Found in time window (" + t2 + ", " + tNow + "):" + var2.toString());
+
+        VariableData testVariable = variableService.findByVariableName("TEST_DEV6");
+
+        long splitTime = TimeUtils.getNanosFromInstant(Instant.now().minus(3, ChronoUnit.HOURS));
+
+        SortedSet<VariableConfigData> newConfig = new TreeSet<>();
+        VariableConfigData firstConf = testVariable.getVariableConfigData().first();
+        newConfig.add(new VariableConfigDataImpl(firstConf.getEntityId(), firstConf.getFieldName(), null,
+                splitTime));
+        newConfig.add(new VariableConfigDataImpl(firstConf.getEntityId(), null, splitTime, null));
+
+        VariableData newVariable = new VariableDataImpl(testVariable.getVariableName(), testVariable.getDescription(),
+                TimeUtils.getNanosFromInstant(Instant.now()), newConfig);
+
+        VariableData var3 = variableService.registerOrUpdateVariableFor(newVariable);
+
+        System.err.println(var3.toString());
+    }
+
+}
diff --git a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/ClientDemo.java b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/ClientDemo.java
index f317e5a1512db4e434864e9e3c44c03bd68b404b..85f675b5e7238d4400e83f55cfcb98f00759e0c7 100644
--- a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/ClientDemo.java
+++ b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/ClientDemo.java
@@ -1,85 +1,130 @@
 package cern.accsoft.nxcals.service.client.demo;
 
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
 import cern.accsoft.nxcals.common.domain.EntityData;
-import cern.accsoft.nxcals.common.domain.PartitionData;
-import cern.accsoft.nxcals.common.domain.SchemaData;
 import cern.accsoft.nxcals.common.domain.SystemData;
+import cern.accsoft.nxcals.common.domain.VariableConfigData;
+import cern.accsoft.nxcals.common.domain.VariableData;
+import cern.accsoft.nxcals.common.domain.impl.VariableConfigDataImpl;
+import cern.accsoft.nxcals.common.domain.impl.VariableDataImpl;
 import cern.accsoft.nxcals.common.utils.TimeUtils;
 import cern.accsoft.nxcals.service.client.api.EntitiesResourcesService;
 import cern.accsoft.nxcals.service.client.api.EntityService;
-import cern.accsoft.nxcals.service.client.api.SystemService;
+import cern.accsoft.nxcals.service.client.api.VariableService;
 import cern.accsoft.nxcals.service.client.api.internal.InternalEntityService;
 import cern.accsoft.nxcals.service.client.api.internal.InternalPartitionService;
 import cern.accsoft.nxcals.service.client.api.internal.InternalSchemaService;
+import cern.accsoft.nxcals.service.client.api.internal.InternalSystemService;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+import cern.accsoft.nxcals.service.client.domain.impl.SimpleKeyValues;
 import cern.accsoft.nxcals.service.client.providers.InternalServiceClientFactory;
 import cern.accsoft.nxcals.service.client.providers.ServiceClientFactory;
-import org.junit.Assert;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang.RandomStringUtils;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.time.Instant;
-import java.time.temporal.ChronoUnit;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 public class ClientDemo {
+    //    protected static final SystemService systemService = ServiceClientFactory.createSystemService();
+    //    protected static final InternalSystemService internalSystemService = InternalServiceClientFactory
+    //            .createSystemService();
+    //    protected static final EntityService entityService = ServiceClientFactory.createEntityService();
+    //    protected static final InternalEntityService internalEntityService = InternalServiceClientFactory
+    //            .createEntityService();
+    //    protected static final InternalPartitionService internalPartitionService = InternalServiceClientFactory
+    //            .createPartitionService();
+    //    protected static final VariableService variableService = ServiceClientFactory.createVariableService();
+    //    protected static final InternalSchemaService internalSchemaService = InternalServiceClientFactory
+    //            .createSchemaService();
+    //    protected static final EntitiesResourcesService entitiesResourcesService = ServiceClientFactory
+    //            .createEntityResourceService();
     static {
-        String USER = System.getProperty("user.name");
-        String USER_HOME = System.getProperty("user.home");
-        System.setProperty("service.url", "http://nxcals-" + USER + "1.cern.ch:19093");
-        System.setProperty("kerberos.keytab", USER_HOME + "/.keytab");
-        System.setProperty("kerberos.principal", USER);
+        try {
+            System.setProperty("service.url", "https://" + InetAddress.getLocalHost().getHostName() + ":19093");
+        } catch (UnknownHostException exception) {
+            throw new RuntimeException(
+                    "Cannot acquire hostname programmatically, provide the name full name of localhost");
+        }
+
+        System.setProperty("kerberos.principal", "mock-system-user");
+        System.setProperty("kerberos.keytab", ".service.keytab");
+
+        System.setProperty("java.security.krb5.conf", "build/LocalKdc/krb5.conf");
+
         System.setProperty("javax.net.ssl.trustStore", "selfsigned.jks");
+        System.setProperty("javax.net.ssl.trustStorePassword", "123456");
     }
 
+    protected static final InternalSystemService internalSystemService = InternalServiceClientFactory
+            .createSystemService();
+    protected static final EntityService entityService = ServiceClientFactory.createEntityService();
+    protected static final InternalEntityService internalEntityService = InternalServiceClientFactory
+            .createEntityService();
+    protected static final InternalPartitionService internalPartitionService = InternalServiceClientFactory
+            .createPartitionService();
+    protected static final VariableService variableService = ServiceClientFactory.createVariableService();
+    protected static final InternalSchemaService internalSchemaService = InternalServiceClientFactory
+            .createSchemaService();
+    protected static final EntitiesResourcesService entitiesResourcesService = ServiceClientFactory
+            .createEntityResourceService();
+
+    private static final String RANDOM_STRING = RandomStringUtils.randomAscii(64);
+
+    static final Map<String, Object> ENTITY_KEY_VALUES = ImmutableMap
+            .of("device", "device_value" + RANDOM_STRING);
+    static final Map<String, Object> ENTITY_KEY_VALUES_RESOURCES_TEST = ImmutableMap
+            .of("device", "device_value_resources_test" + RANDOM_STRING);
+    static final Map<String, Object> ENTITY_KEY_VALUES_SCHEMA_TEST = ImmutableMap
+            .of("device", "device_value_schema_test" + RANDOM_STRING);
+    static final Map<String, Object> ENTITY_KEY_VALUES_VARIABLE_TEST = ImmutableMap
+            .of("device", "device_value_variable_test" + RANDOM_STRING);
+    static final Map<String, Object> PARTITION_KEY_VALUES = ImmutableMap
+            .of("specification", "devClass1" + RANDOM_STRING);
+
+    static final String SCHEMA = "TEST_SCHEMA" + RANDOM_STRING;
+    static final String MOCK_SYSTEM_NAME = "MOCK-SYSTEM";
+    static InternalSystemService systemService = InternalServiceClientFactory.createSystemService();
+    static final SystemData systemData = systemService.findByName(MOCK_SYSTEM_NAME);
+
+    static final long RECORD_TIMESTAMP = 1476789831111222334L;
+    static final long MOCK_SYSTEM_ID = -100;
+
+    static String variableName = "VARIABLE_NAME" + RANDOM_STRING;
+
+
     public static void main(String[] args) {
-        SystemService systemService = ServiceClientFactory.createSystemService();
-        SystemData systemData = systemService.findByName("TEST-CMW");
-        System.out.println(systemData);
-
-        EntityService entityService = ServiceClientFactory.createEntityService();
-        InternalEntityService internalEntityService =
-                InternalServiceClientFactory.createEntityService();
-
-        EntityData entityData1 =
-                internalEntityService.findOrCreateEntityFor(
-                        1,
-                        "{\"device\"=\"dev1\",\"property\"=\"prop1\"}",
-                        "{\"class\"=\"devClass1\",\"property\"=\"prop1\"}",
-                        "brokenSchema1",
-                        1476789831111222334L);
-
-        EntityData entityData2 =
-                internalEntityService.findOrCreateEntityFor(
-                        1,
-                        "{\"device\"=\"dev1\",\"property\"=\"prop1\"}",
-                        "{\"class\"=\"devClass1\",\"property\"=\"prop1\"}",
-                        "brokenSchema1",
-                        1476789831111222334L);
-        System.out.println(entityData1);
-        System.out.println(entityData2);
-
-        Assert.assertEquals(1, entityData1.getEntityHistoryData().size());
-        Assert.assertEquals(1, entityData2.getEntityHistoryData().size());
-
-        EntityData entityData3 = entityService.findBySystemIdAndKeyValues(100, "aaaa");
-        System.out.println("Should be null:" + entityData3);
-
-        InternalSchemaService schemaService = InternalServiceClientFactory.createSchemaService();
-        SchemaData schemaData = schemaService.findById(entityData1.getSchemaData().getId());
-        System.out.println(schemaData);
-
-        InternalPartitionService partitionService =
-                InternalServiceClientFactory.createPartitionService();
-        PartitionData partitionData =
-                partitionService.findBySystemIdAndKeyValues(
-                        1, "{\"class\"=\"devClass1\",\"property\"=\"prop1\"}");
-        System.out.println(partitionData);
-
-        EntitiesResourcesService resourceService = ServiceClientFactory.createEntityResourceService();
-        EntitiesResourcesData resourceData =
-                resourceService.findBySystemIdKeyValuesAndTimeWindow(
-                        1,
-                        "{\"device\"=\"dev1\",\"property\"=\"prop1\"}",
-                        TimeUtils.getNanosFromInstant(Instant.now().minus(10, ChronoUnit.DAYS)),
-                        TimeUtils.getNanosFromInstant(Instant.now()));
-        System.err.println(resourceData.toString());
+        //lets first find some existing entity for which we will create variable
+
+        KeyValues entityKeyValues = new SimpleKeyValues("", ENTITY_KEY_VALUES_VARIABLE_TEST);
+        KeyValues partitionKeyValues = new SimpleKeyValues(null, PARTITION_KEY_VALUES);
+
+        EntityData entityData = internalEntityService
+                .findOrCreateEntityFor(systemData.getId(), entityKeyValues,
+                        partitionKeyValues, "brokenSchema1", RECORD_TIMESTAMP);
+
+        assertNotNull(entityData);
+
+        VariableConfigData varConfData1 = new VariableConfigDataImpl(entityData.getId(), null, null, null);
+        SortedSet<VariableConfigData> varConfSet = new TreeSet<>();
+        varConfSet.add(varConfData1);
+        VariableData varData = new VariableDataImpl(variableName, "Description",
+                TimeUtils.getNanosFromInstant(Instant.now()),
+                varConfSet);
+        VariableData variableData = variableService.registerOrUpdateVariableFor(varData);
+        assertNotNull(variableData);
+        assertEquals(variableName, variableData.getVariableName());
+
+        VariableData foundVariable = variableService.findByVariableName(variableName);
+        assertEquals(variableName, foundVariable.getVariableName());
+
+        VariableData foundVariable2 = variableService.findByVariableNameAndTimeWindow(variableName, 100, 200);
+        assertEquals(variableName, foundVariable2.getVariableName());
     }
 }
diff --git a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/LoadBalanceDemo.java b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/LoadBalanceDemo.java
index 32eb8bf3c4e5834de0f736abba280e629406f3f7..501e917ccd3dd3f248e58648bb33f324914b93aa 100644
--- a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/LoadBalanceDemo.java
+++ b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/LoadBalanceDemo.java
@@ -4,11 +4,17 @@ import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.common.domain.SystemData;
 import cern.accsoft.nxcals.service.client.api.SystemService;
 import cern.accsoft.nxcals.service.client.api.internal.InternalEntityService;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
+import cern.accsoft.nxcals.service.client.domain.impl.SimpleKeyValues;
 import cern.accsoft.nxcals.service.client.providers.InternalServiceClientFactory;
 import cern.accsoft.nxcals.service.client.providers.ServiceClientFactory;
 
 import java.util.concurrent.TimeUnit;
 
+import static cern.accsoft.nxcals.service.client.providers.DomainTestConstants.ENTITY_KEY_VALUES;
+import static cern.accsoft.nxcals.service.client.providers.DomainTestConstants.PARTITION_KEY_VALUES;
+import static cern.accsoft.nxcals.service.client.providers.TestSchemas.RECORD_VERSION_SCHEMA;
+
 public class LoadBalanceDemo {
     static {
         String USER = System.getProperty("user.name");
@@ -18,8 +24,6 @@ public class LoadBalanceDemo {
         System.setProperty("kerberos.keytab", USER_HOME + "/.keytab");
     }
 
-    private static final String schema = "{\"class\"=\"devClass1\",\"property\"=\"prop1\"}";
-
     public static void main(String[] args) throws Exception {
         SystemService systemService = ServiceClientFactory.createSystemService();
         SystemData systemData = systemService.findByName("MOCK-SYSTEM");
@@ -27,11 +31,13 @@ public class LoadBalanceDemo {
 
         InternalEntityService entityService = InternalServiceClientFactory.createEntityService();
 
+        KeyValues entityKeyValues = new SimpleKeyValues("", ENTITY_KEY_VALUES);
+        KeyValues partitionKeyValues = new SimpleKeyValues(null, PARTITION_KEY_VALUES);
+
         //Please stop one of the services (on one machine to see if the balancing works)
         for (int i = 0; i < 120; i++) {
-            EntityData entityData1 = entityService
-                    .findOrCreateEntityFor(systemData.getId(), "test-" + System.currentTimeMillis(),
-                            schema, schema, System.currentTimeMillis() * 1000_000);
+            EntityData entityData1 = entityService.findOrCreateEntityFor(systemData.getId(), entityKeyValues,
+                    partitionKeyValues, RECORD_VERSION_SCHEMA.toString(), System.currentTimeMillis() * 1000_000);
             System.out.println("EntityId=" + entityData1.getId());
             TimeUnit.SECONDS.sleep(3);
         }
diff --git a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/package-info.java b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/package-info.java
index 40c51a19ae4ff6d2bc9fa02aaf2395cb4a7a7b0d..c871f46f85aad36b90c5eedc36b990966a40f39f 100644
--- a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/package-info.java
+++ b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/demo/package-info.java
@@ -2,6 +2,7 @@
  * Copyright (c) 2016 European Organisation for Nuclear Research (CERN), All Rights Reserved.
  *
  * @author jwozniak
+ * @author jwozniak
  */
 /**
  * @author jwozniak
diff --git a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/AbstractProviderTest.java b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/AbstractProviderTest.java
index 4389cec01c601dbbd8e4508cc3cdcb6bf7bf8d26..789c802c5f19a67037aab9c515be97dfbc978bfe 100644
--- a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/AbstractProviderTest.java
+++ b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/AbstractProviderTest.java
@@ -3,8 +3,14 @@
  */
 package cern.accsoft.nxcals.service.client.providers;
 
+import com.google.common.collect.ImmutableMap;
+import org.apache.avro.Schema;
+import org.apache.avro.SchemaBuilder;
 import org.junit.Ignore;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * @author Marcin Sobieszek
  * @date Jul 22, 2016 4:14:41 PM
@@ -12,26 +18,34 @@ import org.junit.Ignore;
 @Ignore
 public abstract class AbstractProviderTest {
 
-    protected static final String DATA_SCHEMA = "{\"type\":\"record\", \"name\":\"test\", " + "\"fields\":["
-            + "{\"name\": \"name\", \"type\": \"string\"}, "
-            + "{\"name\": \"number\", \"type\": \"int\"}, {\"name\": \"flag\", \"type\": \"boolean\"}]}";
-    protected static final String PARTITION_SCHEMA = "{\"type\":\"record\", \"name\":\"test\", " + "\"fields\":["
-            + "{\"name\": \"name\", \"type\": \"string\"}" + "]}";
-    protected static final String ENTITY_SCHEMA = "{\"type\":\"record\", \"name\":\"test\", " + "\"fields\":["
-            + "{\"name\": \"number\", \"type\": \"int\"}" + "]}";
+    protected static final Schema DATA_SCHEMA = SchemaBuilder.record("test").fields()
+            .name("name").type().stringType().noDefault()
+            .name("number").type().intType().noDefault()
+            .name("flag").type().booleanType().noDefault()
+            .endRecord();
+
+    protected static final Schema PARTITION_SCHEMA = SchemaBuilder.record("test").fields()
+            .name("name").type().stringType().noDefault().endRecord();
 
-    protected static final String TIME_KEY_SCHEMA = "{\"type\":\"record\", \"name\":\"test\", " + "\"fields\":["
-            + "{\"name\": \"timestamp\", \"type\": \"long\"}" + "]}";
+    protected static final Schema ENTITY_SCHEMA = SchemaBuilder.record("test").fields()
+            .name("number").type().intType().noDefault().endRecord();
+
+    protected static final Schema TIME_KEY_SCHEMA = SchemaBuilder.record("test").fields()
+            .name("timestamp").type().longType().noDefault().endRecord();
 
     protected static final long SYSTEM_ID = -1;
     protected static final String SYSTEM_NAME = "TEST_SYSTEM";
-    protected static final String ENTITY_KEY_VALUES = "entityKeyValues";
-    protected static final String ENTITY_KEY_VALUES1 = "entityKeyValues1";
-    protected static final String PARTITION_KEY_VALUES = "partitionKeyValues";
-    protected static final String PARTITION_KEY_VALUES1 = "partitionKeyValues1";
-    protected static final String SCHEMA = "schema";
-    protected static final String SCHEMA1 = "schema1";
-    protected static final String SCHEMA2 = "schema2";
+    protected static final Map<String, Object> ENTITY_KEY_VALUES = ImmutableMap.of("value", "1");
+    protected static final Map<String, Object> ENTITY_KEY_VALUES1 = ImmutableMap.of("value", "2");
+    protected static final Map<String, Object> PARTITION_KEY_VALUES = ImmutableMap.of("value", "3");
+    protected static final Map<String, Object> PARTITION_KEY_VALUES1 = ImmutableMap.of("value", "4");
     protected static final long RECORD_TIME = 0;
 
+    protected static final Schema SCHEMA1 = SchemaBuilder.record("schema1").fields()
+            .name("schema1").type().stringType().noDefault().endRecord();
+    protected static final Schema SCHEMA2 = SchemaBuilder.record("schema2").fields()
+            .name("schema2").type().stringType().noDefault().endRecord();
+    protected static final Schema SCHEMA3 = SchemaBuilder.record("schema3").fields()
+            .name("schema3").type().stringType().noDefault().endRecord();
+
 }
diff --git a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/DomainTestConstants.java b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/DomainTestConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..772b510d31d01c3bfcf327fcf52a3b2f883e799b
--- /dev/null
+++ b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/DomainTestConstants.java
@@ -0,0 +1,32 @@
+package cern.accsoft.nxcals.service.client.providers;
+
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
+
+import static cern.accsoft.nxcals.service.client.providers.TestSchemas.ENTITY_DOUBLE_SCHEMA_KEY;
+import static cern.accsoft.nxcals.service.client.providers.TestSchemas.ENTITY_STRING_SCHEMA_KEY;
+import static cern.accsoft.nxcals.service.client.providers.TestSchemas.ENTITY_STRING_SCHEMA_KEY_1;
+import static cern.accsoft.nxcals.service.client.providers.TestSchemas.PARTITION_DOUBLE_SCHEMA_KEY;
+import static cern.accsoft.nxcals.service.client.providers.TestSchemas.PARTITION_STRING_SCHEMA_KEY;
+import static cern.accsoft.nxcals.service.client.providers.TestSchemas.PARTITION_STRING_SCHEMA_KEY_1;
+
+public class DomainTestConstants {
+
+    static final long SYSTEM_ID = 10;
+    static final String SYSTEM_NAME = "SYSTEM_NAME";
+
+    public static final Map<String, Object> PARTITION_KEY_VALUES = ImmutableMap
+            .of(PARTITION_STRING_SCHEMA_KEY, "string", PARTITION_DOUBLE_SCHEMA_KEY, 2d);
+
+    static final Map<String, Object> PARTITION_KEY_VALUES_1 = ImmutableMap
+            .of(PARTITION_STRING_SCHEMA_KEY_1, "string");
+
+    public static final Map<String, Object> ENTITY_KEY_VALUES = ImmutableMap
+            .of(ENTITY_STRING_SCHEMA_KEY, "string", ENTITY_DOUBLE_SCHEMA_KEY, 2d);
+
+    static final Map<String, Object> ENTITY_KEY_VALUES_1 = ImmutableMap
+            .of(ENTITY_STRING_SCHEMA_KEY_1, "string");
+    static final long ENTITY_ID = 40;
+
+}
diff --git a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/EntityProviderTest.java b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/EntityProviderTest.java
index c03aec900f7f9ca0da37e8d698298a9c920dfc6b..7e4a86d442731265c0ffd213909bdaf17fd3b9fa 100644
--- a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/EntityProviderTest.java
+++ b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/EntityProviderTest.java
@@ -3,6 +3,7 @@
  */
 package cern.accsoft.nxcals.service.client.providers;
 
+import cern.accsoft.nxcals.common.domain.impl.FindOrCreateEntityRequestImpl;
 import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.common.domain.EntityHistoryData;
 import cern.accsoft.nxcals.common.domain.impl.EntityDataImpl;
@@ -11,6 +12,7 @@ import cern.accsoft.nxcals.common.domain.impl.PartitionDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.SchemaDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.SystemDataImpl;
 import cern.accsoft.nxcals.service.client.DataConflictRuntimeException;
+import cern.accsoft.nxcals.service.client.domain.KeyValues;
 import cern.accsoft.nxcals.service.client.providers.feign.EntityClient;
 import org.assertj.core.util.Lists;
 import org.junit.Before;
@@ -23,6 +25,7 @@ import org.mockito.junit.MockitoJUnitRunner;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
@@ -59,22 +62,22 @@ public class EntityProviderTest extends AbstractProviderTest {
 
     private EntityData createEntityData(long id, SortedSet<EntityHistoryData> histData) {
         return new EntityDataImpl(id, ENTITY_KEY_VALUES,
-                new SystemDataImpl(1, SYSTEM_NAME, ENTITY_SCHEMA, PARTITION_SCHEMA, TIME_KEY_SCHEMA, null),
-                new PartitionDataImpl(1, PARTITION_KEY_VALUES), new SchemaDataImpl(1, SCHEMA), histData, null, 0L);
+                new SystemDataImpl(1, SYSTEM_NAME, ENTITY_SCHEMA.toString(), PARTITION_SCHEMA.toString(), TIME_KEY_SCHEMA.toString(), null),
+                PartitionDataImpl.builder().id(1).keyValues(PARTITION_KEY_VALUES).build(), new SchemaDataImpl(1, ENTITY_SCHEMA.toString()), histData, null, 0L);
     }
 
-    private EntityData createEntityDataWithHistory(long id, String partitionKeyValues, List<String> schemas) {
+    private EntityData createEntityDataWithHistory(long id, Map<String, Object> partitionKeyValues, List<String> schemas) {
         return createEntityDataWithHistoryWithTimeDiff(id, partitionKeyValues, schemas, 1);
     }
 
-    private EntityData createEntityDataWithHistoryWithTimeDiff(long id, String partitionKeyValues, List<String> schemas,
+    private EntityData createEntityDataWithHistoryWithTimeDiff(long id, Map<String, Object> partitionKeyValues, List<String> schemas,
             long histTimeDifference) {
 
         SortedSet<EntityHistoryData> histData = new TreeSet<>();
         for (int i = 0; i < schemas.size(); i++) {
             histData.add(
                     new EntityHistoryDataImpl(i, new SchemaDataImpl(0, schemas.get(i)),
-                            new PartitionDataImpl(0, partitionKeyValues),
+                            PartitionDataImpl.builder().id(0).keyValues(partitionKeyValues).build(),
                             Long.valueOf(i * histTimeDifference),
                             i == schemas.size() - 1 ? null : Long.valueOf((i + 1) * histTimeDifference)));
         }
@@ -108,20 +111,20 @@ public class EntityProviderTest extends AbstractProviderTest {
 
         // given
         final long ENTITYID = 100;
-        List<String> schemas = Arrays.asList(SCHEMA, SCHEMA);
+        List<String> schemas = Arrays.asList(SCHEMA1.toString(), SCHEMA1.toString());
         long histTimeDifference = 1;
         long firstTimestamp = 10;
 
         SortedSet<EntityHistoryData> histData1 = new TreeSet<>();  // unmodified history
         SortedSet<EntityHistoryData> histData2 = new TreeSet<>();  // history with migration
 
-        histData2.add(new EntityHistoryDataImpl(0, new SchemaDataImpl(0, SCHEMA1),
-                new PartitionDataImpl(0, PARTITION_KEY_VALUES), 0L, 10L));
+        histData2.add(new EntityHistoryDataImpl(0, new SchemaDataImpl(0, SCHEMA2.toString()),
+                PartitionDataImpl.builder().id(0).keyValues(PARTITION_KEY_VALUES).build(), 0L, 10L));
 
         for (int i = 0; i < schemas.size(); i++) {
             EntityHistoryData entityHistoryData = new EntityHistoryDataImpl(i + 1,
                     new SchemaDataImpl(0, schemas.get(i)),
-                    new PartitionDataImpl(0, PARTITION_KEY_VALUES),
+                    PartitionDataImpl.builder().id(0).keyValues(PARTITION_KEY_VALUES).build(),
                     Long.valueOf(i * histTimeDifference + firstTimestamp),
                     i == schemas.size() - 1 ? null : Long.valueOf((i + 1) * histTimeDifference) + firstTimestamp);
 
@@ -133,9 +136,9 @@ public class EntityProviderTest extends AbstractProviderTest {
         EntityData keyData2 = createEntityData(ENTITYID, histData2);
 
         // when
-        when(this.httpClient.extendEntityFirstHistoryDataFor(ENTITYID, 0L, SCHEMA1)).thenReturn(keyData2);
+        when(this.httpClient.extendEntityFirstHistoryDataFor(ENTITYID, 0L, SCHEMA2.toString())).thenReturn(keyData2);
 
-        EntityData data = this.entityProvider.extendEntityFirstHistoryDataFor(ENTITYID, SCHEMA1, 0L);
+        EntityData data = this.entityProvider.extendEntityFirstHistoryDataFor(ENTITYID, SCHEMA2.toString(), 0L);
 
         // then
         assertNotNull(data);
@@ -144,39 +147,69 @@ public class EntityProviderTest extends AbstractProviderTest {
 
     @Test
     public void shouldCreateEntityDataForExistingKeyValuesAndSchemaFromCache() {
-        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA, SCHEMA1));
-        when(this.httpClient
-                .findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES, RECORD_TIME, SCHEMA
-                )).thenReturn(keyData);
+        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1.toString(), SCHEMA2.toString()));
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES)
+                .partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA1.toString())
+                .build();
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest)).thenReturn(keyData);
+
+        KeyValues entityKeyValues = mock(KeyValues.class);
+        when(entityKeyValues.getId()).thenReturn("");
+        when(entityKeyValues.getKeyValues()).thenReturn(ENTITY_KEY_VALUES);
+
+        KeyValues partitionKeyValues = mock(KeyValues.class);
+        when(partitionKeyValues.getKeyValues()).thenReturn(PARTITION_KEY_VALUES);
 
         for (int i = 0; i < 10; i++) {
-            EntityData data = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES,
-                    PARTITION_KEY_VALUES, SCHEMA, RECORD_TIME);
+            EntityData data = entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues, SCHEMA1.toString(), RECORD_TIME);
             assertNotNull(data);
             assertEquals(keyData, data);
         }
-        verify(this.httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA);
+        verify(httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest);
     }
 
     @Test
     public void shouldCreateDifferentEntityDataForExistingKeyValuesAndDifferentSchemaFromCache() {
         // given
-        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA));
-        EntityData keyData1 = createEntityDataWithHistory(1, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1));
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA)).thenReturn(keyData);
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES1, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA1)).thenReturn(keyData1);
+        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1.toString()));
+        EntityData keyData1 = createEntityDataWithHistory(1, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA2.toString()));
+
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest1 = FindOrCreateEntityRequestImpl.builder()
+        .entityKeyValues(ENTITY_KEY_VALUES)
+                .partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA1.toString())
+                .build();
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest2 = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES1)
+                .partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA2.toString())
+                .build();
+
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest1)).thenReturn(keyData);
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest2)).thenReturn(keyData1);
+
+        KeyValues entityKeyValues = mock(KeyValues.class);
+        when(entityKeyValues.getId()).thenReturn("");
+        when(entityKeyValues.getKeyValues()).thenReturn(ENTITY_KEY_VALUES);
+
+        KeyValues entityKeyValues1 = mock(KeyValues.class);
+        when(entityKeyValues1.getId()).thenReturn("1");
+        when(entityKeyValues1.getKeyValues()).thenReturn(ENTITY_KEY_VALUES1);
+
+        KeyValues partitionKeyValues = mock(KeyValues.class);
+        when(partitionKeyValues.getKeyValues()).thenReturn(PARTITION_KEY_VALUES);
+
         // when
-        EntityData data0 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA, RECORD_TIME);
-        EntityData data1 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA, RECORD_TIME);
-        EntityData data2 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES1,
-                PARTITION_KEY_VALUES, SCHEMA1, RECORD_TIME);
-        EntityData data3 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES1,
-                PARTITION_KEY_VALUES, SCHEMA1, RECORD_TIME);
+        EntityData data0 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues,
+                SCHEMA1.toString(), RECORD_TIME);
+        EntityData data1 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues,
+                SCHEMA1.toString(), RECORD_TIME);
+        EntityData data2 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues1, partitionKeyValues,
+                SCHEMA2.toString(), RECORD_TIME);
+        EntityData data3 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues1, partitionKeyValues,
+                SCHEMA2.toString(), RECORD_TIME);
 
         // then
         assertNotNull(data0);
@@ -189,32 +222,56 @@ public class EntityProviderTest extends AbstractProviderTest {
         assertEquals(keyData1, data2);
         assertEquals(data2, data3);
 
-        verify(this.httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA);
-        verify(this.httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES1, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA1);
+        verify(httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME,
+                findOrCreateEntityRequest1);
+        verify(httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME,
+                findOrCreateEntityRequest2);
     }
 
     @Test
     public void shouldCreateDifferentEntityDataForExistingKeyValuesAndDifferentPartitionFromCache() {
         // given
-        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA));
-        EntityData keyData1 = createEntityDataWithHistory(1, PARTITION_KEY_VALUES1, Arrays.asList(SCHEMA));
+        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1.toString()));
+        EntityData keyData1 = createEntityDataWithHistory(1, PARTITION_KEY_VALUES1, Arrays.asList(SCHEMA1.toString()));
+
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest1 = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES)
+                .partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA1.toString())
+                .build();
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest2 = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES1)
+                .partitionKeyValues(PARTITION_KEY_VALUES1)
+                .schema(SCHEMA1.toString())
+                .build();
+
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest1)).thenReturn(keyData);
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest2)).thenReturn(keyData1);
+
+        KeyValues entityKeyValues = mock(KeyValues.class);
+        when(entityKeyValues.getId()).thenReturn("");
+        when(entityKeyValues.getKeyValues()).thenReturn(ENTITY_KEY_VALUES);
+
+        KeyValues entityKeyValues1 = mock(KeyValues.class);
+        when(entityKeyValues1.getId()).thenReturn("1");
+        when(entityKeyValues1.getKeyValues()).thenReturn(ENTITY_KEY_VALUES1);
+
+        KeyValues partitionKeyValues = mock(KeyValues.class);
+        when(partitionKeyValues.getKeyValues()).thenReturn(PARTITION_KEY_VALUES);
+
+        KeyValues partitionKeyValues1 = mock(KeyValues.class);
+        when(partitionKeyValues1.getKeyValues()).thenReturn(PARTITION_KEY_VALUES1);
 
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA)).thenReturn(keyData);
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES1, PARTITION_KEY_VALUES1,
-                RECORD_TIME, SCHEMA)).thenReturn(keyData1);
         // when
-        EntityData data0 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA, RECORD_TIME);
-        EntityData data1 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA, RECORD_TIME);
+        EntityData data0 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues,
+                SCHEMA1.toString(), RECORD_TIME);
+        EntityData data1 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues,
+                SCHEMA1.toString(), RECORD_TIME);
 
-        EntityData data2 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES1,
-                PARTITION_KEY_VALUES1, SCHEMA, RECORD_TIME);
-        EntityData data3 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES1,
-                PARTITION_KEY_VALUES1, SCHEMA, RECORD_TIME);
+        EntityData data2 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues1, partitionKeyValues1,
+                SCHEMA1.toString(), RECORD_TIME);
+        EntityData data3 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues1, partitionKeyValues1,
+                SCHEMA1.toString(), RECORD_TIME);
 
         // then
         assertNotNull(data0);
@@ -227,80 +284,119 @@ public class EntityProviderTest extends AbstractProviderTest {
         assertEquals(keyData1, data2);
         assertEquals(data2, data3);
 
-        verify(this.httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA);
-        verify(this.httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES1, PARTITION_KEY_VALUES1,
-                RECORD_TIME, SCHEMA);
+        verify(httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest1);
+        verify(httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest2);
     }
 
     @Test(expected = IllegalStateException.class)
     public void shouldThrowOnHistoryRewriteWithWrongPartition() {
         // given
-        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1, SCHEMA2));
+        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA2.toString(), SCHEMA3.toString()));
 
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA1)).thenReturn(keyData);
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES)
+                .partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA2.toString())
+                .build();
 
-        // when
-        EntityData data0 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA1, RECORD_TIME);
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest)).thenReturn(keyData);
 
-        EntityData data2 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES,
-                PARTITION_KEY_VALUES1, SCHEMA1, RECORD_TIME);
+        KeyValues entityKeyValues = mock(KeyValues.class);
+        when(entityKeyValues.getId()).thenReturn("");
+        when(entityKeyValues.getKeyValues()).thenReturn(ENTITY_KEY_VALUES);
 
-        // then
-        // exception
+        KeyValues partitionKeyValues = mock(KeyValues.class);
+        when(partitionKeyValues.getKeyValues()).thenReturn(PARTITION_KEY_VALUES);
+
+        KeyValues partitionKeyValues1 = mock(KeyValues.class);
+        when(partitionKeyValues1.getKeyValues()).thenReturn(PARTITION_KEY_VALUES1);
+
+        // when
+        entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues, SCHEMA2.toString(),
+                RECORD_TIME);
+
+        entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues1, SCHEMA2.toString(),
+                RECORD_TIME);
     }
 
     @Test(expected = IllegalStateException.class)
     public void shouldThrowOnHistoryRewriteWithWrongSchema() {
         // given
-        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1, SCHEMA2));
+        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA2.toString(), SCHEMA3.toString()));
 
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA1)).thenReturn(keyData);
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES)
+                .partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA2.toString())
+                .build();
 
-        // when
-        EntityData data0 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA1, RECORD_TIME);
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest)).thenReturn(keyData);
 
-        EntityData data2 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA, RECORD_TIME);
+        KeyValues entityKeyValues = mock(KeyValues.class);
+        when(entityKeyValues.getId()).thenReturn("");
+        when(entityKeyValues.getKeyValues()).thenReturn(ENTITY_KEY_VALUES);
 
-        // then
-        // exception
+        KeyValues partitionKeyValues = mock(KeyValues.class);
+        when(partitionKeyValues.getKeyValues()).thenReturn(PARTITION_KEY_VALUES);
+
+        // when
+        entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues, SCHEMA2.toString(),
+                RECORD_TIME);
+
+        entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues, SCHEMA1.toString(),
+                RECORD_TIME);
     }
 
     @Test
     public void shouldThrowOnHistoryRewriteWithWrongSchemaAndUpdateCache() {
         // given
-        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1, SCHEMA2));
+        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA2.toString(), SCHEMA3.toString()));
 
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA1)).thenReturn(keyData);
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest1 = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES).
+                partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA2.toString())
+                .build();
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest2 = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES)
+                .partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA1.toString())
+                .build();
+
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest1)).thenReturn(keyData);
 
         //this one says Data Conflict for this record.
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME + 10, SCHEMA)).thenThrow(new DataConflictRuntimeException());
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME + 10, findOrCreateEntityRequest2))
+                .thenThrow(new DataConflictRuntimeException());
+
+        KeyValues entityKeyValues = mock(KeyValues.class);
+        when(entityKeyValues.getId()).thenReturn("");
+        when(entityKeyValues.getKeyValues()).thenReturn(ENTITY_KEY_VALUES);
+
+        KeyValues partitionKeyValues = mock(KeyValues.class);
+        when(partitionKeyValues.getKeyValues()).thenReturn(PARTITION_KEY_VALUES);
 
         // when
-        EntityData data0 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA1, RECORD_TIME);
+        entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues,
+                SCHEMA2.toString(), RECORD_TIME);
 
         //thats a wrong call.
 
+        boolean exceptionThrow = false;
+
         try {
             //this should not be able to verify the record without calling the service which should trow an exception.
             //Under this condition the entityProvider should call the service to find the most recent state of this entity.
-            EntityData data2 = this.entityProvider
-                    .findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                            SCHEMA, RECORD_TIME + 10);
+            entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues,
+                            SCHEMA1.toString(), RECORD_TIME + 10);
         } catch (IllegalStateException e) {
-            //ok
+            exceptionThrow = true;
         }
 
+        assertThat(exceptionThrow).isTrue();
+
         // then
-        verify(this.httpClient, times(2)).findBySystemIdAndKeyValues(SYSTEM_ID, ENTITY_KEY_VALUES);
+        verify(httpClient, times(2)).findBySystemIdAndKeyValues(SYSTEM_ID, ENTITY_KEY_VALUES);
 
     }
 
@@ -310,58 +406,87 @@ public class EntityProviderTest extends AbstractProviderTest {
     @Test
     public void shouldAcceptNewSchemaWithOneHistoricalValue() {
         //given
-        EntityData keyData1 = createEntityDataWithHistoryWithTimeDiff(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA),
+        EntityData keyData1 = createEntityDataWithHistoryWithTimeDiff(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1.toString()),
                 100);
         EntityData keyData2 = createEntityDataWithHistoryWithTimeDiff(0, PARTITION_KEY_VALUES,
-                Arrays.asList(SCHEMA, SCHEMA1), 100);
+                Arrays.asList(SCHEMA1.toString(), SCHEMA2.toString()), 100);
 
         final long recordTimestamp = 100;
 
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA)).thenReturn(keyData1);
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest1 = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES)
+                .partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA1.toString())
+                .build();
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest2 = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES)
+                .partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA2.toString())
+                .build();
+
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest1)).thenReturn(keyData1);
+
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, recordTimestamp, findOrCreateEntityRequest2)).thenReturn(keyData2);
+
+        KeyValues entityKeyValues = mock(KeyValues.class);
+        when(entityKeyValues.getId()).thenReturn("");
+        when(entityKeyValues.getKeyValues()).thenReturn(ENTITY_KEY_VALUES);
 
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                recordTimestamp, SCHEMA1)).thenReturn(keyData2);
+        KeyValues partitionKeyValues = mock(KeyValues.class);
+        when(partitionKeyValues.getKeyValues()).thenReturn(PARTITION_KEY_VALUES);
 
         //ask first for existing one to add to the cache
-        this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA, RECORD_TIME);
+        entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues,
+                SCHEMA1.toString(), RECORD_TIME);
 
         // when
-        EntityData data0 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA1, recordTimestamp);
+        EntityData data0 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, entityKeyValues, partitionKeyValues,
+                SCHEMA2.toString(), recordTimestamp);
 
         //then
         assertEquals(data0, keyData2);
-
     }
 
-
-
-
     @Test
     public void shouldCreateSameEntityDataForExistingKeyValuesAndDifferentSchemaFromCache() {
         // given
         long secondRecordTimestamp = RECORD_TIME + 1;
-        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA));
-        EntityData keyData1 = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA, SCHEMA1));
+        EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1.toString()));
+        EntityData keyData1 = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1.toString(), SCHEMA2.toString()));
+
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest1 = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES)
+                .partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA1.toString())
+                .build();
+        FindOrCreateEntityRequestImpl findOrCreateEntityRequest2 = FindOrCreateEntityRequestImpl.builder()
+                .entityKeyValues(ENTITY_KEY_VALUES)
+                .partitionKeyValues(PARTITION_KEY_VALUES)
+                .schema(SCHEMA2.toString())
+                .build();
+
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest1)).thenReturn(keyData);
+        when(httpClient.findOrCreateEntityFor(SYSTEM_ID, secondRecordTimestamp, findOrCreateEntityRequest2)).thenReturn(keyData1);
+
+        KeyValues cachedRequest = mock(KeyValues.class);
+        when(cachedRequest.getId()).thenReturn("");
+        when(cachedRequest.getKeyValues()).thenReturn(ENTITY_KEY_VALUES);
+
+        KeyValues partitionKeyValues = mock(KeyValues.class);
+        when(partitionKeyValues.getKeyValues()).thenReturn(PARTITION_KEY_VALUES);
 
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA)).thenReturn(keyData);
-        when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                secondRecordTimestamp, SCHEMA1)).thenReturn(keyData1);
         // when
-        EntityData data0 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA, RECORD_TIME);
+        EntityData data0 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, cachedRequest, partitionKeyValues,
+                SCHEMA1.toString(), RECORD_TIME);
 
-        EntityData data2 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA1, secondRecordTimestamp);
+        EntityData data2 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, cachedRequest, partitionKeyValues,
+                SCHEMA2.toString(), secondRecordTimestamp);
 
-        EntityData data1 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA, RECORD_TIME);
+        EntityData data1 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, cachedRequest, partitionKeyValues,
+                SCHEMA1.toString(), RECORD_TIME);
 
-        EntityData data3 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                SCHEMA1, secondRecordTimestamp);
+        EntityData data3 = entityProvider.findOrCreateEntityFor(SYSTEM_ID, cachedRequest, partitionKeyValues,
+                SCHEMA2.toString(), secondRecordTimestamp);
 
         // then
         assertNotNull(data0);
@@ -374,35 +499,32 @@ public class EntityProviderTest extends AbstractProviderTest {
         assertEquals(keyData1, data2);
         assertEquals(data2, data3);
 
-        verify(this.httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                RECORD_TIME, SCHEMA);
-        verify(this.httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES,
-                secondRecordTimestamp, SCHEMA1);
+        verify(httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, RECORD_TIME, findOrCreateEntityRequest1);
+        verify(httpClient, times(1)).findOrCreateEntityFor(SYSTEM_ID, secondRecordTimestamp, findOrCreateEntityRequest2);
     }
 
-
     @Test
     public void shouldAcceptNewSchemaWithOneHistoricalValueWithIds() {
         //given
-        EntityData keyData1 = createEntityDataWithHistoryWithTimeDiff(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA),
+        EntityData keyData1 = createEntityDataWithHistoryWithTimeDiff(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1.toString()),
                 100);
         EntityData keyData2 = createEntityDataWithHistoryWithTimeDiff(0, PARTITION_KEY_VALUES,
-                Arrays.asList(SCHEMA, SCHEMA1), 100);
+                Arrays.asList(SCHEMA1.toString(), SCHEMA2.toString()), 100);
 
         final long recordTimestamp = 100;
 
         when(this.httpClient.findByEntityIdAndTimeWindow(keyData1.getId(), RECORD_TIME,RECORD_TIME)).thenReturn(keyData1);
 
         when(this.httpClient.findOrCreateEntityFor(SYSTEM_ID, keyData1.getId(), keyData1.getPartitionData().getId(),
-                recordTimestamp, SCHEMA1)).thenReturn(keyData2);
+                recordTimestamp, SCHEMA2.toString())).thenReturn(keyData2);
 
         //ask first for existing one to add to the cache
         this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, keyData1.getId(), keyData1.getPartitionData().getId(),
-                SCHEMA, RECORD_TIME);
+                SCHEMA1.toString(), RECORD_TIME);
 
         // when
         EntityData data0 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID,keyData1.getId(), keyData1.getPartitionData().getId(),
-                SCHEMA1, recordTimestamp);
+                SCHEMA2.toString(), recordTimestamp);
 
         //then
         assertEquals(data0, keyData2);
@@ -412,7 +534,7 @@ public class EntityProviderTest extends AbstractProviderTest {
     @Test(expected = IllegalArgumentException.class)
     public void shouldThrowOnEntityNotFound() {
         //given
-        EntityData keyData1 = createEntityDataWithHistoryWithTimeDiff(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA),
+        EntityData keyData1 = createEntityDataWithHistoryWithTimeDiff(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1.toString()),
                 100);
 
 
@@ -423,21 +545,17 @@ public class EntityProviderTest extends AbstractProviderTest {
 
         //ask first for existing one to add to the cache
         this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, keyData1.getId(), keyData1.getPartitionData().getId(),
-                SCHEMA, RECORD_TIME);
+                SCHEMA1.toString(), RECORD_TIME);
 
         // when
-        EntityData data0 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID,keyData1.getId(), keyData1.getPartitionData().getId(),
-                SCHEMA1, recordTimestamp);
-
-        //then - Exception
-
+        this.entityProvider.findOrCreateEntityFor(SYSTEM_ID,keyData1.getId(), keyData1.getPartitionData().getId(),
+                SCHEMA2.toString(), recordTimestamp);
     }
 
-
     @Test(expected = IllegalStateException.class)
     public void shouldThrowOnHistoryRewrite() {
         //given
-        EntityData keyData1 = createEntityDataWithHistoryWithTimeDiff(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA,SCHEMA1),
+        EntityData keyData1 = createEntityDataWithHistoryWithTimeDiff(0, PARTITION_KEY_VALUES, Arrays.asList(SCHEMA1.toString(), SCHEMA2.toString()),
                 100);
 
         final long recordTimestamp = 100;
@@ -445,27 +563,23 @@ public class EntityProviderTest extends AbstractProviderTest {
         when(this.httpClient.findByEntityIdAndTimeWindow(keyData1.getId(), RECORD_TIME,RECORD_TIME)).thenReturn(keyData1);
 
         //ask first for existing one to add to the cache
-        this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, keyData1.getId(), keyData1.getPartitionData().getId(),SCHEMA, RECORD_TIME);
+        this.entityProvider.findOrCreateEntityFor(SYSTEM_ID, keyData1.getId(), keyData1.getPartitionData().getId(),SCHEMA1.toString(), RECORD_TIME);
 
         // when
-        EntityData data0 = this.entityProvider.findOrCreateEntityFor(SYSTEM_ID,keyData1.getId(), 10000L, SCHEMA2, RECORD_TIME);
-
-        //then - Exception
-
+        this.entityProvider.findOrCreateEntityFor(SYSTEM_ID,keyData1.getId(), 10000L, SCHEMA3.toString(), RECORD_TIME);
     }
 
-
     @Test
     public void shouldFindBySystemIdKeyValuesAndTimeWindow() {
         //given
         EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES,
-                Arrays.asList(SCHEMA, SCHEMA1, SCHEMA2));
+                Arrays.asList(SCHEMA1.toString(), SCHEMA2.toString(), SCHEMA3.toString()));
 
         //when
-        when(this.httpClient
+        when(httpClient
                 .findBySystemIdKeyValuesAndTimeWindow(SYSTEM_ID, ENTITY_KEY_VALUES, RECORD_TIME, RECORD_TIME + 3))
                 .thenReturn(keyData);
-        EntityData data = this.entityProvider
+        EntityData data = entityProvider
                 .findBySystemIdKeyValuesAndTimeWindow(SYSTEM_ID, ENTITY_KEY_VALUES, RECORD_TIME, RECORD_TIME + 3);
 
         //then
@@ -476,7 +590,7 @@ public class EntityProviderTest extends AbstractProviderTest {
     @Test
     public void shouldUpdateEntityNameBasedOnListOfEntityData() throws Exception {
         //given
-        EntityData entityData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Collections.singletonList(SCHEMA));
+        EntityData entityData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES, Collections.singletonList(SCHEMA1.toString()));
 
         List<EntityData> inputEntityDataList = Lists.newArrayList();
         inputEntityDataList.add(entityData);
@@ -485,7 +599,7 @@ public class EntityProviderTest extends AbstractProviderTest {
         entityDataList.add(entityDataMock);
 
         //when
-        when(httpClient.updateEntities(any(String.class))).thenReturn(entityDataList);
+        when(httpClient.updateEntities(any(List.class))).thenReturn(entityDataList);
         List<EntityData> entityDataReturnedList = entityProvider.updateEntities(inputEntityDataList);
 
         //then
@@ -498,14 +612,12 @@ public class EntityProviderTest extends AbstractProviderTest {
     public void shouldFindEntityById() {
         //given
         EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES,
-                Arrays.asList(SCHEMA, SCHEMA1, SCHEMA2));
+                Arrays.asList(SCHEMA1.toString(), SCHEMA2.toString(), SCHEMA3.toString()));
 
         //when
-        when(this.httpClient.findById(0))
-                .thenReturn(keyData);
+        when(httpClient.findById(0)).thenReturn(keyData);
 
-        EntityData data = this.entityProvider
-                .findById(0);
+        EntityData data = entityProvider.findById(0);
 
         //then
         assertNotNull(data);
@@ -514,40 +626,31 @@ public class EntityProviderTest extends AbstractProviderTest {
 
     @Test(expected = IllegalArgumentException.class)
     public void shouldThrowExceptionWhenFindAllEntitiesByIdInWithNullList() {
-        List<EntityData> fetchedEntities = this.entityProvider
-                .findAllByIdIn(null);
-
-        fail("This method should throw exception when invoked with null instead of collection!");
+        entityProvider.findAllByIdIn(null);
     }
 
     @Test(expected = IllegalArgumentException.class)
     public void shouldThrowExceptionWhenFindAllEntitiesByIdInWithEmptyList() {
-        List<EntityData> fetchedEntities = this.entityProvider
-                .findAllByIdIn(Collections.emptyList());
-
-        fail("This method should throw exception when invoked with empty collection!");
+        entityProvider.findAllByIdIn(Collections.emptyList());
     }
 
     @Test
     public void shouldFindAllEntitiesByIdInList() {
         //given
         EntityData keyData = createEntityDataWithHistory(0, PARTITION_KEY_VALUES,
-                Arrays.asList(SCHEMA, SCHEMA1, SCHEMA2));
+                Arrays.asList(SCHEMA1.toString(), SCHEMA2.toString(), SCHEMA3.toString()));
 
         EntityData otherKeyData = createEntityDataWithHistory(1, PARTITION_KEY_VALUES,
-                Arrays.asList(SCHEMA, SCHEMA1, SCHEMA2));
+                Arrays.asList(SCHEMA1.toString(), SCHEMA2.toString(), SCHEMA3.toString()));
 
         List<Long> requestedEntityIds = Arrays.asList(keyData.getId(), otherKeyData.getId());
         //when
-        when(this.httpClient.findAllByIdIn(requestedEntityIds))
-                .thenReturn(Arrays.asList(keyData, otherKeyData));
+        when(httpClient.findAllByIdIn(requestedEntityIds)).thenReturn(Arrays.asList(keyData, otherKeyData));
 
-        List<EntityData> fetchedEntities = this.entityProvider
-                .findAllByIdIn(requestedEntityIds);
+        List<EntityData> fetchedEntities = entityProvider.findAllByIdIn(requestedEntityIds);
 
         //then
         assertNotNull(fetchedEntities);
         assertEquals(2, fetchedEntities.size());
     }
-
 }
diff --git a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/PartitionProviderTest.java b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/PartitionProviderTest.java
index c7899b84c6134616ebb9c3e64522bac87d49f9c0..d4b154890c755f5548cbd37f94ade03b4bfae8dc 100644
--- a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/PartitionProviderTest.java
+++ b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/PartitionProviderTest.java
@@ -6,23 +6,24 @@ package cern.accsoft.nxcals.service.client.providers;
 import cern.accsoft.nxcals.common.domain.PartitionData;
 import cern.accsoft.nxcals.common.domain.impl.PartitionDataImpl;
 import cern.accsoft.nxcals.service.client.providers.feign.PartitionClient;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.MockitoJUnitRunner;
 
+import static cern.accsoft.nxcals.service.client.providers.DomainTestConstants.PARTITION_KEY_VALUES;
+import static cern.accsoft.nxcals.service.client.providers.DomainTestConstants.SYSTEM_ID;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
 
-/**
- * @author Marcin Sobieszek
- * @date Jul 22, 2016 4:43:56 PM
- */
 @RunWith(MockitoJUnitRunner.class)
-public class PartitionProviderTest extends AbstractProviderTest {
+public class PartitionProviderTest {
     private PartitionProvider partitionProvider;
 
     @Mock
@@ -36,31 +37,28 @@ public class PartitionProviderTest extends AbstractProviderTest {
 
     @Test
     public void shouldNotObtainPartitionDataForNonExistingPartition() {
-
-        Mockito.when(this.httpService.findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES)).thenReturn(null);
-        PartitionData data = this.partitionProvider.findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES);
-        Assert.assertNull(data);
-        data = this.partitionProvider.findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES);
-        Assert.assertNull(data);
-        Mockito.verify(this.httpService, times(2)).findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES);
+        when(httpService.findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES)).thenReturn(null);
+        PartitionData data = partitionProvider.findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES);
+        assertNull(data);
+        data = partitionProvider.findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES);
+        assertNull(data);
+        verify(httpService, times(2)).findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES);
     }
 
     @Test
     public void shouldObtainPartitionCachedDataForExistingPart() {
-
-        PartitionData partData = new PartitionDataImpl(0, PARTITION_KEY_VALUES);
-        Mockito.when(this.httpService.findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES)).thenReturn(partData);
+        PartitionData partData = PartitionDataImpl.builder().id(0).keyValues(PARTITION_KEY_VALUES).build();
+        when(this.httpService.findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES)).thenReturn(partData);
 
         for (int i = 0; i < 10; i++) {
             PartitionData data = this.partitionProvider.findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES);
-            Assert.assertNotNull(data);
-            Assert.assertEquals(partData, data);
+            assertNotNull(data);
+            assertEquals(partData, data);
 
             data = this.partitionProvider.findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES);
-            Assert.assertNotNull(data);
-            Assert.assertEquals(partData, data);
+            assertNotNull(data);
+            assertEquals(partData, data);
         }
-        Mockito.verify(this.httpService, times(1)).findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES);
+        verify(this.httpService, times(1)).findBySystemIdAndKeyValues(SYSTEM_ID, PARTITION_KEY_VALUES);
     }
-
 }
diff --git a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/SchemaProviderTest.java b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/SchemaProviderTest.java
index 7f3bcd4bd96d356383acd1f4eabbd269b1c0b4c7..3215861f8d43e87dca6b777dff687703ba83bec5 100644
--- a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/SchemaProviderTest.java
+++ b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/SchemaProviderTest.java
@@ -50,23 +50,23 @@ public class SchemaProviderTest extends AbstractProviderTest {
 
     @Test
     public void shouldGetSchemaDataById() {
-        when(httpService.findById(1)).thenReturn(new SchemaDataImpl(1, SCHEMA));
+        when(httpService.findById(1)).thenReturn(new SchemaDataImpl(1, SCHEMA1.toString()));
         SchemaData data = schemaProvider.findById(1);
         Assert.assertEquals(1, data.getId());
-        Assert.assertEquals(SCHEMA, data.getSchemaJson());
+        Assert.assertEquals(SCHEMA1.toString(), data.getSchemaJson());
         data = schemaProvider.findById(1);
         Assert.assertEquals(1, data.getId());
-        Assert.assertEquals(SCHEMA, data.getSchemaJson());
+        Assert.assertEquals(SCHEMA1.toString(), data.getSchemaJson());
         Mockito.verify(httpService, times(1)).findById(1);
 
         Mockito.reset(httpService);
-        Mockito.when(httpService.findById(2)).thenReturn(new SchemaDataImpl(2, SCHEMA1));
+        Mockito.when(httpService.findById(2)).thenReturn(new SchemaDataImpl(2, SCHEMA2.toString()));
         data = schemaProvider.findById(2);
         Assert.assertEquals(2, data.getId());
-        Assert.assertEquals(SCHEMA1, data.getSchemaJson());
+        Assert.assertEquals(SCHEMA2.toString(), data.getSchemaJson());
         data = schemaProvider.findById(2);
         Assert.assertEquals(2, data.getId());
-        Assert.assertEquals(SCHEMA1, data.getSchemaJson());
+        Assert.assertEquals(SCHEMA2.toString(), data.getSchemaJson());
         Mockito.verify(httpService, times(1)).findById(2);
     }
 
diff --git a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/SystemProviderTest.java b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/SystemProviderTest.java
index 3e7aa9a51615caff55408b300022174f54d0a757..3773c9140e66218e6ecf1e68cd9f48fa7cbdff24 100644
--- a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/SystemProviderTest.java
+++ b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/SystemProviderTest.java
@@ -50,7 +50,7 @@ public class SystemProviderTest extends AbstractProviderTest {
 
         for (int i = 0; i < 10; i++) {
             String name = "test" + i;
-            SystemData identity = new SystemDataImpl(i, name, SCHEMA, PARTITION_SCHEMA, TIME_KEY_SCHEMA, null);
+            SystemData identity = new SystemDataImpl(i, name, SCHEMA1.toString(), PARTITION_SCHEMA.toString(), TIME_KEY_SCHEMA.toString(), null);
             when(this.httpService.findByName(name)).thenReturn(identity);
             SystemData data = this.systemProvider.findByName(name);
             assertNotNull(data);
diff --git a/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/TestSchemas.java b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/TestSchemas.java
new file mode 100644
index 0000000000000000000000000000000000000000..941e41c718294636c36db939685642428f26bc0c
--- /dev/null
+++ b/accsoft-nxcals-service-client/src/test/java/cern/accsoft/nxcals/service/client/providers/TestSchemas.java
@@ -0,0 +1,49 @@
+package cern.accsoft.nxcals.service.client.providers;
+
+import org.apache.avro.Schema;
+import org.apache.avro.SchemaBuilder;
+
+public class TestSchemas {
+
+    private TestSchemas() {
+        //Test static class
+    }
+
+    static final String PARTITION_STRING_SCHEMA_KEY = "partition_string";
+    static final String PARTITION_STRING_SCHEMA_KEY_1 = "different_partition_string";
+    static final String PARTITION_DOUBLE_SCHEMA_KEY = "partition_double";
+
+    static final String ENTITY_STRING_SCHEMA_KEY = "entity_string";
+    static final String ENTITY_DOUBLE_SCHEMA_KEY = "entity_double";
+    static final String ENTITY_STRING_SCHEMA_KEY_1 = "entity_string_1";
+    static final String ENTITY_STRING_SCHEMA_KEY_2 = "entity_string_2";
+
+    static final String TIME_DOUBLE_SCHEMA_KEY = "time_double";
+    static final String RECORD_VERSION_STRING_SCHEMA_KEY = "record_version_string";
+
+    public static final Schema ENTITY_SCHEMA = SchemaBuilder.record("test_type").fields()
+            .name(ENTITY_STRING_SCHEMA_KEY).type().stringType().noDefault()
+            .name(ENTITY_DOUBLE_SCHEMA_KEY).type().doubleType().noDefault()
+            .endRecord();
+
+    static final Schema ENTITY_SCHEMA_1 = SchemaBuilder.record("differentType")
+            .fields().name(ENTITY_STRING_SCHEMA_KEY_1).type().stringType().noDefault()
+            .endRecord();
+
+    static final Schema ENTITY_SCHEMA_2 = SchemaBuilder.record("differentType")
+            .fields().name(ENTITY_STRING_SCHEMA_KEY_2).type().stringType().noDefault()
+            .endRecord();
+
+    static final Schema PARTITION_SCHEMA = SchemaBuilder.record("test_type").fields()
+            .name(PARTITION_STRING_SCHEMA_KEY).type().stringType().noDefault()
+            .name(PARTITION_DOUBLE_SCHEMA_KEY).type().doubleType().noDefault()
+            .endRecord();
+
+    static final Schema TIME_SCHEMA = SchemaBuilder.record("test_type").fields()
+            .name(TIME_DOUBLE_SCHEMA_KEY).type().doubleType().noDefault()
+            .endRecord();
+
+    public static final Schema RECORD_VERSION_SCHEMA = SchemaBuilder.record("test_type").fields()
+            .name(RECORD_VERSION_STRING_SCHEMA_KEY).type().stringType().noDefault()
+            .endRecord();
+}
diff --git a/accsoft-nxcals-service/build.gradle b/accsoft-nxcals-service/build.gradle
index 9e88cb1d88ecffa3f09188c3dd89818a3b72afe9..58b4cff55c0f160d976a4f6c01e85d4f7664914c 100644
--- a/accsoft-nxcals-service/build.gradle
+++ b/accsoft-nxcals-service/build.gradle
@@ -56,8 +56,10 @@ dependencies {
     compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: fasterxmlJacksonVersion
     compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: fasterxmlJacksonVersion
 
-    testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion
-    testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version:springBootVersion
+    testCompile group: 'org.assertj', name: 'assertj-core', version: assertjCoreVersion
+    testCompile (group: 'org.springframework.boot', name: 'spring-boot-starter-test', version:springBootVersion) {
+        exclude group: 'org.assertj', module: 'assertj-core'
+    }
     testCompile group: 'org.springframework.security', name: 'spring-security-test', version:springSecurityVersion
 
     testCompile (group: 'org.springframework.security.kerberos', name: 'spring-security-kerberos-client', version: springSecurityKerberosVersion) {
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/Entity.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/Entity.java
index 1c8b73551c7ef02ad2722bb6137b222ebbce8e33..392e65ed5be9a7b42798f0d5656df8cfcba0ffdf 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/Entity.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/Entity.java
@@ -24,6 +24,7 @@ import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.stream.Collectors;
 
+import static cern.accsoft.nxcals.common.utils.KeyValuesUtils.convertKeyValuesStringIntoMap;
 import static cern.accsoft.nxcals.service.domain.SequenceType.ENTITY;
 
 @javax.persistence.Entity
@@ -43,8 +44,6 @@ public class Entity extends StandardPersistentEntityWithVersion {
 
     private SortedSet<EntityHistory> entityHistories;
 
-    private Set<VariableConfig> variableConfigs;
-
     private Instant lockedUntilStamp;
 
     @Id
@@ -124,7 +123,7 @@ public class Entity extends StandardPersistentEntityWithVersion {
     }
 
     public EntityData toEntityData() {
-        return new EntityDataImpl(getId(), getKeyValues(),
+        return new EntityDataImpl(getId(), convertKeyValuesStringIntoMap(keyValues),
                 getPartition().getSystem() != null ? getPartition().getSystem().toSystemData() : null,
                 partition != null ? partition.toPartitionData() : null,
                 schema != null ? schema.toSchemaData() : null,
@@ -134,7 +133,7 @@ public class Entity extends StandardPersistentEntityWithVersion {
     }
 
     public EntityData toEntityDataWithHistory(SortedSet<EntityHistoryData> entityHistoryData) {
-        return new EntityDataImpl(getId(), getKeyValues(),
+        return new EntityDataImpl(getId(), convertKeyValuesStringIntoMap(keyValues),
                 getPartition().getSystem() != null ? getPartition().getSystem().toSystemData() : null,
                 partition != null ? partition.toPartitionData() : null,
                 schema != null ? schema.toSchemaData() : null, entityHistoryData,
@@ -174,10 +173,8 @@ public class Entity extends StandardPersistentEntityWithVersion {
                 ", keyValues='" + keyValues + '\'' +
                 ", partition=" + partition +
                 ", schema=" + schema +
-                ", variableConfigs=" + variableConfigs +
                 ", lockedUntilStamp=" + lockedUntilStamp +
                 ", recVersion=" + getRecVersion() +
                 '}';
     }
-
 }
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/Partition.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/Partition.java
index 62bc651e3f80ac32068b526e2d99f5c404b861a6..1b7dee82235f1c310f836e841025ca0d00dcaf7d 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/Partition.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/Partition.java
@@ -17,6 +17,7 @@ import javax.validation.constraints.NotNull;
 import java.util.HashSet;
 import java.util.Set;
 
+import static cern.accsoft.nxcals.common.utils.KeyValuesUtils.convertKeyValuesStringIntoMap;
 import static cern.accsoft.nxcals.service.domain.SequenceType.PARTITION;
 
 @javax.persistence.Entity
@@ -76,7 +77,7 @@ public class Partition extends StandardPersistentEntityWithVersion {
     }
 
     public PartitionData toPartitionData() {
-        return new PartitionDataImpl(this.getId(), this.getKeyValues());
+        return PartitionDataImpl.builder().id(this.getId()).keyValues(convertKeyValuesStringIntoMap(keyValues)).build();
     }
 
     public boolean addEntity(Entity e) {
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/System.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/System.java
index 69e18a2b6865f5a24620ec2a4ef724c763b551ce..1ecbc230d793867e664c8658fa8c36b270412bfe 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/System.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/domain/System.java
@@ -16,9 +16,6 @@ import java.util.Set;
 
 import static cern.accsoft.nxcals.service.domain.SequenceType.SYSTEM;
 
-/**
- * @author ntsvetko
- */
 @javax.persistence.Entity
 @Table(name = "SYSTEMS")
 /**
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityResourcesService.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityResourcesService.java
index c43c818cbe74d3afa0c29aad5b5eaa6019b8f4a2..860e13e7b81c586af98e3a489cc7a429c04ebf00 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityResourcesService.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityResourcesService.java
@@ -5,14 +5,12 @@ package cern.accsoft.nxcals.service.internal;
 
 import cern.accsoft.nxcals.common.domain.EntityResources;
 
+import java.util.Map;
 import java.util.Set;
 
-/**
- * Created by ntsvetko on 4/25/17.
- */
 public interface InternalEntityResourcesService {
 
-    Set<EntityResources> findBySystemIdKeyValuesAndTimeWindow(long systemId, String entityKeyValues,
+    Set<EntityResources> findBySystemIdKeyValuesAndTimeWindow(long systemId, Map<String, Object> entityKeyValues,
             long startTime, long endTime);
 
     Set<EntityResources> findByEntityIdAndTimeWindow(long entityId, long startTime, long endTime);
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityResourcesServiceImpl.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityResourcesServiceImpl.java
index 312968f6839dee431a04095055fa5cee0f7171f2..efeaa8a19f798ea98a7534f53a4966cb21292a36 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityResourcesServiceImpl.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityResourcesServiceImpl.java
@@ -33,9 +33,6 @@ import java.util.stream.Stream;
 
 import static java.time.temporal.ChronoUnit.DAYS;
 
-/**
- * Created by ntsvetko on 4/25/17.
- */
 @Service
 public class InternalEntityResourcesServiceImpl implements InternalEntityResourcesService {
     private final Logger LOGGER = LoggerFactory.getLogger(InternalEntityResourcesServiceImpl.class);
@@ -61,16 +58,15 @@ public class InternalEntityResourcesServiceImpl implements InternalEntityResourc
     }
 
     @Override
-    public Set<EntityResources> findBySystemIdKeyValuesAndTimeWindow(long systemId, String entityKeyValues,
+    public Set<EntityResources> findBySystemIdKeyValuesAndTimeWindow(long systemId, Map<String, Object> entityKeyValues,
             long startTime, long endTime) {
-        Entity entity = this.entityService
-                .findEntityWithHistForTimeWindow(systemId, entityKeyValues, startTime, endTime);
+        Entity entity = entityService.findEntityWithHistForTimeWindow(systemId, entityKeyValues, startTime, endTime);
         return getEntityResourcesData(startTime, endTime, entity);
     }
 
     @Override
     public Set<EntityResources> findByEntityIdAndTimeWindow(long entityId, long startTime, long endTime) {
-        Entity entity = this.entityService.findByEntityIdAndTimeWindow(entityId, startTime, endTime);
+        Entity entity = entityService.findByEntityIdAndTimeWindow(entityId, startTime, endTime);
         return getEntityResourcesData(startTime, endTime, entity);
     }
 
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityService.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityService.java
index 739f1fdeb5590e424c84e77171c50d9710d0c8c6..3ea52afd4e655a8fd4e8407cbf8a3d37a48675be 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityService.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityService.java
@@ -10,11 +10,11 @@ import cern.accsoft.nxcals.service.domain.Partition;
 import cern.accsoft.nxcals.service.domain.Schema;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 public interface InternalEntityService {
 
-
     /**
      * Creates all objects necessary to persist the Entity state in the NXCALS system.
      * In this case only the history might be changed. Otherwise the entity & partition must exist before.
@@ -34,16 +34,14 @@ public interface InternalEntityService {
      */
     Entity findOrCreateEntityFor(long systemId, long entityId, long partitionId, String recordDefinition, long recordTimestamp );
 
-
-
     /**
      * Creates all objects necessary to persist the Entity state in the NXCALS system.
      *
      * @param systemId         an identification number that corresponds to the
      *                         target {@link cern.accsoft.nxcals.service.domain.System}
-     * @param keyValues        a json map of keys and values
-     * @param partitionValues  a json map of keys and values
-     * @param recordDefinition a json map of key names and @see Data types.
+     * @param keyValues        a {@link Map} of keys and values
+     * @param partitionValues  a {@link Map} of keys and values
+     * @param recordDefinition a {@link Map} of key names and @see Data types.
      * @param recordTimestamp  timestamp value to be used as craetion time and history reference
      * @return an {@link Entity} with all corresponding {@link Partition} {@link Schema} and @see
      * @see Partition
@@ -51,27 +49,29 @@ public interface InternalEntityService {
      * @see Entity
      * @see cern.accsoft.nxcals.service.domain.System
      */
-    Entity findOrCreateEntityFor(long systemId, String keyValues, String partitionValues, String recordDefinition, long recordTimestamp);
+    Entity findOrCreateEntityFor(long systemId, Map<String, Object> keyValues, Map<String, Object> partitionValues,
+            String recordDefinition, long recordTimestamp);
 
     /**
      * Finds an entity for given system & keys with history limited to the time range <startTime, endTime>.
      *
      * @param systemId        the identification number that corresponds to the target {@link cern.accsoft.nxcals.service.domain.System}
-     * @param entityKeyValues a json map of properties that belong to an {@link Entity}
+     * @param entityKeyValues a {@link Map} of properties that belong to an {@link Entity}
      * @param startTime       the search start time in epoch milliseconds
      * @param endTime         the search end time in epoch milliseconds
      * @return an {@link Entity} instance that matches the provided search criteria
      */
-    Entity findEntityWithHistForTimeWindow(long systemId, String entityKeyValues, long startTime, long endTime);
+    Entity findEntityWithHistForTimeWindow(long systemId, Map<String, Object> entityKeyValues, long startTime,
+            long endTime);
 
     /**
      * Finds an entity by the given system id and it's key-value properties.
      *
      * @param systemId        the identification number that corresponds to the target {@link cern.accsoft.nxcals.service.domain.System}
-     * @param entityKeyValues a json map of properties that belong to an {@link Entity}
+     * @param entityKeyValues a {@link Map} of properties that belong to an {@link Entity}
      * @return an {@link Entity} instance that matches the given search criteria
      */
-    Entity findByPartitionSystemIdAndKeyValues(long systemId, String entityKeyValues);
+    Entity findByPartitionSystemIdAndKeyValues(long systemId, Map<String, Object> entityKeyValues);
 
     /**
      * Finds an entity by the given entity id for a specified time window
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityServiceImpl.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityServiceImpl.java
index df8a5909e3b04d98e15c1e3c8e4eb5eddb33d31c..04fcc344c524585bc40ccc2ec36f6c075024898d 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityServiceImpl.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalEntityServiceImpl.java
@@ -44,6 +44,7 @@ import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.StreamSupport;
 
+import static cern.accsoft.nxcals.common.utils.KeyValuesUtils.convertMapIntoAvroSchemaString;
 import static cern.accsoft.nxcals.common.utils.TimeUtils.getInstantFromNanos;
 import static java.lang.String.format;
 
@@ -71,13 +72,10 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
 
     @Autowired
     private EntityRepository entityRepository;
-
     @Autowired
     private PartitionRepository partitionRepository;
-
     @Autowired
     private SystemRepository systemRepository;
-
     @Autowired
     private SchemaRepository schemaRepository;
 
@@ -90,33 +88,33 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
     @Autowired
     private BulkAction<Set<Long>, Set<Entity>> splitBatchAction;
 
-
-
     @Override
     @Transactional(transactionManager = "jpaTransactionManager")
-    public Entity findOrCreateEntityFor(long systemId, String entityKeyValues, String partitionKeyValues,
+    public Entity findOrCreateEntityFor(long systemId, Map<String, Object> entityKeyValues,
+            Map<String, Object> partitionKeyValues,
             String recordFieldsWithTypes, long recordTimestamp) {
 
         log.info("findOrCreateEntityFor system={}, entity={} partition={} schema={} recordTimestamp={}", systemId,
                 entityKeyValues, partitionKeyValues, recordFieldsWithTypes, recordTimestamp);
 
-        System clientSystem = this.systemRepository.findById(systemId).orElseThrow(() -> {
+        System clientSystem = systemRepository.findById(systemId).orElseThrow(() -> {
             log.warn("There is no system coresponding to systemId = {}", systemId);
             return new NotFoundRuntimeException(format(ENTITY_NOT_FOUND_ERROR_FORMAT, systemId));
         });
 
         return internalFindOrCreateEntityFor(clientSystem, entityKeyValues, partitionKeyValues, recordFieldsWithTypes,
                 recordTimestamp);
-
     }
 
     @Override
-    public Entity findEntityWithHistForTimeWindow(long systemId, String entityKeyValues, long startTime, long endTime) {
+    public Entity findEntityWithHistForTimeWindow(long systemId, Map<String, Object> entityKeyValues, long startTime,
+            long endTime) {
         if (startTime > endTime) {
             throw new IllegalArgumentException(
                     "Start time must be less or equal end time for systemId=" + systemId + " entityKey="
                             + entityKeyValues + " startTime=" + startTime + " endTime=" + endTime);
         }
+
         Entity entity = findEntityBySystemIdAndKeyValuesOrThrow(systemId, entityKeyValues);
         SortedSet<EntityHistory> entityHistory = getEntityHist(startTime, endTime, entity);
         entity.setEntityHistories(entityHistory);
@@ -129,7 +127,7 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
     }
 
     @Override
-    public Entity findByPartitionSystemIdAndKeyValues(long systemId, String entityKeyValues) {
+    public Entity findByPartitionSystemIdAndKeyValues(long systemId, Map<String, Object> entityKeyValues) {
         Entity entity = findEntityBySystemIdAndKeyValuesOrThrow(systemId, entityKeyValues);
         EntityHistory entityHistory = entityHistoryRepository.findByEntityAndValidToStamp(entity, null)
                 .orElseThrow(() -> new NotFoundRuntimeException("Cannot find history for entityId=" + entity.getId()));
@@ -152,10 +150,6 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
         return entity;
     }
 
-
-
-
-
     @Transactional(transactionManager = "jpaTransactionManager")
     @Override
     public Entity extendEntityFirstHistoryDataFor(long entityId, String schemaAsString, long fromNanos) {
@@ -186,8 +180,6 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
             } else {
                 throw new ConfigDataConflictException("The timestamp=" + fromNanos + " is not before or within the first history record for entity" + entity);
             }
-
-
         }
     }
 
@@ -222,7 +214,8 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
             entityManager.detach(fetchedEntity);
             fetchedEntity.setRecVersion(entityData.getRecVersion());
 
-            fetchedEntity.setKeyValues(entityData.getEntityKeyValues());
+            fetchedEntity.setKeyValues(convertMapIntoAvroSchemaString(entityData.getEntityKeyValues(),
+                    fetchedEntity.getPartition().getSystem().getEntityKeyDefs()));
 
             Instant lockedUntilStamp = entityData.getLockUntilEpochNanos() == null ?
                     null : TimeUtils.getInstantFromNanos(entityData.getLockUntilEpochNanos());
@@ -289,10 +282,17 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
         return entities;
     }
 
-    private Entity findEntityBySystemIdAndKeyValuesOrThrow(long entityId, String keyValues) {
-        return entityRepository.findByPartitionSystemIdAndKeyValues(entityId, keyValues)
+    private Entity findEntityBySystemIdAndKeyValuesOrThrow(long systemId, Map<String, Object> keyValues) {
+        String entityKeyDefinitions = findSystemOrThrowError(systemId).getEntityKeyDefs();
+        return entityRepository.findByPartitionSystemIdAndKeyValues(systemId,
+                convertMapIntoAvroSchemaString(keyValues, entityKeyDefinitions))
                 .orElseThrow(() -> new NotFoundRuntimeException(
-                        String.format("Entity with id %s  and key values %s not found.", entityId, keyValues)));
+                        String.format("Entity of system with id %s and key values %s not found.", systemId, keyValues)));
+    }
+
+    private System findSystemOrThrowError(long id) {
+        return systemRepository.findById(id)
+                .orElseThrow(() -> new NotFoundRuntimeException(format("System with id %s not found", id)));
     }
 
     private Entity findEntityByIdOrThrow(long id) {
@@ -330,12 +330,16 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
     }
 
 
-    private Entity internalFindOrCreateEntityFor(System system, String entityKeyValues, String partitionKeyValues,
-            String recordFieldsWithTypes, long recordTimestamp) {
-        try (AutoCloseableLock lock = this.getLockFor(system.getId() + entityKeyValues)) {
+    private Entity internalFindOrCreateEntityFor(System system, Map<String, Object> entityKeyValues,
+            Map<String, Object> partitionKeyValues, String recordFieldsWithTypes, long recordTimestamp) {
+
+        String entityKeyValuesString = convertMapIntoAvroSchemaString(entityKeyValues, system.getEntityKeyDefs());
+        String partitionKeyValuesString = convertMapIntoAvroSchemaString(partitionKeyValues, system.getPartitionKeyDefs());
+
+        try (AutoCloseableLock lock = this.getLockFor(system.getId() + entityKeyValuesString)) {
             // find or create entity for the given system & entity key values.
-            Entity entity = getEntity(system, entityKeyValues);
-            Partition partition = getPartition(system, partitionKeyValues, entity);
+            Entity entity = getEntity(system, entityKeyValuesString);
+            Partition partition = getPartition(system, partitionKeyValuesString, entity);
             Schema schema = getSchema(recordFieldsWithTypes, entity);
             return updateEntityHistoryFor(entity, partition, schema, recordTimestamp);
         }
@@ -346,7 +350,7 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
         String md5Hash = DigestUtils.md5Hex(schemaAsString);
         Schema schema;
         if (entity.getSchema() == null || !md5Hash.equals(entity.getSchema().getContentHash())) {
-            schema = this.findOrCreateSchema(md5Hash, schemaAsString);
+            schema = findOrCreateSchema(md5Hash, schemaAsString);
         } else {
             schema = entity.getSchema();
         }
@@ -358,8 +362,7 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
         // find or create partition for a given system & partition key values
         if (entity.getPartition() == null || !partitionKeyValues.equals(entity.getPartition().getKeyValues())) {
             // This is different partition than on the entity, maybe changed partition
-            partition = this.findOrCreatePartition(system, partitionKeyValues);
-            //entity.setPartition(p);
+            partition = findOrCreatePartition(system, partitionKeyValues);
         } else {
             partition = entity.getPartition();
         }
@@ -367,8 +370,8 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
     }
 
     private Entity getEntity(System system, String entityKeyValues) {
-        return this.entityRepository.findByPartitionSystemIdAndKeyValues(system.getId(), entityKeyValues)
-                .orElseGet(() -> this.createEntity(entityKeyValues));
+        return entityRepository.findByPartitionSystemIdAndKeyValues(system.getId(), entityKeyValues)
+                .orElseGet(() -> createEntity(entityKeyValues));
     }
 
     private Entity extendEntityHistoryFor(Entity entity, Partition newPartition, Schema newSchema, long fromNanos, long toNanos) {
@@ -402,7 +405,7 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
     private EntityHistory handleExistingEntity(Entity entity, Partition newPartition, Schema newSchema,
             Instant recordTime) {
         //This is not a new entity so we search in the history
-        Optional<EntityHistory> entityHistOptional = this.entityHistoryRepository
+        Optional<EntityHistory> entityHistOptional = entityHistoryRepository
                 .findByEntityAndTimestamp(entity, recordTime);
         return entityHistOptional
                 .map(hist -> handleExistingEntityHist(entity, newPartition, newSchema, recordTime, hist))
@@ -488,30 +491,28 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
     }
 
     private Entity saveEntity(Entity entity, EntityHistory entityHistory) {
-        Entity ret = this.entityRepository.save(entity);
-        ret.clearHistory();
-        ret.addEntityHist(entityHistory);
-        return ret;
+        Entity newEntity = entityRepository.save(entity);
+        newEntity.clearHistory();
+        newEntity.addEntityHist(entityHistory);
+        return newEntity;
     }
 
     private EntityHistory handleNewEntity(Entity entity, Partition newPartition, Schema newSchema, Instant recordTime) {
-        EntityHistory entityHistory;//This is a new entity and it has no history
         entity.setPartition(newPartition);
         entity.setSchema(newSchema);
-        entityHistory = createAndPersistEntityHistory(this.entityRepository.save(entity), newPartition, newSchema,
+        return createAndPersistEntityHistory(entityRepository.save(entity), newPartition, newSchema,
                 recordTime, null);
-        return entityHistory;
     }
 
     /**
      * Create new history record for a given entity with the corresponding validFrom and validTo timestamps
      */
-    private EntityHistory createAndPersistEntityHistory(Entity e, Partition p, Schema s, Instant validFromStamp,
-            Instant validToStamp) {
+    private EntityHistory createAndPersistEntityHistory(Entity entity, Partition partition, Schema schema,
+            Instant validFromStamp, Instant validToStamp) {
         EntityHistory newEntityHistory = new EntityHistory();
-        newEntityHistory.setEntity(e);
-        newEntityHistory.setSchema(s);
-        newEntityHistory.setPartition(p);
+        newEntityHistory.setEntity(entity);
+        newEntityHistory.setSchema(schema);
+        newEntityHistory.setPartition(partition);
         newEntityHistory.setValidFromStamp(validFromStamp);
         newEntityHistory.setValidToStamp(validToStamp);
         return entityHistoryRepository.save(newEntityHistory);
@@ -524,15 +525,15 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
 
     private Schema findOrCreateSchema(String md5Hash, String schemaAsString) {
         try (AutoCloseableLock lock = this.getLockFor(md5Hash)) {
-            return this.schemaRepository.findByContentHash(md5Hash)
-                    .orElseGet(() -> this.createAndPersistSchema(md5Hash, schemaAsString));
+            return schemaRepository.findByContentHash(md5Hash)
+                    .orElseGet(() -> createAndPersistSchema(md5Hash, schemaAsString));
         }
     }
 
     private Partition findOrCreatePartition(System system, String partitionKeyValues) {
-        try (AutoCloseableLock lock = this.getLockFor(system.getId() + partitionKeyValues)) {
-            return this.partitionRepository.findBySystemIdAndKeyValues(system.getId(), partitionKeyValues)
-                    .orElseGet(() -> this.createAndPersistPartition(system, partitionKeyValues));
+        try (AutoCloseableLock lock = getLockFor(system.getId() + partitionKeyValues)) {
+            return partitionRepository.findBySystemIdAndKeyValues(system.getId(), partitionKeyValues)
+                    .orElseGet(() -> createAndPersistPartition(system, partitionKeyValues));
         }
     }
 
@@ -546,15 +547,13 @@ public class InternalEntityServiceImpl extends BaseService implements InternalEn
         Schema schema = new Schema();
         schema.setContent(recordFieldsWithTypes);
         schema.setContentHash(md5Hash);
-        return this.schemaRepository.save(schema);
+        return schemaRepository.save(schema);
     }
 
     private Partition createAndPersistPartition(System system, String partitionKeyValues) {
-        Partition partition;
-        partition = new Partition();
+        Partition partition = new Partition();
         partition.setKeyValues(partitionKeyValues);
         partition.setSystem(system);
-        return this.partitionRepository.save(partition);
-
+        return partitionRepository.save(partition);
     }
 }
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalVariableService.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalVariableService.java
index 69884f0d718a8f76b5f267d1dfd174b188f673ef..bd10176aebfa4f0b05fd22148a18b2f726c99d43 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalVariableService.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalVariableService.java
@@ -9,9 +9,6 @@ import cern.accsoft.nxcals.service.domain.Variable;
 
 import java.util.List;
 
-/**
- * Created by ntsvetko on 1/12/17.
- */
 public interface InternalVariableService {
 
     Variable registerOrUpdateVariableFor(VariableData variableData);
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalVariableServiceImpl.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalVariableServiceImpl.java
index ba2c647dac87ff03efe422884e264f52fc8d55f6..6ea9c5a19ab0ccd593beeb0d9f546151a6674483 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalVariableServiceImpl.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/internal/InternalVariableServiceImpl.java
@@ -31,9 +31,6 @@ import java.util.Set;
 import java.util.SortedSet;
 import java.util.stream.Collectors;
 
-/**
- * Created by ntsvetko on 1/12/17.
- */
 @Service
 @Slf4j
 public class InternalVariableServiceImpl implements InternalVariableService {
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/CompactionController.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/CompactionController.java
index 563f1bfa4d26cfc75d77b2592da91d6016b08739..d556eb7f40c36a8feb15a42b0527dd7a7a32fb99 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/CompactionController.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/CompactionController.java
@@ -2,22 +2,21 @@ package cern.accsoft.nxcals.service.rest;
 
 import cern.accsoft.nxcals.service.internal.InternalCompactionService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import static cern.accsoft.nxcals.common.web.Endpoints.COMPACTION_SHOULD_COMPACT;
 import static org.springframework.web.bind.annotation.RequestMethod.POST;
 
-/**
- * Created by ntsvetko on 7/26/17.
- */
 @RestController
 public class CompactionController {
 
     @Autowired
     private InternalCompactionService internalCompactionService;
 
-    @RequestMapping(value = "/compaction/shouldCompact", method = POST)
+    @RequestMapping(value = COMPACTION_SHOULD_COMPACT, method = POST)
     public boolean shouldCompact(@RequestBody String path) {
         return internalCompactionService.shouldCompact(path);
     }
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/EntitiesResourcesController.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/EntitiesResourcesController.java
deleted file mode 100644
index 08121d37c0622c7b3af5e4ceb36bc120b8818e9d..0000000000000000000000000000000000000000
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/EntitiesResourcesController.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Copyright (c) 2017 European Organisation for Nuclear Research (CERN), All Rights Reserved.
- */
-package cern.accsoft.nxcals.service.rest;
-
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
-import cern.accsoft.nxcals.common.domain.impl.EntitiesResourcesDataImpl;
-import cern.accsoft.nxcals.service.internal.InternalEntityResourcesService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import static org.springframework.web.bind.annotation.RequestMethod.GET;
-
-@RestController
-public class EntitiesResourcesController {
-    private static final Logger LOGGER = LoggerFactory.getLogger(EntitiesResourcesController.class);
-
-    @Autowired
-    private InternalEntityResourcesService entityResourcesService;
-
-    @RequestMapping(value = "/resources/search/findBySystemIdKeyValuesAndTimeWindow", method = GET)
-    public EntitiesResourcesDataImpl findBySystemIdKeyValuesAndTimeWindow(@RequestParam("systemId") long systemId,
-            @RequestParam("entityKeyValues") String entityKeyValues, @RequestParam("startTime") long startTime,
-            @RequestParam("endTime") long endTime) {
-
-        return new EntitiesResourcesDataImpl(this.entityResourcesService
-                .findBySystemIdKeyValuesAndTimeWindow(systemId, entityKeyValues, startTime, endTime));
-
-    }
-
-    @RequestMapping(value = "/resources/search/findByEntityIdAndTimeWindow", method = GET)
-    public EntitiesResourcesData findByEntityIdAndTimeWindow(@RequestParam("entityId") long entityId,
-            @RequestParam("startTime") long startTime, @RequestParam("endTime") long endTime) {
-        return new EntitiesResourcesDataImpl(
-                this.entityResourcesService.findByEntityIdAndTimeWindow(entityId, startTime, endTime));
-    }
-}
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/EntityController.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/EntityController.java
index 9a380e1c8492c50dcddae59c5967e2fd1bdbddaf..2002046f04bcbcc16f0e9f433e0d26e41515aca4 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/EntityController.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/EntityController.java
@@ -3,6 +3,7 @@
  */
 package cern.accsoft.nxcals.service.rest;
 
+import cern.accsoft.nxcals.common.domain.impl.FindOrCreateEntityRequestImpl;
 import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.service.domain.Entity;
 import cern.accsoft.nxcals.service.internal.InternalEntityService;
@@ -17,11 +18,16 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.validation.constraints.NotEmpty;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITIES;
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITY_EXTEND_FIRST_HISTORY;
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITY_UPDATE;
 import static java.util.stream.Collectors.toList;
 import static org.springframework.web.bind.annotation.RequestMethod.GET;
+import static org.springframework.web.bind.annotation.RequestMethod.POST;
 import static org.springframework.web.bind.annotation.RequestMethod.PUT;
 
 /**
@@ -35,88 +41,79 @@ public class EntityController {
     @Autowired
     private InternalEntityService entityService;
 
-    @RequestMapping(value = "/entities/search/findBySystemIdAndKeyValues", method = GET)
+    @RequestMapping(value = ENTITIES, method = POST, params = "systemId", consumes = MediaType.APPLICATION_JSON_VALUE)
     public EntityData findBySystemIdAndKeyValues(@RequestParam("systemId") long systemId,
-            @RequestParam("entityKeyValues") String entityKeyValues) {
-
+            @RequestBody Map<String, Object> entityKeyValues) {
         return entityService.findByPartitionSystemIdAndKeyValues(systemId, entityKeyValues).toEntityData();
-
     }
 
-    @RequestMapping(value = "/entities/search/findOrCreateEntityFor", method = PUT)
+    @RequestMapping(value = ENTITIES, method = PUT, params = {"systemId", "recordTimestamp"})
     @PreAuthorize("hasSystemPermission(#systemId, ACCESS_WRITE)")
-    public EntityData findOrCreateEntityFor(@RequestParam("systemId") long systemId,
-            @RequestParam("entityKeyValues") String entityKeyValues,
-            @RequestParam("partitionKeyValues") String partitionKeyValues, @RequestBody String recordFieldDefinitions,
-            @RequestParam("recordTimestamp") long recordTimestamp) {
-
+    public EntityData findOrCreateEntityFor(@RequestParam long systemId,
+            @RequestParam long recordTimestamp,
+            @RequestBody FindOrCreateEntityRequestImpl findOrCreateEntityRequest) {
         return entityService
-                .findOrCreateEntityFor(systemId, entityKeyValues, partitionKeyValues, recordFieldDefinitions,
+                .findOrCreateEntityFor(systemId, findOrCreateEntityRequest.getEntityKeyValues(),
+                        findOrCreateEntityRequest.getPartitionKeyValues(), findOrCreateEntityRequest.getSchema(),
                         recordTimestamp).toEntityData();
-
     }
 
-    @RequestMapping(value = "/entities/search/findOrCreateEntityForIds", method = PUT)
+    @RequestMapping(value = ENTITIES, method = PUT, params = {"systemId", "entityId", "partitionId", "recordTimestamp"})
     @PreAuthorize("hasSystemPermission(#systemId, ACCESS_WRITE)")
-    public EntityData findOrCreateEntityFor(@RequestParam("systemId") long systemId,
-                                            @RequestParam("entityId") long entityId,
-                                            @RequestParam("partitionId") long partitionId,
-                                            @RequestBody String recordFieldDefinitions,
-                                            @RequestParam("recordTimestamp") long recordTimestamp) {
-
-        return entityService
-                .findOrCreateEntityFor(systemId, entityId, partitionId, recordFieldDefinitions,
+    public EntityData findOrCreateEntityFor(@RequestParam long systemId,
+            @RequestParam long entityId,
+            @RequestParam long partitionId,
+            @RequestBody String recordFieldDefinitions,
+            @RequestParam long recordTimestamp) {
+        return entityService.findOrCreateEntityFor(systemId, entityId, partitionId, recordFieldDefinitions,
                         recordTimestamp).toEntityData();
-
     }
 
-
-
-    @RequestMapping(value = "/entities/search/extendEntityFirstHistoryDataFor", method = PUT)
+    @RequestMapping(value = ENTITY_EXTEND_FIRST_HISTORY, method = PUT, params = {"entityId", "from"})
     @PreAuthorize("hasEntityPermission(#entityId, ACCESS_WRITE)")
-    public EntityData extendEntityFirstHistoryDataFor(@RequestParam("entityId") long entityId,
-            @RequestBody String schema,
-            @RequestParam("from") long fromNanos) {
-        return entityService.extendEntityFirstHistoryDataFor(entityId, schema, fromNanos).toEntityData();
-
+    public EntityData extendEntityFirstHistoryDataFor(@RequestParam long entityId,
+            @RequestParam long from,
+            @RequestBody String schema) {
+        return entityService.extendEntityFirstHistoryDataFor(entityId, schema, from).toEntityData();
     }
 
-    @RequestMapping(value = "/entities/search/findBySystemIdKeyValuesAndTimeWindow", method = GET)
-    public EntityData findBySystemIdKeyValuesAndTimeWindow(@RequestParam("systemId") long systemId,
-            @RequestParam("entityKeyValues") String entityKeyValues, @RequestParam("startTime") long startTime,
-            @RequestParam("endTime") long endTime) {
+    @RequestMapping(value = ENTITIES, method = POST, params = {"systemId", "startTime", "endTime"},
+            consumes = MediaType.APPLICATION_JSON_VALUE)
+    public EntityData findBySystemIdKeyValuesAndTimeWindow(@RequestParam long systemId,
+            @RequestBody Map<String, Object> entityKeyValues, @RequestParam long startTime,
+            @RequestParam long endTime) {
         return entityService.findEntityWithHistForTimeWindow(systemId, entityKeyValues, startTime, endTime)
                 .toEntityData();
     }
 
-    @RequestMapping(value = "/entities/search/findByEntityIdAndTimeWindow", method = GET)
-    public EntityData findByEntityIdAndTimeWindow(@RequestParam("entityId") long entityId,
-            @RequestParam("startTime") long startTime, @RequestParam("endTime") long endTime) {
+    @RequestMapping(value = ENTITIES, method = GET, params = { "entityId", "startTime", "endTime" })
+    public EntityData findByEntityIdAndTimeWindow(@RequestParam long entityId,
+            @RequestParam long startTime, @RequestParam long endTime) {
         return entityService.findByEntityIdAndTimeWindow(entityId, startTime, endTime).toEntityData();
     }
 
-    @RequestMapping(value = "/entities/search/findByExpression/keyValues", method = GET)
-    public List<EntityData> findByKeyValuesLike(@RequestParam("expression") String keyValuesExpression) {
+    @RequestMapping(value = ENTITIES, method = GET, params = "keyValuesExpression")
+    public List<EntityData> findByKeyValuesLike(@RequestParam String keyValuesExpression) {
         return entityService.findByKeyValueLike(keyValuesExpression).stream().map(Entity::toEntityData).collect(
                 toList());
     }
 
-    @RequestMapping(value = "/entities/update", method = PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
+    // TODO: this one is new and we did not agree in any endpoint for it? Do I leave it as is?
+    @RequestMapping(value = ENTITY_UPDATE, method = PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
     @PreAuthorize("hasEntityPermission(#entityDataList, ACCESS_WRITE)")
     public List<EntityData> updateEntities(@NotEmpty @RequestBody List<EntityData> entityDataList) {
         return entityService.updateEntities(entityDataList).stream().map(Entity::toEntityData).collect(toList());
     }
 
-    @RequestMapping(value = "/entities/{entityId}", method = GET)
+    @RequestMapping(value = ENTITIES + "/{entityId}", method = GET)
     public EntityData findOneById(@PathVariable("entityId") long entityId) {
         return entityService.findById(entityId).toEntityData();
     }
 
-    @RequestMapping(value = "/entities", method = GET)
-    public Set<EntityData> findAllById(@NotEmpty @RequestParam("ids") Set<Long> entityIds) {
-        return entityService.findAllByIdIn(entityIds).stream()
+    @RequestMapping(value = ENTITIES, method = GET, params = "ids")
+    public Set<EntityData> findAllById(@NotEmpty @RequestParam Set<Long> ids) {
+        return entityService.findAllByIdIn(ids).stream()
                 .map(Entity::toEntityData)
                 .collect(Collectors.toSet());
     }
-
 }
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/EntityResourcesController.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/EntityResourcesController.java
new file mode 100644
index 0000000000000000000000000000000000000000..9116369d26619293c54ae59f797951abd307f60f
--- /dev/null
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/EntityResourcesController.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2017 European Organisation for Nuclear Research (CERN), All Rights Reserved.
+ */
+package cern.accsoft.nxcals.service.rest;
+
+import cern.accsoft.nxcals.common.domain.EntityResources;
+import cern.accsoft.nxcals.service.internal.InternalEntityResourcesService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+import java.util.Set;
+
+import static cern.accsoft.nxcals.common.web.Endpoints.RESOURCES;
+import static org.springframework.web.bind.annotation.RequestMethod.GET;
+import static org.springframework.web.bind.annotation.RequestMethod.POST;
+
+@RestController
+public class EntityResourcesController {
+    @Autowired
+    private InternalEntityResourcesService entityResourcesService;
+
+    @RequestMapping(value = RESOURCES, method = POST, params = { "systemId", "startTime", "endTime" },
+            consumes = MediaType.APPLICATION_JSON_VALUE)
+    public Set<EntityResources> findBySystemIdKeyValuesAndTimeWindow(@RequestParam long systemId,
+            @RequestBody Map<String, Object> entityKeyValues, @RequestParam long startTime,
+            @RequestParam long endTime) {
+        return entityResourcesService
+                .findBySystemIdKeyValuesAndTimeWindow(systemId, entityKeyValues, startTime, endTime);
+    }
+
+    @RequestMapping(value = RESOURCES, method = GET, params = { "entityId", "startTime", "endTime" })
+    public Set<EntityResources> findByEntityIdAndTimeWindow(@RequestParam long entityId,
+            @RequestParam long startTime,
+            @RequestParam long endTime) {
+        return entityResourcesService.findByEntityIdAndTimeWindow(entityId, startTime, endTime);
+    }
+}
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/PartitionController.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/PartitionController.java
index 6eb3b2603a7e8204604aebab12182296de0373ba..2f5e81b475abfedff18cf0ec9d9ae55cd2c22906 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/PartitionController.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/PartitionController.java
@@ -5,34 +5,47 @@ package cern.accsoft.nxcals.service.rest;
 
 import cern.accsoft.nxcals.common.domain.PartitionData;
 import cern.accsoft.nxcals.service.domain.Partition;
+import cern.accsoft.nxcals.service.domain.System;
 import cern.accsoft.nxcals.service.repository.PartitionRepository;
+import cern.accsoft.nxcals.service.repository.SystemRepository;
 import com.google.common.annotations.VisibleForTesting;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.Map;
+
+import static cern.accsoft.nxcals.common.utils.KeyValuesUtils.convertMapIntoAvroSchemaString;
+import static cern.accsoft.nxcals.common.web.Endpoints.PARTITIONS;
 import static java.lang.String.format;
-import static org.springframework.web.bind.annotation.RequestMethod.GET;
+import static org.springframework.web.bind.annotation.RequestMethod.POST;
 
-/**
- * Partition Controller API.
- */
 @RestController
 public class PartitionController {
 
     @Autowired
     private PartitionRepository partitionRepository;
 
+    @Autowired
+    private SystemRepository systemRepository;
+
     @VisibleForTesting
     static final String ERROR_MESSAGE = "Partition for system %s and %s not found";
 
-    @RequestMapping(value = "/partitions/search/findBySystemIdAndKeyValues", method = GET)
-    public PartitionData findBySystemIdAndKeyValues(@RequestParam("systemId") long systemId,
-            @RequestParam("partitionKeyValues") String partitionKeyValues) {
+    @RequestMapping(value = PARTITIONS, method = POST, params = "systemId", consumes = MediaType.APPLICATION_JSON_VALUE)
+    public PartitionData findBySystemIdAndKeyValues(@RequestParam long systemId,
+            @RequestBody Map<String, Object> partitionKeyValuesMap) {
+
+        System system = systemRepository.findById(systemId)
+                .orElseThrow(() -> new NotFoundRuntimeException(format("System with id: %s not found", systemId)));
+        String partitionKeyValues = convertMapIntoAvroSchemaString(partitionKeyValuesMap, system.getPartitionKeyDefs());
 
         Partition partition = partitionRepository.findBySystemIdAndKeyValues(systemId, partitionKeyValues)
-                .orElseThrow(() -> new NotFoundRuntimeException(format(ERROR_MESSAGE, systemId, partitionKeyValues)));
+                .orElseThrow(
+                        () -> new NotFoundRuntimeException(format(ERROR_MESSAGE, systemId, partitionKeyValuesMap)));
         return partition.toPartitionData();
     }
 }
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/SchemaController.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/SchemaController.java
index 494be7f875daca11ec0692206fd020b12477cd2e..018c67fedccb88f1e2d2f1acc30a5caae1d15161 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/SchemaController.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/SchemaController.java
@@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import static cern.accsoft.nxcals.common.web.Endpoints.SCHEMA_WITH_ID;
 import static org.springframework.web.bind.annotation.RequestMethod.GET;
 
 /**
@@ -22,7 +23,7 @@ public class SchemaController {
     @Autowired
     private SchemaRepository schemaService;
 
-    @RequestMapping(value = "/schemas/{schemaId}", method = GET)
+    @RequestMapping(value = SCHEMA_WITH_ID, method = GET)
     public SchemaData findById(@PathVariable(value = "schemaId") long schemaId) {
         Schema schema = schemaService.findById(schemaId)
                 .orElseThrow(() -> new NotFoundRuntimeException("Schema for id " + schemaId + " not found"));
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/SystemController.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/SystemController.java
index d03f5185bb50d0bd7e25e1a4759bb1aeb0ea50cd..1997527e5d0d6b45f10752f6cf47555b291c78d7 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/SystemController.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/SystemController.java
@@ -7,33 +7,32 @@ import cern.accsoft.nxcals.common.domain.SystemData;
 import cern.accsoft.nxcals.service.domain.System;
 import cern.accsoft.nxcals.service.repository.SystemRepository;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import static cern.accsoft.nxcals.common.web.Endpoints.SYSTEMS;
+import static cern.accsoft.nxcals.common.web.Endpoints.SYSTEM_WITH_ID;
 import static org.springframework.web.bind.annotation.RequestMethod.GET;
 
-/**
- * @author Marcin Sobieszek
- * @author jwozniak
- * @date Jul 19, 2016 2:40:29 PM
- */
 @RestController
 public class SystemController {
+
     @Autowired
     private SystemRepository systemRepository;
 
-    @RequestMapping(value = "/systems/search/findByName", method = GET)
-    public SystemData findByName(@RequestParam("name") String name) {
-        System system = this.systemRepository.findByName(name)
+    @RequestMapping(value = SYSTEMS, method = GET, params = "name")
+    public SystemData findByName(@RequestParam String name) {
+        System system = systemRepository.findByName(name)
                 .orElseThrow(() -> new NotFoundRuntimeException("System for name " + name + " not found"));
         return system.toSystemData();
     }
 
-    @RequestMapping(value = "/systems/search/findById", method = GET)
-    public SystemData findById(@RequestParam("id") long systemId) {
-        System system = this.systemRepository.findById(systemId)
-                .orElseThrow(() -> new NotFoundRuntimeException("System for id " + systemId + " not found"));
+    @RequestMapping(value = SYSTEM_WITH_ID, method = GET)
+    public SystemData findById(@PathVariable long id) {
+        System system = systemRepository.findById(id)
+                .orElseThrow(() -> new NotFoundRuntimeException("System for id " + id + " not found"));
         return system.toSystemData();
     }
 
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/VariableController.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/VariableController.java
index 7d3f499e030aee58f727086650619c3913ff71ec..3fada45f3c8ec97f0c5183f9a66e5b458bb123a3 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/VariableController.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/rest/VariableController.java
@@ -4,6 +4,7 @@ import cern.accsoft.nxcals.common.domain.VariableData;
 import cern.accsoft.nxcals.service.domain.Variable;
 import cern.accsoft.nxcals.service.internal.InternalVariableService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -12,48 +13,46 @@ import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
 
+import static cern.accsoft.nxcals.common.web.Endpoints.VARIABLES;
+import static cern.accsoft.nxcals.common.web.Endpoints.VARIABLE_REGISTER_OR_UPDATE;
 import static java.util.stream.Collectors.toList;
 import static org.springframework.web.bind.annotation.RequestMethod.GET;
 import static org.springframework.web.bind.annotation.RequestMethod.PUT;
 
-/**
- * Created by ntsvetko on 1/16/17.
- */
 @RestController
 public class VariableController {
 
     @Autowired
     private InternalVariableService internalVariableService;
 
-    @RequestMapping(value = "/variables/search/findByVariableName", method = GET)
-    public VariableData findByVariableName(@RequestParam("variableName") String variableName) {
-        return internalVariableService.findByVariableName(variableName).toVariableData();
+    @RequestMapping(value = VARIABLES, method = GET, params = "name")
+    public VariableData findByVariableName(@RequestParam String name) {
+        return internalVariableService.findByVariableName(name).toVariableData();
     }
 
-    @RequestMapping(value = "/variables/search/findByVariableNameAndTimeWindow", method = GET)
-    public VariableData findByVariableNameAndTimeWindow(@RequestParam("variableName") String variableName,
-            @RequestParam("startTime") long startTime,
-            @RequestParam("endTime") long endTime) {
-        return internalVariableService.findByVariableNameAndTimeWindow(variableName, startTime, endTime)
+    @RequestMapping(value = VARIABLES, method = GET, params = { "name", "startTime", "endTime" })
+    public VariableData findByVariableNameAndTimeWindow(@RequestParam String name,
+            @RequestParam Long startTime,
+            @RequestParam Long endTime) {
+        return internalVariableService.findByVariableNameAndTimeWindow(name, startTime, endTime)
                 .toVariableData();
     }
 
-    @RequestMapping(value = "/variables/registerOrUpdateVariableFor", method = PUT)
+    @RequestMapping(value = VARIABLE_REGISTER_OR_UPDATE, method = PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
     @PreAuthorize("hasPermission('VARIABLE', ACCESS_WRITE)")
     public VariableData registerOrUpdateVariableFor(@RequestBody VariableData variableData) {
         return internalVariableService.registerOrUpdateVariableFor(variableData).toVariableData();
     }
 
-    @RequestMapping(value = "/variables/search/findByExpression/name", method = GET)
-    public List<VariableData> findByNameLike(@RequestParam(value = "expression") String nameExpression) {
+    @RequestMapping(value = VARIABLES, method = GET, params = { "nameExpression" })
+    public List<VariableData> findByNameLike(@RequestParam String nameExpression) {
         return internalVariableService.findByNameLike(nameExpression).stream().map(Variable::toVariableData)
                 .collect(toList());
     }
 
-    @RequestMapping(value = "/variables/search/findByExpression/desc", method = GET)
-    public List<VariableData> findByDescriptionLike(@RequestParam(value = "expression") String descriptionExpression) {
+    @RequestMapping(value = VARIABLES, method = GET, params = { "descriptionExpression" })
+    public List<VariableData> findByDescriptionLike(@RequestParam String descriptionExpression) {
         return internalVariableService.findByDescriptionLike(descriptionExpression).stream()
                 .map(Variable::toVariableData).collect(toList());
     }
-
 }
diff --git a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/security/resolvers/ConcatenatingPermissionResolver.java b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/security/resolvers/ConcatenatingPermissionResolver.java
index 681f6679c34b6be1e9e34f84b2de47dba4433dc0..bed47d6fe5771559f5dff327fb3a7d0bf6315178 100644
--- a/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/security/resolvers/ConcatenatingPermissionResolver.java
+++ b/accsoft-nxcals-service/src/main/java/cern/accsoft/nxcals/service/security/resolvers/ConcatenatingPermissionResolver.java
@@ -1,6 +1,5 @@
 package cern.accsoft.nxcals.service.security.resolvers;
 
-
 import org.springframework.stereotype.Component;
 
 @Component
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/BaseTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/BaseTest.java
index 9554776109b321b99e880c9faba254d2e29c4ade..eb53deb832d1f38154654dd834d01e96ab8b81df 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/BaseTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/BaseTest.java
@@ -4,6 +4,7 @@
 
 package cern.accsoft.nxcals.service;
 
+import cern.accsoft.nxcals.common.utils.KeyValuesUtils;
 import cern.accsoft.nxcals.common.utils.TimeUtils;
 import cern.accsoft.nxcals.service.domain.Entity;
 import cern.accsoft.nxcals.service.domain.EntityHistory;
@@ -11,7 +12,6 @@ import cern.accsoft.nxcals.service.domain.Partition;
 import cern.accsoft.nxcals.service.domain.Schema;
 import cern.accsoft.nxcals.service.domain.System;
 import cern.accsoft.nxcals.service.domain.Variable;
-import cern.accsoft.nxcals.service.domain.VariableConfig;
 import cern.accsoft.nxcals.service.domain.security.Permission;
 import cern.accsoft.nxcals.service.domain.security.Realm;
 import cern.accsoft.nxcals.service.domain.security.Role;
@@ -27,6 +27,7 @@ import cern.accsoft.nxcals.service.repository.security.PermissionRepository;
 import cern.accsoft.nxcals.service.repository.security.RealmRepository;
 import cern.accsoft.nxcals.service.repository.security.RoleRepository;
 import cern.accsoft.nxcals.service.repository.security.UserRepository;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import org.apache.commons.codec.digest.DigestUtils;
@@ -41,24 +42,32 @@ import org.springframework.context.ApplicationContextAware;
 import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.transaction.annotation.Transactional;
 
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
+import javax.transaction.Transactional;
 import java.time.Instant;
 import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 import java.util.Collections;
 import java.util.List;
-import java.util.SortedSet;
-import java.util.UUID;
+import java.util.Map;
 
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.TIME_SCHEMA;
+
+//FIXME tests based on this class are integration tests and not really unit tests
+// This makes it hard to understand, change and maintain. Also slows down significantly the test execution.
+// It should be changed so that we actually mock the next layers instead of recreating the whole context every single time
 @Ignore
 @RunWith(SpringJUnit4ClassRunner.class)
 @SpringBootTest(classes = ApplicationDev.class)
 @TestPropertySource(locations = "classpath:application.properties")
 @ActiveProfiles("test")
-@Transactional(transactionManager = "jpaTransactionManager")
+@Transactional
 public abstract class BaseTest implements ApplicationContextAware {
     protected final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd")
             .withZone(ZoneOffset.UTC);
@@ -77,9 +86,7 @@ public abstract class BaseTest implements ApplicationContextAware {
             .newArrayList("UNIT_TEST_PERMISSION:READ", "UNIT_TEST_PERMISSION:WRITE");
     public static final String TEST_NAME = "Test Name";
     protected static final String TEST_DEF_CONTENT = "Test Content";
-    public static final String TEST_KEY_VALUE = "Test Key Value";
-    public static final String TEST_SCHEMA_CONTENT = "{\"class\":\"string\", \"property\":\"string\"}";
-    public static final String TEST_SCHEMA_CONTENT2 = "{\"class\":\"string\", \"property\":\"string\", \"field\":\"string\"}";
+
     public static final long TEST_RECORD_TIME = 1000000000L;
     protected static final String WRITE_PERMISSION = "WRITE";
     public static final String SYSTEM_NAME = "SYSTEM_NAME";
@@ -94,7 +101,6 @@ public abstract class BaseTest implements ApplicationContextAware {
 
     public static final String VARIABLE = "VARIABLE";
     public static final String VARIABLE_AUTHORITY = VARIABLE + ":" + WRITE_PERMISSION;
-    // protected static final String TEST_SCHEMA_CONTENT = "Test schema content";
 
     @PersistenceContext
     protected EntityManager entityManager;
@@ -126,159 +132,129 @@ public abstract class BaseTest implements ApplicationContextAware {
         IdGeneratorFactory.setContext(context);
     }
 
-    protected System createAndPersistClientSystem(String systemName) {
-        System cs = new System();
-        cs.setEntityKeyDefs(TEST_SCHEMA_CONTENT);
-        cs.setPartitionKeyDefs(TEST_SCHEMA_CONTENT);
-        cs.setTimeKeyDefs(TEST_DEF_CONTENT);
-        cs.setName(systemName);
-        return this.systemRepository.save(cs);
-        // return cs;
-    }
-
-    /*
-     * protected System createAndSaveClientSystem(String systemName) { System cs =
-     * this.createAndPersistClientSystem(systemName); this.entityManager.flush(); return cs; }
-     */
-
-    protected Partition createAndPersistPartitionKey(String systemName, String hashValue) {
-        System cs = this.createAndPersistClientSystem(systemName);
-        return createAndPersistPartitionKey(cs,hashValue);
+    protected System createAndPersistClientSystem(String systemName, org.apache.avro.Schema entitySchema,
+            org.apache.avro.Schema partitionSchema, org.apache.avro.Schema timeSchema) {
+        System system = new System();
+        if (entitySchema != null) {
+            system.setEntityKeyDefs(entitySchema.toString());
+        }
+        if (partitionSchema != null) {
+            system.setPartitionKeyDefs(partitionSchema.toString());
+        }
+        if (timeSchema != null) {
+            system.setTimeKeyDefs(timeSchema.toString());
+        }
+        if (systemName != null) {
+            system.setName(systemName);
+        }
+        return systemRepository.save(system);
     }
 
-    protected Partition createAndPersistPartitionKey(System cs, String hashValue) {
-        Partition part = new Partition();
-        part.setSystem(cs);
-        part.setKeyValues(hashValue);
-        return this.partitionRepository.save(part);
+    protected Partition createPartition(System system, Map<String, Object> partitionKeyValues,
+            org.apache.avro.Schema schema) {
+        Partition partition = new Partition();
+        partition.setSystem(system);
+        String keyValuesContent = partitionKeyValues != null ?
+                KeyValuesUtils.convertMapIntoAvroSchemaString(partitionKeyValues, schema.toString()) :
+                null;
+        partition.setKeyValues(keyValuesContent);
+        return partition;
     }
 
-    /*
-     * protected Partition createAndSavePartitionKey(String SystemName, String hashValue) { Partition key =
-     * this.createAndPersistPartitionKey(SystemName, hashValue); this.entityManager.flush(); return key; }
-     */
-    protected Schema createAndPersistSchema(String schemaContent) {
-        Schema schema = new Schema();
-        schema.setContent(schemaContent);
-        if (schemaContent != null) {
-            schema.setContentHash(DigestUtils.md5Hex(schemaContent));
-        }
-        return this.schemaRepository.save(schema);
+    protected Partition createPartition(String systemName, Map<String, Object> partitionKeyValues,
+            org.apache.avro.Schema schema) {
+        System system = createAndPersistClientSystem(systemName, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA);
+        return createPartition(system, partitionKeyValues, schema);
     }
 
-    protected Schema createNonPersistedSchema(String schemaContent) {
-        Schema schema = new Schema();
-        schema.setContent(schemaContent);
+    protected Schema createSchema(org.apache.avro.Schema schema) {
+        Schema newSchema = new Schema();
+        String schemaContent = schema != null ? schema.toString() : null;
+        newSchema.setContent(schemaContent);
         if (schemaContent != null) {
-            schema.setContentHash(DigestUtils.md5Hex(schemaContent));
+            newSchema.setContentHash(DigestUtils.md5Hex(schemaContent));
         }
-        return schema;
+        return newSchema;
     }
 
-
-    /*
-     * protected Schema createAndSaveCalsSchema(String schemaContent) { Schema schema =
-     * this.createAndPersistCalsSchema(schemaContent); this.entityManager.flush(); return schema; }
-     */
-
-    protected Entity createAndPersistEntity(Schema schema, Partition part, String entityKeyValues) {
-        Entity entity = new Entity();
-        entity.setKeyValues(entityKeyValues);
-        entity.setSchema(schema);
-        entity.setPartition(part);
-        return this.entityRepository.save(entity);
+    protected Entity createEntity(String systemName,
+            Map<String, Object> entityKeyValues, org.apache.avro.Schema entitySchema,
+            Map<String, Object> partitionKeyValues, org.apache.avro.Schema partitionSchema) {
+        return createEntity(systemName, entityKeyValues, entitySchema, partitionKeyValues, partitionSchema, null);
     }
 
-    protected Entity createAndPersistEntityWithLockUntilStamp(Schema schema, Partition part, String entityKeyValues,
-            Instant lockUntilStamp) {
+    protected Entity createEntity(String systemName,
+            Map<String, Object> entityKeyValues, org.apache.avro.Schema entitySchema,
+            Map<String, Object> partitionKeyValues, org.apache.avro.Schema partitionSchema, Instant lockedTimestamp) {
         Entity entity = new Entity();
-        entity.setKeyValues(entityKeyValues);
-        entity.setSchema(schema);
-        entity.setPartition(part);
-        entity.setLockedUntilStamp(lockUntilStamp);
-        return this.entityRepository.save(entity);
-    }
-
-    protected Variable createAndPersistVariable(String variableName, String variableDescription, Instant creationTime) {
-        Variable variable = new Variable(variableName, variableDescription, creationTime);
-        return variableRepository.save(variable);
+        String entityKeyValuesString = entityKeyValues != null ?
+                KeyValuesUtils.convertMapIntoAvroSchemaString(entityKeyValues, entitySchema.toString()) :
+                null;
+        entity.setKeyValues(entityKeyValuesString);
+        entity.setSchema(createSchema(entitySchema));
+        entity.setPartition(createPartition(systemName, partitionKeyValues, partitionSchema));
+        if (lockedTimestamp != null) {
+            entity.setLockedUntilStamp(lockedTimestamp);
+        }
+        return entity;
     }
 
-    protected Variable createAndPersistVariable(String variableName, String variableDescription, Instant creationTime,
-            SortedSet<VariableConfig> variableConfigs) {
-        Variable variable = new Variable(variableName, variableDescription, creationTime, variableConfigs);
-        return variableRepository.save(variable);
+    protected Entity createAndPersistEntity(String systemName,
+            Map<String, Object> entityKeyValues, org.apache.avro.Schema entitySchema,
+            Map<String, Object> partitionKeyValues, org.apache.avro.Schema partitionSchema) {
+        return createAndPersistEntity(systemName, entityKeyValues, entitySchema, partitionKeyValues, partitionSchema,
+                null);
     }
 
-    protected Entity createAndSaveDefaultTestEntityKey() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Schema schema = this.createAndPersistSchema(TEST_SCHEMA_CONTENT);
-        Entity key = this.createAndPersistEntity(schema, part, TEST_KEY_VALUE);
-        createAndPersistEntityHistory(key, part, schema, TEST_RECORD_TIME);
-
-        return key;
+    protected Entity createAndPersistEntity(String systemName,
+            Map<String, Object> entityKeyValues, org.apache.avro.Schema entitySchema,
+            Map<String, Object> partitionKeyValues, org.apache.avro.Schema partitionSchema,
+            Instant lockedTimestamp) {
+        return persistEntity(createEntity(systemName, entityKeyValues, entitySchema, partitionKeyValues,
+                partitionSchema, lockedTimestamp));
     }
 
-    protected Entity createDefaultNonPersistedEntity() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Schema schema = this.createNonPersistedSchema(TEST_SCHEMA_CONTENT);
+    protected Entity persistEntity(Entity entity) {
+        if (entity.getPartition() != null) {
+            partitionRepository.save(entity.getPartition());
+        }
 
-        Entity entity = new Entity();
-        entity.setKeyValues(TEST_KEY_VALUE);
-        entity.setSchema(schema);
-        entity.setPartition(part);
+        if (entity.getSchema() != null) {
+            schemaRepository.save(entity.getSchema());
+        }
 
-        createAndAssociateNonPersistedEntityHist(entity, part, schema, TEST_RECORD_TIME);
-        return entity;
+        return entityRepository.save(entity);
     }
 
-    protected Entity createAndSaveDefaultTestEntityKeyWithLockTime(Instant time) {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Schema schema = this.createAndPersistSchema(TEST_SCHEMA_CONTENT);
-        Entity key = this.createAndPersistEntityWithLockUntilStamp(schema, part, TEST_KEY_VALUE, time);
-        createAndPersistEntityHistory(key, part, schema, TEST_RECORD_TIME);
-
-        return key;
+    protected Variable createAndPersistVariable(String variableName, String variableDescription, Instant creationTime) {
+        Variable variable = new Variable(variableName, variableDescription, creationTime);
+        return variableRepository.save(variable);
     }
 
-    protected EntityHistory createAndPersistEntityHistory(Entity key, Partition part, Schema schema,
-            Long recordTimestamp) {
-        EntityHistory firstHistory = new EntityHistory();
-        firstHistory.setEntity(key);
-        firstHistory.setPartition(part);
-        firstHistory.setSchema(schema);
-        if (recordTimestamp != null) {
-            firstHistory.setValidFromStamp(TimeUtils.getInstantFromNanos(recordTimestamp));
-        }
-        if (key != null) {
-            key.addEntityHist(firstHistory);
-        }
-        return this.entityHistRepository.save(firstHistory);
-
+    protected Entity createAndSaveDefaultTestEntityKey() {
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
+        return entity;
     }
 
-    protected EntityHistory createAndAssociateNonPersistedEntityHist(Entity entity, Partition part, Schema schema,
+    // FIXME entity already has partition and schema, do we use this to force different partitions ands schemas somewhere? If not receive only entity.
+    protected EntityHistory createAndPersistEntityHist(Entity key, Partition part, Schema schema,
             Long recordTimestamp) {
         EntityHistory history = new EntityHistory();
-
-        history.setEntity(entity);
-
-        history.setRecVersion(0L);
+        history.setEntity(key);
         history.setPartition(part);
         history.setSchema(schema);
         if (recordTimestamp != null) {
             history.setValidFromStamp(TimeUtils.getInstantFromNanos(recordTimestamp));
         }
-
-        if (entity != null) {
-            entity.addEntityHist(history);
+        if (key != null) {
+            key.addEntityHist(history);
         }
-
-        return history;
-
+        return this.entityHistRepository.save(history);
     }
 
-    protected EntityHistory createAndPersistEntityHistory(Entity key, Partition part, Schema schema, Long fromTimestamp,
+    protected EntityHistory createAndPersistEntityHist(Entity key, Partition part, Schema schema, Long fromTimestamp,
             Long toTimestamp) {
         EntityHistory history = new EntityHistory();
         history.setEntity(key);
@@ -294,25 +270,48 @@ public abstract class BaseTest implements ApplicationContextAware {
         if (key != null) {
             key.addEntityHist(history);
         }
-        return this.entityHistRepository.save(history);
+        return entityHistRepository.save(history);
 
     }
+/*
+    protected Entity createAndSaveDefaultTestEntityKeyWithRandomSchemaContent() {
+        Partition part = this.createAndPersistPartitionKey(TEST_NAME, SCHEMA_VALUE);
 
-    protected EntityHistory createAndPersistDefaultTestEntityKeyHist() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Schema schema = this.createAndPersistSchema(TEST_SCHEMA_CONTENT);
+        String randomScemaContent = String.format("{\"class\":\"%s\", \"property\":\"string\"}",
+                UUID.randomUUID().toString());
+        Schema schema = this.createAndPersistSchema(randomScemaContent);
         Entity key = this.createAndPersistEntity(schema, part, TEST_KEY_VALUE);
-        EntityHistory entityHistory = createAndPersistEntityHistory(key, part, schema, TEST_RECORD_TIME);
+        createAndPersistEntityHistory(key, part, schema, TEST_RECORD_TIME, null);
+        createAndPersistEntityHistory(key, part, schema, TEST_RECORD_TIME + 1000, TEST_RECORD_TIME + 3000);
+        createAndPersistEntityHistory(key, part, schema, TEST_RECORD_TIME + 3000, TEST_RECORD_TIME + 5000);
+        // this.entityManager.flush();
 
-        this.entityRepository.save(key);
-        return entityHistory;
+        return key;
     }
+*/
 
-    protected Entity createAndPersistEntityWithNoHistory() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Schema schema = this.createAndPersistSchema(TEST_SCHEMA_CONTENT);
+    protected EntityHistory createAndPersistEntityHistory(Entity key, Partition part, Schema schema,
+            Long recordTimestamp) {
+        EntityHistory firstHistory = new EntityHistory();
+        firstHistory.setEntity(key);
+        firstHistory.setPartition(part);
+        firstHistory.setSchema(schema);
+        if (recordTimestamp != null) {
+            firstHistory.setValidFromStamp(TimeUtils.getInstantFromNanos(recordTimestamp));
+        }
+        if (key != null) {
+            key.addEntityHist(firstHistory);
+        }
+        return this.entityHistRepository.save(firstHistory);
+    }
 
-        return this.createAndPersistEntity(schema, part, TEST_KEY_VALUE);
+    protected EntityHistory createAndPersistDefaultTestEntityKeyHist() {
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
+        EntityHistory entityHistory = createAndPersistEntityHistory(entity, entity.getPartition(), entity.getSchema(),
+                TEST_RECORD_TIME);
+        this.entityRepository.save(entity);
+        return entityHistory;
     }
 
     protected void createAndPersistUser() {
@@ -341,34 +340,4 @@ public abstract class BaseTest implements ApplicationContextAware {
 
         userRepository.save(user1);
     }
-
-    protected Entity createAndSaveDefaultTestEntityKeyWithRandomSchemaContent() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-
-        String randomScemaContent = String.format("{\"class\":\"%s\", \"property\":\"string\"}",
-                UUID.randomUUID().toString());
-        Schema schema = this.createAndPersistSchema(randomScemaContent);
-        Entity key = this.createAndPersistEntity(schema, part, TEST_KEY_VALUE);
-        createAndPersistEntityHistory(key, part, schema, TEST_RECORD_TIME, null);
-        createAndPersistEntityHistory(key, part, schema, TEST_RECORD_TIME + 1000, TEST_RECORD_TIME + 3000);
-        createAndPersistEntityHistory(key, part, schema, TEST_RECORD_TIME + 3000, TEST_RECORD_TIME + 5000);
-        // this.entityManager.flush();
-
-        return key;
-    }
-
-    protected Entity createAndSaveTestEntityKeyWithRandomSchemaContent() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-
-        String schemaContentTemplate = "{\"class\":\"string\", \"property\":\"string\", \"uuid\":\"%s\"}";
-
-        String randomSchemaContentTemplate = String.format(schemaContentTemplate, UUID.randomUUID().toString());
-
-        Schema schema = this.createAndPersistSchema(randomSchemaContentTemplate);
-        Entity key = this.createAndPersistEntity(schema, part, TEST_KEY_VALUE);
-        createAndPersistEntityHistory(key, part, schema, TEST_RECORD_TIME);
-        // this.entityManager.flush();
-
-        return key;
-    }
 }
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/EntityHistoryTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/EntityHistoryTest.java
deleted file mode 100644
index 25bb55be709536d888a6694e3418232a43e2286e..0000000000000000000000000000000000000000
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/EntityHistoryTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- * Copyright (c) 2016 European Organisation for Nuclear Research (CERN), All Rights Reserved.
- */
-
-package cern.accsoft.nxcals.service.domain;
-
-import cern.accsoft.nxcals.common.utils.TimeUtils;
-import cern.accsoft.nxcals.service.BaseTest;
-import cern.accsoft.nxcals.service.repository.EntityHistoryRepository;
-import org.hamcrest.Matchers;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.annotation.Rollback;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.validation.ConstraintViolationException;
-import java.time.Instant;
-import java.util.Optional;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-@Transactional(transactionManager = "jpaTransactionManager")
-public class EntityHistoryTest extends BaseTest {
-
-    @Autowired
-    private EntityHistoryRepository entityHistoryRepository;
-
-    @Test(expected = ConstraintViolationException.class)
-    @Rollback
-    public void shouldNotCreateHistoryWithoutPartition() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Schema schema = this.createAndPersistSchema(TEST_SCHEMA_CONTENT);
-        Entity entity = this.createAndPersistEntity(schema, part, TEST_KEY_VALUE);
-        this.createAndPersistEntityHistory(entity, null, schema, TEST_RECORD_TIME);
-        this.entityManager.flush();
-    }
-
-    @Test(expected = ConstraintViolationException.class)
-    @Rollback
-    public void shouldNotCreateHistoryWithoutSchema() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Schema schema = this.createAndPersistSchema(TEST_SCHEMA_CONTENT);
-        Entity entity = this.createAndPersistEntity(schema, part, TEST_KEY_VALUE);
-        this.createAndPersistEntityHistory(entity, part, null, TEST_RECORD_TIME);
-        this.entityManager.flush();
-    }
-
-    @Test(expected = NullPointerException.class)
-    @Rollback
-    public void shouldNotCreateHistoryWithoutValidFromStamp() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Schema schema = this.createAndPersistSchema(TEST_SCHEMA_CONTENT);
-        Entity entity = this.createAndPersistEntity(schema, part, TEST_KEY_VALUE);
-        this.createAndPersistEntityHistory(entity, part, schema, null);
-        this.entityManager.flush();
-    }
-
-    @Test
-    @Rollback
-    public void shouldCreateEntityHist() {
-        EntityHistory entityHistory = this.createAndPersistDefaultTestEntityKeyHist();
-        Long id = entityHistory.getId();
-        Optional<EntityHistory> found = this.entityHistoryRepository.findById(id);
-
-        assertNotNull(found);
-        assertTrue(found.isPresent());
-        assertThat(found.get().getEntity().getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        assertThat(found.get().getPartition().getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        assertThat(found.get().getSchema().getContent(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-        assertThat(found.get().getValidFromStamp(),
-                Matchers.equalTo(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME)));
-        assertNull(found.get().getValidToStamp());
-    }
-
-    @Test
-    @Rollback
-    public void shouldUpdateEntityHistPartition() {
-        EntityHistory entityHistory = this.createAndPersistDefaultTestEntityKeyHist();
-        Long id = entityHistory.getId();
-        String testPartitionKeys = "NEW_PARTITION";
-        EntityHistory found = this.entityHistoryRepository.findById(id).get();
-        this.updateEntityHistPartition(found, TEST_NAME, testPartitionKeys);
-
-        Optional<EntityHistory> foundUpdatedHist = this.entityHistoryRepository.findById(id);
-
-        assertNotNull(foundUpdatedHist);
-        assertTrue(foundUpdatedHist.isPresent());
-        assertThat(foundUpdatedHist.get().getPartition().getSystem().getName(), Matchers.equalTo(TEST_NAME));
-        assertThat(foundUpdatedHist.get().getPartition().getKeyValues(), Matchers.equalTo(testPartitionKeys));
-        assertThat(foundUpdatedHist.get().getSchema().getContent(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-        assertThat(foundUpdatedHist.get().getValidFromStamp(),
-                Matchers.equalTo(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME)));
-        assertNull(foundUpdatedHist.get().getValidToStamp());
-    }
-
-    @Test
-    @Rollback
-    public void shouldUpdateEntityHistSchema() {
-        EntityHistory entityHistory = this.createAndPersistDefaultTestEntityKeyHist();
-        Long id = entityHistory.getId();
-        String testSchemaContent = "NEW_SCHEMA";
-
-        EntityHistory found = this.entityHistoryRepository.findById(id).get();
-        this.updateEntityHistSchema(found, testSchemaContent);
-
-        Optional<EntityHistory> foundUpdatedHist = this.entityHistoryRepository.findById(id);
-
-        assertNotNull(foundUpdatedHist);
-        assertTrue(foundUpdatedHist.isPresent());
-        assertThat(foundUpdatedHist.get().getPartition().getSystem().getName(), Matchers.equalTo(TEST_NAME));
-        assertThat(foundUpdatedHist.get().getPartition().getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        assertThat(foundUpdatedHist.get().getSchema().getContent(), Matchers.equalTo(testSchemaContent));
-        assertThat(foundUpdatedHist.get().getValidFromStamp(),
-                Matchers.equalTo(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME)));
-        assertNull(foundUpdatedHist.get().getValidToStamp());
-    }
-
-    @Test
-    @Rollback
-    public void shouldUpdateEntityHistTimes() {
-        EntityHistory entityHistory = this.createAndPersistDefaultTestEntityKeyHist();
-        Long id = entityHistory.getId();
-        Instant testTime = TimeUtils.getInstantFromNanos(TEST_RECORD_TIME).plusSeconds(10);
-
-        EntityHistory found = this.entityHistoryRepository.findById(id).get();
-        found.setValidFromStamp(testTime);
-        found.setValidToStamp(testTime);
-        this.entityHistoryRepository.save(found);
-
-        Optional<EntityHistory> foundUpdatedHist = this.entityHistoryRepository.findById(id);
-
-        assertNotNull(foundUpdatedHist);
-        assertTrue(foundUpdatedHist.isPresent());
-        assertThat(foundUpdatedHist.get().getPartition().getSystem().getName(), Matchers.equalTo(TEST_NAME));
-        assertThat(foundUpdatedHist.get().getPartition().getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        assertThat(foundUpdatedHist.get().getSchema().getContent(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-        assertThat(foundUpdatedHist.get().getValidFromStamp(), Matchers.equalTo(testTime));
-        assertThat(foundUpdatedHist.get().getValidToStamp(), Matchers.equalTo(testTime));
-    }
-
-    private void updateEntityHistSchema(EntityHistory entityHistory, String newSchemaContent) {
-        Schema newSchema = this.createAndPersistSchema(newSchemaContent);
-        entityHistory.setSchema(newSchema);
-        this.entityHistRepository.save(entityHistory);
-    }
-
-    private void updateEntityHistPartition(EntityHistory entityHistory, String systemName, String hashValue) {
-        Partition newPart = this.createAndPersistPartitionKey(systemName, hashValue);
-        entityHistory.setPartition(newPart);
-        this.entityHistRepository.save(entityHistory);
-    }
-}
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/EntityTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/EntityTest.java
deleted file mode 100644
index 5ea8745767fd9fe8ebb1b19e8dfb8f399d6ec665..0000000000000000000000000000000000000000
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/EntityTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * Copyright (c) 2016 European Organisation for Nuclear Research (CERN), All Rights Reserved.
- */
-
-package cern.accsoft.nxcals.service.domain;
-
-import cern.accsoft.nxcals.service.BaseTest;
-import org.hamcrest.Matchers;
-import org.junit.Assert;
-import org.junit.Test;
-import org.springframework.test.annotation.Rollback;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.validation.ConstraintViolationException;
-import java.time.Instant;
-import java.time.temporal.ChronoUnit;
-
-@SuppressWarnings("unused")
-@Transactional(transactionManager = "jpaTransactionManager")
-public class EntityTest extends BaseTest {
-
-    @Test(expected = ConstraintViolationException.class)
-    @Rollback
-    public void shouldNotCreateEntityWithoutHashValue() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Schema schema = this.createAndPersistSchema(TEST_SCHEMA_CONTENT);
-        Entity key = this.createAndPersistEntity(schema, part, null);
-        entityManager.flush();
-    }
-
-    @Test(expected = ConstraintViolationException.class)
-    @Rollback
-    public void shouldNotCreateEntityWithoutSchema() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Entity key = this.createAndPersistEntity(null, part, TEST_KEY_VALUE);
-        entityManager.flush();
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    @Rollback
-    public void shouldNotCreateEntityWithoutPartition() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Schema schema = this.createAndPersistSchema(TEST_SCHEMA_CONTENT);
-        Entity key = this.createAndPersistEntity(schema, null, TEST_KEY_VALUE);
-        entityManager.flush();
-    }
-
-    @Test
-    @Rollback
-    public void shouldCreateEntityKey() {
-        Entity key = createAndSaveDefaultTestEntityKey();
-        Long id = key.getId();
-        Entity found = this.entityRepository.findById(id).get();
-
-        Assert.assertThat(found.getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        Assert.assertThat(found.getPartition().getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        Assert.assertThat(found.getSchema().getContent(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-        Assert.assertThat(found.getPartition().getSystem().getName(), Matchers.equalTo(TEST_NAME));
-    }
-
-    @Test
-    @Rollback
-    public void shouldChangeEntityKeySchema() {
-        Entity key = createAndSaveDefaultTestEntityKey();
-        Long id = key.getId();
-
-        String newSchemaContent = "{\"class1\":\"string\", \"property\":\"string\"}";
-
-        Entity found = this.entityRepository.findById(id).get();
-        updateEntitySchema(found, newSchemaContent);
-
-        Entity foundUpdatedKey = this.entityRepository.findById(id).get();
-        Assert.assertNotNull(foundUpdatedKey);
-        Assert.assertThat(foundUpdatedKey.getSchema().getContent(), Matchers.equalTo(newSchemaContent));
-        Assert.assertThat(foundUpdatedKey.getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        Assert.assertThat(foundUpdatedKey.getPartition().getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        Assert.assertThat(foundUpdatedKey.getPartition().getSystem().getName(), Matchers.equalTo(TEST_NAME));
-    }
-
-    @Test
-    @Rollback
-    public void shouldChangeEntityKeyPartition() {
-        Entity key = createAndSaveDefaultTestEntityKey();
-        Long id = key.getId();
-
-        Entity found = this.entityRepository.findById(id).get();
-        updateEntityPartition(found, TEST_NAME, TEST_KEY_VALUE + "_NEW");
-
-        Entity foundUpdatedKey = this.entityRepository.findById(id).get();
-        Assert.assertNotNull(foundUpdatedKey);
-        Assert.assertThat(foundUpdatedKey.getPartition().getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE + "_NEW"));
-        Assert.assertThat(foundUpdatedKey.getSchema().getContent(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-        Assert.assertThat(foundUpdatedKey.getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        Assert.assertThat(foundUpdatedKey.getPartition().getSystem().getName(), Matchers.equalTo(TEST_NAME));
-        Assert.assertThat(foundUpdatedKey.getPartition().getSystem().getName(), Matchers.equalTo(TEST_NAME));
-    }
-
-    @Test
-    @Rollback
-    public void shouldChangeEntityKeyHashValue() {
-        Entity key = createAndSaveDefaultTestEntityKey();
-        Long id = key.getId();
-
-        Entity found = this.entityRepository.findById(id).get();
-        updateKeyHashValue(found, TEST_KEY_VALUE + "_NEW");
-
-        Entity foundUpdatedKey = this.entityRepository.findById(id).get();
-        Assert.assertNotNull(foundUpdatedKey);
-        Assert.assertThat(foundUpdatedKey.getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE + "_NEW"));
-        Assert.assertThat(foundUpdatedKey.getSchema().getContent(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-        Assert.assertThat(foundUpdatedKey.getPartition().getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        Assert.assertThat(foundUpdatedKey.getPartition().getSystem().getName(), Matchers.equalTo(TEST_NAME));
-    }
-
-    @Test
-    @Rollback
-    public void shouldChangeEntityLockedUntilStamp() {
-        Entity key = createAndSaveDefaultTestEntityKey();
-        Long id = key.getId();
-
-        Instant lockUntilStamp = Instant.now().plus(2, ChronoUnit.HOURS);
-
-        Entity found = this.entityRepository.findById(id).get();
-        updateLockUntilStamp(found, lockUntilStamp);
-
-        Entity foundUpdatedLockUntilStamp = this.entityRepository.findById(id).get();
-        Assert.assertNotNull(foundUpdatedLockUntilStamp);
-        Assert.assertThat(foundUpdatedLockUntilStamp.getLockedUntilStamp(), Matchers.equalTo(lockUntilStamp));
-        Assert.assertThat(foundUpdatedLockUntilStamp.getSchema().getContent(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-        Assert.assertThat(foundUpdatedLockUntilStamp.getPartition().getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        Assert.assertThat(foundUpdatedLockUntilStamp.getPartition().getSystem().getName(), Matchers.equalTo(TEST_NAME));
-    }
-
-    @Test
-    @Rollback
-    public void shouldWriteEntityLockedUntilStampAsNull() {
-        Entity key = createAndSaveDefaultTestEntityKey();
-        Long id = key.getId();
-
-        Entity found = this.entityRepository.findById(id).get();
-        updateLockUntilStamp(found, null);
-
-        Entity foundUpdatedLockUntilStamp = this.entityRepository.findById(id).get();
-        Assert.assertNotNull(foundUpdatedLockUntilStamp);
-        Assert.assertNull(foundUpdatedLockUntilStamp.getLockedUntilStamp());
-        Assert.assertThat(foundUpdatedLockUntilStamp.getSchema().getContent(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-        Assert.assertThat(foundUpdatedLockUntilStamp.getPartition().getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        Assert.assertThat(foundUpdatedLockUntilStamp.getPartition().getSystem().getName(), Matchers.equalTo(TEST_NAME));
-    }
-
-    private void updateEntitySchema(Entity entity, String newSchemaContent) {
-        Schema newSchema = this.createAndPersistSchema(newSchemaContent);
-        entity.setSchema(newSchema);
-        this.entityRepository.save(entity);
-    }
-
-    private void updateEntityPartition(Entity entityKey, String systemName, String hashValue) {
-        Partition newPart = this.createAndPersistPartitionKey(systemName, hashValue);
-        entityKey.setPartition(newPart);
-        this.entityRepository.save(entityKey);
-    }
-
-    private void updateKeyHashValue(Entity entityKey, String hashValue) {
-        entityKey.setKeyValues(hashValue);
-        this.entityRepository.save(entityKey);
-    }
-
-    private void updateLockUntilStamp(Entity entity, Instant lockUntilStamp) {
-        entity.setLockedUntilStamp(lockUntilStamp);
-        this.entityRepository.save(entity);
-    }
-
-}
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/PartitionTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/PartitionTest.java
deleted file mode 100644
index b9ea2a25cbb77becc26dab218cafa9fa638d1c9c..0000000000000000000000000000000000000000
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/PartitionTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Copyright (c) 2016 European Organisation for Nuclear Research (CERN), All Rights Reserved.
- */
-
-package cern.accsoft.nxcals.service.domain;
-
-import cern.accsoft.nxcals.service.BaseTest;
-import org.hamcrest.Matchers;
-import org.junit.Assert;
-import org.junit.Test;
-import org.springframework.test.annotation.Rollback;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.validation.ConstraintViolationException;
-
-@SuppressWarnings("unused")
-@Transactional(transactionManager = "jpaTransactionManager")
-public class PartitionTest extends BaseTest {
-
-    @Test(expected = ConstraintViolationException.class)
-    @Rollback
-    public void shouldNotCreatePartitionKeyWithoutSystem() {
-        Partition part = createAndPersistPartitionKey((String)null, TEST_KEY_VALUE);
-        entityManager.flush();
-    }
-
-    @Test(expected = ConstraintViolationException.class)
-    @Rollback
-    public void shouldNotCreatePartitionKeyWithoutHashValue() {
-        Partition part = createAndPersistPartitionKey(TEST_NAME, null);
-        entityManager.flush();
-    }
-
-    @Test
-    @Rollback
-    public void shouldCreatePartitionKey() {
-        Partition part = createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Long id = part.getId();
-
-        Partition found = this.partitionRepository.findById(id).get();
-
-        Assert.assertThat(found.getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        Assert.assertThat(found.getSystem().getName(), Matchers.equalTo(TEST_NAME));
-    }
-
-}
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/SchemaTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/SchemaTest.java
deleted file mode 100644
index 2956d370a6ce516e77cfea923db8bb180541c375..0000000000000000000000000000000000000000
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/SchemaTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Copyright (c) 2016 European Organisation for Nuclear Research (CERN), All Rights Reserved.
- */
-
-package cern.accsoft.nxcals.service.domain;
-
-import cern.accsoft.nxcals.service.BaseTest;
-import org.hamcrest.Matchers;
-import org.junit.Assert;
-import org.junit.Test;
-import org.springframework.test.annotation.Rollback;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.validation.ConstraintViolationException;
-
-@Transactional(transactionManager = "jpaTransactionManager")
-public class SchemaTest extends BaseTest {
-
-    @SuppressWarnings("unused")
-    @Test(expected = ConstraintViolationException.class)
-    @Rollback(value = true)
-    public void shouldNotCreateSchemaWithoutContent() {
-        System system = this.createAndPersistClientSystem(TEST_NAME);
-        Schema schema = this.createAndPersistSchema(null);
-        this.entityManager.flush();
-    }
-
-    @Test
-    @Rollback
-    public void shouldCreateSchema() {
-        System system = this.createAndPersistClientSystem(TEST_NAME);
-        Schema schema = this.createAndPersistSchema(TEST_SCHEMA_CONTENT);
-        Long id = schema.getId();
-
-        Schema foundSchema = this.schemaRepository.findById(id).get();
-        Assert.assertThat(foundSchema.getContent(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-    }
-
-}
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/SystemTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/SystemTest.java
deleted file mode 100644
index def2bfc25604b6ca0064abd49af44164077e8f99..0000000000000000000000000000000000000000
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/domain/SystemTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * Copyright (c) 2016 European Organisation for Nuclear Research (CERN), All Rights Reserved.
- */
-
-package cern.accsoft.nxcals.service.domain;
-
-import cern.accsoft.nxcals.service.BaseTest;
-import org.hamcrest.Matchers;
-import org.junit.Assert;
-import org.junit.Test;
-import org.springframework.test.annotation.Rollback;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.validation.ConstraintViolationException;
-
-/**
- * @author ntsvetko
- */
-@Transactional(transactionManager = "jpaTransactionManager")
-public class SystemTest extends BaseTest {
-
-    @Test(expected = ConstraintViolationException.class)
-    @Rollback
-    public void shouldNotCreateSystemWithoutName() {
-        System cs = new System();
-        cs.setEntityKeyDefs(TEST_DEF_CONTENT);
-        cs.setPartitionKeyDefs(TEST_DEF_CONTENT);
-        cs.setTimeKeyDefs(TEST_DEF_CONTENT);
-        systemRepository.save(cs);
-        entityManager.flush();
-    }
-
-    @Test(expected = ConstraintViolationException.class)
-    @Rollback
-    public void shouldNotCreateSystemWithoutKeyDef() {
-        System cs = new System();
-        cs.setPartitionKeyDefs(TEST_DEF_CONTENT);
-        cs.setTimeKeyDefs(TEST_DEF_CONTENT);
-        cs.setName(TEST_NAME);
-        systemRepository.save(cs);
-        entityManager.flush();
-    }
-
-    @Test(expected = ConstraintViolationException.class)
-    @Rollback
-    public void shouldNotCreateSystemWithoutPartitionDef() {
-        System cs = new System();
-        cs.setEntityKeyDefs(TEST_DEF_CONTENT);
-        cs.setTimeKeyDefs(TEST_DEF_CONTENT);
-        cs.setName(TEST_NAME);
-        systemRepository.save(cs);
-        entityManager.flush();
-    }
-
-    @Test(expected = ConstraintViolationException.class)
-    @Rollback
-    public void shouldNotCreateSystemWithoutTimeDef() {
-        System cs = new System();
-        cs.setEntityKeyDefs(TEST_DEF_CONTENT);
-        cs.setPartitionKeyDefs(TEST_DEF_CONTENT);
-        cs.setName(TEST_DEF_CONTENT);
-        systemRepository.save(cs);
-        entityManager.flush();
-    }
-
-    @Test
-    @Rollback
-    public void shouldCreateClientSystem() {
-        System cs = this.createAndPersistClientSystem(TEST_NAME);
-        Long id = cs.getId();
-
-        System found = this.systemRepository.findById(id).get();
-
-        Assert.assertThat(found.getName(), Matchers.equalTo(TEST_NAME));
-        Assert.assertThat(found.getEntityKeyDefs(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-        Assert.assertThat(found.getPartitionKeyDefs(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-        Assert.assertThat(found.getTimeKeyDefs(), Matchers.equalTo(TEST_DEF_CONTENT));
-    }
-
-}
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/DataLocationServiceImplTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/DataLocationServiceImplTest.java
index a827d7d6f08f67f36f47b6d35731ebc82b464b47..5d832d1485c6e36eb8408cae8c25b4c74c016da5 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/DataLocationServiceImplTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/DataLocationServiceImplTest.java
@@ -13,7 +13,6 @@ import cern.accsoft.nxcals.service.domain.Partition;
 import cern.accsoft.nxcals.service.domain.Schema;
 import cern.accsoft.nxcals.service.domain.System;
 import cern.accsoft.nxcals.service.repository.EntityHistoryRepository;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -23,7 +22,6 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.net.URI;
 import java.time.Instant;
-import java.time.temporal.ChronoUnit;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -33,7 +31,18 @@ import java.util.TreeSet;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES_JSON;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_JSON_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.RECORD_VERSION_SCHEMA;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.TIME_SCHEMA;
 import static java.time.temporal.ChronoUnit.DAYS;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.when;
@@ -59,7 +68,7 @@ public class DataLocationServiceImplTest extends BaseTest {
         //given
         // Time window: Start time: 1970-01-01T00:00:01 End time: 1970-01-03T00:00:01Z
         startTime = TEST_RECORD_TIME;
-        Instant endTimeInstant = TimeUtils.getInstantFromNanos(startTime).plus(2, ChronoUnit.DAYS);
+        Instant endTimeInstant = TimeUtils.getInstantFromNanos(startTime).plus(2, DAYS);
         endTime = TimeUtils.getNanosFromInstant(endTimeInstant);
 
     }
@@ -68,14 +77,13 @@ public class DataLocationServiceImplTest extends BaseTest {
     @Test(expected = IllegalArgumentException.class)
     public void shouldNotGetEntityWithoutHistory() {
         // given
-        Entity entity = this.createEntity();
+        Entity entity = createEntity();
 
-        when(entityRepoMocked.findEntityWithHistForTimeWindow(anyLong(), eq(TEST_KEY_VALUE), anyLong(), anyLong()))
+        when(entityRepoMocked.findEntityWithHistForTimeWindow(anyLong(), eq(ENTITY_KEY_VALUES), anyLong(), anyLong()))
                 .thenReturn(entity);
         // when
-        Set<EntityResources> resourceData = this.entityResourcesService
-                .findBySystemIdKeyValuesAndTimeWindow(entity.getPartition().getSystem().getId(),
-                        TEST_KEY_VALUE, startTime, endTime);
+        entityResourcesService.findBySystemIdKeyValuesAndTimeWindow(entity.getPartition().getSystem().getId(),
+                ENTITY_KEY_VALUES, startTime, endTime);
     }
 
     @Test
@@ -91,30 +99,30 @@ public class DataLocationServiceImplTest extends BaseTest {
         listEntityHistory.add(entityHistory);
         entity.setEntityHistories(listEntityHistory);
 
-        when(entityRepoMocked.findEntityWithHistForTimeWindow(anyLong(), eq(TEST_KEY_VALUE), anyLong(), anyLong()))
+        when(entityRepoMocked.findEntityWithHistForTimeWindow(anyLong(), eq(ENTITY_KEY_VALUES), anyLong(), anyLong()))
                 .thenReturn(entity);
 
         Map<Long, Set<URI>> paths = entity.getEntityHistories().stream()
                 .filter(h -> h.getValidFromStamp().truncatedTo(DAYS).equals(startTimeInstant.truncatedTo(DAYS)))
-                .collect(Collectors.toMap(h -> h.getSchema().getId(), h -> this.buildDataLocationPath(h)));
+                .collect(Collectors.toMap(h -> h.getSchema().getId(), h -> buildDataLocationPath(h)));
 
         // when
         Set<EntityResources> resourceData = this.entityResourcesService.findBySystemIdKeyValuesAndTimeWindow(
-                entity.getPartition().getSystem().getId(), TEST_KEY_VALUE,
+                entity.getPartition().getSystem().getId(), ENTITY_KEY_VALUES,
                 startTime, endTime);
 
         // then
-        Assert.assertNotNull(resourceData);
-        Assert.assertEquals(1, resourceData.size());
-        Assert.assertEquals(3,
+        assertNotNull(resourceData);
+        assertEquals(1, resourceData.size());
+        assertEquals(3,
                 (int) resourceData.stream().map(rd -> rd.getResourcesData().getHdfsPaths().size()).findFirst().get());
-        Assert.assertEquals(1,
+        assertEquals(1,
                 (int) resourceData.stream().map(rd -> rd.getResourcesData().getHbaseTableNames().size()).findFirst()
                         .get());
-        Assert.assertEquals(1,
+        assertEquals(1,
                 resourceData.stream().filter(rd -> rd.getResourcesData().getHdfsPaths().containsAll(paths.get(3L)))
                         .count());
-        Assert.assertEquals(1,
+        assertEquals(1,
                 resourceData.stream().filter(rd -> rd.getResourcesData().getHbaseTableNames().containsAll(
                         Stream.of(hbaseTablespace + ":1__2__3").collect(Collectors.toSet())
                 )).count());
@@ -133,7 +141,7 @@ public class DataLocationServiceImplTest extends BaseTest {
 
         Schema new_schema = new Schema();
         new_schema.setId(5L);
-        new_schema.setContent(TEST_SCHEMA_CONTENT + "_NEW");
+        new_schema.setContent(ENTITY_SCHEMA_2.toString());
 
         EntityHistory entityHistory2 = createEntityHistory(entity, new_schema, startTimeInstant, null);
 
@@ -142,38 +150,38 @@ public class DataLocationServiceImplTest extends BaseTest {
         listEntityHistory.add(entityHistory2);
         entity.setEntityHistories(listEntityHistory);
 
-        when(entityRepoMocked.findEntityWithHistForTimeWindow(anyLong(), eq(TEST_KEY_VALUE), anyLong(), anyLong()))
+        when(entityRepoMocked.findEntityWithHistForTimeWindow(anyLong(), eq(ENTITY_KEY_VALUES), anyLong(), anyLong()))
                 .thenReturn(entity);
 
         Map<Long, Set<URI>> paths = entity.getEntityHistories().stream()
                 .filter(h -> h.getValidFromStamp().truncatedTo(DAYS).equals(startTimeInstant.truncatedTo(DAYS)))
-                .collect(Collectors.toMap(h -> h.getSchema().getId(), h -> this.buildDataLocationPath(h)));
+                .collect(Collectors.toMap(h -> h.getSchema().getId(), h -> buildDataLocationPath(h)));
 
         // when
-        Set<EntityResources> resourceData = this.entityResourcesService
-                .findBySystemIdKeyValuesAndTimeWindow(1L, TEST_KEY_VALUE,
+        Set<EntityResources> resourceData = entityResourcesService
+                .findBySystemIdKeyValuesAndTimeWindow(1L, ENTITY_KEY_VALUES,
                         startTime, endTime);
 
         // then
-        Assert.assertNotNull(resourceData);
-        Assert.assertEquals(2, resourceData.size());
-        Assert.assertEquals(1, (int) resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 3L)
+        assertNotNull(resourceData);
+        assertEquals(2, resourceData.size());
+        assertEquals(1, (int) resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 3L)
                 .map(rd -> rd.getResourcesData().getHdfsPaths().size()).findFirst().get());
-        Assert.assertEquals(1, (int) resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 3L)
+        assertEquals(1, (int) resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 3L)
                 .map(rd -> rd.getResourcesData().getHbaseTableNames().size()).findFirst().get());
-        Assert.assertEquals(3, (int) resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 5L)
+        assertEquals(3, (int) resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 5L)
                 .map(rd -> rd.getResourcesData().getHdfsPaths().size()).findFirst().get());
-        Assert.assertEquals(1, (int) resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 5L)
+        assertEquals(1, (int) resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 5L)
                 .map(rd -> rd.getResourcesData().getHbaseTableNames().size()).findFirst().get());
-        Assert.assertEquals(1, resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 3L &&
+        assertEquals(1, resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 3L &&
                 rd.getResourcesData().getHdfsPaths().containsAll(paths.get(3L))).count());
-        Assert.assertEquals(1, resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 3L &&
+        assertEquals(1, resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 3L &&
                 rd.getResourcesData().getHbaseTableNames().containsAll(
                         Stream.of(hbaseTablespace + ":1__2__3").collect(Collectors.toSet())
                 )).count());
-        Assert.assertEquals(1, resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 5L &&
+        assertEquals(1, resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 5L &&
                 rd.getResourcesData().getHdfsPaths().containsAll(paths.get(5L))).count());
-        Assert.assertEquals(1, resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 5L &&
+        assertEquals(1, resourceData.stream().filter(rd -> rd.getSchemaData().getId() == 5L &&
                 rd.getResourcesData().getHbaseTableNames().containsAll(
                         Stream.of(hbaseTablespace + ":1__2__5").collect(Collectors.toSet())
                 )).count());
@@ -195,26 +203,26 @@ public class DataLocationServiceImplTest extends BaseTest {
         System system = new System();
         system.setId(1L);
         system.setName(TEST_NAME);
-        system.setEntityKeyDefs(TEST_SCHEMA_CONTENT);
-        system.setPartitionKeyDefs(TEST_SCHEMA_CONTENT);
-        system.setRecordVersionKeyDefs(TEST_SCHEMA_CONTENT);
-        system.setTimeKeyDefs(TEST_SCHEMA_CONTENT);
+        system.setEntityKeyDefs(ENTITY_SCHEMA_1.toString());
+        system.setPartitionKeyDefs(PARTITION_SCHEMA_1.toString());
+        system.setRecordVersionKeyDefs(RECORD_VERSION_SCHEMA.toString());
+        system.setTimeKeyDefs(TIME_SCHEMA.toString());
 
         // Partition
         Partition part = new Partition();
         part.setId(2L);
         part.setSystem(system);
-        part.setKeyValues(TEST_KEY_VALUE);
+        part.setKeyValues(PARTITION_KEY_VALUES_JSON_1);
 
         // Schema
         Schema schema = new Schema();
         schema.setId(3L);
-        schema.setContent(TEST_SCHEMA_CONTENT);
+        schema.setContent(ENTITY_SCHEMA_1.toString());
 
         // Entity
         Entity entity = new Entity();
         entity.setId(4L);
-        entity.setKeyValues(TEST_KEY_VALUE);
+        entity.setKeyValues(ENTITY_KEY_VALUES_JSON);
         entity.setPartition(part);
         entity.setSchema(schema);
         return entity;
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/InternalEntityServiceImplTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/InternalEntityServiceImplTest.java
index df47a9a9ca444b06919d689d92f7d7fa0c1f3944..b2a4063b6f65c60d02d3301e999ba7e352e3306f 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/InternalEntityServiceImplTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/InternalEntityServiceImplTest.java
@@ -15,8 +15,6 @@ import cern.accsoft.nxcals.service.domain.System;
 import cern.accsoft.nxcals.service.rest.ConfigDataConflictException;
 import cern.accsoft.nxcals.service.rest.NotFoundRuntimeException;
 import com.google.common.collect.Sets;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.junit.Assert;
 import org.junit.Test;
 import org.springframework.dao.InvalidDataAccessApiUsageException;
 import org.springframework.test.annotation.Rollback;
@@ -27,18 +25,31 @@ import java.time.Instant;
 import java.time.temporal.ChronoUnit;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.SortedSet;
-import java.util.stream.Collectors;
 
+import static cern.accsoft.nxcals.common.utils.KeyValuesUtils.convertMapIntoAvroSchemaString;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES_2;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.KEY_VALUES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_STRING_SCHEMA_KEY_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_STRING_SCHEMA_KEY_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.TIME_SCHEMA;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.getFullSchema;
+import static java.util.stream.Collectors.toCollection;
+import static java.util.stream.Collectors.toList;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 @Transactional(transactionManager = "jpaTransactionManager")
 public class InternalEntityServiceImplTest extends BaseTest {
@@ -46,570 +57,628 @@ public class InternalEntityServiceImplTest extends BaseTest {
     @Test(expected = NotFoundRuntimeException.class)
     @Rollback
     public void shouldNotCreateEntityKeyForNonExistingSystem() {
-        Entity entity = service.findOrCreateEntityFor(-1L, TEST_KEY_VALUE, TEST_KEY_VALUE, TEST_SCHEMA_CONTENT,
-                TEST_RECORD_TIME);
-        Assert.assertNotNull(entity);
+        Entity entity = service.findOrCreateEntityFor(-1L, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
+        assertThat(entity).isNotNull();
     }
 
     @Test(expected = ConfigDataConflictException.class)
     @Rollback
     public void shouldNotGetResultForLateEntityWithSchemaNotPresentedInTheHistory() {
-        System system = createAndPersistClientSystem(TEST_NAME);
+        System system = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA);
         Long systemId = system.getId();
 
-        service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, TEST_SCHEMA_CONTENT,
-                TEST_RECORD_TIME);
-        service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, "NEW_SCHEMA_CONTENT",
-                100 * TEST_RECORD_TIME);
-        service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, "NEW_SCHEMA_CONTENT",
-                TEST_RECORD_TIME + 10);
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                ENTITY_SCHEMA_2.toString(), 100 * TEST_RECORD_TIME);
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                ENTITY_SCHEMA_2.toString(), TEST_RECORD_TIME + 10);
     }
 
     @Test(expected = ConfigDataConflictException.class)
     @Rollback
     public void shouldNotGetResultForLateEntityWithPartitionNotPresentedInTheHistory() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
 
-        service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, TEST_SCHEMA_CONTENT,
-                TEST_RECORD_TIME);
-        service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, "NEW_PARTITION", TEST_SCHEMA_CONTENT,
-                100 * TEST_RECORD_TIME);
+        long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
+
+        HashMap<String, Object> newPartitionKeyValues = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues.put(PARTITION_STRING_SCHEMA_KEY_1, "new_value");
+
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
+
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, newPartitionKeyValues,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), 100 * TEST_RECORD_TIME);
 
-        service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, "NEW_PARTITION", TEST_SCHEMA_CONTENT,
-                TEST_RECORD_TIME + 10);
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, newPartitionKeyValues,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME + 10);
     }
 
     @Test(expected = ConfigDataConflictException.class)
     @Rollback
     public void shouldRejectHistoryWithDifferentSchemaAndSameCreationTime() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
 
-        Entity entity1 = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE,
-                TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
-        Entity entity2 = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE,
-                "NEW_SCHEMA_CONTENT", TEST_RECORD_TIME);
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                ENTITY_SCHEMA_2.toString(), TEST_RECORD_TIME);
     }
 
     @Test
     @Rollback
     public void shouldCreateEntity() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
+
+        Long schemaId = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME).getSchema().getId();
+        Optional<Schema> optionalSchema = schemaRepository.findById(schemaId);
 
-        Entity entity = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE,
-                TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
-        Schema foundSchema = schemaRepository.findById(entity.getSchema().getId()).get();
+        assertThat(optionalSchema).isPresent();
 
-        Assert.assertEquals(TEST_SCHEMA_CONTENT, foundSchema.getContent());
-        Assert.assertEquals(foundSchema.getId(), entity.getSchema().getId());
+        Schema foundSchema = optionalSchema.get();
+        assertThat(foundSchema.getContent()).isEqualTo(getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString());
     }
 
 
     @Test
     @Rollback
     public void shouldFindOrCreateEntityWithId() {
-        Entity entity = createAndSaveDefaultTestEntityKey();
-        Partition partition = entity.getPartition();
-        Long systemId = partition.getSystem().getId();
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1,
+                PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
 
-        Entity foundEntity = service.findOrCreateEntityFor(systemId, entity.getId(), partition.getId(),
-                TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
-        Schema foundSchema = schemaRepository.findById(foundEntity.getSchema().getId()).get();
+        Entity foundEntity = service
+                .findOrCreateEntityFor(entity.getPartition().getSystem().getId(), entity.getId(),
+                        entity.getPartition().getId(), ENTITY_SCHEMA_1.toString(), TEST_RECORD_TIME);
 
-        Assert.assertEquals(TEST_SCHEMA_CONTENT, foundSchema.getContent());
-        Assert.assertEquals(foundSchema.getId(), foundEntity.getSchema().getId());
+        assertThat(foundEntity.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_1.toString());
+        assertThat(foundEntity.getId()).isEqualTo(entity.getId());
     }
 
-
     @Test
     @Rollback
     public void shouldFindOrCreateEntityWithIdForNextTimestamp() {
-        Entity entity = createAndSaveDefaultTestEntityKey();
-        Partition partition = entity.getPartition();
-        Long systemId = partition.getSystem().getId();
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1,
+                PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
 
-        Entity foundEntity = service.findOrCreateEntityFor(systemId, entity.getId(), partition.getId(),
-                TEST_SCHEMA_CONTENT, TEST_RECORD_TIME+TEST_RECORD_TIME);
-        Schema foundSchema = schemaRepository.findById(foundEntity.getSchema().getId()).get();
+        Entity foundEntity = service.findOrCreateEntityFor(entity.getPartition().getSystem().getId(), entity.getId(),
+                entity.getPartition().getId(), ENTITY_SCHEMA_1.toString(), TEST_RECORD_TIME+TEST_RECORD_TIME);
 
-        Assert.assertEquals(TEST_SCHEMA_CONTENT, foundSchema.getContent());
-        Assert.assertEquals(foundSchema.getId(), foundEntity.getSchema().getId());
+        assertThat(foundEntity.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_1.toString());
     }
 
     @Test
     @Rollback
     public void shouldFindOrCreateEntityWithIdForDifferentSchema() {
-        Entity entity = createAndSaveDefaultTestEntityKey();
-        Partition partition = entity.getPartition();
-        Long systemId = partition.getSystem().getId();
-
-        Entity foundEntity = service.findOrCreateEntityFor(systemId, entity.getId(), partition.getId(),
-                TEST_SCHEMA_CONTENT2, TEST_RECORD_TIME+TEST_RECORD_TIME);
-        Schema foundSchema = schemaRepository.findById(foundEntity.getSchema().getId()).get();
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1,
+                PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
 
-        Assert.assertEquals(TEST_SCHEMA_CONTENT2, foundSchema.getContent());
-        Assert.assertEquals(foundSchema.getId(), foundEntity.getSchema().getId());
-        Assert.assertEquals(1,foundEntity.getEntityHistories().size());
-        EntityHistory hist = foundEntity.getEntityHistories().first();
+        Entity foundEntity = service.findOrCreateEntityFor(entity.getPartition().getSystem().getId(), entity.getId(),
+                entity.getPartition().getId(),ENTITY_SCHEMA_2.toString(), TEST_RECORD_TIME+TEST_RECORD_TIME);
 
-        Assert.assertEquals(TimeUtils.getNanosFromInstant(hist.getValidFromStamp()), TEST_RECORD_TIME+TEST_RECORD_TIME);
-        Assert.assertNull(hist.getValidToStamp());
+        assertThat(foundEntity.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_2.toString());
+        assertThat(foundEntity.getEntityHistories()).hasSize(1);
+        EntityHistory entityHistory = foundEntity.getEntityHistories().first();
 
-        Assert.assertEquals(TEST_SCHEMA_CONTENT2,hist.getSchema().getContent());
-        Assert.assertEquals(partition.getId(),hist.getPartition().getId());
+        assertThat(entityHistory.getValidFromStamp()).isEqualTo(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME+TEST_RECORD_TIME));
+        assertThat(entityHistory.getValidToStamp()).isNull();
     }
 
-
-
     private void verifyTest(String testSchemaContent) {
-        Entity entity = createAndSaveDefaultTestEntityKey();
-        String newPartitionKeys = TEST_KEY_VALUE+"_CHANGED";
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1,
+                PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
 
-        Partition partition = this.createAndPersistPartitionKey(entity.getPartition().getSystem(), newPartitionKeys);
-        Long systemId = entity.getPartition().getSystem().getId();
+        HashMap<String, Object> newPartitionKeyValues = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues.put(PARTITION_STRING_SCHEMA_KEY_1, "new_value");
+
+        Partition newPartition = createPartition(entity.getPartition().getSystem(), newPartitionKeyValues,
+                PARTITION_SCHEMA_1);
+        partitionRepository.save(newPartition);
 
-        Entity foundEntity = service.findOrCreateEntityFor(systemId, entity.getId(), partition.getId(),
-                testSchemaContent, TEST_RECORD_TIME+TEST_RECORD_TIME);
-        Schema foundSchema = schemaRepository.findById(foundEntity.getSchema().getId()).get();
+        Entity foundEntity = service
+                .findOrCreateEntityFor(entity.getPartition().getSystem().getId(), entity.getId(), newPartition.getId(),
+                        testSchemaContent, TEST_RECORD_TIME + TEST_RECORD_TIME);
 
-        Assert.assertEquals(testSchemaContent, foundSchema.getContent());
-        Assert.assertEquals(foundSchema.getId(), foundEntity.getSchema().getId());
-        Assert.assertEquals(1,foundEntity.getEntityHistories().size());
-        EntityHistory hist = foundEntity.getEntityHistories().first();
+        assertThat(foundEntity.getSchema().getContent()).isEqualTo(testSchemaContent);
+        assertThat(foundEntity.getEntityHistories()).hasSize(1);
 
-        Assert.assertEquals(TimeUtils.getNanosFromInstant(hist.getValidFromStamp()), TEST_RECORD_TIME+TEST_RECORD_TIME);
-        Assert.assertNull(hist.getValidToStamp());
+        EntityHistory entityHistory = foundEntity.getEntityHistories().first();
 
-        Assert.assertEquals(testSchemaContent,hist.getSchema().getContent());
-        Assert.assertEquals(partition.getId(),hist.getPartition().getId());
+        assertThat(entityHistory.getValidFromStamp()).isEqualTo(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + TEST_RECORD_TIME));
+        assertThat(entityHistory.getValidToStamp()).isNull();
     }
 
     @Test
     @Rollback
     public void shouldFindOrCreateEntityWithIdForDifferentPartition() {
-        verifyTest(TEST_SCHEMA_CONTENT);
+        verifyTest(ENTITY_SCHEMA_1.toString());
     }
 
     @Test
     @Rollback
     public void shouldFindOrCreateEntityWithIdForDifferentPartitionAndSchema() {
-        verifyTest(TEST_SCHEMA_CONTENT2);
+        verifyTest(ENTITY_SCHEMA_2.toString());
     }
 
-
     @Test(expected = ConfigDataConflictException.class)
     @Rollback
     public void shouldFailToFindOrCreateEntityWithIdForDifferentPartitionAndSchemaWithUsedTimestamp() {
-        Entity entity = createAndSaveDefaultTestEntityKey();
-        String newPartitionKeys = TEST_KEY_VALUE+"_CHANGED";
-
-        Partition partition = this.createAndPersistPartitionKey(entity.getPartition().getSystem(), newPartitionKeys);
-        Long systemId = entity.getPartition().getSystem().getId();
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1,
+                PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
 
-        Entity foundEntity = service.findOrCreateEntityFor(systemId, entity.getId(), partition.getId(),
-                TEST_SCHEMA_CONTENT2, TEST_RECORD_TIME);
+        HashMap<String, Object> newPartitionKeyValues = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues.put(PARTITION_STRING_SCHEMA_KEY_1, "new_value");
 
+        Partition newPartition = createPartition(entity.getPartition().getSystem(), newPartitionKeyValues,
+                PARTITION_SCHEMA_1);
+        partitionRepository.save(newPartition);
 
+        service.findOrCreateEntityFor(entity.getPartition().getSystem().getId(), entity.getId(), newPartition.getId(),
+                ENTITY_SCHEMA_2.toString(), TEST_RECORD_TIME);
     }
 
-
     @Test(expected = IllegalArgumentException.class)
     @Rollback
     public void shouldFailOnFindOrCreateEntityWithIdWithWrongSystem() {
-        Entity entity = createAndSaveDefaultTestEntityKey();
-        Partition partition = entity.getPartition();
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1,
+                PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
+
         //This is another system
-        System system = createAndPersistClientSystem(TEST_NAME);
+        System system = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, ENTITY_SCHEMA_1, ENTITY_SCHEMA_1);
         Long systemId = system.getId();
 
-        Entity foundEntity = service.findOrCreateEntityFor(systemId, entity.getId(), partition.getId(),
-                TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
-        Schema foundSchema = schemaRepository.findById(foundEntity.getSchema().getId()).get();
-
-        Assert.assertEquals(TEST_SCHEMA_CONTENT, foundSchema.getContent());
-        Assert.assertEquals(foundSchema.getId(), foundEntity.getSchema().getId());
+        Entity foundEntity = service.findOrCreateEntityFor(systemId, entity.getId(), entity.getPartition().getId(),
+                ENTITY_SCHEMA_1.toString(), TEST_RECORD_TIME);
     }
 
-
-
     @Test
     @Rollback
     public void shouldUpdateEntitySchema() {
-        Entity key = createAndSaveDefaultTestEntityKey();
-        Long systemId = key.getPartition().getSystem().getId();
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
+
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
 
-        String newSchemaContent = "{\"class\":\"string\", \"property\":\"string\"}";
+        // TODO: Confirm why in the previous test there was no need to increment the recordTimestamp, it should not be possible to send the same as far as I know?
+        Long schemaId = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME + 10).getSchema()
+                .getId();
 
-        Entity entity = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, newSchemaContent,
-                TEST_RECORD_TIME);
+        Optional<Schema> optionalSchema = schemaRepository.findById(schemaId);
 
-        Schema foundSchema = schemaRepository.findById(entity.getSchema().getId()).get();
+        assertThat(optionalSchema).isPresent();
 
-        Assert.assertEquals(foundSchema.getContent(), newSchemaContent);
-        Assert.assertEquals(foundSchema.getId(), entity.getSchema().getId());
+        Schema foundSchema = optionalSchema.get();
+
+        assertThat(foundSchema.getContent()).isEqualTo(getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString());
+        assertThat(foundSchema.getId()).isEqualTo(schemaId);
     }
 
     @Test
     @Rollback
     public void shouldUpdateEntityPartition() {
-        Entity key = createAndSaveDefaultTestEntityKey();
-        Long systemId = key.getPartition().getSystem().getId();
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
+
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
+
+        Map<String, Object> newPartitionKeyValues = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues.put(PARTITION_STRING_SCHEMA_KEY_1, "new_value");
+
+        Long systemId = entity.getPartition().getSystem().getId();
+
+        Long entityId = service
+                .findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, newPartitionKeyValues,
+                        getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME + 10).getId();
 
-        // creates entity with new partition, entity should be the same, partition should be new
-        Entity entity = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE + "_NEW",
-                TEST_SCHEMA_CONTENT, TEST_RECORD_TIME + 1);
-        Entity foundEntity = entityRepository.findById(key.getId()).get();
+        Optional<Entity> optionalEntity = entityRepository.findById(entityId);
 
-        assertEquals(key.getId(), entity.getId());
-        assertEquals(foundEntity.getId(), entity.getId());
-        assertEquals(key.getKeyValues(), foundEntity.getKeyValues());
-        Assert.assertEquals(foundEntity.getPartition().getKeyValues(), TEST_KEY_VALUE + "_NEW");
-        Assert.assertEquals(foundEntity.getSchema().getId(), entity.getSchema().getId());
+        assertThat(optionalEntity).isPresent();
+
+        Entity foundEntity = optionalEntity.get();
+
+        assertThat(foundEntity.getPartition().getKeyValues())
+                .isEqualTo(convertMapIntoAvroSchemaString(newPartitionKeyValues, PARTITION_SCHEMA_1.toString()));
     }
 
     @Test(expected = NotFoundRuntimeException.class)
     @Rollback
     public void shouldThrowExceptionOnUpdateWhenEntityDoesNotExists() {
-        Entity persistedEntity = createAndSaveDefaultTestEntityKey();
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
+
+        Map<String, Object> newEntityKeyValues = new HashMap<>(ENTITY_KEY_VALUES);
+        newEntityKeyValues.put(ENTITY_STRING_SCHEMA_KEY_1, "new_value");
 
-        EntityDataImpl updatedEntityData = new EntityDataImpl.Builder(persistedEntity.toEntityData())
-                .withNewEntityKeyValues("Super changed entity key-values")
+        EntityDataImpl updatedEntityData = new EntityDataImpl.Builder(entity.toEntityData())
+                .withNewEntityKeyValues(newEntityKeyValues)
                 .create();
 
-        Entity nonExistingEntity = createDefaultNonPersistedEntity();
+        Entity nonExistingEntity = createEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
         nonExistingEntity.setRecVersion(0L);
+        EntityDataImpl nonExistingEntityData = new EntityDataImpl.Builder(nonExistingEntity.toEntityData())
+                .create();
 
-        service.updateEntities(Arrays.asList(updatedEntityData, nonExistingEntity.toEntityData()));
-
-        fail("This method should throw exception when provided list contains data for nonExisting entities");
+        service.updateEntities(Arrays.asList(updatedEntityData, nonExistingEntityData));
     }
 
     @Test(expected = org.springframework.orm.ObjectOptimisticLockingFailureException.class)
     @Rollback
     public void shouldThrowExceptionWhenProvidedUpdateEntityIsOlderVersion() {
-        Entity initiallyPersistedEntity = createAndSaveDefaultTestEntityKey();
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
+
+        Map<String, Object> oldEntityKeyValues = new HashMap<>(ENTITY_KEY_VALUES);
+        oldEntityKeyValues.put(ENTITY_STRING_SCHEMA_KEY_1, "old_value");
 
-        EntityDataImpl oldEntityData = new EntityDataImpl.Builder(initiallyPersistedEntity.toEntityData())
-                .withNewEntityKeyValues("old-key-values")
+        Map<String, Object> newEntityKeyValues = new HashMap<>(ENTITY_KEY_VALUES);
+        newEntityKeyValues.put(ENTITY_STRING_SCHEMA_KEY_1, "new_value");
+
+        EntityDataImpl oldEntityData = new EntityDataImpl.Builder(entity.toEntityData())
+                .withNewEntityKeyValues(oldEntityKeyValues)
                 .create();
 
-        EntityDataImpl updatedEntityData = new EntityDataImpl.Builder(initiallyPersistedEntity.toEntityData())
-                .withNewEntityKeyValues("new-key-values")
+        EntityDataImpl updatedEntityData = new EntityDataImpl.Builder(entity.toEntityData())
+                .withNewEntityKeyValues(newEntityKeyValues)
                 .create();
-        service.updateEntities(Collections.singletonList(updatedEntityData)); //should pass normally
 
-        service.updateEntities(Collections.singletonList(oldEntityData)); // should throw opt version exception!
+        service.updateEntities(Collections.singletonList(updatedEntityData));
 
-        fail("This method should throw exception when trying to update entity with a data obtained by it's older version!");
+        service.updateEntities(Collections.singletonList(oldEntityData));
     }
 
     @Test
     @Rollback
     public void shouldUpdateAndLockOneEntity() {
-        Entity persistedEntity = createAndSaveDefaultTestEntityKey();
+
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
 
         long lockUntilEpochNanos = TimeUtils.getNanosFromInstant(Instant.now().plus(2, ChronoUnit.HOURS));
 
-        EntityDataImpl updatedEntityData = new EntityDataImpl.Builder(persistedEntity.toEntityData())
+        EntityDataImpl updatedEntityData = new EntityDataImpl.Builder(entity.toEntityData())
                 .lockUntil(lockUntilEpochNanos)
                 .create();
 
         LinkedList<Entity> updatedEntities = new LinkedList<>(
                 service.updateEntities(Collections.singletonList(updatedEntityData)));
 
-        assertNotNull(updatedEntities);
-        assertTrue(updatedEntities.size() == 1);
+        assertThat(updatedEntities).isNotNull();
+        assertThat(updatedEntities).hasSize(1);
 
         Entity updatedEntity = updatedEntities.getFirst();
 
-        assertEquals(persistedEntity.getId(), updatedEntity.getId());
-        assertEquals(lockUntilEpochNanos, TimeUtils.getNanosFromInstant(updatedEntity.getLockedUntilStamp()));
+        assertThat(updatedEntity.getId()).isEqualTo(entity.getId());
+        assertThat(TimeUtils.getNanosFromInstant(updatedEntity.getLockedUntilStamp())).isEqualTo(lockUntilEpochNanos);
     }
 
     @Test
     @Rollback
     public void shouldUpdateAndUnlockOneEntity() {
-        Entity persistedEntity = createAndSaveDefaultTestEntityKeyWithLockTime(
-                Instant.now().plus(2, ChronoUnit.HOURS));
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1, Instant.now().plus(2, ChronoUnit.HOURS));
 
-        EntityDataImpl updatedEntityData = new EntityDataImpl.Builder(persistedEntity.toEntityData())
+        EntityDataImpl updatedEntityData = new EntityDataImpl.Builder(entity.toEntityData())
                 .unlock()
                 .create();
 
         LinkedList<Entity> updatedEntities = new LinkedList<>(
                 service.updateEntities(Collections.singletonList(updatedEntityData)));
 
-        assertNotNull(updatedEntities);
-        assertTrue(updatedEntities.size() == 1);
-
+        assertThat(updatedEntities).hasSize(1);
         Entity updatedEntity = updatedEntities.getFirst();
-
-        assertEquals(persistedEntity.getId(), updatedEntity.getId());
-        assertNull(updatedEntity.getLockedUntilStamp());
+        assertThat(updatedEntity.getId()).isEqualTo(entity.getId());
+        assertThat(updatedEntity.getLockedUntilStamp()).isNull();
     }
 
     @Test
     @Rollback
     public void shouldCreateEntityWithNewKeyValues() {
-        Entity key = createAndSaveDefaultTestEntityKey();
-        Long systemId = key.getPartition().getSystem().getId();
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
+
+        Long systemId = entity.getPartition().getSystem().getId();
 
-        Entity entity = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE + "_NEW", TEST_KEY_VALUE,
-                TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
-        Entity foundKey = entityRepository.findByPartitionSystemIdAndKeyValues(systemId, TEST_KEY_VALUE + "_NEW")
-                .get();
+        Map<String, Object> newEntityKeysValues = new HashMap<>(ENTITY_KEY_VALUES);
+        newEntityKeysValues.put(ENTITY_STRING_SCHEMA_KEY_1, "new_value");
 
-        Assert.assertEquals(foundKey.getKeyValues(), TEST_KEY_VALUE + "_NEW");
-        Assert.assertEquals(foundKey.getSchema().getId(), entity.getSchema().getId());
-        Assert.assertEquals(key.getSchema().getId(), foundKey.getSchema().getId());
-        Assert.assertEquals(key.getSchema().getContent(), foundKey.getSchema().getContent());
+        service.findOrCreateEntityFor(systemId, newEntityKeysValues, PARTITION_KEY_VALUES_1,
+                ENTITY_SCHEMA_1.toString(), TEST_RECORD_TIME);
+
+        String newEntityKeyValuesString = convertMapIntoAvroSchemaString(newEntityKeysValues,
+                ENTITY_SCHEMA_1.toString());
+
+        Optional<Entity> optionalEntity = entityRepository
+                .findByPartitionSystemIdAndKeyValues(systemId, newEntityKeyValuesString);
+
+        assertThat(optionalEntity).isPresent();
+        Entity newEntity = optionalEntity.get();
+        assertThat(newEntity.getKeyValues()).isEqualTo(newEntityKeyValuesString);
+        assertThat(newEntity.getSchema().getId()).isEqualTo(entity.getSchema().getId());
     }
 
     @Test
     @Rollback
     public void shouldCreateEntityHistory() {
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
 
-        Entity key = createAndSaveDefaultTestEntityKey();
-        Long systemId = key.getPartition().getSystem().getId();
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
 
-        Entity entityWithChangedPartition = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE,
-                TEST_KEY_VALUE + "NEW_PARTITION", TEST_SCHEMA_CONTENT, TEST_RECORD_TIME + 1);
+        Map<String, Object> newPartitionKeyValues = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues.put(PARTITION_STRING_SCHEMA_KEY_1, "new_value");
+
+        Long systemId = entity.getPartition().getSystem().getId();
 
-        assertEquals(key.getId(), entityWithChangedPartition.getId());
+        Entity entityWithChangedPartition = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES,
+                newPartitionKeyValues, getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(),
+                TEST_RECORD_TIME + 1);
 
-        assertEquals(1, entityWithChangedPartition.getEntityHistories().size());
+        assertThat(entityWithChangedPartition.getId()).isEqualTo(entity.getId());
+        assertThat(entityWithChangedPartition.getEntityHistories()).hasSize(1);
     }
 
     @Test
     @Rollback
     public void shouldGetLatestHistoryFromExistingEntity() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
 
-        Entity entity1 = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE,
-                TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
+        Entity entity1 = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
 
-        Entity found1 = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, TEST_SCHEMA_CONTENT,
-                TEST_RECORD_TIME);
+        Entity found1 = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
 
-        Entity found2 = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, TEST_SCHEMA_CONTENT,
-                TEST_RECORD_TIME + 1_000_000);
+        Entity found2 = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME + 1_000_000);
 
-        Assert.assertNotNull(found1);
-        Assert.assertNotNull(found2);
-        Assert.assertEquals(entity1, found1);
-        Assert.assertEquals(found1, found2);
-        Assert.assertEquals(1, found1.getEntityHistories().size());
-        Assert.assertEquals(1, found2.getEntityHistories().size());
+        assertThat(found1).isNotNull();
+        assertThat(found2).isNotNull();
+        assertThat(found1).isEqualTo(entity1);
+        assertThat(found2).isEqualTo(found2);
+        assertThat(found1.getEntityHistories()).hasSize(1);
+        assertThat(found2.getEntityHistories()).hasSize(1);
     }
 
     @Test
     @Rollback
     public void shouldGetHistoryForExistingEntityWithDifferentSchemaFromThePast() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
 
-        Entity entity1 = service
-                .findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
+        Entity entity1 = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
 
-        service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, "NEW_SCHEMA_CONTENT",
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1, ENTITY_SCHEMA_2.toString(),
                 100 * TEST_RECORD_TIME);
-        Entity found = service
-                .findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
+        Entity found = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
 
-        Assert.assertNotNull(found);
-        Assert.assertEquals(entity1, found);
-        Assert.assertEquals("NEW_SCHEMA_CONTENT", found.getSchema().getContent());
-        Assert.assertEquals(1, found.getEntityHistories().size());
-        Assert.assertEquals(TEST_SCHEMA_CONTENT, found.getEntityHistories().first().getSchema().getContent());
+        assertThat(found).isNotNull();
+        assertThat(found).isEqualTo(entity1);
+        assertThat(found.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_2.toString());
+        assertThat(found.getEntityHistories()).hasSize(1);
+        assertThat(found.getEntityHistories().first().getSchema().getContent())
+                .isEqualTo(getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString());
     }
 
     @Test
     @Rollback
     public void shouldGetHistoryForExistingEntityWithDifferentPartitionFromThePast() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
 
-        Entity entity1 = service
-                .findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
-        //this creates a new historical entry with new partition
-        service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, "NEW_PARTITION", TEST_SCHEMA_CONTENT,
-                100 * TEST_RECORD_TIME);
-        Entity found = service
-                .findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
+        Map<String, Object> newPartitionKeyValues = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues.put(PARTITION_STRING_SCHEMA_KEY_1, "new_value");
 
-        Assert.assertNotNull(found);
-        Assert.assertEquals(found, entity1);
-        Assert.assertEquals("NEW_PARTITION", found.getPartition().getKeyValues());
-        Assert.assertEquals(1, found.getEntityHistories().size());
-        Assert.assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME),
-                found.getEntityHistories().first().getValidFromStamp());
-        Assert.assertEquals(TimeUtils.getInstantFromNanos(100 * TEST_RECORD_TIME),
-                found.getEntityHistories().first().getValidToStamp());
-        Assert.assertEquals(TEST_KEY_VALUE, found.getEntityHistories().first().getPartition().getKeyValues());
-        Assert.assertEquals(TEST_SCHEMA_CONTENT, found.getEntityHistories().first().getSchema().getContent());
+        Entity entity1 = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
+        //this creates a new historical entry with new partition
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, newPartitionKeyValues,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), 100 * TEST_RECORD_TIME);
+        Entity found = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
+
+        assertThat(found).isNotNull();
+        assertThat(found).isEqualTo(entity1);
+        assertThat(found.getPartition().getKeyValues())
+                .isEqualTo(convertMapIntoAvroSchemaString(newPartitionKeyValues, PARTITION_SCHEMA_1.toString()));
+        assertThat(found.getEntityHistories()).hasSize(1);
+        assertThat(found.getEntityHistories().first().getValidFromStamp())
+                .isEqualTo(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME));
+        assertThat(found.getEntityHistories().first().getValidToStamp())
+                .isEqualTo(TimeUtils.getInstantFromNanos(100 * TEST_RECORD_TIME));
+        assertThat(found.getEntityHistories().first().getPartition().getKeyValues())
+                .isEqualTo(convertMapIntoAvroSchemaString(PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1.toString()));
+        assertThat(found.getEntityHistories().first().getSchema().getContent())
+                .isEqualTo(getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString());
     }
 
     @Test(expected = ConfigDataConflictException.class)
     public void shouldNotCreateHistoryForLateDataWithDifferentSchemaBeforeEntityCreationTime() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
-
-        service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE,
-                TEST_SCHEMA_CONTENT, 100 * TEST_RECORD_TIME);
-        service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE,
-                "NEW_SCHEMA_CONTENT", TEST_RECORD_TIME);
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
 
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), 100 * TEST_RECORD_TIME);
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                ENTITY_SCHEMA_2.toString(), TEST_RECORD_TIME);
     }
 
-    @Test()
+    @Test
     @Rollback
     public void shouldExtendHistoryForLateDataWithTheSameSchemaBeforeEntityCreationTime() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
 
-        Entity entity1 = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE,
-                TEST_SCHEMA_CONTENT, 100 * TEST_RECORD_TIME);
-        Entity entity2 = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE,
-                TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
+        Entity entity1 = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), 100 * TEST_RECORD_TIME);
+        Entity entity2 = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
 
-        Assert.assertNotNull(entity1);
-        Assert.assertNotNull(entity2);
-        Assert.assertEquals(entity1, entity2);
-        Assert.assertEquals(TEST_SCHEMA_CONTENT, entity2.getSchema().getContent());
-        Assert.assertEquals(1, entity2.getEntityHistories().size());
-        Assert.assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME),
-                entity2.getEntityHistories().first().getValidFromStamp());
-        Assert.assertEquals(null, entity2.getEntityHistories().first().getValidToStamp());
+        assertThat(entity1).isNotNull();
+        assertThat(entity2).isNotNull();
+        assertThat(entity1).isEqualTo(entity2);
+        assertThat(entity2.getSchema().getContent())
+                .isEqualTo(getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString());
+        assertThat(entity2.getEntityHistories()).hasSize(1);
+        assertThat(entity2.getEntityHistories().first().getValidFromStamp())
+                .isEqualTo(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME));
+        assertThat(entity2.getEntityHistories().first().getValidToStamp()).isNull();
     }
 
-    @Test()
+    @Test
     @Rollback
     public void shouldExtendFirstHistoryForMigration() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
         Long timestamp = 100 * TEST_RECORD_TIME;
 
-        Entity entity1 = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE,
-                TEST_SCHEMA_CONTENT, timestamp);
+        Entity entity1 = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), timestamp);
 
-        Entity entity2 = service.extendEntityFirstHistoryDataFor(entity1.getId(),TEST_SCHEMA_CONTENT2, 0);
+        Entity entity2 = service.extendEntityFirstHistoryDataFor(entity1.getId(), ENTITY_SCHEMA_2.toString(), 0);
 
-        Assert.assertNotNull(entity1);
-        Assert.assertNotNull(entity2);
-
-
-        Assert.assertEquals(1, entity2.getEntityHistories().size());
-        Assert.assertEquals(TimeUtils.getInstantFromNanos(0),
-                entity2.getEntityHistories().first().getValidFromStamp());
-        Assert.assertEquals(TimeUtils.getInstantFromNanos(timestamp), entity2.getEntityHistories().first().getValidToStamp());
+        assertThat(entity1).isNotNull();
+        assertThat(entity2).isNotNull();
+        assertThat(entity2.getEntityHistories()).hasSize(1);
+        assertThat(entity2.getEntityHistories().first().getValidFromStamp())
+                .isEqualTo(TimeUtils.getInstantFromNanos(0));
+        assertThat(entity2.getEntityHistories().first().getValidToStamp())
+                .isEqualTo(TimeUtils.getInstantFromNanos(timestamp));
     }
 
-
     @Test
     @Rollback
     public void shouldAcceptEntityWithPartitionNotPresentedInTheHistory() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
 
-        service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE, TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
-        Entity entity = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, "NEW_PARTITION", TEST_SCHEMA_CONTENT,
-                100 * TEST_RECORD_TIME);
+        Map<String, Object> newPartitionKeyValues = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues.put(PARTITION_STRING_SCHEMA_KEY_1, "new_value");
+
+        service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
+        Entity entity = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, newPartitionKeyValues,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), 100 * TEST_RECORD_TIME);
 
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(1, entity.getEntityHistories().size());
+        assertThat(entity).isNotNull();
+        assertThat(entity.getEntityHistories()).hasSize(1);
     }
 
     @Test
     @Rollback
     public void shouldUpdateHistoryForLateDataWithSameSchemaBeforeEntityCreationTime() {
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
 
-        Entity entity1 = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE,
-                TEST_SCHEMA_CONTENT, 100 * TEST_RECORD_TIME);
-        Entity entity2 = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, TEST_KEY_VALUE,
-                TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
+        Entity entity1 = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), 100 * TEST_RECORD_TIME);
+        Entity entity2 = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME);
 
-        Assert.assertNotNull(entity1);
-        Assert.assertNotNull(entity2);
-        Assert.assertEquals(entity1, entity2);
-        Assert.assertEquals(TEST_SCHEMA_CONTENT, entity2.getSchema().getContent());
-        Assert.assertEquals(1, entity2.getEntityHistories().size());
+        assertThat(entity1).isNotNull();
+        assertThat(entity2).isNotNull();
+        assertThat(entity1).isEqualTo(entity2);
+        assertThat(entity2.getSchema().getContent())
+                .isEqualTo(getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString());
+        assertThat(entity2.getEntityHistories()).hasSize(1);
     }
 
     @Test
     public void shouldFindEntityHistForAdvancingTimeWindow() {
         //given
-        System system = createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
-
-        Entity entity = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, "NEW_PARTITION1", TEST_SCHEMA_CONTENT,
-                TEST_RECORD_TIME + 100);
+        Long systemId = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA)
+                .getId();
+
+        Map<String, Object> newPartitionKeyValues1 = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues1.put(PARTITION_STRING_SCHEMA_KEY_1, "value1");
+        Map<String, Object> newPartitionKeyValues2 = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues2.put(PARTITION_STRING_SCHEMA_KEY_1, "value2");
+        Map<String, Object> newPartitionKeyValues3 = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues3.put(PARTITION_STRING_SCHEMA_KEY_1, "value3");
+        Map<String, Object> newPartitionKeyValues4 = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues4.put(PARTITION_STRING_SCHEMA_KEY_1, "value4");
+        Map<String, Object> newPartitionKeyValues5 = new HashMap<>(PARTITION_KEY_VALUES_1);
+        newPartitionKeyValues5.put(PARTITION_STRING_SCHEMA_KEY_1, "value5");
+
+        Entity entity = service
+                .findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, newPartitionKeyValues1,
+                        getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(),
+                        TEST_RECORD_TIME + 100);
         checkEntityHistory(entity, TEST_RECORD_TIME + 100, null);
 
-        entity = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, "NEW_PARTITION2", TEST_SCHEMA_CONTENT,
-                TEST_RECORD_TIME + 200);
+        entity = service
+                .findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, newPartitionKeyValues2,
+                        getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(),
+                        TEST_RECORD_TIME + 200);
         checkEntityHistory(entity, TEST_RECORD_TIME + 200, null);
 
-        entity = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, "NEW_PARTITION3", TEST_SCHEMA_CONTENT,
-                TEST_RECORD_TIME + 300);
+        entity = service
+                .findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, newPartitionKeyValues3,
+                        getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(),
+                        TEST_RECORD_TIME + 300);
         checkEntityHistory(entity, TEST_RECORD_TIME + 300, null);
 
-        entity = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, "NEW_PARTITION4", TEST_SCHEMA_CONTENT,
-                TEST_RECORD_TIME + 400);
+        entity = service
+                .findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, newPartitionKeyValues4,
+                        getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(),
+                        TEST_RECORD_TIME + 400);
         checkEntityHistory(entity, TEST_RECORD_TIME + 400, null);
 
-        entity = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE, "NEW_PARTITION5", "NEW_SCHEMA",
-                TEST_RECORD_TIME + 500);
+        entity = service
+                .findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, newPartitionKeyValues5,
+                        getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(),
+                        TEST_RECORD_TIME + 500);
         checkEntityHistory(entity, TEST_RECORD_TIME + 500, null);
 
         //when
         Entity entityWithHistForTimeWindow = service
-                .findEntityWithHistForTimeWindow(systemId, entity.getKeyValues(), TEST_RECORD_TIME + 100,
+                .findEntityWithHistForTimeWindow(systemId, ENTITY_KEY_VALUES, TEST_RECORD_TIME + 100,
                         TEST_RECORD_TIME + 300);
         SortedSet<EntityHistory> filteredHistory = entityWithHistForTimeWindow.getEntityHistories();
 
         //then
-        assertNotNull(filteredHistory);
-        assertEquals(3, filteredHistory.size());
+        assertThat(filteredHistory).hasSize(3);
 
         EntityHistory[] entityHistsArray = filteredHistory.toArray(new EntityHistory[0]);
-        assertEquals("NEW_PARTITION3", entityHistsArray[0].getPartition().getKeyValues());
-        assertEquals("NEW_PARTITION2", entityHistsArray[1].getPartition().getKeyValues());
-        assertEquals("NEW_PARTITION1", entityHistsArray[2].getPartition().getKeyValues());
-
-    }
-
-    private void checkEntityHistory(Entity entity, long start, Long stop) {
-        assertEquals(1, entity.getEntityHistories().size());
-        assertEquals(TimeUtils.getInstantFromNanos(start), entity.getEntityHistories().first().getValidFromStamp());
-        if (stop != null) {
-            assertEquals(TimeUtils.getInstantFromNanos(stop), entity.getEntityHistories().first().getValidToStamp());
-        } else {
-            assertEquals(null, entity.getEntityHistories().first().getValidToStamp());
-        }
+        assertThat(entityHistsArray[0].getPartition().getKeyValues())
+                .isEqualTo(convertMapIntoAvroSchemaString(newPartitionKeyValues3, PARTITION_SCHEMA_1.toString()));
+        assertThat(entityHistsArray[1].getPartition().getKeyValues())
+                .isEqualTo(convertMapIntoAvroSchemaString(newPartitionKeyValues2, PARTITION_SCHEMA_1.toString()));
+        assertThat(entityHistsArray[2].getPartition().getKeyValues())
+                .isEqualTo(convertMapIntoAvroSchemaString(newPartitionKeyValues1, PARTITION_SCHEMA_1.toString()));
     }
 
     @Test
     @Rollback
     public void shouldFetchEntityWithoutHistoryInThatTimeWindow() {
         //given
-        Partition part = createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Schema schema = createAndPersistSchema(TEST_SCHEMA_CONTENT);
-        Entity entity = createAndPersistEntity(schema, part, TEST_KEY_VALUE);
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
 
         //when
         Entity entityWithoutHistory = service
-                .findEntityWithHistForTimeWindow(entity.getPartition().getSystem().getId(), entity.getKeyValues(),
+                .findEntityWithHistForTimeWindow(entity.getPartition().getSystem().getId(), ENTITY_KEY_VALUES,
                         TEST_RECORD_TIME, TEST_RECORD_TIME);
 
         //then
-        assertNotNull(entityWithoutHistory);
-        assertTrue(entityWithoutHistory.getEntityHistories().isEmpty());
-
+        assertThat(entityWithoutHistory).isNotNull();
+        assertThat(entityWithoutHistory.getEntityHistories()).isEmpty();
     }
 
     @Test(expected = InvalidDataAccessApiUsageException.class)
@@ -620,86 +689,86 @@ public class InternalEntityServiceImplTest extends BaseTest {
     @Test
     @Rollback
     public void shouldFindEntityWithGivenRegex() {
-        Entity key = createAndSaveDefaultTestEntityKey();
-        Long systemId = key.getPartition().getSystem().getId();
-        String regex = "%NEW%";
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
+
+        Long systemId = entity.getPartition().getSystem().getId();
 
-        Entity entity = service.findOrCreateEntityFor(systemId, TEST_KEY_VALUE + "_NEW", TEST_KEY_VALUE,
-                TEST_SCHEMA_CONTENT, TEST_RECORD_TIME);
+        Entity newEntity = service.findOrCreateEntityFor(systemId, ENTITY_KEY_VALUES, PARTITION_KEY_VALUES_1,
+                getFullSchema(ENTITY_SCHEMA_1, PARTITION_SCHEMA_1).toString(), TEST_RECORD_TIME + 1);
+
+        String regex = "%trin%";
         List<Entity> foundKeys = entityRepository.findByKeyValuesLike(regex);
 
-        assertThat(foundKeys).containsExactly(entity);
+        assertThat(foundKeys).containsExactly(newEntity);
     }
 
     @Test
     @Rollback
     public void shouldFindEntityById() {
-        Entity persistedEntity = createAndSaveDefaultTestEntityKey();
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
 
-        Entity fetchedEntity = service.findById(persistedEntity.getId());
+        createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
 
-        assertNotNull(fetchedEntity);
-        assertTrue(EqualsBuilder.reflectionEquals(persistedEntity, fetchedEntity));
+        Entity fetchedEntity = service.findById(entity.getId());
 
-        assertNotNull(fetchedEntity.getEntityHistories());
-        assertEquals(1, fetchedEntity.getEntityHistories().size());
+        assertThat(fetchedEntity).isNotNull();
+        assertThat(fetchedEntity.getEntityHistories()).hasSize(1);
     }
 
     @Test(expected = NotFoundRuntimeException.class)
     public void shouldThrowExceptionWhenTryingToFindOneEntityById() throws Exception {
-        long nonExistingId = 12345L;
-        Entity fetchedEntity = service.findById(nonExistingId);
-
-        fail("This method should throw exception when entity not found!");
+        service.findById(12345L);
     }
 
     @Test
     @Rollback
     public void shouldFindAllEntitiesById() {
-        Entity persistedEntity = createAndSaveTestEntityKeyWithRandomSchemaContent();
-        Entity persistedEntityOther = createAndSaveTestEntityKeyWithRandomSchemaContent();
-
-        Set<Long> entityIds = Sets.newHashSet(persistedEntity.getId(), persistedEntityOther.getId());
-        Set<Entity> fetchedEntities = service.findAllByIdIn(entityIds);
+        Entity entity1 = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1,
+                PARTITION_SCHEMA_1);
+        createAndPersistEntityHist(entity1, entity1.getPartition(), entity1.getSchema(), TEST_RECORD_TIME);
 
-        assertNotNull(fetchedEntities);
-        assertEquals(2, fetchedEntities.size());
+        Entity entity2 = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES_2, ENTITY_SCHEMA_2, PARTITION_KEY_VALUES_2,
+                PARTITION_SCHEMA_2);
+        createAndPersistEntityHist(entity2, entity2.getPartition(), entity2.getSchema(), TEST_RECORD_TIME);
 
-        LinkedList<Entity> testEntities = new LinkedList<>(fetchedEntities);
+        Set<Entity> fetchedEntities = service.findAllByIdIn(Sets.newHashSet(entity1.getId(), entity2.getId()));
 
-        assertNotNull(testEntities.getFirst());
-        assertNotNull(testEntities.getLast());
+        assertThat(fetchedEntities).hasSize(2);
+        assertThat(fetchedEntities).doesNotContainNull();
 
-        List<Long> fetchedIds = testEntities.stream().map(entity -> entity.getId()).collect(Collectors.toList());
+        List<Long> fetchedIds = fetchedEntities.stream().map(Entity::getId).collect(toList());
+        assertThat(fetchedIds).contains(entity1.getId(), entity2.getId());
 
-        assertTrue(fetchedIds.contains(persistedEntity.getId()));
-        assertTrue(fetchedIds.contains(persistedEntityOther.getId()));
-
-        assertNotNull(testEntities.getFirst().getEntityHistories());
-        assertNotNull(testEntities.getLast().getEntityHistories());
-
-        assertEquals(1, testEntities.getFirst().getEntityHistories().size());
-        assertEquals(1, testEntities.getLast().getEntityHistories().size());
+        LinkedList<SortedSet<EntityHistory>> fetchedHistories = fetchedEntities.stream().map(Entity::getEntityHistories)
+                .collect(toCollection(LinkedList::new));
 
+        assertThat(fetchedHistories.getFirst()).hasSize(1);
+        assertThat(fetchedHistories.getLast()).hasSize(1);
     }
 
     @Test
     public void shouldFetchEmptyListWhenTryingToFindAllNonExistingEntitiesById() {
-        long nonExistingId = 12345L;
-        long otherNonExistingId = 123456L;
-
-        Set<Entity> fetchedEntities = service.findAllByIdIn(Sets.newHashSet(nonExistingId, otherNonExistingId));
-
-        assertNotNull(fetchedEntities);
-        assertTrue(fetchedEntities.isEmpty());
-
+        Set<Entity> fetchedEntities = service.findAllByIdIn(Sets.newHashSet(12345L, 123456L));
+        assertThat(fetchedEntities).hasSize(0);
     }
 
     @Test(expected = IllegalArgumentException.class)
-    public void shouldThrowExceptionWhenGivenNullListOfIds() throws Exception {
+    public void shouldThrowExceptionWhenGivenNullListOfIds() {
         service.findAllByIdIn(null);
-
-        fail("This method, given the above input should throw exception, but it didn't!!");
     }
 
+    private void checkEntityHistory(Entity entity, long start, Long stop) {
+        assertThat(entity.getEntityHistories()).hasSize(1);
+        assertThat(entity.getEntityHistories().first().getValidFromStamp())
+                .isEqualTo(TimeUtils.getInstantFromNanos(start));
+        if (stop != null) {
+            assertThat(entity.getEntityHistories().first().getValidToStamp())
+                    .isEqualTo(TimeUtils.getInstantFromNanos(stop));
+        } else {
+            assertThat(entity.getEntityHistories().first().getValidToStamp()).isNull();
+        }
+    }
 }
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/InternalVariableServiceImplTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/InternalVariableServiceImplTest.java
index a8b47f0cda351e9c7b1c050a1ef7a40d2580d3bf..2df903974b3fe9356b9e2abc46ae9a04522552ab 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/InternalVariableServiceImplTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/internal/InternalVariableServiceImplTest.java
@@ -12,6 +12,7 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.annotation.Rollback;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.Instant;
 import java.time.LocalDateTime;
@@ -23,9 +24,7 @@ import java.util.TreeSet;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-/**
- * Created by ntsvetko on 1/16/17.
- */
+@Transactional(transactionManager = "jpaTransactionManager")
 public class InternalVariableServiceImplTest extends BaseTest {
 
     @Autowired
@@ -164,8 +163,9 @@ public class InternalVariableServiceImplTest extends BaseTest {
     @Test
     public void shouldReturnMatchedVariablesByName() {
         //given
-        String nameExpression = "R%";
-        Variable variable = createAndPersistVariable("REGEX", "DESC", Instant.now());
+        String nameExpression = "R%VARIABLE_THAT_WILL_NEVER%";
+        Variable variable = createAndPersistVariable("REGEX_VARIABLE_THAT_WILL_NEVER_BE_IN_DATABASE",
+                "DESC", Instant.now());
 
         //when
         final List<Variable> returnedVariables = internalVariableService.findByNameLike(nameExpression);
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/EntityHistoryRepositoryTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/EntityHistoryRepositoryTest.java
index 877d1e54add022db18fd4c5234ad13d964a27da4..1e414f6d3912b4fba5402f81ffc8a840ea10c36e 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/EntityHistoryRepositoryTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/EntityHistoryRepositoryTest.java
@@ -5,226 +5,142 @@ import cern.accsoft.nxcals.service.BaseTest;
 import cern.accsoft.nxcals.service.domain.Entity;
 import cern.accsoft.nxcals.service.domain.EntityHistory;
 import cern.accsoft.nxcals.service.domain.Partition;
-import cern.accsoft.nxcals.service.domain.Schema;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.annotation.Rollback;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.SortedSet;
+import javax.validation.ConstraintViolationException;
+import java.time.Instant;
+import java.util.Map;
+import java.util.Optional;
+
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES_JSON;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_2;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_STRING_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_STRING_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_2;
+import static org.assertj.core.api.Assertions.assertThat;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-/**
- * Created by jwozniak on 14/02/17.
- */
 @Transactional(transactionManager = "jpaTransactionManager")
 public class EntityHistoryRepositoryTest extends BaseTest {
 
     @Autowired
     private EntityHistoryRepository entityHistoryRepository;
 
-    private Entity createEntityWithHistory() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Schema schema = this.createAndPersistSchema(TEST_SCHEMA_CONTENT);
-        Entity key = this.createAndPersistEntity(schema, part, TEST_KEY_VALUE);
-
-        createAndPersistEntityHistory(key, key.getPartition(),
-                createAndPersistSchema( TEST_SCHEMA_CONTENT + "1"),
-                TEST_RECORD_TIME + 100, TEST_RECORD_TIME + 200);
-        createAndPersistEntityHistory(key, key.getPartition(),
-                createAndPersistSchema(TEST_SCHEMA_CONTENT + "2"),
-                TEST_RECORD_TIME + 200, TEST_RECORD_TIME + 300);
-        createAndPersistEntityHistory(key, key.getPartition(),
-                createAndPersistSchema(TEST_SCHEMA_CONTENT + "3"),
-                TEST_RECORD_TIME + 300, TEST_RECORD_TIME + 400);
-        createAndPersistEntityHistory(key, key.getPartition(),
-                createAndPersistSchema(TEST_SCHEMA_CONTENT + "4"),
-                TEST_RECORD_TIME + 400, TEST_RECORD_TIME + 500);
-        createAndPersistEntityHistory(key, key.getPartition(),
-                createAndPersistSchema(TEST_SCHEMA_CONTENT + "5"),
-                TEST_RECORD_TIME + 500, null);
-        return key;
-    }
-
-    @Test
+    @Test(expected = ConstraintViolationException.class)
     @Rollback
-    public void shouldFindByEntityAndTimestamp() throws Exception {
-        Entity key = createEntityWithHistory();
-
-        EntityHistory entityHistory = entityHistoryRepository
-                .findByEntityAndTimestamp(key, TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 110))
-                .orElseThrow(() -> new IllegalStateException("Should find history"));
-
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 100), entityHistory.getValidFromStamp());
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 200), entityHistory.getValidToStamp());
-
+    public void shouldNotCreateHistoryWithoutPartition() {
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        createAndPersistEntityHistory(entity, null, entity.getSchema(), TEST_RECORD_TIME);
+        entityManager.flush();
     }
 
-    @Test
+    @Test(expected = ConstraintViolationException.class)
     @Rollback
-    public void shouldFindByEntityAndTimestampLatest() throws Exception {
-        Entity key = createEntityWithHistory();
-
-        EntityHistory entityHistory = entityHistoryRepository
-                .findByEntityAndTimestamp(key, TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 510))
-                .orElseThrow(() -> new IllegalStateException("Should find history"));
-
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 500), entityHistory.getValidFromStamp());
-        assertEquals(null, entityHistory.getValidToStamp());
-
+    public void shouldNotCreateHistoryWithoutSchema() {
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        createAndPersistEntityHistory(entity, entity.getPartition(), null, TEST_RECORD_TIME);
+        entityManager.flush();
     }
 
-    @Test
-    @Rollback
-    public void shouldFindByEntityIdForTimestampsWithinOneHistoryRecord() throws Exception {
-        Entity key = createEntityWithHistory();
-
-        SortedSet<EntityHistory> entityHistories = entityHistoryRepository
-                .findByEntityAndTimestamps(key, TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 110),
-                        TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 120));
-
-        assertEquals(1, entityHistories.size());
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 100),
-                entityHistories.first().getValidFromStamp());
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 200), entityHistories.first().getValidToStamp());
-
-    }
-
-    @Test
-    @Rollback
-    public void shouldFindByEntityIdForTimestampsAcrossHistoryRecords() throws Exception {
-        Entity key = createEntityWithHistory();
-
-        SortedSet<EntityHistory> entityHistories = entityHistoryRepository
-                .findByEntityAndTimestamps(key, TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 100),
-                        TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 350));
-
-        assertEquals(3, entityHistories.size());
-        EntityHistory[] entityHistsArr = entityHistories.toArray(new EntityHistory[0]);
-
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 300), entityHistsArr[0].getValidFromStamp());
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 400), entityHistsArr[0].getValidToStamp());
-
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 200), entityHistsArr[1].getValidFromStamp());
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 300), entityHistsArr[1].getValidToStamp());
-
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 100), entityHistsArr[2].getValidFromStamp());
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 200), entityHistsArr[2].getValidToStamp());
-
-    }
-
-    @Test
+    @Test(expected = NullPointerException.class)
     @Rollback
-    public void shouldFindByEntityIdForTimestampsWithinOneHistoryRecordExactValidFrom() throws Exception {
-        Entity key = createEntityWithHistory();
-
-        SortedSet<EntityHistory> entityHistories = entityHistoryRepository
-                .findByEntityAndTimestamps(key, TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 100),
-                        TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 199));
-
-        assertEquals(1, entityHistories.size());
-        EntityHistory[] entityHistsArr = entityHistories.toArray(new EntityHistory[0]);
-
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 100), entityHistsArr[0].getValidFromStamp());
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 200), entityHistsArr[0].getValidToStamp());
-
+    public void shouldNotCreateHistoryWithoutValidFromStamp() {
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        createAndPersistEntityHistory(entity, entity.getPartition(), entity.getSchema(), null);
+        entityManager.flush();
     }
 
     @Test
     @Rollback
-    public void shouldFindByEntityIdForTimestampsAcrossRecordExactValidTo() throws Exception {
-        Entity key = createEntityWithHistory();
-
-        SortedSet<EntityHistory> entityHistories = entityHistoryRepository
-                .findByEntityAndTimestamps(key, TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 100),
-                        TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 200));
-
-        assertEquals(2, entityHistories.size());
-        EntityHistory[] entityHistsArr = entityHistories.toArray(new EntityHistory[0]);
-
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 200), entityHistsArr[0].getValidFromStamp());
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 300), entityHistsArr[0].getValidToStamp());
-
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 100), entityHistsArr[1].getValidFromStamp());
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 200), entityHistsArr[1].getValidToStamp());
-
+    public void shouldCreateEntityHist() {
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        Long historyId = createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME).getId();
+        Optional<EntityHistory> optionalEntityHistory = entityHistoryRepository.findById(historyId);
+
+        assertThat(optionalEntityHistory).isPresent();
+        EntityHistory entityHistory = optionalEntityHistory.get();
+        assertThat(entityHistory.getEntity().getKeyValues()).isEqualTo(ENTITY_KEY_VALUES_JSON);
+        assertThat(entityHistory.getPartition().getKeyValues()).isEqualTo(PARTITION_KEY_VALUES_STRING_1);
+        assertThat(entityHistory.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_1.toString());
+        assertThat(entityHistory.getValidFromStamp()).isEqualTo(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME));
+        assertThat(entityHistory.getValidToStamp()).isNull();
     }
 
     @Test
     @Rollback
-    public void shouldFindByEntityIdForTimestampsAcrossHistoryRecords2() throws Exception {
-        Entity key = createEntityWithHistory();
-
-        SortedSet<EntityHistory> entityHistories = entityHistoryRepository
-                .findByEntityAndTimestamps(key, TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 100),
-                        TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 199));
-
-        assertEquals(1, entityHistories.size());
-        EntityHistory[] entityHistsArr = entityHistories.toArray(new EntityHistory[0]);
-
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 100), entityHistsArr[0].getValidFromStamp());
-        assertEquals(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 200), entityHistsArr[0].getValidToStamp());
-
+    public void shouldUpdateEntityHistPartition() {
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        EntityHistory entityHistory = createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
+        updateEntityHistoryPartition(entityHistory, TEST_NAME, PARTITION_KEY_VALUES_2, PARTITION_SCHEMA_2);
+
+        Optional<EntityHistory> optionalEntityHistory = entityHistoryRepository.findById(entityHistory.getId());
+
+        assertThat(optionalEntityHistory).isPresent();
+        EntityHistory foundEntityHistory = optionalEntityHistory.get();
+        assertThat(foundEntityHistory.getPartition().getSystem().getName()).isEqualTo(TEST_NAME);
+        assertThat(foundEntityHistory.getPartition().getKeyValues()).isEqualTo(PARTITION_KEY_VALUES_STRING_2);
+        assertThat(foundEntityHistory.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_1.toString());
+        assertThat(foundEntityHistory.getValidFromStamp()).isEqualTo(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME));
+        assertThat(foundEntityHistory.getValidToStamp()).isNull();
     }
 
     @Test
     @Rollback
-    public void shouldFindByEntityIdForTimestampsAfterNewestRecord() throws Exception {
-        Entity key = createEntityWithHistory();
-
-        SortedSet<EntityHistory> entityHistories = entityHistoryRepository
-                .findByEntityAndTimestamps(key, TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 510),
-                        TimeUtils.getInstantFromNanos(TEST_RECORD_TIME + 520));
-
-        assertEquals(1, entityHistories.size());
-
+    public void shouldUpdateEntityHistSchema() {
+        Entity entity = createAndPersistEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        EntityHistory entityHistory = createAndPersistEntityHist(entity, entity.getPartition(), entity.getSchema(), TEST_RECORD_TIME);
+        updateEntityHistorySchema(entityHistory, ENTITY_SCHEMA_2);
+
+        Optional<EntityHistory> optionalEntityHistory = entityHistoryRepository.findById(entityHistory.getId());
+
+        assertThat(optionalEntityHistory).isPresent();
+        EntityHistory foundEntityHistory = optionalEntityHistory.get();
+        assertThat(foundEntityHistory.getPartition().getSystem().getName()).isEqualTo(TEST_NAME);
+        assertThat(foundEntityHistory.getPartition().getKeyValues()).isEqualTo(PARTITION_KEY_VALUES_STRING_1);
+        assertThat(foundEntityHistory.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_2.toString());
+        assertThat(foundEntityHistory.getValidFromStamp()).isEqualTo(TimeUtils.getInstantFromNanos(TEST_RECORD_TIME));
+        assertThat(foundEntityHistory.getValidToStamp()).isNull();
     }
 
     @Test
     @Rollback
-    public void shouldNotFindByEntityIdForTimestampsBeforeOldestRecord() throws Exception {
-        Entity key = createEntityWithHistory();
-
-        SortedSet<EntityHistory> entityHistories = entityHistoryRepository
-                .findByEntityAndTimestamps(key, TimeUtils.getInstantFromNanos(TEST_RECORD_TIME - 100),
-                        TimeUtils.getInstantFromNanos(TEST_RECORD_TIME - 50));
-
-        assertEquals(0, entityHistories.size());
-
+    public void shouldUpdateEntityHistTimes() {
+        EntityHistory entityHistory = createAndPersistDefaultTestEntityKeyHist();
+        Instant testTime = TimeUtils.getInstantFromNanos(TEST_RECORD_TIME).plusSeconds(10);
+        entityHistory.setValidFromStamp(testTime);
+        entityHistory.setValidToStamp(testTime);
+        entityHistoryRepository.save(entityHistory);
+
+        Optional<EntityHistory> optionalUpdatedHistory = entityHistoryRepository.findById(entityHistory.getId());
+
+        assertThat(optionalUpdatedHistory).isPresent();
+        EntityHistory foundEntityHistory = optionalUpdatedHistory.get();
+        assertThat(foundEntityHistory.getPartition().getSystem().getName()).isEqualTo(TEST_NAME);
+        assertThat(foundEntityHistory.getPartition().getKeyValues()).isEqualTo(PARTITION_KEY_VALUES_STRING_1);
+        assertThat(foundEntityHistory.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_1.toString());
+        assertThat(foundEntityHistory.getValidFromStamp()).isEqualTo(testTime);
+        assertThat(foundEntityHistory.getValidToStamp()).isEqualTo(testTime);
     }
 
-    @Test
-    @Rollback
-    public void shouldFindByEntityIdAndValidToStampNull() throws Exception {
-        Entity key = createAndSaveDefaultTestEntityKey();
-        EntityHistory entityHistory = entityHistoryRepository.findByEntityAndValidToStamp(key, null)
-                .orElseThrow(() -> new RuntimeException("EntityHistory not found"));
+    private void updateEntityHistorySchema(EntityHistory entityHistory, org.apache.avro.Schema newSchemaContent) {
+        cern.accsoft.nxcals.service.domain.Schema newSchema = createSchema(newSchemaContent);
+        schemaRepository.save(newSchema);
+        entityHistory.setSchema(newSchema);
+        entityHistRepository.save(entityHistory);
     }
 
-
-
-    @Test
-    @Rollback
-    public void shouldFindAllFirstEntriesByEntityIdIn() throws Exception {
-        Entity key1 = createAndSaveDefaultTestEntityKeyWithRandomSchemaContent();
-        Entity key2 = createAndSaveDefaultTestEntityKeyWithRandomSchemaContent();
-
-        Set<Entity> entities = new HashSet<>(Arrays.asList(key1, key2));
-
-        Set<EntityHistory> fetchedFirstEntries = entityHistoryRepository.findAllFirstEntriesByEntityIn(entities);
-        assertNotNull(fetchedFirstEntries);
-        assertEquals(2, fetchedFirstEntries.size());
-        for (EntityHistory entiryHistory : fetchedFirstEntries) {
-            assertEquals(TEST_RECORD_TIME, TimeUtils.getNanosFromInstant(entiryHistory.getValidFromStamp()));
-            assertNull(entiryHistory.getValidToStamp());
-        }
-
+    private void updateEntityHistoryPartition(EntityHistory entityHistory, String systemName,
+            Map<String, Object> partitionKeyValues, org.apache.avro.Schema partitionSchema) {
+        Partition newPartition = createPartition(systemName, partitionKeyValues, partitionSchema);
+        partitionRepository.save(newPartition);
+        entityHistory.setPartition(newPartition);
+        entityHistRepository.save(entityHistory);
     }
-
 }
\ No newline at end of file
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/EntityRepositoryTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/EntityRepositoryTest.java
index f2c13ac2e4819ad777514c4b2c02de4f8d08586d..38d6bc8dfd2b4ec8a5309f4e89db14cf04e397ee 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/EntityRepositoryTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/EntityRepositoryTest.java
@@ -6,121 +6,247 @@ package cern.accsoft.nxcals.service.repository;
 
 import cern.accsoft.nxcals.service.BaseTest;
 import cern.accsoft.nxcals.service.domain.Entity;
-import org.hamcrest.Matchers;
-import org.junit.Assert;
+import cern.accsoft.nxcals.service.domain.Partition;
+import cern.accsoft.nxcals.service.domain.Schema;
+import org.junit.Before;
 import org.junit.Test;
 import org.springframework.test.annotation.Rollback;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.validation.ConstraintViolationException;
 import java.time.Instant;
 import java.time.temporal.ChronoUnit;
 import java.util.List;
 import java.util.Optional;
 
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES_JSON;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_2;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_JSON_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_STRING_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_2;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 
 @Transactional(transactionManager = "jpaTransactionManager")
 public class EntityRepositoryTest extends BaseTest {
 
-    @SuppressWarnings("unused")
+    private Entity newEntity;
+
+    @Before
+    public void setUp() {
+        newEntity = createEntity(TEST_NAME, ENTITY_KEY_VALUES, ENTITY_SCHEMA_1, PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    @Rollback
+    public void shouldNotCreateEntityWithoutKeyValues() {
+        newEntity.setKeyValues(null);
+        persistEntity(newEntity);
+        entityManager.flush();
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    @Rollback
+    public void shouldNotCreateEntityWithoutSchema() {
+        newEntity.setSchema(null);
+        persistEntity(newEntity);
+        entityManager.flush();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    @Rollback
+    public void shouldNotCreateEntityWithoutPartition() {
+        newEntity.setPartition(null);
+        entityRepository.save(newEntity);
+        entityManager.flush();
+    }
+    @Test
+    @Rollback
+    public void shouldCreateEntity() {
+        persistEntity(newEntity);
+        Entity savedEntity = entityRepository.save(newEntity);
+        assertThat(savedEntity).isNotNull();
+        assertThat(savedEntity.getKeyValues()).isEqualTo(ENTITY_KEY_VALUES_JSON);
+        assertThat(savedEntity.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_1.toString());
+        assertThat(savedEntity.getPartition().getKeyValues()).isEqualTo(PARTITION_KEY_VALUES_JSON_1);
+    }
+
+    @Test
+    @Rollback
+    public void shouldChangeEntitySchema() {
+        persistEntity(newEntity);
+        Schema newSchema = createSchema(ENTITY_SCHEMA_2);
+        schemaRepository.save(newSchema);
+        newEntity.setSchema(newSchema);
+        entityRepository.save(newEntity);
+        entityManager.flush();
+
+        Optional<Entity> optionalEntity = entityRepository.findById(newEntity.getId());
+
+        assertThat(optionalEntity).isPresent();
+        assertThat(optionalEntity.get().getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_2.toString());
+    }
+
+    @Test
+    @Rollback
+    public void shouldChangeEntityPartition() {
+        persistEntity(newEntity);
+        Partition newPartition = createPartition(TEST_NAME, PARTITION_KEY_VALUES_2, PARTITION_SCHEMA_2);
+        partitionRepository.save(newPartition);
+        newEntity.setPartition(newPartition);
+        entityRepository.save(newEntity);
+        entityManager.flush();
+
+        Optional<Entity> optionalEntity = entityRepository.findById(newEntity.getId());
+
+        assertThat(optionalEntity).isPresent();
+        assertThat(optionalEntity.get().getPartition().getKeyValues()).isEqualTo(PARTITION_KEY_VALUES_STRING_2);
+    }
+
+    //TODO Check why this test fails
+    /*@Test
+    @Rollback
+    public void shouldChangeEntityKeyValues() {
+        persistEntity(newEntity);
+        newEntity.setKeyValues(getKeyValuesString("Test"));
+        entityRepository.save(newEntity);
+
+        Optional<Entity> optionalEntity = entityRepository.findById(newEntity.getId());
+
+        assertThat(optionalEntity).isPresent();
+        Entity foundEntity = optionalEntity.get();
+
+        assertThat(foundEntity.getKeyValues()).isEqualTo(getKeyValuesString("Test"));
+        assertThat(foundEntity.getSchema().getContent()).isEqualTo(getSchema());
+        assertThat(foundEntity.getPartition().getKeyValues()).isEqualTo(getKeyValuesString());
+        assertThat(foundEntity.getPartition().getSystem().getName()).isEqualTo(TEST_NAME);
+    }*/
+
+    @Test
+    @Rollback
+    public void shouldChangeEntityLockedUntilStamp() {
+        persistEntity(newEntity);
+
+        Instant lockUntilStamp = Instant.now().plus(2, ChronoUnit.HOURS);
+        newEntity.setLockedUntilStamp(lockUntilStamp);
+        entityRepository.save(newEntity);
+
+        Optional<Entity> optionalEntity = entityRepository.findById(newEntity.getId());
+
+        assertThat(optionalEntity).isPresent();
+
+        Entity foundEntity = optionalEntity.get();
+
+        assertThat(foundEntity.getLockedUntilStamp()).isEqualTo(lockUntilStamp);
+        assertThat(foundEntity.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_1.toString());
+        assertThat(foundEntity.getPartition().getKeyValues()).isEqualTo(PARTITION_KEY_VALUES_JSON_1);
+        assertThat(foundEntity.getPartition().getSystem().getName()).isEqualTo(TEST_NAME);
+    }
+
     @Test
     @Rollback
     public void shouldNotFindResult() {
-        Entity key = createAndSaveDefaultTestEntityKey();
+        persistEntity(newEntity);
 
-        Optional<Entity> foundKey = entityRepository.findByPartitionSystemIdAndKeyValues(-1, TEST_KEY_VALUE);
+        Optional<Entity> entity = entityRepository.findByPartitionSystemIdAndKeyValues(-1, ENTITY_KEY_VALUES_JSON);
 
-        assertFalse(foundKey.isPresent());
+        assertThat(entity).isEmpty();
     }
 
     @Test
     @Rollback
     public void shouldNotFindResultWhileQueryingWithRegex() {
-        Entity entity = createAndSaveDefaultTestEntityKey();
+        persistEntity(newEntity);
 
-        List<Entity> foundEntities = entityRepository.findByKeyValuesLike("__est%");
+        List<Entity> foundEntities = entityRepository.findByKeyValuesLike("%rsdfin%");
 
-        assertThat(foundEntities).hasSize(0);
+        assertThat(foundEntities).isEmpty();
     }
 
     @Test
     @Rollback
     public void shouldFindEntitiesWhileQueryingWithRegex() {
-        Entity entity = createAndSaveDefaultTestEntityKey();
+        persistEntity(newEntity);
 
-        List<Entity> foundEntities = entityRepository.findByKeyValuesLike("%Test%");
+        List<Entity> foundEntities = entityRepository.findByKeyValuesLike("%trin%");
 
-        assertThat(foundEntities).containsExactly(entity);
+        assertThat(foundEntities).containsExactly(newEntity);
     }
 
     @Test
     @Rollback
-    public void shouldGetKeyForSystemAndKeyValues() {
-        Entity key = createAndSaveDefaultTestEntityKey();
+    public void shouldGetEntityForSystemAndKeyValues() {
+        persistEntity(newEntity);
+        createAndPersistEntityHist(newEntity, newEntity.getPartition(), newEntity.getSchema(), TEST_RECORD_TIME);
+
+        Long systemId = newEntity.getPartition().getSystem().getId();
+        Optional<Entity> optionalEntity = entityRepository.findByPartitionSystemIdAndKeyValues(systemId, ENTITY_KEY_VALUES_JSON);
 
-        Long systemId = key.getPartition().getSystem().getId();
-        Entity foundKey = entityRepository.findByPartitionSystemIdAndKeyValues(systemId, TEST_KEY_VALUE).get();
+        assertThat(optionalEntity).isPresent();
 
-        Assert.assertThat(foundKey.getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        Assert.assertThat(foundKey.getSchema().getContent(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
-        Assert.assertThat(foundKey.getPartition().getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
-        Assert.assertThat(foundKey.getPartition().getSystem().getName(), Matchers.equalTo(TEST_NAME));
+        Entity foundEntity = optionalEntity.get();
 
-        System.err.println("$$$$$$$$$$$$$$$$$$$$$$$");
-        Assert.assertEquals(1, foundKey.getEntityHistories().size());
+        assertThat(foundEntity.getKeyValues()).isEqualTo(ENTITY_KEY_VALUES_JSON);
+        assertThat(foundEntity.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_1.toString());
+        assertThat(foundEntity.getPartition().getKeyValues()).isEqualTo(PARTITION_KEY_VALUES_JSON_1);
+        assertThat(foundEntity.getPartition().getSystem().getName()).isEqualTo(TEST_NAME);
+
+        assertThat(foundEntity.getEntityHistories()).hasSize(1);
     }
 
     @Test
     @Rollback
     public void shouldCountOneEntityWithLockUntilStampGreaterThanProvided() {
-        Entity persistedEntity = createAndSaveDefaultTestEntityKey();
+        persistEntity(newEntity);
 
-        Long partitionId = persistedEntity.getPartition().getId();
-        Long systemId = persistedEntity.getPartition().getSystem().getId();
+        Long partitionId = newEntity.getPartition().getId();
+        Long systemId = newEntity.getPartition().getSystem().getId();
         Instant lockedUntilStamp = Instant.now().plus(4, ChronoUnit.HOURS);
 
-        persistedEntity.setLockedUntilStamp(lockedUntilStamp);
+        newEntity.setLockedUntilStamp(lockedUntilStamp);
 
-        Entity lockedEntity = entityRepository.save(persistedEntity);
+        entityRepository.save(newEntity);
 
         Instant appliedActionOnEntityStamp = Instant.now();
 
-        long lockedEntituesNum = entityRepository
+        long lockedEntitiesNum = entityRepository
                 .countByPartitionSystemIdAndPartitionIdAndLockedUntilStampGreaterThanEqual(
                         systemId, partitionId, appliedActionOnEntityStamp);
-        assertEquals(1L, lockedEntituesNum);
+        assertThat(lockedEntitiesNum).isOne();
     }
 
     @Test
     @Rollback
     public void shouldCountOneEntityWithLockUntilStampEqualWithProvided() {
-        Entity persistedEntity = createAndSaveDefaultTestEntityKey();
+        persistEntity(newEntity);
 
-        Long partitionId = persistedEntity.getPartition().getId();
-        Long systemId = persistedEntity.getPartition().getSystem().getId();
+        Long partitionId = newEntity.getPartition().getId();
+        Long systemId = newEntity.getPartition().getSystem().getId();
         Instant lockedUntilStamp = Instant.now().plus(4, ChronoUnit.HOURS);
 
-        persistedEntity.setLockedUntilStamp(lockedUntilStamp);
+        newEntity.setLockedUntilStamp(lockedUntilStamp);
 
         Instant appliedActionOnEntityStamp = lockedUntilStamp;
 
-        Entity lockedEntity = entityRepository.save(persistedEntity);
+        entityRepository.save(newEntity);
 
-        long lockedEntituesNum = entityRepository
+        long lockedEntitiesNum = entityRepository
                 .countByPartitionSystemIdAndPartitionIdAndLockedUntilStampGreaterThanEqual(
                         systemId, partitionId, appliedActionOnEntityStamp);
-        assertEquals(1L, lockedEntituesNum);
+        assertThat(lockedEntitiesNum).isOne();
     }
 
     @Test
     @Rollback
     public void shouldCountZeroEntitiesWithLockUntilStampGreaterOrEqualThanProvided() {
-        Entity persistedEntity = createAndSaveDefaultTestEntityKey();
+        persistEntity(newEntity);
 
-        Long partitionId = persistedEntity.getPartition().getId();
-        Long systemId = persistedEntity.getPartition().getSystem().getId();
+        Long partitionId = newEntity.getPartition().getId();
+        Long systemId = newEntity.getPartition().getSystem().getId();
 
         /**
          * Old time to ensure that no entity is locked for that timestamp and before
@@ -128,10 +254,28 @@ public class EntityRepositoryTest extends BaseTest {
          */
         Instant appliedActionOnEntityStamp = Instant.now().plus(300, ChronoUnit.DAYS);
 
-        long lockedEntituesNum = entityRepository
+        long lockedEntitiesNum = entityRepository
                 .countByPartitionSystemIdAndPartitionIdAndLockedUntilStampGreaterThanEqual(
                         systemId, partitionId, appliedActionOnEntityStamp);
-        assertEquals(0, lockedEntituesNum);
+        assertThat(lockedEntitiesNum).isZero();
     }
 
+    @Test
+    @Rollback
+    public void shouldWriteEntityLockedUntilStampAsNull() {
+        persistEntity(newEntity);
+        newEntity.setLockedUntilStamp(null);
+        entityRepository.save(newEntity);
+
+        Optional<Entity> optionalEntity = entityRepository.findById(newEntity.getId());
+
+        assertThat(optionalEntity).isPresent();
+
+        Entity foundEntity = optionalEntity.get();
+
+        assertThat(foundEntity.getLockedUntilStamp()).isNull();
+        assertThat(foundEntity.getSchema().getContent()).isEqualTo(ENTITY_SCHEMA_1.toString());
+        assertThat(foundEntity.getPartition().getKeyValues()).isEqualTo(PARTITION_KEY_VALUES_JSON_1);
+        assertThat(foundEntity.getPartition().getSystem().getName()).isEqualTo(TEST_NAME);
+    }
 }
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/PartitionRepositoryTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/PartitionRepositoryTest.java
index 884c0c672990c38f190d04cc3b01493209ad8558..d26348cbebfbc53ea15281bf50e1b929cd10080f 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/PartitionRepositoryTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/PartitionRepositoryTest.java
@@ -6,38 +6,78 @@ package cern.accsoft.nxcals.service.repository;
 
 import cern.accsoft.nxcals.service.BaseTest;
 import cern.accsoft.nxcals.service.domain.Partition;
-import org.hamcrest.Matchers;
+import cern.accsoft.nxcals.service.domain.System;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
 import org.springframework.test.annotation.Rollback;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.validation.ConstraintViolationException;
 import java.util.Optional;
 
-import static org.junit.Assert.assertFalse;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_JSON_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_STRING_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_1;
+import static org.assertj.core.api.Assertions.assertThat;
 
 @Transactional(transactionManager = "jpaTransactionManager")
 public class PartitionRepositoryTest extends BaseTest {
 
+    private Partition newPartition;
+
+    @Before
+    public void setUp() {
+        newPartition = createPartition(TEST_NAME, PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+    }
+
     @Test
-    @SuppressWarnings("unused")
     @Rollback
     public void shouldNotFindPartition() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
+        Optional<Partition> foundPartition = partitionRepository.findBySystemIdAndKeyValues(-1, PARTITION_KEY_VALUES_STRING_1);
+        assertThat(foundPartition).isNotPresent();
+    }
+
+    @Test
+    @Rollback
+    public void shouldGetPartitionForSystemAndKeyValues() {
+        partitionRepository.save(newPartition);
+        Long systemId = newPartition.getSystem().getId();
+
+        Partition foundPartition = partitionRepository.findBySystemIdAndKeyValues(systemId, PARTITION_KEY_VALUES_STRING_1).get();
 
-        Optional<Partition> foundPart = this.partitionRepository.findBySystemIdAndKeyValues(-1, TEST_KEY_VALUE);
-        assertFalse(foundPart.isPresent());
+        assertThat(foundPartition.getSystem().getName()).isEqualTo(TEST_NAME);
+        assertThat(foundPartition.getKeyValues()).isEqualTo(PARTITION_KEY_VALUES_STRING_1);
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    @Rollback
+    public void shouldNotCreatePartitionWithoutSystem() {
+        partitionRepository.save(createPartition((System) null, PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1));
+        entityManager.flush();
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    @Rollback
+    public void shouldNotCreatePartitionWithoutKeyValues() {
+        partitionRepository.save(createPartition(TEST_NAME, null, null));
+        entityManager.flush();
     }
 
     @Test
     @Rollback
-    public void shouldGetPartitionForSystemAndHash() {
-        Partition part = this.createAndPersistPartitionKey(TEST_NAME, TEST_KEY_VALUE);
-        Long systemId = part.getSystem().getId();
+    public void shouldCreatePartitionKey() {
+        Partition partition = createPartition(TEST_NAME, PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1);
+        Long partitionId = partitionRepository.save(partition).getId();
+
+        Optional<Partition> optionalPartition = partitionRepository.findById(partitionId);
+
+        assertThat(optionalPartition).isPresent();
 
-        Partition foundPart = this.partitionRepository.findBySystemIdAndKeyValues(systemId, TEST_KEY_VALUE).get();
-        Assert.assertThat(foundPart.getSystem().getName(), Matchers.equalTo(TEST_NAME));
-        Assert.assertThat(foundPart.getKeyValues(), Matchers.equalTo(TEST_KEY_VALUE));
+        Partition foundPartition = optionalPartition.get();
 
+        assertThat(foundPartition.getKeyValues()).isEqualTo(PARTITION_KEY_VALUES_JSON_1);
+        assertThat(foundPartition.getSystem().getName()).isEqualTo(TEST_NAME);
     }
-}
+}
\ No newline at end of file
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/SchemaRepositoryTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/SchemaRepositoryTest.java
index 3ab5ca65599651dbffc70c629bf925493a556713..98c1b497cf320fc2db55189fe1d857d629b37c70 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/SchemaRepositoryTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/SchemaRepositoryTest.java
@@ -10,9 +10,11 @@ import org.junit.Test;
 import org.springframework.test.annotation.Rollback;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.validation.ConstraintViolationException;
 import java.util.Optional;
 
-import static org.junit.Assert.assertFalse;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_1;
+import static org.assertj.core.api.Assertions.*;
 
 @Transactional(transactionManager = "jpaTransactionManager")
 public class SchemaRepositoryTest extends BaseTest {
@@ -20,8 +22,30 @@ public class SchemaRepositoryTest extends BaseTest {
     @Test
     @Rollback
     public void shouldNotFindSchemaWrongId() {
-        Optional<Schema> foundSchema = this.schemaRepository.findById(-1L);
-        assertFalse(foundSchema.isPresent());
+        Optional<Schema> optionalSchema = schemaRepository.findById(-1L);
+        assertThat(optionalSchema).isNotPresent();
     }
 
+    @Test(expected = ConstraintViolationException.class)
+    @Rollback
+    public void shouldNotCreateSchemaWithoutContent() {
+        Schema schema = createSchema(null);
+        schemaRepository.save(schema);
+        entityManager.flush();
+    }
+
+    @Test
+    @Rollback
+    public void shouldCreateSchema() {
+        Schema newSchema = createSchema(ENTITY_SCHEMA_1);
+        schemaRepository.save(newSchema);
+
+        Optional<Schema> optionalSchema = schemaRepository.findById(newSchema.getId());
+
+        assertThat(optionalSchema).isPresent();
+
+        Schema foundSchema = optionalSchema.get();
+
+        assertThat(foundSchema.getContent()).isEqualTo(ENTITY_SCHEMA_1.toString());
+    }
 }
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/SystemRepositoryTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/SystemRepositoryTest.java
index fa4c854f32cba67f80bf90bf690fa2a0431c908a..a2835482bc9bf61dc7202981811d3d2a2bae8c43 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/SystemRepositoryTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/repository/SystemRepositoryTest.java
@@ -6,38 +6,88 @@ package cern.accsoft.nxcals.service.repository;
 
 import cern.accsoft.nxcals.service.BaseTest;
 import cern.accsoft.nxcals.service.domain.System;
-import org.hamcrest.Matchers;
-import org.junit.Assert;
 import org.junit.Test;
 import org.springframework.test.annotation.Rollback;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.validation.ConstraintViolationException;
 import java.util.Optional;
 
-import static org.junit.Assert.assertFalse;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.TIME_SCHEMA;
+import static org.assertj.core.api.Assertions.assertThat;
 
-@SuppressWarnings("unused")
 @Transactional(transactionManager = "jpaTransactionManager")
 public class SystemRepositoryTest extends BaseTest {
 
     @Test
     @Rollback
-    public void shouldNotFindIdForSystem() {
-        System system = this.createAndPersistClientSystem(TEST_NAME);
+    public void shouldNotFindSystemWIthWrongName() {
+        createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA);
 
-        Optional<System> foundSys = this.systemRepository.findByName("");
-        assertFalse(foundSys.isPresent());
+        Optional<System> foundSystem = systemRepository.findByName("");
+        assertThat(foundSystem).isNotPresent();
     }
 
     @Test
     @Rollback
-    public void shouldGetIdForSystem() {
-        System system = this.createAndPersistClientSystem(TEST_NAME);
-        Long systemId = system.getId();
+    public void shouldFindSystemWithCorrectName() {
+        Long id = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA).getId();
 
-        System foundSys = this.systemRepository.findByName(TEST_NAME).get();
+        Optional<System> optionalSystem = systemRepository.findByName(TEST_NAME);
 
-        Assert.assertThat(foundSys.getId(), Matchers.equalTo(systemId));
-        Assert.assertThat(system.getEntityKeyDefs(), Matchers.equalTo(TEST_SCHEMA_CONTENT));
+        assertThat(optionalSystem).isPresent();
+
+        System foundSystem = optionalSystem.get();
+
+        assertThat(foundSystem.getId()).isEqualTo(id);
+        assertThat(foundSystem.getEntityKeyDefs()).isEqualTo(ENTITY_SCHEMA_1.toString());
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    @Rollback
+    public void shouldNotCreateSystemWithoutName() {
+        createAndPersistClientSystem(null, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA);
+        entityManager.flush();
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    @Rollback
+    public void shouldNotCreateSystemWithoutKeyDefinitions() {
+        createAndPersistClientSystem(TEST_NAME, null, PARTITION_SCHEMA_1, TIME_SCHEMA);
+        entityManager.flush();
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    @Rollback
+    public void shouldNotCreateSystemWithoutPartitionDefinitions() {
+        createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, null, TIME_SCHEMA);
+        entityManager.flush();
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    @Rollback
+    public void shouldNotCreateSystemWithoutTimeDefinitions() {
+        createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, null);
+        entityManager.flush();
+    }
+
+    @Test
+    @Rollback
+    public void shouldCreateClientSystem() {
+
+        Long id = createAndPersistClientSystem(TEST_NAME, ENTITY_SCHEMA_1, PARTITION_SCHEMA_1, TIME_SCHEMA).getId();
+
+        Optional<System> optionalSystem = systemRepository.findById(id);
+
+        assertThat(optionalSystem).isPresent();
+
+        System foundSystem = optionalSystem.get();
+
+        assertThat(foundSystem.getName()).isEqualTo(TEST_NAME);
+        assertThat(foundSystem.getEntityKeyDefs()).isEqualTo(ENTITY_SCHEMA_1.toString());
+        assertThat(foundSystem.getPartitionKeyDefs()).isEqualTo(PARTITION_SCHEMA_1.toString());
+        assertThat(foundSystem.getTimeKeyDefs()).isEqualTo(TIME_SCHEMA.toString());
     }
 }
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/ControllerTestUtils.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/ControllerTestUtils.java
deleted file mode 100644
index a432c5f545cb38084ffe8db96ffa43672ab09488..0000000000000000000000000000000000000000
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/ControllerTestUtils.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package cern.accsoft.nxcals.service.rest;
-
-import cern.accsoft.nxcals.common.domain.PartitionData;
-import cern.accsoft.nxcals.common.domain.SchemaData;
-import cern.accsoft.nxcals.common.domain.SystemData;
-import cern.accsoft.nxcals.common.domain.VariableConfigData;
-import cern.accsoft.nxcals.common.domain.VariableData;
-import cern.accsoft.nxcals.common.domain.impl.EntityDataImpl;
-import cern.accsoft.nxcals.common.domain.impl.PartitionDataImpl;
-import cern.accsoft.nxcals.common.domain.impl.SchemaDataImpl;
-import cern.accsoft.nxcals.common.domain.impl.SystemDataImpl;
-import cern.accsoft.nxcals.common.domain.impl.VariableConfigDataImpl;
-import cern.accsoft.nxcals.common.domain.impl.VariableDataImpl;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.collect.Sets;
-
-import java.util.Collections;
-
-import static cern.accsoft.nxcals.service.BaseTest.SYSTEM_NAME;
-import static cern.accsoft.nxcals.service.BaseTest.SYSTEM_NAME2;
-
-class ControllerTestUtils {
-
-    static final String FIND_OR_CREATE_ENDPOINT = "/entities/search/findOrCreateEntityFor?"
-            + "systemId=%s&entityKeyValues=%s&partitionKeyValues=%s&recordTimestamp=%s";
-    static final String FIND_OR_CREATE_ENDPOINT_BY_IDS = "/entities/search/findOrCreateEntityForIds?"
-            + "systemId=%s&entityId=%s&partitionId=%s&recordTimestamp=%s";
-    static final String UPDATE_ENTITIES = "/entities/update";
-    static final String EXTEND_ENTITY_FIRST_HISTORY_DATA_FOR = "/entities/search/extendEntityFirstHistoryDataFor?entityId=%s&from=%s";
-
-    static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
-    static final String TEST_REGEX = "TEST_REGEX";
-
-    static final String TEST_MESSAGE = "TEST_MESSAGE";
-    static final long TIMESTAMP = 1;
-
-    static final long SYSTEM_ID = 10;
-    static final long SYSTEM_ID2 = 20;
-    static final long PARTITION_ID = 20;
-    static final String PARTITION_KEY_VALUES = "PARTITION_KEY_VALUES";
-    static final PartitionData PARTITION_DATA = new PartitionDataImpl(PARTITION_ID, PARTITION_KEY_VALUES);
-    static final String SCHEMA_VALUE = "SCHEMA_VALUE";
-    static final long ENTITY_ID = 40;
-    static final long ENTITY_ID2 = 80;
-    static final String KEY_VALUES = "KEY_VALUES";
-    static final String NEW_KEY_VALUES = "NEW_KEY_VALUES";
-
-    static final Long NEW_LOCK_UNTIL_STAMP = 1511278189185000000L;
-
-    static final String EMPTY_JSON_ARRAY = "[]";
-
-    static final long SCHEMA_ID = 30;
-    static final SchemaData SCHEMA_DATA = new SchemaDataImpl(SCHEMA_ID, SCHEMA_VALUE);
-
-    private static final String SYSTEM_ENTITY_KEY_DEFINITIONS = "SYSTEM_ENTITY_KEY_DEFINITIONS";
-    private static final String SYSTEM_PARTITION_KEY_DEFINITIONS = "SYSTEM_PARTITION_KEY_DEFINITIONS";
-    private static final String SYSTEM_TIME_KEY_DEFINITIONS = "SYSTEM_TIME_KEY_DEFINITIONS";
-    private static final String SYSTEM_RECORD_VERSION_KEY_DEFINITIONS = "SYSTEM_RECORD_VERSION_KEY_DEFINITIONS";
-
-    static final String VARIABLE_NAME = "VARIABLE_NAME";
-    static final String VARIABLE_DESCRIPTION = "VARIABLE_DESCRIPTION";
-    private static final String VARIABLE_CONFIG_FIELD_NAME = "VARIABLE_CONFIG_FIELD_NAME";
-    private static final VariableConfigData VARIABLE_CONFIG_DATA = new VariableConfigDataImpl(ENTITY_ID,
-            VARIABLE_CONFIG_FIELD_NAME, TIMESTAMP, TIMESTAMP);
-    static final VariableData VARIABLE_DATA = new VariableDataImpl(VARIABLE_NAME, VARIABLE_DESCRIPTION, TIMESTAMP,
-            Sets.newTreeSet(Collections.singletonList(VARIABLE_CONFIG_DATA)));
-
-    static final SystemData SYSTEM_DATA = new SystemDataImpl(SYSTEM_ID, SYSTEM_NAME,
-            SYSTEM_ENTITY_KEY_DEFINITIONS, SYSTEM_PARTITION_KEY_DEFINITIONS, SYSTEM_TIME_KEY_DEFINITIONS,
-            SYSTEM_RECORD_VERSION_KEY_DEFINITIONS);
-
-    private static final SystemData SYSTEM_DATA2 = new SystemDataImpl(SYSTEM_ID2, SYSTEM_NAME2,
-            SYSTEM_ENTITY_KEY_DEFINITIONS, SYSTEM_PARTITION_KEY_DEFINITIONS, SYSTEM_TIME_KEY_DEFINITIONS,
-            SYSTEM_RECORD_VERSION_KEY_DEFINITIONS);
-
-    private static final long REC_VERSION = 0L;
-    static final EntityDataImpl ENTITY_DATA = new EntityDataImpl(ENTITY_ID, KEY_VALUES, SYSTEM_DATA,
-            PARTITION_DATA, SCHEMA_DATA, Collections.emptySortedSet(), NEW_LOCK_UNTIL_STAMP, REC_VERSION);
-    private static final long REC_VERSION2 = 1L;
-    static final EntityDataImpl ENTITY_DATA2 = new EntityDataImpl(ENTITY_ID2, KEY_VALUES, SYSTEM_DATA2,
-            PARTITION_DATA, SCHEMA_DATA, Collections.emptySortedSet(), null, REC_VERSION2);
-    private static final long NEW_REC_VERSION = 1L;
-    static final EntityDataImpl NEW_ENTITY_DATA = new EntityDataImpl(ENTITY_ID, NEW_KEY_VALUES, SYSTEM_DATA,
-            PARTITION_DATA, SCHEMA_DATA, Collections.emptySortedSet(), NEW_LOCK_UNTIL_STAMP, NEW_REC_VERSION);
-
-    public static EntityDataImpl createDefaultEntityData(long entityId) {
-        return new EntityDataImpl(entityId, KEY_VALUES, SYSTEM_DATA,
-                PARTITION_DATA, SCHEMA_DATA, Collections.emptySortedSet(), null, REC_VERSION);
-    }
-}
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/DevProfileResolverTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/DevProfileResolverTest.java
index d69570b02eb41db0441af98c31c0667edbb12b87..5509e16b8bdff51bf45fe9e9c01db04008b3c3af 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/DevProfileResolverTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/DevProfileResolverTest.java
@@ -12,6 +12,7 @@ import org.mockito.Mock;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
 import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
 import org.springframework.test.context.ActiveProfiles;
@@ -24,15 +25,13 @@ import org.springframework.web.context.WebApplicationContext;
 
 import java.util.Optional;
 
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITIES;
 import static cern.accsoft.nxcals.service.BaseTest.TEST_NAME;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.ENTITY_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.FIND_OR_CREATE_ENDPOINT;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.KEY_VALUES;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.PARTITION_KEY_VALUES;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SCHEMA_VALUE;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SYSTEM_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.TIMESTAMP;
-import static java.lang.String.format;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.FIND_OR_CREATE_ENTITY_REQUEST_JSON;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TIMESTAMP;
+import static org.mockito.Matchers.anyMapOf;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isA;
 import static org.mockito.Mockito.when;
@@ -45,6 +44,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
 @TestPropertySource(locations = "classpath:application.properties")
 @ActiveProfiles("dev")
 public class DevProfileResolverTest {
+
     @MockBean
     private SystemRepository systemRepository;
 
@@ -66,8 +66,8 @@ public class DevProfileResolverTest {
     public void setup() {
         when(entity.getId()).thenReturn(ENTITY_ID);
 
-        when(internalEntityService.findOrCreateEntityFor(isA(Long.class), isA(String.class), isA(String.class),
-                isA(String.class), isA(Long.class))).thenReturn(entity);
+        when(internalEntityService.findOrCreateEntityFor(isA(Long.class), anyMapOf(String.class, Object.class),
+                anyMapOf(String.class, Object.class), isA(String.class), isA(Long.class))).thenReturn(entity);
 
         when(system.getName()).thenReturn(TEST_NAME);
 
@@ -81,8 +81,11 @@ public class DevProfileResolverTest {
     @Test
     @WithMockUser(authorities = "ALL")
     public void shouldAuthorizeWithDevProfileAndAllAuthority() throws Exception {
-        mockMvc.perform(put(format(FIND_OR_CREATE_ENDPOINT, SYSTEM_ID, KEY_VALUES, PARTITION_KEY_VALUES,
-                TIMESTAMP)).content(SCHEMA_VALUE))
+        mockMvc.perform(put(ENTITIES)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .param("recordTimestamp", String.valueOf(TIMESTAMP))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(FIND_OR_CREATE_ENTITY_REQUEST_JSON))
                 .andExpect(status().isOk());
     }
 }
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/DomainTestConstants.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/DomainTestConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..41aa07d08bd9898c3499dbcb0ee7e91bc2413ffa
--- /dev/null
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/DomainTestConstants.java
@@ -0,0 +1,108 @@
+package cern.accsoft.nxcals.service.rest;
+
+import cern.accsoft.nxcals.common.domain.impl.FindOrCreateEntityRequestImpl;
+import cern.accsoft.nxcals.common.domain.PartitionData;
+import cern.accsoft.nxcals.common.domain.SchemaData;
+import cern.accsoft.nxcals.common.domain.SystemData;
+import cern.accsoft.nxcals.common.domain.VariableConfigData;
+import cern.accsoft.nxcals.common.domain.VariableData;
+import cern.accsoft.nxcals.common.domain.impl.PartitionDataImpl;
+import cern.accsoft.nxcals.common.domain.impl.SchemaDataImpl;
+import cern.accsoft.nxcals.common.domain.impl.SystemDataImpl;
+import cern.accsoft.nxcals.common.domain.impl.VariableConfigDataImpl;
+import cern.accsoft.nxcals.common.domain.impl.VariableDataImpl;
+import cern.accsoft.nxcals.common.utils.KeyValuesUtils;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+
+import java.util.Collections;
+import java.util.Map;
+
+import static cern.accsoft.nxcals.common.utils.KeyValuesUtils.convertMapIntoAvroSchemaString;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_DOUBLE_SCHEMA_KEY_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_DOUBLE_SCHEMA_KEY_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_STRING_SCHEMA_KEY_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_STRING_SCHEMA_KEY_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_DOUBLE_SCHEMA_KEY_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_DOUBLE_SCHEMA_KEY_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_STRING_SCHEMA_KEY_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_STRING_SCHEMA_KEY_2;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.RECORD_VERSION_SCHEMA;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.TIME_SCHEMA;
+
+public class DomainTestConstants {
+
+    public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+    public static final long SYSTEM_ID = 10;
+    public static final String SYSTEM_NAME = "SYSTEM_NAME";
+    public static final String TEST_REGEX = "TEST_REGEX";
+    public static final String TEST_MESSAGE = "TEST_MESSAGE";
+    public static final long TIMESTAMP = 1;
+
+    public static final long PARTITION_ID = 20;
+
+    public static final Map<String, Object> PARTITION_KEY_VALUES_1 = ImmutableMap
+            .of(PARTITION_STRING_SCHEMA_KEY_1, "string_1", PARTITION_DOUBLE_SCHEMA_KEY_1, 1d);
+
+    public static final String PARTITION_KEY_VALUES_STRING_1 = convertMapIntoAvroSchemaString(PARTITION_KEY_VALUES_1,
+            PARTITION_SCHEMA_1.toString());
+
+    public static final Map<String, Object> PARTITION_KEY_VALUES_2 = ImmutableMap
+            .of(PARTITION_STRING_SCHEMA_KEY_2, "string_2", PARTITION_DOUBLE_SCHEMA_KEY_2, 2d);
+
+    public static final String PARTITION_KEY_VALUES_STRING_2 = convertMapIntoAvroSchemaString(PARTITION_KEY_VALUES_2,
+            PARTITION_SCHEMA_2.toString());
+
+    public static final PartitionData PARTITION_DATA = PartitionDataImpl.builder().id(PARTITION_ID).keyValues(PARTITION_KEY_VALUES_1).build();
+
+    public static final Map<String, Object> ENTITY_KEY_VALUES = ImmutableMap
+            .of(ENTITY_STRING_SCHEMA_KEY_1, "string", ENTITY_DOUBLE_SCHEMA_KEY_1, 1d);
+
+    public static final Map<String, Object> ENTITY_KEY_VALUES_2 = ImmutableMap
+            .of(ENTITY_STRING_SCHEMA_KEY_2, "string", ENTITY_DOUBLE_SCHEMA_KEY_2, 1d);
+
+    public static final String ENTITY_KEY_VALUES_JSON = KeyValuesUtils
+            .convertMapIntoAvroSchemaString(ENTITY_KEY_VALUES, ENTITY_SCHEMA_1.toString());
+    public static final String PARTITION_KEY_VALUES_JSON_1 = KeyValuesUtils
+            .convertMapIntoAvroSchemaString(PARTITION_KEY_VALUES_1, PARTITION_SCHEMA_1.toString());
+
+    public static final String SCHEMA_VALUE = "SCHEMA_VALUE";
+    public static final long ENTITY_ID = 40;
+    public static final String KEY_VALUES = "KEY_VALUES";
+    public static final long SCHEMA_ID = 30;
+    public static final SchemaData SCHEMA_DATA = new SchemaDataImpl(SCHEMA_ID, SCHEMA_VALUE);
+    public static final String VARIABLE_NAME = "VARIABLE_NAME";
+    public static final String VARIABLE_DESCRIPTION = "VARIABLE_DESCRIPTION";
+    public static final String VARIABLE_CONFIG_FIELD_NAME = "VARIABLE_CONFIG_FIELD_NAME";
+    public static final VariableConfigData VARIABLE_CONFIG_DATA = new VariableConfigDataImpl(ENTITY_ID,
+            VARIABLE_CONFIG_FIELD_NAME, TIMESTAMP, TIMESTAMP);
+    public static final VariableData VARIABLE_DATA = new VariableDataImpl(VARIABLE_NAME, VARIABLE_DESCRIPTION,
+            TIMESTAMP,
+            Sets.newTreeSet(Collections.singletonList(VARIABLE_CONFIG_DATA)));
+
+    public static final SystemData SYSTEM_DATA = new SystemDataImpl(SYSTEM_ID, SYSTEM_NAME,
+            ENTITY_SCHEMA_1.toString(), PARTITION_SCHEMA_1.toString(), TIME_SCHEMA.toString(),
+            RECORD_VERSION_SCHEMA.toString());
+
+    static String FIND_OR_CREATE_ENTITY_REQUEST_JSON;
+    static String VARIABLE_DATA_JSON;
+
+    static {
+        try {
+            FIND_OR_CREATE_ENTITY_REQUEST_JSON =
+                    OBJECT_MAPPER.writeValueAsString(FindOrCreateEntityRequestImpl.builder()
+                            .entityKeyValues(ENTITY_KEY_VALUES)
+                            .partitionKeyValues(PARTITION_KEY_VALUES_1)
+                            .schema(ENTITY_SCHEMA_1.toString())
+                    .build());
+
+            VARIABLE_DATA_JSON = OBJECT_MAPPER.writeValueAsString(VARIABLE_DATA);
+        } catch (Exception exception) {
+            throw new RuntimeException("Error initializing necessary variables for testing.", exception);
+        }
+    }
+}
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/EntityControllerTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/EntityControllerTest.java
index 0847bfd3668e6c78522b743b681d06a695d416f6..543ba2679f7f8fe55737be3eb4ce818773ebdc29 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/EntityControllerTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/EntityControllerTest.java
@@ -6,10 +6,12 @@ package cern.accsoft.nxcals.service.rest;
 
 import cern.accsoft.nxcals.common.domain.EntityData;
 import cern.accsoft.nxcals.common.domain.impl.EntityDataImpl;
+import cern.accsoft.nxcals.service.BaseTest;
 import cern.accsoft.nxcals.service.domain.Entity;
 import cern.accsoft.nxcals.service.internal.InternalEntityService;
 import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Sets;
 import org.assertj.core.util.Lists;
 import org.junit.Before;
@@ -22,6 +24,7 @@ import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.springframework.http.MediaType;
+import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 
@@ -29,18 +32,47 @@ import javax.persistence.OptimisticLockException;
 import javax.validation.ConstraintViolationException;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.*;
-import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.*;
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITIES;
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITY_UPDATE;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES_JSON;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.FIND_OR_CREATE_ENTITY_REQUEST_JSON;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.OBJECT_MAPPER;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SCHEMA_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SCHEMA_VALUE;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TEST_MESSAGE;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TEST_REGEX;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TIMESTAMP;
+import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.CONSTRAIN_VIOLATION_ERROR_FORMAT;
+import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.DATA_CONFLICT_ERROR_FORMAT;
+import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.ILLEGAL_ARGUMENT_ERROR_FORMAT;
+import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.INTERNAL_ERROR_FORMAT;
+import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.NOT_FOUND_ERROR_FORMAT;
+import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.VERSION_MISMATCH_ERROR_FORMAT;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_DOUBLE_SCHEMA_KEY_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_STRING_SCHEMA_KEY_1;
 import static java.lang.String.format;
+import static org.hamcrest.Matchers.is;
 import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+import static org.mockito.Matchers.anyListOf;
 import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyMapOf;
 import static org.mockito.Matchers.anySetOf;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isA;
 import static org.mockito.Mockito.when;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
 import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
@@ -52,14 +84,19 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
  */
 @RunWith(MockitoJUnitRunner.class)
 public class EntityControllerTest {
-    private static final String FIND_BY_SYSTEM_ENDPOINT = "/entities/search/findBySystemIdAndKeyValues?"
-            + "systemId=%s&entityKeyValues=%s";
-    private static final String FIND_BY_TIME_WINDOW_ENDPOINT = "/entities/search/findBySystemIdKeyValuesAndTimeWindow?"
-            + "systemId=%s&entityKeyValues=%s&startTime=%s&endTime=%s";
-    private static final String FIND_BY_EXPRESSION_ENDPOINT = "/entities/search/findByExpression/keyValues?expression=%s";
+    private static final long LOCK_UNTIL_EPOCH_NANOS = 1511278189185000000L;
+    private static final long REC_VERSION = 0L;
+    private static final long NEW_REC_VERSION = 1L;
+    private static final Map<String, Object> NEW_KEY_VALUES = ImmutableMap
+            .of(ENTITY_STRING_SCHEMA_KEY_1, "new_string", ENTITY_DOUBLE_SCHEMA_KEY_1, "new_double");
 
-    private static final String FIND_BY_ID_ENDPOINT = "/entities";
-    private static final String FIND_ALL_BY_ID_ENDPOINT = "/entities?ids=%s,%s";
+    static final EntityDataImpl ENTITY_DATA = new EntityDataImpl(ENTITY_ID, ENTITY_KEY_VALUES, SYSTEM_DATA,
+            PARTITION_DATA, SCHEMA_DATA, Collections.emptySortedSet(), LOCK_UNTIL_EPOCH_NANOS, REC_VERSION);
+    private static final EntityDataImpl NEW_ENTITY_DATA = new EntityDataImpl(ENTITY_ID + 1, NEW_KEY_VALUES, SYSTEM_DATA,
+            PARTITION_DATA, SCHEMA_DATA, Collections.emptySortedSet(), LOCK_UNTIL_EPOCH_NANOS, NEW_REC_VERSION);
+
+    private static final String EMPTY_JSON_ARRAY = "[]";
+    private static final String FIND_ALL_BY_ID_ENDPOINT = ENTITIES + "?ids=%s,%s";
 
     @InjectMocks
     private EntityController entityController;
@@ -73,7 +110,7 @@ public class EntityControllerTest {
     private MockMvc mockMvc;
 
     @Rule
-    public ExpectedException thrown = ExpectedException.none();
+    public ExpectedException expectedException = ExpectedException.none();
 
     @Before
     public void setup() {
@@ -86,19 +123,26 @@ public class EntityControllerTest {
 
     @Test
     public void shouldFindBySystemIdAndKeyValues() throws Exception {
-        when(internalEntityService.findByPartitionSystemIdAndKeyValues(eq(SYSTEM_ID), eq(KEY_VALUES)))
+        when(internalEntityService.findByPartitionSystemIdAndKeyValues(eq(SYSTEM_ID), eq(ENTITY_KEY_VALUES)))
                 .thenReturn(entity);
 
-        mockMvc.perform(get(format(FIND_BY_SYSTEM_ENDPOINT, SYSTEM_ID, KEY_VALUES)))
+        mockMvc.perform(post(ENTITIES)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(ENTITY_KEY_VALUES_JSON))
                 .andExpect(status().isOk()).andExpect(jsonPath("id").value(ENTITY_ID))
                 .andExpect(jsonPath("schemaData.schemaJson").value(SCHEMA_VALUE));
     }
 
     @Test
     public void shouldReturn404WhenFindBySystemIdAndKeyValuesFindsNothing() throws Exception {
-        when(internalEntityService.findByPartitionSystemIdAndKeyValues(isA(Long.class), isA(String.class)))
+        when(internalEntityService
+                .findByPartitionSystemIdAndKeyValues(isA(Long.class), anyMapOf(String.class, Object.class)))
                 .thenThrow(new NotFoundRuntimeException(TEST_MESSAGE));
-        mockMvc.perform(get(format(FIND_BY_SYSTEM_ENDPOINT, SYSTEM_ID, KEY_VALUES)))
+        mockMvc.perform(post(ENTITIES)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(ENTITY_KEY_VALUES_JSON))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT, TEST_MESSAGE)));
     }
@@ -106,10 +150,14 @@ public class EntityControllerTest {
     @Test
     public void shouldReturn500WhenFindBySystemIdAndKeyValuesFailsUnexpectedly() throws Exception {
         RuntimeException runtimeException = new RuntimeException(TEST_MESSAGE);
-        when(internalEntityService.findByPartitionSystemIdAndKeyValues(isA(Long.class), isA(String.class)))
+        when(internalEntityService
+                .findByPartitionSystemIdAndKeyValues(isA(Long.class), anyMapOf(String.class, Object.class)))
                 .thenThrow(runtimeException);
 
-        mockMvc.perform(get(format(FIND_BY_SYSTEM_ENDPOINT, SYSTEM_ID, KEY_VALUES)))
+        mockMvc.perform(post(ENTITIES)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(ENTITY_KEY_VALUES_JSON))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
@@ -117,39 +165,52 @@ public class EntityControllerTest {
 
     @Test
     public void shouldFindOrCreateEntity() throws Exception {
-        when(internalEntityService.findOrCreateEntityFor(eq(SYSTEM_ID), eq(KEY_VALUES), eq(PARTITION_KEY_VALUES),
-                eq(SCHEMA_VALUE), eq(TIMESTAMP))).thenReturn(entity);
+        when(internalEntityService.findOrCreateEntityFor(eq(SYSTEM_ID), eq(ENTITY_KEY_VALUES), eq(
+                PARTITION_KEY_VALUES_1),
+                eq(ENTITY_SCHEMA_1.toString()), eq(TIMESTAMP))).thenReturn(entity);
 
-        mockMvc.perform(put(format(FIND_OR_CREATE_ENDPOINT, SYSTEM_ID, KEY_VALUES, PARTITION_KEY_VALUES,
-                TIMESTAMP)).content(SCHEMA_VALUE))
+        mockMvc.perform(put(ENTITIES)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .param("recordTimestamp", String.valueOf(TIMESTAMP))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(FIND_OR_CREATE_ENTITY_REQUEST_JSON))
+                .andDo(print())
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("id").value(ENTITY_ID))
                 .andExpect(jsonPath("schemaData.schemaJson").value(SCHEMA_VALUE));
     }
 
     @Test
+    @WithMockUser(authorities = BaseTest.AUTHORITY)
     public void shouldReturn500WhenFindOrCreateEntityFailsUnexpectedly() throws Exception {
         RuntimeException runtimeException = new RuntimeException(TEST_MESSAGE);
-        when(internalEntityService.findOrCreateEntityFor(isA(Long.class), isA(String.class), isA(String.class),
+        when(internalEntityService.findOrCreateEntityFor(isA(Long.class), anyMapOf(String.class, Object.class),
+                anyMapOf(String.class, Object.class),
                 isA(String.class), isA(Long.class))).thenThrow(runtimeException);
 
-        mockMvc.perform(put(format(FIND_OR_CREATE_ENDPOINT, SYSTEM_ID, KEY_VALUES, PARTITION_KEY_VALUES,
-                TIMESTAMP)).content(SCHEMA_VALUE))
+        mockMvc.perform(put(ENTITIES)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .param("recordTimestamp", String.valueOf(TIMESTAMP))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(FIND_OR_CREATE_ENTITY_REQUEST_JSON))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
     }
 
-
-
     @Test
     public void shouldReturn409WhenFindOrCreateEntityFailsWithConfigDataConflictException() throws Exception {
         ConfigDataConflictException runtimeException = new ConfigDataConflictException(TEST_MESSAGE);
         when(internalEntityService.findOrCreateEntityFor(isA(Long.class), isA(Long.class), isA(Long.class),
                 isA(String.class), isA(Long.class))).thenThrow(runtimeException);
 
-        mockMvc.perform(put(format(FIND_OR_CREATE_ENDPOINT_BY_IDS, SYSTEM_ID,ENTITY_ID, PARTITION_ID,
-                TIMESTAMP)).content(SCHEMA_VALUE))
+        mockMvc.perform(put(ENTITIES)
+                    .param("systemId", String.valueOf(SYSTEM_ID))
+                    .param("entityId", String.valueOf(ENTITY_ID))
+                    .param("partitionId", String.valueOf(PARTITION_ID))
+                    .param("recordTimestamp", String.valueOf(TIMESTAMP))
+                    .contentType(MediaType.APPLICATION_JSON)
+                    .content(SCHEMA_VALUE))
                 .andExpect(status().isConflict())
                 .andExpect(content().string(format(DATA_CONFLICT_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
@@ -161,8 +222,13 @@ public class EntityControllerTest {
         when(internalEntityService.findOrCreateEntityFor(isA(Long.class), isA(Long.class), isA(Long.class),
                 isA(String.class), isA(Long.class))).thenThrow(runtimeException);
 
-        mockMvc.perform(put(format(FIND_OR_CREATE_ENDPOINT_BY_IDS, SYSTEM_ID,ENTITY_ID, PARTITION_ID,
-                TIMESTAMP)).content(SCHEMA_VALUE))
+        mockMvc.perform(put(ENTITIES)
+                    .param("systemId", String.valueOf(SYSTEM_ID))
+                    .param("entityId", String.valueOf(ENTITY_ID))
+                    .param("partitionId", String.valueOf(PARTITION_ID))
+                    .param("recordTimestamp", String.valueOf(TIMESTAMP))
+                    .contentType(MediaType.APPLICATION_JSON)
+                    .content(SCHEMA_VALUE))
                 .andExpect(status().isConflict())
                 .andExpect(content().string(format(ILLEGAL_ARGUMENT_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
@@ -170,34 +236,50 @@ public class EntityControllerTest {
 
     @Test
     public void shouldFindBySystemIdKeyValuesAndTimeWindow() throws Exception {
-        when(internalEntityService.findEntityWithHistForTimeWindow(eq(SYSTEM_ID), eq(KEY_VALUES), eq(TIMESTAMP),
+        when(internalEntityService.findEntityWithHistForTimeWindow(eq(SYSTEM_ID), eq(ENTITY_KEY_VALUES), eq(TIMESTAMP),
                 eq(TIMESTAMP))).thenReturn(entity);
 
-        mockMvc.perform(get(format(FIND_BY_TIME_WINDOW_ENDPOINT, SYSTEM_ID, KEY_VALUES, TIMESTAMP, TIMESTAMP)))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("id").value(ENTITY_ID))
+        mockMvc.perform(post(ENTITIES)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(ENTITY_KEY_VALUES_JSON))
+                .andExpect(status().isOk()).andExpect(jsonPath("id").value(ENTITY_ID))
                 .andExpect(jsonPath("schemaData.schemaJson").value(SCHEMA_VALUE));
     }
 
     @Test
     public void shouldReturn404WhenFindBySystemIdKeyValuesAndTimeWindowFindsNothing() throws Exception {
-        when(internalEntityService.findEntityWithHistForTimeWindow(isA(Long.class), isA(String.class), isA(Long.class),
-                isA(Long.class)))
+        when(internalEntityService
+                .findEntityWithHistForTimeWindow(isA(Long.class), anyMapOf(String.class, Object.class), isA(Long.class),
+                        isA(Long.class)))
                 .thenThrow(new NotFoundRuntimeException(TEST_MESSAGE));
 
-        mockMvc.perform(get(format(FIND_BY_TIME_WINDOW_ENDPOINT, SYSTEM_ID, KEY_VALUES, TIMESTAMP, TIMESTAMP)))
+        mockMvc.perform(post(ENTITIES)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(ENTITY_KEY_VALUES_JSON))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT, TEST_MESSAGE)));
     }
 
     @Test
-    public void shouldReturn500WhenFindBySystemIdKeyValuesAndTimeWindowFailsUnexpectedly() throws Exception {
+    public void shouldReturn500WhenFindBySystemIdKeyvaluesAndTimeWindowFailsUnexpectedly() throws Exception {
         RuntimeException runtimeException = new RuntimeException(TEST_MESSAGE);
-        when(internalEntityService.findEntityWithHistForTimeWindow(isA(Long.class), isA(String.class), isA(Long.class),
-                isA(Long.class)))
+        when(internalEntityService
+                .findEntityWithHistForTimeWindow(isA(Long.class), anyMapOf(String.class, Object.class), isA(Long.class),
+                        isA(Long.class)))
                 .thenThrow(runtimeException);
 
-        mockMvc.perform(get(format(FIND_BY_TIME_WINDOW_ENDPOINT, SYSTEM_ID, KEY_VALUES, TIMESTAMP, TIMESTAMP)))
+        mockMvc.perform(post(ENTITIES)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(ENTITY_KEY_VALUES_JSON))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
@@ -207,10 +289,11 @@ public class EntityControllerTest {
     public void shouldFindByExpression() throws Exception {
         when(internalEntityService.findByKeyValueLike(eq(TEST_REGEX))).thenReturn(ImmutableList.of(entity));
 
-        mockMvc.perform(get(format(FIND_BY_EXPRESSION_ENDPOINT, TEST_REGEX)))
+        mockMvc.perform(get(ENTITIES)
+                .param("keyValuesExpression", TEST_REGEX))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$", hasSize(1)))
-                .andExpect(jsonPath("$[0].entityKeyValues").value(KEY_VALUES));
+                .andExpect(jsonPath("$[0].entityKeyValues").value(is(ENTITY_KEY_VALUES)));
     }
 
     @Test
@@ -218,7 +301,8 @@ public class EntityControllerTest {
         when(internalEntityService.findByKeyValueLike(isA(String.class)))
                 .thenThrow(new NotFoundRuntimeException(TEST_MESSAGE));
 
-        mockMvc.perform(get(format(FIND_BY_EXPRESSION_ENDPOINT, TEST_REGEX)))
+        mockMvc.perform(get(ENTITIES)
+                .param("keyValuesExpression", TEST_REGEX))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT, TEST_MESSAGE)));
     }
@@ -229,7 +313,8 @@ public class EntityControllerTest {
         when(internalEntityService.findByKeyValueLike(isA(String.class)))
                 .thenThrow(runtimeException);
 
-        mockMvc.perform(get(format(FIND_BY_EXPRESSION_ENDPOINT, TEST_REGEX)))
+        mockMvc.perform(get(ENTITIES)
+                .param("keyValuesExpression", TEST_REGEX))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
@@ -245,11 +330,11 @@ public class EntityControllerTest {
 
         when(internalEntityService.updateEntities(eq(entityDataList))).thenReturn(entityList);
 
-        mockMvc.perform(put(UPDATE_ENTITIES)
+        mockMvc.perform(put(ENTITY_UPDATE)
                 .contentType(MediaType.APPLICATION_JSON)
                 .content(OBJECT_MAPPER.writeValueAsString(entityDataList)))
                 .andDo(print())
-                .andExpect(jsonPath("$[0].entityKeyValues").value(NEW_KEY_VALUES));
+                .andExpect(jsonPath("$[0].entityKeyValues").value(is(NEW_KEY_VALUES)));
     }
 
     @Test
@@ -260,11 +345,11 @@ public class EntityControllerTest {
         when(internalEntityService.updateEntities(eq(entityDataList)))
                 .thenReturn(Collections.singletonList(entity));
 
-        mockMvc.perform(put(UPDATE_ENTITIES)
+        mockMvc.perform(put(ENTITY_UPDATE)
                 .contentType(MediaType.APPLICATION_JSON)
                 .content(OBJECT_MAPPER.writeValueAsString(entityDataList)))
                 .andDo(print())
-                .andExpect(jsonPath("$[0].lockUntilEpochNanos").value(NEW_LOCK_UNTIL_STAMP));
+                .andExpect(jsonPath("$[0].lockUntilEpochNanos").value(LOCK_UNTIL_EPOCH_NANOS));
     }
 
     @Test
@@ -277,7 +362,7 @@ public class EntityControllerTest {
         List<EntityData> entityDataList = Collections.singletonList(nonLockedEntityData);
         when(internalEntityService.updateEntities(eq(entityDataList))).thenReturn(Collections.singletonList(entity));
 
-        mockMvc.perform(put(UPDATE_ENTITIES)
+        mockMvc.perform(put(ENTITY_UPDATE)
                 .contentType(MediaType.APPLICATION_JSON)
                 .content(OBJECT_MAPPER.writeValueAsString(entityDataList)))
                 .andDo(print())
@@ -286,10 +371,10 @@ public class EntityControllerTest {
 
     @Test
     public void shouldReturn409CodeWhenThereIsRecordVersionMismatch() throws Exception {
-        when(internalEntityService.updateEntities(isA(List.class)))
+        when(internalEntityService.updateEntities(anyListOf(EntityData.class)))
                 .thenThrow(new VersionMismatchException(TEST_MESSAGE));
 
-        mockMvc.perform(put(UPDATE_ENTITIES)
+        mockMvc.perform(put(ENTITY_UPDATE)
                 .contentType(MediaType.APPLICATION_JSON)
                 .content(EMPTY_JSON_ARRAY))
                 .andExpect(status().isConflict())
@@ -298,10 +383,10 @@ public class EntityControllerTest {
 
     @Test
     public void shouldReturn409CodeWhenThereIsJPAOptimisticLockException() throws Exception {
-        when(internalEntityService.updateEntities(isA(List.class)))
+        when(internalEntityService.updateEntities(anyListOf(EntityData.class)))
                 .thenThrow(new OptimisticLockException(TEST_MESSAGE));
 
-        mockMvc.perform(put(UPDATE_ENTITIES)
+        mockMvc.perform(put(ENTITY_UPDATE)
                 .contentType(MediaType.APPLICATION_JSON)
                 .content(EMPTY_JSON_ARRAY))
                 .andExpect(status().isConflict())
@@ -310,10 +395,10 @@ public class EntityControllerTest {
 
     @Test
     public void shouldReturn409CodeWhenThereIsConstraintViolationException() throws Exception {
-        when(internalEntityService.updateEntities(isA(List.class)))
-                .thenThrow(new ConstraintViolationException(TEST_MESSAGE, Collections.emptySet()));
+        when(internalEntityService.updateEntities(anyListOf(EntityData.class)))
+                .thenThrow(new ConstraintViolationException(TEST_MESSAGE, Sets.newHashSet()));
 
-        mockMvc.perform(put(UPDATE_ENTITIES)
+        mockMvc.perform(put(ENTITY_UPDATE)
                 .contentType(MediaType.APPLICATION_JSON)
                 .content(EMPTY_JSON_ARRAY))
                 .andExpect(status().isConflict())
@@ -325,7 +410,7 @@ public class EntityControllerTest {
         when(internalEntityService.findById(eq(ENTITY_ID)))
                 .thenReturn(entity);
 
-        mockMvc.perform(get(FIND_BY_ID_ENDPOINT + "/" + ENTITY_ID))
+        mockMvc.perform(get(ENTITIES + "/" + ENTITY_ID))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("id").value(ENTITY_ID));
     }
@@ -337,7 +422,7 @@ public class EntityControllerTest {
 
         long nonExistingId = 123456L;
 
-        mockMvc.perform(get(FIND_BY_ID_ENDPOINT + "/" + nonExistingId))
+        mockMvc.perform(get(ENTITIES + "/" + nonExistingId))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT, TEST_MESSAGE)));
     }
@@ -345,20 +430,14 @@ public class EntityControllerTest {
     @Test
     public void shouldFindAllEntitiesById() throws Exception {
         Entity anEntity = Mockito.mock(Entity.class);
-        long anEntityId = 123456L;
-
-        EntityDataImpl anEntityData = createDefaultEntityData(anEntityId);
-        when(anEntity.toEntityData()).thenReturn(anEntityData);
+        when(anEntity.toEntityData()).thenReturn(ENTITY_DATA);
 
         Entity otherEntity = Mockito.mock(Entity.class);
-        long otherEntityId = 654321L;
-
-        EntityDataImpl otherEntityData = createDefaultEntityData(otherEntityId);
-        when(otherEntity.toEntityData()).thenReturn(otherEntityData);
+        when(otherEntity.toEntityData()).thenReturn(NEW_ENTITY_DATA);
 
         Set<Long> requestEntityIds = Sets.newHashSet(
-                anEntityId,
-                otherEntityId
+                ENTITY_DATA.getId(),
+                NEW_ENTITY_DATA.getId()
         );
 
         Set<Entity> fetchedEntities = Sets.newHashSet(
@@ -368,7 +447,10 @@ public class EntityControllerTest {
         when(internalEntityService.findAllByIdIn(eq(requestEntityIds)))
                 .thenReturn(fetchedEntities);
 
-        mockMvc.perform(get(format(FIND_ALL_BY_ID_ENDPOINT, anEntityId, otherEntityId)))
+        String h = format(FIND_ALL_BY_ID_ENDPOINT, ENTITY_DATA.getId(), NEW_ENTITY_DATA.getId());
+
+        mockMvc.perform(get(ENTITIES)
+                .param("ids", String.valueOf(ENTITY_DATA.getId()), String.valueOf(NEW_ENTITY_DATA.getId())))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$", hasSize(2)))
                 .andExpect(jsonPath("$[0].id").isNotEmpty())
@@ -379,13 +461,13 @@ public class EntityControllerTest {
     public void shouldGetEmptyListWhenFindOneEntityByNonExistingId() throws Exception {
         when(internalEntityService.findAllByIdIn(anySetOf(Long.class))).thenReturn(Collections.emptySet());
 
-        long nonExistingId = 123456L;
-        long otherNonExistingId = 654321L;
+        String nonExistingId = String.valueOf(123456L);
+        String otherNonExistingId = String.valueOf(654321L);
 
-        mockMvc.perform(get(format(FIND_ALL_BY_ID_ENDPOINT, nonExistingId, otherNonExistingId)))
+        mockMvc.perform(get(ENTITIES)
+                .param("ids", nonExistingId, otherNonExistingId))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$").isArray())
                 .andExpect(jsonPath("$").isEmpty());
     }
-
 }
\ No newline at end of file
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/EntityResourcesControllerTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/EntityResourcesControllerTest.java
index 2f540d16c940cc3d500ca70769e8fb77ac98cd1e..399ed86bb11594ce00601fcb78d5c58b25022655 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/EntityResourcesControllerTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/EntityResourcesControllerTest.java
@@ -4,10 +4,8 @@
 
 package cern.accsoft.nxcals.service.rest;
 
-import cern.accsoft.nxcals.common.domain.EntitiesResourcesData;
 import cern.accsoft.nxcals.common.domain.EntityResources;
 import cern.accsoft.nxcals.common.domain.ResourceData;
-import cern.accsoft.nxcals.common.domain.impl.EntitiesResourcesDataImpl;
 import cern.accsoft.nxcals.common.domain.impl.EntityResourcesImpl;
 import cern.accsoft.nxcals.common.domain.impl.ResourceDataImpl;
 import cern.accsoft.nxcals.service.internal.InternalEntityResourcesService;
@@ -18,26 +16,32 @@ import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.springframework.http.MediaType;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 
 import java.net.URI;
 
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.ENTITY_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.KEY_VALUES;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.PARTITION_DATA;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SCHEMA_DATA;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SYSTEM_DATA;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SYSTEM_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.TEST_MESSAGE;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.TIMESTAMP;
+import static cern.accsoft.nxcals.common.web.Endpoints.RESOURCES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.KEY_VALUES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.OBJECT_MAPPER;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SCHEMA_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TEST_MESSAGE;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TIMESTAMP;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.INTERNAL_ERROR_FORMAT;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.NOT_FOUND_ERROR_FORMAT;
 import static com.google.common.collect.Sets.newHashSet;
 import static java.lang.String.format;
+import static org.mockito.Matchers.anyMapOf;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isA;
 import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
@@ -46,37 +50,21 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
 @RunWith(MockitoJUnitRunner.class)
 public class EntityResourcesControllerTest {
 
-    private static final String RESOURCES_SEARCH_FIND_BY_SYSTEM_ID_KEY_VALUES_AND_TIME_WINDOW_ENDPOINT =
-            "/resources/search/findBySystemIdKeyValuesAndTimeWindow?"
-                    + "systemId=%s&"
-                    + "entityKeyValues=%s&"
-                    + "startTime=%s&"
-                    + "endTime=%s";
-
-    private static final String RESOURCES_SEARCH_FIND_BY_ENTITY_ID_AND_TIME_WINDOW_ENDPOINT =
-            "/resources/search/findByEntityIdAndTimeWindow?"
-                    + "entityId=%s&"
-                    + "startTime=%s&"
-                    + "endTime=%s";
-
     @Mock
     private InternalEntityResourcesService internalEntitiesResourceService;
 
     @InjectMocks
-    private EntitiesResourcesController entitiesResourcesController;
+    private EntityResourcesController entityResourcesController;
 
     private MockMvc mockMvc;
 
-    @Mock
-    private EntityResources entityResources;
-
     private static URI HDFS_PATH;
 
     static {
         try {
             HDFS_PATH = new URI("HDFS_PATH");
         } catch (Exception e) {
-
+            throw new RuntimeException("Cannot initialize HDFS_PATH", e);
         }
     }
 
@@ -85,12 +73,10 @@ public class EntityResourcesControllerTest {
             newHashSet(HDFS_TABLE_NAME));
     private static final EntityResources ENTITY_RESOURCES = new EntityResourcesImpl(SYSTEM_ID, KEY_VALUES, SYSTEM_DATA,
             PARTITION_DATA, SCHEMA_DATA, RESOURCE_DATA);
-    private final EntitiesResourcesData ENTITY_RESOURCE_DATA = new EntitiesResourcesDataImpl(
-            newHashSet(entityResources));
 
     @Before
     public void setup() {
-        mockMvc = MockMvcBuilders.standaloneSetup(entitiesResourcesController)
+        mockMvc = MockMvcBuilders.standaloneSetup(entityResourcesController)
                 .setControllerAdvice(new GlobalControllerExceptionHandler())
                 .build();
     }
@@ -98,19 +84,24 @@ public class EntityResourcesControllerTest {
     @Test
     public void shouldFindBySystemIdKeyValuesAndTimeWindow() throws Exception {
         when(internalEntitiesResourceService
-                .findBySystemIdKeyValuesAndTimeWindow(eq(SYSTEM_ID), eq(KEY_VALUES), eq(TIMESTAMP), eq(TIMESTAMP)))
+                .findBySystemIdKeyValuesAndTimeWindow(eq(SYSTEM_ID), eq(ENTITY_KEY_VALUES), eq(TIMESTAMP),
+                        eq(TIMESTAMP)))
                 .thenReturn(newHashSet(ENTITY_RESOURCES));
 
-        mockMvc.perform(get(format(RESOURCES_SEARCH_FIND_BY_SYSTEM_ID_KEY_VALUES_AND_TIME_WINDOW_ENDPOINT, SYSTEM_ID,
-                KEY_VALUES, TIMESTAMP, TIMESTAMP)))
+        mockMvc.perform(post(RESOURCES, SYSTEM_ID, TIMESTAMP, TIMESTAMP)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(OBJECT_MAPPER.writeValueAsString(ENTITY_KEY_VALUES)))
                 .andExpect(status().isOk())
-                .andExpect(jsonPath("entityResources[0].id").value(ENTITY_RESOURCES.getId()))
-                .andExpect(jsonPath("entityResources[0].entityKeyValues").value(KEY_VALUES))
-                .andExpect(jsonPath("entityResources[0].systemData.id").value(SYSTEM_DATA.getId()))
-                .andExpect(jsonPath("entityResources[0].partitionData.id").value(PARTITION_DATA.getId()))
-                .andExpect(jsonPath("entityResources[0].schemaData.id").value(SCHEMA_DATA.getId()))
-                .andExpect(jsonPath("entityResources[0].resourcesData.hdfsPaths[0]").value(HDFS_PATH.toString()))
-                .andExpect(jsonPath("entityResources[0].resourcesData.hbaseTableNames[0]").value(HDFS_TABLE_NAME));
+                .andExpect(jsonPath("$[0].id").value(ENTITY_RESOURCES.getId()))
+                .andExpect(jsonPath("$[0].entityKeyValues").value(KEY_VALUES))
+                .andExpect(jsonPath("$[0].systemData.id").value(SYSTEM_DATA.getId()))
+                .andExpect(jsonPath("$[0].partitionData.id").value(PARTITION_DATA.getId()))
+                .andExpect(jsonPath("$[0].schemaData.id").value(SCHEMA_DATA.getId()))
+                .andExpect(jsonPath("$[0].resourcesData.hdfsPaths[0]").value(HDFS_PATH.toString()))
+                .andExpect(jsonPath("$[0].resourcesData.hbaseTableNames[0]").value(HDFS_TABLE_NAME));
     }
 
     @Test
@@ -118,16 +109,18 @@ public class EntityResourcesControllerTest {
         when(internalEntitiesResourceService.findByEntityIdAndTimeWindow(eq(ENTITY_ID), eq(TIMESTAMP), eq(TIMESTAMP)))
                 .thenReturn(newHashSet(ENTITY_RESOURCES));
 
-        mockMvc.perform(get(format(
-                RESOURCES_SEARCH_FIND_BY_ENTITY_ID_AND_TIME_WINDOW_ENDPOINT, ENTITY_ID, TIMESTAMP, TIMESTAMP)))
+        mockMvc.perform(get(RESOURCES, ENTITY_ID, TIMESTAMP, TIMESTAMP)
+                .param("entityId", String.valueOf(ENTITY_ID))
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP)))
                 .andExpect(status().isOk())
-                .andExpect(jsonPath("entityResources[0].id").value(ENTITY_RESOURCES.getId()))
-                .andExpect(jsonPath("entityResources[0].entityKeyValues").value(KEY_VALUES))
-                .andExpect(jsonPath("entityResources[0].systemData.id").value(SYSTEM_DATA.getId()))
-                .andExpect(jsonPath("entityResources[0].partitionData.id").value(PARTITION_DATA.getId()))
-                .andExpect(jsonPath("entityResources[0].schemaData.id").value(SCHEMA_DATA.getId()))
-                .andExpect(jsonPath("entityResources[0].resourcesData.hdfsPaths[0]").value(HDFS_PATH.toString()))
-                .andExpect(jsonPath("entityResources[0].resourcesData.hbaseTableNames[0]").value(HDFS_TABLE_NAME));
+                .andExpect(jsonPath("$[0].id").value(ENTITY_RESOURCES.getId()))
+                .andExpect(jsonPath("$[0].entityKeyValues").value(KEY_VALUES))
+                .andExpect(jsonPath("$[0].systemData.id").value(SYSTEM_DATA.getId()))
+                .andExpect(jsonPath("$[0].partitionData.id").value(PARTITION_DATA.getId()))
+                .andExpect(jsonPath("$[0].schemaData.id").value(SCHEMA_DATA.getId()))
+                .andExpect(jsonPath("$[0].resourcesData.hdfsPaths[0]").value(HDFS_PATH.toString()))
+                .andExpect(jsonPath("$[0].resourcesData.hbaseTableNames[0]").value(HDFS_TABLE_NAME));
     }
 
     @Test
@@ -135,8 +128,10 @@ public class EntityResourcesControllerTest {
         when(internalEntitiesResourceService.findByEntityIdAndTimeWindow(eq(ENTITY_ID), eq(TIMESTAMP), eq(TIMESTAMP)))
                 .thenThrow(new NotFoundRuntimeException(TEST_MESSAGE));
 
-        mockMvc.perform(get(format(
-                RESOURCES_SEARCH_FIND_BY_ENTITY_ID_AND_TIME_WINDOW_ENDPOINT, ENTITY_ID, TIMESTAMP, TIMESTAMP)))
+        mockMvc.perform(get(RESOURCES, SYSTEM_ID, TIMESTAMP, TIMESTAMP)
+                .param("entityId", String.valueOf(ENTITY_ID))
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP)))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT, TEST_MESSAGE)));
     }
@@ -144,12 +139,16 @@ public class EntityResourcesControllerTest {
     @Test
     public void shouldGet404WhenFindBySystemIdKyValuesAndTimeWindowFindsNothing() throws Exception {
         when(internalEntitiesResourceService
-                .findBySystemIdKeyValuesAndTimeWindow(isA(Long.class), isA(String.class), isA(Long.class),
-                        isA(Long.class)))
+                .findBySystemIdKeyValuesAndTimeWindow(isA(Long.class), anyMapOf(String.class, Object.class),
+                        isA(Long.class), isA(Long.class)))
                 .thenThrow(new NotFoundRuntimeException(TEST_MESSAGE));
 
-        mockMvc.perform(get(format(RESOURCES_SEARCH_FIND_BY_SYSTEM_ID_KEY_VALUES_AND_TIME_WINDOW_ENDPOINT, SYSTEM_ID,
-                KEY_VALUES, TIMESTAMP, TIMESTAMP)))
+        mockMvc.perform(post(RESOURCES, SYSTEM_ID, TIMESTAMP, TIMESTAMP)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP))
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(OBJECT_MAPPER.writeValueAsString(ENTITY_KEY_VALUES)))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT, TEST_MESSAGE)));
     }
@@ -161,8 +160,10 @@ public class EntityResourcesControllerTest {
                 .findByEntityIdAndTimeWindow(isA(Long.class), isA(Long.class), isA(Long.class)))
                 .thenThrow(runtimeException);
 
-        mockMvc.perform(get(format(
-                RESOURCES_SEARCH_FIND_BY_ENTITY_ID_AND_TIME_WINDOW_ENDPOINT, ENTITY_ID, TIMESTAMP, TIMESTAMP)))
+        mockMvc.perform(get(RESOURCES, SYSTEM_ID, TIMESTAMP, TIMESTAMP)
+                .param("entityId", String.valueOf(ENTITY_ID))
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP)))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
@@ -172,15 +173,18 @@ public class EntityResourcesControllerTest {
     public void shouldGet500WhenFindBySystemIdKyValuesAndTimeWindowFailsUnexpectedly() throws Exception {
         RuntimeException runtimeException = new RuntimeException(TEST_MESSAGE);
         when(internalEntitiesResourceService
-                .findBySystemIdKeyValuesAndTimeWindow(isA(Long.class), isA(String.class), isA(Long.class),
-                        isA(Long.class)))
+                .findBySystemIdKeyValuesAndTimeWindow(isA(Long.class), anyMapOf(String.class, Object.class),
+                        isA(Long.class), isA(Long.class)))
                 .thenThrow(runtimeException);
 
-        mockMvc.perform(get(format(RESOURCES_SEARCH_FIND_BY_SYSTEM_ID_KEY_VALUES_AND_TIME_WINDOW_ENDPOINT, SYSTEM_ID,
-                KEY_VALUES, TIMESTAMP, TIMESTAMP)))
+        mockMvc.perform(post(RESOURCES, SYSTEM_ID, TIMESTAMP, TIMESTAMP)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(OBJECT_MAPPER.writeValueAsString(ENTITY_KEY_VALUES)))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
     }
-
 }
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/NonDevProfileResolverTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/NonDevProfileResolverTest.java
index f464cf3049a76b067cbe368015b76e624f13d586..8f7b1397a847efa6563751d63885b41ed86f6a72 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/NonDevProfileResolverTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/NonDevProfileResolverTest.java
@@ -15,6 +15,7 @@ import org.mockito.internal.matchers.Contains;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
 import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
 import org.springframework.test.context.TestPropertySource;
@@ -26,16 +27,15 @@ import org.springframework.web.context.WebApplicationContext;
 
 import java.util.Optional;
 
-import static cern.accsoft.nxcals.service.BaseTest.SYSTEM_NAME;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.ENTITY_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.FIND_OR_CREATE_ENDPOINT;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.KEY_VALUES;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.PARTITION_KEY_VALUES;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SCHEMA_VALUE;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SYSTEM_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.TIMESTAMP;
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITIES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.FIND_OR_CREATE_ENTITY_REQUEST_JSON;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_NAME;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TIMESTAMP;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.FORBIDDEN_ERROR_FORMAT;
 import static java.lang.String.format;
+import static org.mockito.Matchers.anyMapOf;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isA;
 import static org.mockito.Mockito.when;
@@ -69,8 +69,8 @@ public class NonDevProfileResolverTest {
     public void setup() {
         when(entity.getId()).thenReturn(ENTITY_ID);
 
-        when(internalEntityService.findOrCreateEntityFor(isA(Long.class), isA(String.class), isA(String.class),
-                isA(String.class), isA(Long.class))).thenReturn(entity);
+        when(internalEntityService.findOrCreateEntityFor(isA(Long.class), anyMapOf(String.class, Object.class),
+                anyMapOf(String.class, Object.class), isA(String.class), isA(Long.class))).thenReturn(entity);
 
         when(system.getName()).thenReturn(SYSTEM_NAME);
 
@@ -85,9 +85,11 @@ public class NonDevProfileResolverTest {
     @WithMockUser(authorities = "ALL")
     public void shouldNotAuthorizeToFindOrCreateEntityFor() throws Exception {
         Matcher<String> contains = new Contains(format(FORBIDDEN_ERROR_FORMAT, ""));
-        this.mockMvc
-                .perform(put(format(FIND_OR_CREATE_ENDPOINT, SYSTEM_ID, KEY_VALUES, PARTITION_KEY_VALUES,
-                        TIMESTAMP)).content(SCHEMA_VALUE))
+        mockMvc.perform(put(ENTITIES)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .param("recordTimestamp", String.valueOf(TIMESTAMP))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(FIND_OR_CREATE_ENTITY_REQUEST_JSON))
                 .andExpect(status().isForbidden())
                 .andExpect(content().string(contains));
     }
@@ -95,8 +97,11 @@ public class NonDevProfileResolverTest {
     @Test
     @WithMockUser(authorities = BaseTest.AUTHORITY)
     public void shouldAuthorizeWithDefaultProfile() throws Exception {
-        mockMvc.perform(put(format(FIND_OR_CREATE_ENDPOINT, SYSTEM_ID, KEY_VALUES, PARTITION_KEY_VALUES,
-                TIMESTAMP)).content(SCHEMA_VALUE))
+        mockMvc.perform(put(ENTITIES)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .param("recordTimestamp", String.valueOf(TIMESTAMP))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(FIND_OR_CREATE_ENTITY_REQUEST_JSON))
                 .andExpect(status().isOk());
     }
 }
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/PartitionControllerTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/PartitionControllerTest.java
index f1ca9d857f903558f958f0d056cc47ec7c5dc6bd..dd5ec7f37eb37ef9ba0d1eb7ad51f770f3c96d09 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/PartitionControllerTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/PartitionControllerTest.java
@@ -5,7 +5,9 @@
 package cern.accsoft.nxcals.service.rest;
 
 import cern.accsoft.nxcals.service.domain.Partition;
+import cern.accsoft.nxcals.service.domain.System;
 import cern.accsoft.nxcals.service.repository.PartitionRepository;
+import cern.accsoft.nxcals.service.repository.SystemRepository;
 import com.google.common.base.Throwables;
 import org.junit.Before;
 import org.junit.Test;
@@ -14,24 +16,29 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.springframework.http.MediaType;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 
 import java.util.Optional;
 
-import static cern.accsoft.nxcals.service.BaseTest.PARTITION_FIND_BY_SYSTEM_ID_KEYVALUES_ENDPOINT;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.PARTITION_DATA;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.PARTITION_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.PARTITION_KEY_VALUES;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SYSTEM_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.TEST_MESSAGE;
+import static cern.accsoft.nxcals.common.web.Endpoints.PARTITIONS;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.OBJECT_MAPPER;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_STRING_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TEST_MESSAGE;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.INTERNAL_ERROR_FORMAT;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.NOT_FOUND_ERROR_FORMAT;
 import static cern.accsoft.nxcals.service.rest.PartitionController.ERROR_MESSAGE;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_1;
 import static java.lang.String.format;
+import static org.hamcrest.Matchers.is;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.when;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
 import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
@@ -43,6 +50,9 @@ public class PartitionControllerTest {
     @Mock
     private PartitionRepository partitionRepository;
 
+    @Mock
+    private SystemRepository systemRepository;
+
     @InjectMocks
     private PartitionController partitionController;
 
@@ -51,11 +61,16 @@ public class PartitionControllerTest {
     @Mock
     private Partition partition;
 
+    @Mock
+    private System system;
+
     @Before
     public void setup() {
         when(partition.toPartitionData()).thenReturn(PARTITION_DATA);
         when(partition.getId()).thenReturn(PARTITION_ID);
-        when(partition.getKeyValues()).thenReturn(PARTITION_KEY_VALUES);
+        when(partition.getKeyValues()).thenReturn(PARTITION_KEY_VALUES_STRING_1);
+        when(systemRepository.findById(SYSTEM_ID)).thenReturn(Optional.of(system));
+        when(system.getPartitionKeyDefs()).thenReturn(PARTITION_SCHEMA_1.toString());
         mockMvc = MockMvcBuilders.standaloneSetup(partitionController)
                 .setControllerAdvice(new GlobalControllerExceptionHandler())
                 .build();
@@ -63,37 +78,44 @@ public class PartitionControllerTest {
 
     @Test
     public void shouldGetPartitionBySystemIdAndKeyValues() throws Exception {
-        Mockito.when(partitionRepository.findBySystemIdAndKeyValues(eq(SYSTEM_ID), eq(PARTITION_KEY_VALUES)))
+        Mockito.when(partitionRepository.findBySystemIdAndKeyValues(eq(SYSTEM_ID), eq(PARTITION_KEY_VALUES_STRING_1)))
                 .thenReturn(Optional.of(partition));
 
-        this.mockMvc
-                .perform(get(format(PARTITION_FIND_BY_SYSTEM_ID_KEYVALUES_ENDPOINT, SYSTEM_ID, PARTITION_KEY_VALUES)))
+        String expectedValue = OBJECT_MAPPER.writeValueAsString(PARTITION_KEY_VALUES_1);
+        mockMvc.perform(post(PARTITIONS)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(expectedValue))
                 .andExpect(status().isOk())
                 .andDo(print())
-                .andExpect(jsonPath("id").value(PARTITION_ID))
-                .andExpect(jsonPath("keyValues").value(PARTITION_KEY_VALUES));
+                .andExpect(jsonPath("$.id").value(PARTITION_ID))
+                .andExpect(jsonPath("$.keyValues").value(is(PARTITION_KEY_VALUES_1)));
     }
 
     @Test
     public void shouldGet404WhenFindBySystemIdFindsNothing() throws Exception {
-        Mockito.when(partitionRepository.findBySystemIdAndKeyValues(eq(SYSTEM_ID), eq(PARTITION_KEY_VALUES)))
+        Mockito.when(partitionRepository.findBySystemIdAndKeyValues(eq(SYSTEM_ID), eq(PARTITION_KEY_VALUES_STRING_1)))
                 .thenReturn(Optional.empty());
 
-        this.mockMvc
-                .perform(get(format(PARTITION_FIND_BY_SYSTEM_ID_KEYVALUES_ENDPOINT, SYSTEM_ID, PARTITION_KEY_VALUES)))
+        mockMvc.perform(post(PARTITIONS)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(OBJECT_MAPPER.writeValueAsString(PARTITION_KEY_VALUES_1)))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT,
-                        format(ERROR_MESSAGE, SYSTEM_ID, PARTITION_KEY_VALUES))));
+                        format(ERROR_MESSAGE, SYSTEM_ID, PARTITION_KEY_VALUES_1))));
     }
 
     @Test
     public void shouldGet500WhenFindBySystemIdFailsUnexpectedly() throws Exception {
         RuntimeException runtimeException = new RuntimeException(TEST_MESSAGE);
-        Mockito.when(partitionRepository.findBySystemIdAndKeyValues(eq(SYSTEM_ID), eq(PARTITION_KEY_VALUES)))
+        Mockito.when(partitionRepository.findBySystemIdAndKeyValues(eq(SYSTEM_ID), eq(PARTITION_KEY_VALUES_STRING_1)))
                 .thenThrow(runtimeException);
 
-        this.mockMvc
-                .perform(get(format(PARTITION_FIND_BY_SYSTEM_ID_KEYVALUES_ENDPOINT, SYSTEM_ID, PARTITION_KEY_VALUES)))
+        mockMvc.perform(post(PARTITIONS)
+                .param("systemId", String.valueOf(SYSTEM_ID))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(OBJECT_MAPPER.writeValueAsString(PARTITION_KEY_VALUES_1)))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SchemaControllerTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SchemaControllerTest.java
index e682bb8b1f1ac16d8fa84c27028d03e8b0135410..bab34d1751076cb37f534e5d0297156ffbe39b8d 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SchemaControllerTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SchemaControllerTest.java
@@ -18,10 +18,11 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 
 import java.util.Optional;
 
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SCHEMA_DATA;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SCHEMA_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SCHEMA_VALUE;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.TEST_MESSAGE;
+import static cern.accsoft.nxcals.common.web.Endpoints.SCHEMA_WITH_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SCHEMA_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SCHEMA_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SCHEMA_VALUE;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TEST_MESSAGE;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.INTERNAL_ERROR_FORMAT;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.NOT_FOUND_ERROR_FORMAT;
 import static java.lang.String.format;
@@ -35,8 +36,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
 @RunWith(MockitoJUnitRunner.class)
 public class SchemaControllerTest {
 
-    private static final String SCHEMA_GET_ENDPOINT = "/schemas/%s";
-
     @Mock
     private SchemaRepository schemaRepository;
 
@@ -60,7 +59,7 @@ public class SchemaControllerTest {
     public void shouldGetSchemaById() throws Exception {
         when(schemaRepository.findById(eq(SCHEMA_ID))).thenReturn(Optional.of(schema));
 
-        this.mockMvc.perform(get(format(SCHEMA_GET_ENDPOINT, SCHEMA_ID)))
+        mockMvc.perform(get(SCHEMA_WITH_ID, SCHEMA_ID))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("id").value(SCHEMA_ID))
                 .andExpect(jsonPath("schemaJson").value(SCHEMA_VALUE));
@@ -70,7 +69,7 @@ public class SchemaControllerTest {
     public void shouldGet404WhenFindByIdFindsNothing() throws Exception {
         when(schemaRepository.findById(eq(SCHEMA_ID))).thenThrow(new NotFoundRuntimeException(TEST_MESSAGE));
 
-        this.mockMvc.perform(get(format(SCHEMA_GET_ENDPOINT, SCHEMA_ID)))
+        mockMvc.perform(get(SCHEMA_WITH_ID, SCHEMA_ID))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT, TEST_MESSAGE)));
     }
@@ -80,7 +79,7 @@ public class SchemaControllerTest {
         RuntimeException runtimeException = new RuntimeException(TEST_MESSAGE);
         when(schemaRepository.findById(eq(SCHEMA_ID))).thenThrow(runtimeException);
 
-        this.mockMvc.perform(get(format(SCHEMA_GET_ENDPOINT, SCHEMA_ID)))
+        mockMvc.perform(get(SCHEMA_WITH_ID, SCHEMA_ID))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SecurityTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SecurityTest.java
index 0f37439f19b1db40f9ca73a618310d7faf866966..5079581472c86563ff913a50179597175aa2ecc6 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SecurityTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SecurityTest.java
@@ -4,8 +4,12 @@
 
 package cern.accsoft.nxcals.service.rest;
 
+import cern.accsoft.nxcals.common.domain.impl.FindOrCreateEntityRequestImpl;
 import cern.accsoft.nxcals.common.domain.EntityData;
+import cern.accsoft.nxcals.common.domain.SystemData;
 import cern.accsoft.nxcals.common.domain.VariableData;
+import cern.accsoft.nxcals.common.domain.impl.EntityDataImpl;
+import cern.accsoft.nxcals.common.domain.impl.SystemDataImpl;
 import cern.accsoft.nxcals.service.BaseTest;
 import cern.accsoft.nxcals.service.domain.Entity;
 import cern.accsoft.nxcals.service.domain.Partition;
@@ -29,26 +33,30 @@ import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfig
 import org.springframework.test.context.web.WebAppConfiguration;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.context.WebApplicationContext;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.ENTITY_DATA;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.ENTITY_DATA2;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.ENTITY_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.EXTEND_ENTITY_FIRST_HISTORY_DATA_FOR;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.FIND_OR_CREATE_ENDPOINT;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.KEY_VALUES;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.OBJECT_MAPPER;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.PARTITION_KEY_VALUES;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SCHEMA_VALUE;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SYSTEM_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.TIMESTAMP;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.UPDATE_ENTITIES;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.VARIABLE_DATA;
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITIES;
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITY_EXTEND_FIRST_HISTORY;
+import static cern.accsoft.nxcals.common.web.Endpoints.ENTITY_UPDATE;
+import static cern.accsoft.nxcals.common.web.Endpoints.VARIABLE_REGISTER_OR_UPDATE;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.ENTITY_KEY_VALUES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.OBJECT_MAPPER;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.PARTITION_KEY_VALUES_1;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SCHEMA_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TIMESTAMP;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.VARIABLE_DATA;
+import static cern.accsoft.nxcals.service.rest.EntityControllerTest.ENTITY_DATA;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.FORBIDDEN_ERROR_FORMAT;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_1;
 import static java.lang.String.format;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
@@ -62,9 +70,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
  * Test suite that checks if the endpoints defined in {@link EntityController} follow the desired contract.
  */
 @WebAppConfiguration
+@Transactional(transactionManager = "jpaTransactionManager")
 public class SecurityTest extends BaseTest {
 
-    private static final String VARIABLES_REGISTER_OR_UPDATE_VARIABLE_FOR_ENDPOINT = "/variables/registerOrUpdateVariableFor";
+    private static final SystemData SYSTEM_DATA2 = new SystemDataImpl(20, SYSTEM_NAME2.toString(),
+            ENTITY_SCHEMA_1.toString(), ENTITY_SCHEMA_1.toString(), ENTITY_SCHEMA_1.toString(), ENTITY_SCHEMA_1.toString());
+
+
+    static final EntityDataImpl ENTITY_DATA2 = new EntityDataImpl(20, ENTITY_KEY_VALUES, SYSTEM_DATA2,
+            PARTITION_DATA, SCHEMA_DATA, Collections.emptySortedSet(), null, 1);
 
     @MockBean
     private SystemRepository systemRepository;
@@ -101,7 +115,7 @@ public class SecurityTest extends BaseTest {
     public void setup() {
         when(entity.getId()).thenReturn(ENTITY_ID);
 
-        when(internalEntityService.findOrCreateEntityFor(isA(Long.class), isA(String.class), isA(String.class),
+        when(internalEntityService.findOrCreateEntityFor(isA(Long.class), isA(Map.class), isA(Map.class),
                 isA(String.class), isA(Long.class))).thenReturn(entity);
 
         when(internalEntityService.extendEntityFirstHistoryDataFor(isA(Long.class), isA(String.class), isA(Long.class))).thenReturn(entity);
@@ -126,17 +140,28 @@ public class SecurityTest extends BaseTest {
     @Test
     @WithMockUser(authorities = BaseTest.AUTHORITY)
     public void shouldFindOrCreateEntity() throws Exception {
-        mockMvc.perform(put(format(FIND_OR_CREATE_ENDPOINT, SYSTEM_ID, KEY_VALUES, PARTITION_KEY_VALUES,
-                TIMESTAMP)).content(SCHEMA_VALUE))
+        mockMvc.perform(put(ENTITIES)
+                    .param("systemId", String.valueOf(SYSTEM_ID))
+                    .param("recordTimestamp", String.valueOf(TIMESTAMP))
+                    .contentType(MediaType.APPLICATION_JSON)
+                    .content(OBJECT_MAPPER.writeValueAsString(FindOrCreateEntityRequestImpl.builder()
+                            .entityKeyValues(ENTITY_KEY_VALUES)
+                            .partitionKeyValues(PARTITION_KEY_VALUES_1)
+                            .schema(ENTITY_SCHEMA_1.toString()).build())))
                 .andExpect(status().isOk());
     }
 
     @Test
     @WithMockUser(authorities = "SOME_AUTHORITY")
     public void shouldNotAuthorizeToFindOrCreateEntityFor() throws Exception {
-        this.mockMvc
-                .perform(put(format(FIND_OR_CREATE_ENDPOINT, SYSTEM_ID, KEY_VALUES, PARTITION_KEY_VALUES,
-                        TIMESTAMP)).content(SCHEMA_VALUE))
+        mockMvc.perform(put(ENTITIES)
+                    .param("systemId", String.valueOf(SYSTEM_ID))
+                    .param("recordTimestamp", String.valueOf(TIMESTAMP))
+                    .contentType(MediaType.APPLICATION_JSON)
+                    .content(OBJECT_MAPPER.writeValueAsString(FindOrCreateEntityRequestImpl.builder()
+                            .entityKeyValues(ENTITY_KEY_VALUES)
+                            .partitionKeyValues(PARTITION_KEY_VALUES_1)
+                            .schema(ENTITY_SCHEMA_1.toString()).build())))
                 .andExpect(status().isForbidden())
                 .andExpect(content().string(ERROR_MESSAGE_CONTENT));
     }
@@ -144,17 +169,18 @@ public class SecurityTest extends BaseTest {
     @Test
     @WithMockUser(authorities = BaseTest.VARIABLE_AUTHORITY)
     public void shouldRegisterOrUpdateVariable() throws Exception {
-        mockMvc.perform(put(VARIABLES_REGISTER_OR_UPDATE_VARIABLE_FOR_ENDPOINT).contentType(MediaType.APPLICATION_JSON)
-                .content(OBJECT_MAPPER.writeValueAsString(VARIABLE_DATA)))
+        mockMvc.perform(put(VARIABLE_REGISTER_OR_UPDATE)
+                    .contentType(MediaType.APPLICATION_JSON)
+                    .content(OBJECT_MAPPER.writeValueAsString(VARIABLE_DATA)))
                 .andExpect(status().isOk());
     }
 
     @Test
     @WithMockUser(authorities = "SOME_AUTHORITY")
     public void shouldNotAuthorizeToRegisterOrUpdateVariableFor() throws Exception {
-        this.mockMvc
-                .perform(put(VARIABLES_REGISTER_OR_UPDATE_VARIABLE_FOR_ENDPOINT).contentType(MediaType.APPLICATION_JSON)
-                        .content(OBJECT_MAPPER.writeValueAsString(VARIABLE_DATA)))
+        mockMvc.perform(put(VARIABLE_REGISTER_OR_UPDATE)
+                    .contentType(MediaType.APPLICATION_JSON)
+                    .content(OBJECT_MAPPER.writeValueAsString(VARIABLE_DATA)))
                 .andExpect(status().isForbidden())
                 .andExpect(content().string(ERROR_MESSAGE_CONTENT));
     }
@@ -169,10 +195,10 @@ public class SecurityTest extends BaseTest {
 
         when(internalEntityService.updateEntities(eq(entityDataList))).thenReturn(entityList);
 
-        mockMvc.perform(put(UPDATE_ENTITIES)
+        mockMvc.perform(put(ENTITY_UPDATE)
                 .contentType(MediaType.APPLICATION_JSON)
                 .content(OBJECT_MAPPER.writeValueAsString(entityDataList)))
-                .andExpect(status().isOk());
+            .andExpect(status().isOk());
     }
 
     @Test
@@ -184,7 +210,7 @@ public class SecurityTest extends BaseTest {
 
         when(internalEntityService.updateEntities(eq(entityDataList))).thenReturn(entityList);
 
-        mockMvc.perform(put(UPDATE_ENTITIES)
+        mockMvc.perform(put(ENTITY_UPDATE)
                 .contentType(MediaType.APPLICATION_JSON)
                 .content(OBJECT_MAPPER.writeValueAsString(entityDataList)))
                 .andExpect(status().isOk());
@@ -200,18 +226,21 @@ public class SecurityTest extends BaseTest {
 
         when(internalEntityService.updateEntities(eq(entityDataList))).thenReturn(entityList);
 
-        mockMvc.perform(put(UPDATE_ENTITIES)
+        mockMvc.perform(put(ENTITY_UPDATE)
                 .contentType(MediaType.APPLICATION_JSON)
                 .content(OBJECT_MAPPER.writeValueAsString(entityDataList)))
                 .andExpect(content().string(ERROR_MESSAGE_CONTENT))
                 .andExpect(status().isForbidden());
     }
 
-
     @Test
     @WithMockUser(authorities = BaseTest.AUTHORITY)
     public void shouldExtendEntityFirstHistoryDataFor() throws Exception {
-        mockMvc.perform(put(format(EXTEND_ENTITY_FIRST_HISTORY_DATA_FOR, ENTITY_ID, TIMESTAMP)).content(SCHEMA_VALUE))
+        mockMvc.perform(put(ENTITY_EXTEND_FIRST_HISTORY)
+                .param("entityId", String.valueOf(ENTITY_ID))
+                .param("from", String.valueOf(TIMESTAMP))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(ENTITY_SCHEMA_1.toString()))
                 .andExpect(status().isOk());
     }
 
@@ -219,9 +248,12 @@ public class SecurityTest extends BaseTest {
     @WithMockUser(authorities = "SOME_AUTHORITY")
     public void shouldNotAuthorizeToExtendEntityFirstHistoryDataFor() throws Exception {
         this.mockMvc
-                .perform(put(format(EXTEND_ENTITY_FIRST_HISTORY_DATA_FOR, ENTITY_ID, TIMESTAMP)).content(SCHEMA_VALUE))
+                .perform(put(ENTITY_EXTEND_FIRST_HISTORY)
+                        .param("entityId", String.valueOf(ENTITY_ID))
+                        .param("from", String.valueOf(TIMESTAMP))
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(ENTITY_SCHEMA_1.toString()))
                 .andExpect(status().isForbidden())
                 .andExpect(content().string(ERROR_MESSAGE_CONTENT));
     }
-
 }
\ No newline at end of file
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SystemControllerTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SystemControllerTest.java
index 0b47cd26fb1233ed7289978813fdea3bb807ed9a..ae45f2abe5bd41946d34abb023dc75d890300fd9 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SystemControllerTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/SystemControllerTest.java
@@ -14,15 +14,16 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 
 import java.util.Optional;
 
-import static cern.accsoft.nxcals.service.BaseTest.SYSTEMS_SEARCH_FIND_BY_NAME_ENDPOINT;
-import static cern.accsoft.nxcals.service.BaseTest.SYSTEM_NAME;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SYSTEM_DATA;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.SYSTEM_ID;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.TEST_MESSAGE;
+import static cern.accsoft.nxcals.common.web.Endpoints.SYSTEMS;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_ID;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.SYSTEM_NAME;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TEST_MESSAGE;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.INTERNAL_ERROR_FORMAT;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.NOT_FOUND_ERROR_FORMAT;
 import static java.lang.String.format;
@@ -36,8 +37,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
 @RunWith(MockitoJUnitRunner.class)
 public class SystemControllerTest {
 
-    private static final String SYSTEMS_SEARCH_FIND_BY_ID_ENDPOINT = "/systems/search/findById?id=%s";
-
     @Mock
     private SystemRepository systemRepository;
 
@@ -61,7 +60,8 @@ public class SystemControllerTest {
     public void shouldGetIdForSystemName() throws Exception {
         when(systemRepository.findByName(eq(SYSTEM_NAME))).thenReturn(Optional.of(system));
 
-        mockMvc.perform(get(format(SYSTEMS_SEARCH_FIND_BY_NAME_ENDPOINT, SYSTEM_NAME)))
+        mockMvc.perform(get(SYSTEMS)
+                .param("name", SYSTEM_NAME))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("id").value(SYSTEM_ID))
                 .andExpect(jsonPath("name").value(SYSTEM_NAME));
@@ -71,7 +71,8 @@ public class SystemControllerTest {
     public void shouldGetIdForSystemId() throws Exception {
         when(systemRepository.findById(eq(SYSTEM_ID))).thenReturn(Optional.of(system));
 
-        mockMvc.perform(get(format(SYSTEMS_SEARCH_FIND_BY_ID_ENDPOINT, SYSTEM_ID))).andExpect(status().isOk())
+        mockMvc.perform(get(SYSTEMS + "/{id}", SYSTEM_ID))
+                .andExpect(status().isOk())
                 .andExpect(jsonPath("id").value(SYSTEM_ID))
                 .andExpect(jsonPath("name").value(SYSTEM_NAME));
     }
@@ -80,7 +81,8 @@ public class SystemControllerTest {
     public void shouldGet404WhenFindsByNameFindsNothing() throws Exception {
         when(systemRepository.findByName(eq(SYSTEM_NAME))).thenThrow(new NotFoundRuntimeException(TEST_MESSAGE));
 
-        mockMvc.perform(get(format(SYSTEMS_SEARCH_FIND_BY_NAME_ENDPOINT, SYSTEM_NAME)))
+        mockMvc.perform(get(SYSTEMS)
+                .param("name", SYSTEM_NAME))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT, TEST_MESSAGE)));
     }
@@ -90,7 +92,8 @@ public class SystemControllerTest {
         RuntimeException runtimeException = new RuntimeException(TEST_MESSAGE);
         when(systemRepository.findByName(eq(SYSTEM_NAME))).thenThrow(runtimeException);
 
-        mockMvc.perform(get(format(SYSTEMS_SEARCH_FIND_BY_NAME_ENDPOINT, SYSTEM_NAME)))
+        mockMvc.perform(get(SYSTEMS)
+                .param("name", SYSTEM_NAME))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
@@ -100,7 +103,7 @@ public class SystemControllerTest {
     public void shouldGet404WhenFindsBySystemIdFindsNothing() throws Exception {
         when(systemRepository.findById(eq(SYSTEM_ID))).thenThrow(new NotFoundRuntimeException(TEST_MESSAGE));
 
-        mockMvc.perform(get(format(SYSTEMS_SEARCH_FIND_BY_ID_ENDPOINT, SYSTEM_ID)))
+        mockMvc.perform(get(SYSTEMS + "/{id}", SYSTEM_ID))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT, TEST_MESSAGE)));
     }
@@ -110,7 +113,7 @@ public class SystemControllerTest {
         RuntimeException runtimeException = new RuntimeException(TEST_MESSAGE);
         when(systemRepository.findById(eq(SYSTEM_ID))).thenThrow(runtimeException);
 
-        mockMvc.perform(get(format(SYSTEMS_SEARCH_FIND_BY_ID_ENDPOINT, SYSTEM_ID)))
+        mockMvc.perform(get(SYSTEMS + "/{id}", SYSTEM_ID))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         Throwables.getStackTraceAsString(runtimeException))));
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/TestSchemas.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/TestSchemas.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1b36ae115dbdb67fa5bc8e8720df6abcd9e295a
--- /dev/null
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/TestSchemas.java
@@ -0,0 +1,62 @@
+package cern.accsoft.nxcals.service.rest;
+
+import org.apache.avro.Schema;
+import org.apache.avro.SchemaBuilder;
+
+public class TestSchemas {
+
+    private TestSchemas() {
+        //Test static class
+    }
+
+    public static final String ENTITY_STRING_SCHEMA_KEY_1 = "entity_string_1";
+    public static final String ENTITY_DOUBLE_SCHEMA_KEY_1 = "entity_double_1";
+    public static final String ENTITY_STRING_SCHEMA_KEY_2 = "entity_string_2";
+    public static final String ENTITY_DOUBLE_SCHEMA_KEY_2 = "entity_double_2";
+
+    public static final String PARTITION_STRING_SCHEMA_KEY_1 = "partition_string_1";
+    public static final String PARTITION_DOUBLE_SCHEMA_KEY_1 = "partition_double_1";
+    public static final String PARTITION_STRING_SCHEMA_KEY_2 = "partition_string_2";
+    public static final String PARTITION_DOUBLE_SCHEMA_KEY_2 = "partition_double_2";
+
+    public static final String TIME_DOUBLE_SCHEMA_KEY = "time_double";
+    public static final String RECORD_VERSION_STRING_SCHEMA_KEY = "record_version_string";
+
+    public static final Schema getFullSchema(Schema... schemas) {
+        SchemaBuilder.FieldAssembler<Schema> fieldBuilder = SchemaBuilder.record("schema").fields();
+        for (Schema schema : schemas) {
+            for (Schema.Field field : schema.getFields()) {
+                fieldBuilder.name(field.name()).type(field.schema()).noDefault();
+            }
+        }
+        return fieldBuilder.endRecord();
+    }
+
+    public static final Schema ENTITY_SCHEMA_1 = SchemaBuilder.record("entity_type_1").fields()
+            .name(ENTITY_STRING_SCHEMA_KEY_1).type().stringType().noDefault()
+            .name(ENTITY_DOUBLE_SCHEMA_KEY_1).type().doubleType().noDefault()
+            .endRecord();
+
+    public static final Schema ENTITY_SCHEMA_2 = SchemaBuilder.record("entity_type_2").fields()
+            .name(ENTITY_STRING_SCHEMA_KEY_2).type().stringType().noDefault()
+            .name(ENTITY_DOUBLE_SCHEMA_KEY_2).type().doubleType().noDefault()
+            .endRecord();
+
+    public static final Schema PARTITION_SCHEMA_1 = SchemaBuilder.record("partition_type_1").fields()
+            .name(PARTITION_STRING_SCHEMA_KEY_1).type().stringType().noDefault()
+            .name(PARTITION_DOUBLE_SCHEMA_KEY_1).type().doubleType().noDefault()
+            .endRecord();
+
+    public static final Schema PARTITION_SCHEMA_2 = SchemaBuilder.record("partition_type_2").fields()
+            .name(PARTITION_STRING_SCHEMA_KEY_2).type().stringType().noDefault()
+            .name(PARTITION_DOUBLE_SCHEMA_KEY_2).type().doubleType().noDefault()
+            .endRecord();
+
+    public static final Schema TIME_SCHEMA = SchemaBuilder.record("test_type").fields()
+            .name(TIME_DOUBLE_SCHEMA_KEY).type().doubleType().noDefault()
+            .endRecord();
+
+    public static final Schema RECORD_VERSION_SCHEMA = SchemaBuilder.record("test_type").fields()
+            .name(RECORD_VERSION_STRING_SCHEMA_KEY).type().stringType().noDefault()
+            .endRecord();
+}
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/VariableControllerTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/VariableControllerTest.java
index 4df733bf067ee4246ace2337e1d43f6358b3c398..ab80526bb7acd5938eba953b044b7b4fc50d62cc 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/VariableControllerTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/rest/VariableControllerTest.java
@@ -13,12 +13,13 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 
 import java.util.Collections;
 
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.TEST_MESSAGE;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.TEST_REGEX;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.TIMESTAMP;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.VARIABLE_DATA;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.VARIABLE_DESCRIPTION;
-import static cern.accsoft.nxcals.service.rest.ControllerTestUtils.VARIABLE_NAME;
+import static cern.accsoft.nxcals.common.web.Endpoints.VARIABLES;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TEST_MESSAGE;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TEST_REGEX;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.TIMESTAMP;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.VARIABLE_DATA;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.VARIABLE_DESCRIPTION;
+import static cern.accsoft.nxcals.service.rest.DomainTestConstants.VARIABLE_NAME;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.INTERNAL_ERROR_FORMAT;
 import static cern.accsoft.nxcals.service.rest.GlobalControllerExceptionHandler.NOT_FOUND_ERROR_FORMAT;
 import static com.google.common.base.Throwables.getStackTraceAsString;
@@ -34,15 +35,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
 @RunWith(MockitoJUnitRunner.class)
 public class VariableControllerTest {
 
-    private static final String VARIABLES_SEARCH_FIND_BY_VARIABLE_NAME_ENDPOINT = "/variables/search/findByVariableName?variableName=%s";
-    private static final String VARIABLES_SEARCH_FIND_BY_VARIABLE_NAME_AND_TIME_WINDOW_ENDPOINT =
-            "/variables/search/findByVariableNameAndTimeWindow?"
-                    + "variableName=%s&"
-                    + "startTime=%s&"
-                    + "endTime=%s";
-    private static final String VARIABLES_SEARCH_FIND_BY_NAME_LIKE_ENDPOINT = "/variables/search/findByExpression/name?expression=%s";
-    private static final String VARIABLES_SEARCH_FIND_BY_DESCRIPTION_REGEX_ENDPOINT = "/variables/search/findByExpression/desc?expression=%s";
-
     @Mock
     private InternalVariableService variableService;
 
@@ -66,8 +58,8 @@ public class VariableControllerTest {
     public void shouldGetVariableByName() throws Exception {
         when(variableService.findByVariableName(eq(VARIABLE_NAME))).thenReturn(variable);
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_VARIABLE_NAME_ENDPOINT, VARIABLE_NAME)))
+        mockMvc.perform(get(VARIABLES)
+                .param("name", VARIABLE_NAME))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("variableName").value(VARIABLE_NAME))
                 .andExpect(jsonPath("description").value(VARIABLE_DESCRIPTION))
@@ -79,8 +71,8 @@ public class VariableControllerTest {
         RuntimeException runtimeException = new RuntimeException(TEST_MESSAGE);
         when(variableService.findByVariableName(eq(VARIABLE_NAME))).thenThrow(runtimeException);
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_VARIABLE_NAME_ENDPOINT, VARIABLE_NAME)))
+        mockMvc.perform(get(VARIABLES)
+                .param("name", VARIABLE_NAME))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         getStackTraceAsString(runtimeException))));
@@ -91,8 +83,8 @@ public class VariableControllerTest {
         when(variableService.findByVariableName(eq(VARIABLE_NAME)))
                 .thenThrow(new NotFoundRuntimeException(TEST_MESSAGE));
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_VARIABLE_NAME_ENDPOINT, VARIABLE_NAME)))
+        mockMvc.perform(get(VARIABLES)
+                .param("name", VARIABLE_NAME))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT, TEST_MESSAGE)));
     }
@@ -102,9 +94,10 @@ public class VariableControllerTest {
         when(variableService.findByVariableNameAndTimeWindow(eq(VARIABLE_NAME), eq(TIMESTAMP), eq(TIMESTAMP)))
                 .thenReturn(variable);
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_VARIABLE_NAME_AND_TIME_WINDOW_ENDPOINT, VARIABLE_NAME,
-                        TIMESTAMP, TIMESTAMP)))
+        mockMvc.perform(get(VARIABLES)
+                .param("name", VARIABLE_NAME)
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP)))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("variableName").value(VARIABLE_NAME))
                 .andExpect(jsonPath("description").value(VARIABLE_DESCRIPTION))
@@ -117,9 +110,11 @@ public class VariableControllerTest {
         when(variableService.findByVariableNameAndTimeWindow(eq(VARIABLE_NAME), eq(TIMESTAMP), eq(TIMESTAMP)))
                 .thenThrow(runtimeException);
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_VARIABLE_NAME_AND_TIME_WINDOW_ENDPOINT, VARIABLE_NAME,
-                        TIMESTAMP, TIMESTAMP))).andExpect(status().isInternalServerError())
+        mockMvc.perform(get(VARIABLES)
+                .param("name", VARIABLE_NAME)
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP)))
+                .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         getStackTraceAsString(runtimeException))));
     }
@@ -129,9 +124,10 @@ public class VariableControllerTest {
         when(variableService.findByVariableNameAndTimeWindow(eq(VARIABLE_NAME), eq(TIMESTAMP), eq(TIMESTAMP)))
                 .thenThrow(new NotFoundRuntimeException(TEST_MESSAGE));
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_VARIABLE_NAME_AND_TIME_WINDOW_ENDPOINT, VARIABLE_NAME,
-                        TIMESTAMP, TIMESTAMP)))
+        mockMvc.perform(get(VARIABLES)
+                .param("name", VARIABLE_NAME)
+                .param("startTime", String.valueOf(TIMESTAMP))
+                .param("endTime", String.valueOf(TIMESTAMP)))
                 .andExpect(status().isNotFound())
                 .andExpect(content().string(format(NOT_FOUND_ERROR_FORMAT, TEST_MESSAGE)));
     }
@@ -140,8 +136,8 @@ public class VariableControllerTest {
     public void shouldFindVariableByRegexName() throws Exception {
         when(variableService.findByNameLike(eq(TEST_REGEX))).thenReturn(Collections.singletonList(variable));
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_NAME_LIKE_ENDPOINT, TEST_REGEX)))
+        mockMvc.perform(get(VARIABLES)
+                .param("nameExpression", TEST_REGEX))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$", hasSize(1)))
                 .andExpect(jsonPath("$[0].variableName").value(VARIABLE_NAME))
@@ -153,8 +149,8 @@ public class VariableControllerTest {
     public void shouldGetEmptyListWhenFindByVariableByRegexNameFindsNothing() throws Exception {
         when(variableService.findByNameLike(eq(TEST_REGEX))).thenReturn(Collections.emptyList());
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_NAME_LIKE_ENDPOINT, TEST_REGEX)))
+        mockMvc.perform(get(VARIABLES)
+                .param("nameExpression", TEST_REGEX))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$", hasSize(0)));
     }
@@ -165,8 +161,8 @@ public class VariableControllerTest {
         when(variableService.findByNameLike(eq(TEST_REGEX)))
                 .thenThrow(runtimeException);
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_NAME_LIKE_ENDPOINT, TEST_REGEX)))
+        mockMvc.perform(get(VARIABLES)
+                .param("nameExpression", TEST_REGEX))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         getStackTraceAsString(runtimeException))));
@@ -176,8 +172,8 @@ public class VariableControllerTest {
     public void shouldGetVariableByDescriptionRegex() throws Exception {
         when(variableService.findByDescriptionLike(eq(TEST_REGEX))).thenReturn(Collections.singletonList(variable));
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_DESCRIPTION_REGEX_ENDPOINT, TEST_REGEX)))
+        mockMvc.perform(get(VARIABLES)
+                .param("descriptionExpression", TEST_REGEX))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$", hasSize(1)))
                 .andExpect(jsonPath("$[0].variableName").value(VARIABLE_NAME))
@@ -189,8 +185,8 @@ public class VariableControllerTest {
     public void shouldGetEmptyListWhenFindByVariableByDescriptionRegexFindsNothing() throws Exception {
         when(variableService.findByDescriptionLike(eq(TEST_REGEX))).thenReturn(Collections.emptyList());
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_DESCRIPTION_REGEX_ENDPOINT, TEST_REGEX)))
+        mockMvc.perform(get(VARIABLES)
+                .param("descriptionExpression", TEST_REGEX))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$", hasSize(0)));
     }
@@ -201,11 +197,10 @@ public class VariableControllerTest {
         when(variableService.findByDescriptionLike(eq(TEST_REGEX)))
                 .thenThrow(runtimeException);
 
-        mockMvc
-                .perform(get(format(VARIABLES_SEARCH_FIND_BY_DESCRIPTION_REGEX_ENDPOINT, TEST_REGEX)))
+        mockMvc.perform(get(VARIABLES)
+                .param("descriptionExpression", TEST_REGEX))
                 .andExpect(status().isInternalServerError())
                 .andExpect(content().string(format(INTERNAL_ERROR_FORMAT, TEST_MESSAGE,
                         getStackTraceAsString(runtimeException))));
     }
-
 }
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/KerberosAuthenticationTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/KerberosAuthenticationTest.java
index 86106bac83a655abd6ca49563bba14297fdace95..c7db39ca9398e826ec72de28114e2864106aa0d4 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/KerberosAuthenticationTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/KerberosAuthenticationTest.java
@@ -17,16 +17,21 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
 import org.springframework.security.kerberos.client.KerberosRestTemplate;
 import org.springframework.test.annotation.Rollback;
 import org.springframework.test.context.TestPropertySource;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.client.RestClientException;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 
+import static cern.accsoft.nxcals.service.rest.TestSchemas.ENTITY_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.PARTITION_SCHEMA_1;
+import static cern.accsoft.nxcals.service.rest.TestSchemas.TIME_SCHEMA;
 import static java.lang.String.format;
 
 @SpringBootTest(classes = ApplicationDev.class, webEnvironment = WebEnvironment.DEFINED_PORT)
 @TestPropertySource(locations = "classpath:kerberos.application.properties")
 @Ignore("Won't pass on jenkins or with junit db. Still useful for debugging security in local env.")
+@Transactional(transactionManager = "jpaTransactionManager")
 public class KerberosAuthenticationTest extends BaseTest {
     private static final Logger LOGGER = LoggerFactory.getLogger(KerberosAuthenticationTest.class);
 
@@ -59,7 +64,8 @@ public class KerberosAuthenticationTest extends BaseTest {
     @Test
     @Rollback
     public void shouldAuthenticateToFindSystem() {
-        cern.accsoft.nxcals.service.domain.System system = createAndPersistClientSystem(MOCK_SYSTEM_NAME);
+        cern.accsoft.nxcals.service.domain.System system = createAndPersistClientSystem(MOCK_SYSTEM_NAME, ENTITY_SCHEMA_1,
+                PARTITION_SCHEMA_1, TIME_SCHEMA);
         String endpoint = format(SYSTEMS_SEARCH_FIND_BY_NAME_ENDPOINT, system.getName());
 
         KerberosRestTemplate restTemplate = new KerberosRestTemplate(KEYTAB_PATH, TEST_PRINCIPAL + "@CERN.CH");
@@ -77,5 +83,4 @@ public class KerberosAuthenticationTest extends BaseTest {
         KerberosRestTemplate restTemplate = new KerberosRestTemplate(KEYTAB_PATH, TEST_PRINCIPAL + "-fail@CERN.CH");
         restTemplate.getForObject("https://" + HOST + ":" + port + endpoint, String.class);
     }
-
 }
\ No newline at end of file
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/LocalKdc.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/LocalKdc.java
index bd1cee41cfcb2b8b85b5fc4d6529c71afeb7ac18..80d859a4cb2ac4a7ae4b60f349fa370168a819ee 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/LocalKdc.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/LocalKdc.java
@@ -132,7 +132,7 @@ public class LocalKdc {
      * @param workDirParent working directory, it should be the build directory. Under
      *                      this directory an ApacheDS working directory will be created, this
      *                      directory will be deleted when the MiniKdc stops.
-     * @throws Exception thrown if the MiniKdc could not be created.
+     * @throws Exception expectedException if the MiniKdc could not be created.
      */
     public LocalKdc(Properties conf, File workDirParent, String workDir) throws Exception {
         if (!conf.keySet().containsAll(PROPERTIES)) {
@@ -207,7 +207,7 @@ public class LocalKdc {
     /**
      * Starts the MiniKdc.
      *
-     * @throws Exception thrown if the MiniKdc could not be started.
+     * @throws Exception expectedException if the MiniKdc could not be started.
      */
     public synchronized void start() throws Exception {
         if (kdc != null) {
@@ -428,7 +428,7 @@ public class LocalKdc {
      *
      * @param principal principal name, do not include the domain.
      * @param password  password.
-     * @throws Exception thrown if the principal could not be created.
+     * @throws Exception expectedException if the principal could not be created.
      */
     public synchronized void createPrincipal(String principal, String password)
             throws Exception {
@@ -460,7 +460,7 @@ public class LocalKdc {
      *
      * @param keytabFile keytab file to add the created principal.s
      * @param principals principals to add to the KDC, do not include the domain.
-     * @throws Exception thrown if the principals or the keytab file could not be
+     * @throws Exception expectedException if the principals or the keytab file could not be
      *                   created.
      */
     public void createPrincipal(File keytabFile, String... principals)
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/MethodSecurityExpressionRootTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/MethodSecurityExpressionRootTest.java
index 6f8f7becb2ea440af31a59f6c56530dcb2b6a6f1..e91e20b74a3473def9dd3007d9cad3d355ff3ac2 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/MethodSecurityExpressionRootTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/MethodSecurityExpressionRootTest.java
@@ -16,6 +16,7 @@ import org.junit.Test;
 import org.mockito.Mock;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.Optional;
 
@@ -24,10 +25,7 @@ import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.when;
 
-/**
- * @author kpodsiad
- */
-
+@Transactional(transactionManager = "jpaTransactionManager")
 public class MethodSecurityExpressionRootTest extends BaseTest {
 
     private final static long SYSTEM_ID = 1L;
@@ -210,11 +208,6 @@ public class MethodSecurityExpressionRootTest extends BaseTest {
                 .hasEntityPermission(Lists.newArrayList(entityData1, entityData2, entityData3), WRITE_PERMISSION));
     }
 
-
-
-
-
-
     @Test
     @WithMockUser(authorities = BaseTest.AUTHORITY)
     public void shouldAcceptAfterEntityIdChecking() throws Exception {
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/RootChangeMethodSecurityExpressionHandlerTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/RootChangeMethodSecurityExpressionHandlerTest.java
index 7353573fa5e1d162be01175dcee0a479704d58b4..10dafdbf0744b20592e8b702b268efb8b9bcfb90 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/RootChangeMethodSecurityExpressionHandlerTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/RootChangeMethodSecurityExpressionHandlerTest.java
@@ -7,13 +7,12 @@ import org.springframework.security.access.expression.method.MethodSecurityExpre
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.transaction.annotation.Transactional;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
-/**
- * @author kpodsiad
- */
+@Transactional(transactionManager = "jpaTransactionManager")
 public class RootChangeMethodSecurityExpressionHandlerTest extends BaseTest {
 
     private RootChangeMethodSecurityExpressionHandler expressionHandler;
diff --git a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/UserDetailsImplTest.java b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/UserDetailsImplTest.java
index ce4441cd6f1ac0ae167d90258d6390bf9f7a1a62..947965fc7b7be1751e8f7a2b7b605f16bb82d610 100644
--- a/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/UserDetailsImplTest.java
+++ b/accsoft-nxcals-service/src/test/java/cern/accsoft/nxcals/service/security/UserDetailsImplTest.java
@@ -5,6 +5,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.Arrays;
 
@@ -14,9 +15,7 @@ import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-/**
- * @author kpodsiad
- */
+@Transactional(transactionManager = "jpaTransactionManager")
 public class UserDetailsImplTest extends BaseTest {
 
     private static final String TEST_AUTHORITY_A = "AAA";
diff --git a/accsoft-nxcals-service/src/test/resources/application.properties b/accsoft-nxcals-service/src/test/resources/application.properties
index 65772280dd2aa40195e976d68dcb0593a7b81224..46b48e0473cce2f3d3e9cb952a9d1b70a43ee58a 100644
--- a/accsoft-nxcals-service/src/test/resources/application.properties
+++ b/accsoft-nxcals-service/src/test/resources/application.properties
@@ -14,7 +14,7 @@ server.tomcat.uri-encoding = UTF-8
 server.port=19093
 #this must be a keystore that is valid for the machine where the service is running!!! Do not commit the selfsigned.jks certificate.
 server.ssl.key-store=selfsigned.jks
-server.ssl.key-store-password=ALA123
+server.ssl.key-store-password=123456
 server.ssl.keyStoreType=JKS
 server.ssl.key-alias=nxcals
 
@@ -41,7 +41,7 @@ spring.datasource.id-generator-db-properties.tnsnamesOraPath=classpath:cern/accs
 spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
 spring.datasource.initialize=false
 
-data.location.prefix=/project/nxcals/nxcals_dev_ntsvetko/data/
+data.location.prefix=/project/nxcals/nxcals_dev_timartin/data/
 data.location.suffix=/*.parquet
 data.location.hbase.tablespace=nxcals
 service.kerberos.keytab=.service.keytab
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 08db766e481c274606ad69216d976098552e2eaa..4786a1ed50b52a87dcc68dfeb0ef4fb30af84f0d 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Mon Dec 04 11:39:10 CET 2017
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip
\ No newline at end of file