001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.eclipse.aether.named.redisson;
020
021import java.io.IOException;
022import java.io.InputStream;
023import java.nio.file.Files;
024import java.nio.file.Path;
025import java.nio.file.Paths;
026
027import org.eclipse.aether.named.support.NamedLockFactorySupport;
028import org.redisson.Redisson;
029import org.redisson.api.RedissonClient;
030import org.redisson.config.Config;
031
032/**
033 * Support class for factories using {@link RedissonClient}.
034 */
035public abstract class RedissonNamedLockFactorySupport extends NamedLockFactorySupport {
036    protected static final String NAME_PREFIX = "maven:resolver:";
037
038    private static final String DEFAULT_CONFIG_FILE_NAME = "maven-resolver-redisson.yaml";
039
040    private static final String DEFAULT_CLIENT_NAME = "maven-resolver";
041
042    /**
043     * Path to a Redisson configuration file in YAML format. Read official documentation for details.
044     *
045     * @since 1.7.0
046     * @configurationSource {@link System#getProperty(String, String)}
047     * @configurationType {@link java.lang.String}
048     */
049    public static final String SYSTEM_PROP_CONFIG_FILE = "aether.syncContext.named.redisson.configFile";
050
051    /**
052     * Address of the Redis instance. Optional.
053     *
054     * @since 2.0.0
055     * @configurationSource {@link System#getProperty(String, String)}
056     * @configurationType {@link java.lang.String}
057     * @configurationDefaultValue {@link #DEFAULT_REDIS_ADDRESS}
058     */
059    public static final String SYSTEM_PROP_REDIS_ADDRESS = "aether.syncContext.named.redisson.address";
060
061    public static final String DEFAULT_REDIS_ADDRESS = "redis://localhost:6379";
062
063    protected final RedissonClient redissonClient;
064
065    public RedissonNamedLockFactorySupport() {
066        this.redissonClient = createRedissonClient();
067    }
068
069    @Override
070    protected void doShutdown() {
071        logger.trace("Shutting down Redisson client with id '{}'", redissonClient.getId());
072        redissonClient.shutdown();
073    }
074
075    private RedissonClient createRedissonClient() {
076        Path configFilePath = null;
077
078        String configFile = System.getProperty(SYSTEM_PROP_CONFIG_FILE);
079        if (configFile != null && !configFile.isEmpty()) {
080            configFilePath = Paths.get(configFile);
081            if (Files.notExists(configFilePath)) {
082                throw new IllegalArgumentException(
083                        "The specified Redisson config file does not exist: " + configFilePath);
084            }
085        }
086
087        if (configFilePath == null) {
088            String mavenConf = System.getProperty("maven.conf");
089            if (mavenConf != null && !mavenConf.isEmpty()) {
090                configFilePath = Paths.get(mavenConf, DEFAULT_CONFIG_FILE_NAME);
091                if (Files.notExists(configFilePath)) {
092                    configFilePath = null;
093                }
094            }
095        }
096
097        Config config;
098
099        if (configFilePath != null) {
100            logger.trace("Reading Redisson config file from '{}'", configFilePath);
101            try (InputStream is = Files.newInputStream(configFilePath)) {
102                config = Config.fromYAML(is);
103            } catch (IOException e) {
104                throw new IllegalStateException("Failed to read Redisson config file: " + configFilePath, e);
105            }
106        } else {
107            config = new Config();
108            String defaultRedisAddress = System.getProperty(SYSTEM_PROP_REDIS_ADDRESS, DEFAULT_REDIS_ADDRESS);
109            config.useSingleServer().setAddress(defaultRedisAddress).setClientName(DEFAULT_CLIENT_NAME);
110        }
111
112        RedissonClient redissonClient = Redisson.create(config);
113        logger.trace("Created Redisson client with id '{}'", redissonClient.getId());
114
115        return redissonClient;
116    }
117}