All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.redisson.RedissonJsonBuckets Maven / Gradle / Ivy

Go to download

Easy Redis Java client and Real-Time Data Platform. Valkey compatible. Sync/Async/RxJava3/Reactive API. Client side caching. Over 50 Redis based Java objects and services: JCache API, Apache Tomcat, Hibernate, Spring, Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Scheduler, RPC

There is a newer version: 3.40.2
Show newest version
/**
 * Copyright (c) 2013-2024 Nikita Koksharov
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.redisson;

import org.redisson.api.RFuture;
import org.redisson.api.RJsonBuckets;
import org.redisson.client.protocol.RedisCommand;
import org.redisson.client.protocol.RedisCommands;
import org.redisson.codec.JsonCodec;
import org.redisson.codec.JsonCodecWrapper;
import org.redisson.command.CommandAsyncExecutor;
import org.redisson.connection.decoder.BucketsDecoder;
import org.redisson.connection.decoder.MapGetAllDecoder;
import org.redisson.misc.CompletableFutureWrapper;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

public class RedissonJsonBuckets implements RJsonBuckets {
    
    protected final JsonCodec codec;
    protected final CommandAsyncExecutor commandExecutor;
    
    public RedissonJsonBuckets(JsonCodec codec, CommandAsyncExecutor commandExecutor) {
        this.codec = codec;
        this.commandExecutor = commandExecutor;
    }
    
    @Override
    public  Map get(String... keys) {
        RFuture> future = getAsync(keys);
        return commandExecutor.get(future);
    }
    
    @Override
    public  RFuture> getAsync(String... keys) {
        return getAsync(codec, ".", keys);
    }
    
    @Override
    public  Map get(JsonCodec codec, String path, String... keys) {
        RFuture> future = getAsync(codec, path, keys);
        return commandExecutor.get(future);
    }
    
    @Override
    public  RFuture> getAsync(JsonCodec codec, String path, String... keys) {
        if (keys.length == 0) {
            return new CompletableFutureWrapper<>(Collections.emptyMap());
        }
        
        List keysList = Arrays.stream(keys)
                .map(k -> commandExecutor.getServiceManager().getConfig().getNameMapper().map(k))
                .collect(Collectors.toList());
        
        JsonCodecWrapper jsonCodec = new JsonCodecWrapper(codec);
        RedisCommand> command = new RedisCommand>("JSON.MGET", new MapGetAllDecoder(keysList, 0));
        return commandExecutor.readBatchedAsync(jsonCodec, command, new SlotCallback, Map>() {
            
            public Map onResult(Collection> result) {
                return result.stream()
                        .flatMap(c -> c.entrySet().stream())
                        .filter(e -> e.getKey() != null && e.getValue() != null)
                        .map(e -> {
                            String key = commandExecutor.getServiceManager().getConfig().getNameMapper().unmap((String) e.getKey());
                            return new AbstractMap.SimpleEntry<>(key, (V) e.getValue());
                        }).collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
            }
            
            @Override
            public RedisCommand> createCommand(List keys) {
                return new RedisCommand<>("JSON.MGET", new BucketsDecoder(keys));
            }
            
            @Override
            public Object[] createParams(List params) {
                ArrayList newParams = new ArrayList<>(params);
                newParams.add(path);
                return newParams.toArray();
            }
        }, keysList.toArray(new Object[0]));
    }
    
    @Override
    public void set(Map buckets) {
        commandExecutor.get(setAsync(buckets));
    }
    
    @Override
    public RFuture setAsync(Map buckets) {
        return setAsync(codec, ".", buckets);
    }
    
    @Override
    public void set(JsonCodec codec, String path, Map buckets) {
        commandExecutor.get(setAsync(codec, path, buckets));
    }
    
    @Override
    public RFuture setAsync(JsonCodec codec, String path, Map buckets) {
        if (buckets.isEmpty()) {
            return new CompletableFutureWrapper<>((Void) null);
        }
        
        Map mappedBuckets = buckets.entrySet().stream().collect(
                Collectors.toMap(e -> commandExecutor.getServiceManager().getConfig().getNameMapper().map(e.getKey()),
                        Map.Entry::getValue));
        JsonCodecWrapper jsonCodec = new JsonCodecWrapper(codec);
        return commandExecutor.writeBatchedAsync(jsonCodec, RedisCommands.JSON_MSET, new VoidSlotCallback() {
            @Override
            public Object[] createParams(List keys) {
                List params = new ArrayList<>(keys.size());
                for (Object key : keys) {
                    params.add(key);
                    params.add(path);
                    try {
                        params.add(jsonCodec.getValueEncoder().encode(mappedBuckets.get(key)));
                    } catch (IOException e) {
                        throw new IllegalArgumentException(e);
                    }
                }
                return params.toArray();
            }
        }, mappedBuckets.keySet().toArray(new Object[0]));
    }
}