code: public <T> CompletableFuture<VersionedMetadata<T>> getData(final String path, Function<byte[], T> fromBytes) {
          final CompletableFuture<VersionedMetadata<T>> result = new CompletableFuture<>();
  
          try {
              client.getData().inBackground(
                      callback(event -> {
                                  try {
                                      T deserialized = fromBytes.apply(event.getData());
                                      result.complete(new VersionedMetadata<>(deserialized, new Version.IntVersion(event.getStat().getVersion())));
                                  } catch (Exception e) {
                                      log.error("Exception thrown while deserializing the data", e);
                                      result.completeExceptionally(e);
                                  }
                              },
                              result::completeExceptionally, path), executor)
                      .forPath(path);
          } catch (Exception e) {
              result.completeExceptionally(StoreException.create(StoreException.Type.UNKNOWN, e, path));
          }
  
          return result;
      }
docs: Method to retrieve an entity from zookeeper and then deserialize it using the supplied `fromBytes` function.
  @param path Zk path where entity is stored
  @param fromBytes Deserialization function for creating object of type T
  @param <T> Type of Object to retrieve.
  @return CompletableFuture which when completed will have the object of type T retrieved from path and deserialized
  using fromBytes function.