Feature - commandName setting added #3998

pull/5068/head
Nikita Koksharov 2 years ago
parent 3e4ea61e54
commit 3a09aa3566

@ -20,7 +20,9 @@ import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.resolver.AddressResolverGroup;
import io.netty.util.Timer;
import org.redisson.config.CommandMapper;
import org.redisson.config.CredentialsResolver;
import org.redisson.config.DefaultCommandMapper;
import org.redisson.config.SslProvider;
import org.redisson.misc.RedisURI;
@ -75,6 +77,8 @@ public class RedisClientConfig {
private Consumer<InetSocketAddress> connectedListener;
private Consumer<InetSocketAddress> disconnectedListener;
private CommandMapper commandMapper = new DefaultCommandMapper();
public RedisClientConfig() {
}
@ -113,6 +117,7 @@ public class RedisClientConfig {
this.disconnectedListener = config.disconnectedListener;
this.sslKeyManagerFactory = config.sslKeyManagerFactory;
this.sslTrustManagerFactory = config.sslTrustManagerFactory;
this.commandMapper = config.commandMapper;
}
public NettyHook getNettyHook() {
@ -390,4 +395,13 @@ public class RedisClientConfig {
this.sslKeyManagerFactory = sslKeyManagerFactory;
return this;
}
public CommandMapper getCommandMapper() {
return commandMapper;
}
public RedisClientConfig setCommandMapper(CommandMapper commandMapper) {
this.commandMapper = commandMapper;
return this;
}
}

@ -40,6 +40,7 @@ import io.netty.util.CharsetUtil;
import org.redisson.client.ChannelName;
import org.redisson.client.protocol.CommandData;
import org.redisson.client.protocol.RedisCommands;
import org.redisson.config.CommandMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -52,14 +53,18 @@ import org.slf4j.LoggerFactory;
@Sharable
public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
public static final CommandEncoder INSTANCE = new CommandEncoder();
private final Logger log = LoggerFactory.getLogger(getClass());
private static final char ARGS_PREFIX = '*';
private static final char BYTES_PREFIX = '$';
private static final byte[] CRLF = "\r\n".getBytes();
private CommandMapper commandMapper;
public CommandEncoder(CommandMapper commandMapper) {
this.commandMapper = commandMapper;
}
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (acceptOutboundMessage(msg)) {
@ -87,7 +92,8 @@ public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
out.writeCharSequence(Long.toString(len), CharsetUtil.US_ASCII);
out.writeBytes(CRLF);
writeArgument(out, msg.getCommand().getName().getBytes(CharsetUtil.UTF_8));
String name = commandMapper.map(msg.getCommand().getName());
writeArgument(out, name.getBytes(CharsetUtil.UTF_8));
if (msg.getCommand().getSubName() != null) {
writeArgument(out, msg.getCommand().getSubName().getBytes(CharsetUtil.UTF_8));
}

@ -83,7 +83,7 @@ public class RedisChannelInitializer extends ChannelInitializer<Channel> {
ch.pipeline().addLast(
connectionWatchdog,
CommandEncoder.INSTANCE,
new CommandEncoder(config.getCommandMapper()),
CommandBatchEncoder.INSTANCE);
if (type == Type.PLAIN) {

@ -108,6 +108,7 @@ public class BaseConfig<T extends BaseConfig<T>> {
private NameMapper nameMapper = NameMapper.direct();
private CommandMapper commandMapper = CommandMapper.direct();
BaseConfig() {
}
@ -137,6 +138,7 @@ public class BaseConfig<T extends BaseConfig<T>> {
setTcpNoDelay(config.isTcpNoDelay());
setNameMapper(config.getNameMapper());
setCredentialsResolver(config.getCredentialsResolver());
setCommandMapper(config.getCommandMapper());
}
/**
@ -557,4 +559,20 @@ public class BaseConfig<T extends BaseConfig<T>> {
this.sslKeyManagerFactory = keyManagerFactory;
return this;
}
public CommandMapper getCommandMapper() {
return commandMapper;
}
/**
* Defines Command mapper which maps Redis command name.
* Applied to all Redis commands.
*
* @param commandMapper Redis command name mapper object
* @return config
*/
public BaseConfig<T> setCommandMapper(CommandMapper commandMapper) {
this.commandMapper = commandMapper;
return this;
}
}

@ -0,0 +1,43 @@
/**
* Copyright (c) 2013-2022 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.config;
/**
* Maps Redis command names.
*
* @author Nikita Koksharov
*
*/
public interface CommandMapper {
/**
* Applies map function to the input Redis command <code>name</code>
*
* @param name - original command name
* @return mapped command name
*/
String map(String name);
/**
* Returns input Redis command name. Used by default
*
* @return NameMapper instance
*/
static CommandMapper direct() {
return new DefaultCommandMapper();
}
}

@ -0,0 +1,28 @@
/**
* Copyright (c) 2013-2022 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.config;
/**
*
* @author Nikita Koksharov
*
*/
public class DefaultCommandMapper implements CommandMapper {
@Override
public String map(String name) {
return name;
}
}

@ -204,6 +204,9 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
c.setSslKeystore(cfg.getSslKeystore());
c.setSslKeystorePassword(cfg.getSslKeystorePassword());
c.setSslProtocols(cfg.getSslProtocols());
c.setSslCiphers(cfg.getSslCiphers());
c.setSslKeyManagerFactory(cfg.getSslKeyManagerFactory());
c.setSslTrustManagerFactory(cfg.getSslTrustManagerFactory());
c.setRetryInterval(cfg.getRetryInterval());
c.setRetryAttempts(cfg.getRetryAttempts());
@ -231,6 +234,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
c.setTcpNoDelay(cfg.isTcpNoDelay());
c.setNameMapper(cfg.getNameMapper());
c.setCredentialsResolver(cfg.getCredentialsResolver());
c.setCommandMapper(cfg.getCommandMapper());
return c;
}
@ -287,6 +291,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
.setUsername(config.getUsername())
.setPassword(config.getPassword())
.setNettyHook(serviceManager.getCfg().getNettyHook())
.setCommandMapper(config.getCommandMapper())
.setCredentialsResolver(config.getCredentialsResolver())
.setConnectedListener(addr -> {
if (!serviceManager.isShuttingDown()) {

@ -42,6 +42,9 @@ public class SingleConnectionManager extends MasterSlaveConnectionManager {
newconfig.setSslKeystore(cfg.getSslKeystore());
newconfig.setSslKeystorePassword(cfg.getSslKeystorePassword());
newconfig.setSslProtocols(cfg.getSslProtocols());
newconfig.setSslCiphers(cfg.getSslCiphers());
newconfig.setSslKeyManagerFactory(cfg.getSslKeyManagerFactory());
newconfig.setSslTrustManagerFactory(cfg.getSslTrustManagerFactory());
newconfig.setRetryAttempts(cfg.getRetryAttempts());
newconfig.setRetryInterval(cfg.getRetryInterval());
@ -66,6 +69,7 @@ public class SingleConnectionManager extends MasterSlaveConnectionManager {
newconfig.setTcpNoDelay(cfg.isTcpNoDelay());
newconfig.setNameMapper(cfg.getNameMapper());
newconfig.setCredentialsResolver(cfg.getCredentialsResolver());
newconfig.setCommandMapper(cfg.getCommandMapper());
return newconfig;
}

@ -891,6 +891,25 @@ public class RedissonTest extends BaseTest {
}
@Test
public void testCommandMapper() {
Config c = createConfig();
c.useSingleServer().setCommandMapper(n -> {
if (n.equals("EVAL")) {
return "EVAL_111";
}
return n;
});
RedissonClient redisson = Redisson.create(c);
RBucket<String> b = redisson.getBucket("test");
RedisException e = Assertions.assertThrows(RedisException.class, () -> {
b.compareAndSet("test", "v1");
});
assertThat(e.getMessage()).startsWith("ERR unknown command `EVAL_111`");
redisson.shutdown();
}
@Test
public void testURIPassword() throws InterruptedException, IOException {
RedisProcess runner = new RedisRunner()

Loading…
Cancel
Save