Java tutorial
/* * Copyright (C) 2014-2015 ULYSSIS VZW * * This file is part of i++. * * i++ is free software: you can redistribute it and/or modify * it under the terms of version 3 of the GNU Affero General Public License * as published by the Free Software Foundation. No other versions apply. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ package org.ulyssis.ipp.config; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableList; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.IOException; import java.net.URI; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.util.Optional; /** * Defines all configuration options of the counting system. * * Read from JSON. * * Care should be taken to ensure that this class is immutable. Only * Jackson may write to the members of this class, when reading the * configuration from JSON. */ public class Config { private static final Logger LOG = LogManager.getLogger(Config.class); private double trackLength; private ImmutableList<ReaderConfig> readers = ImmutableList.of(); private ImmutableList<URI> speedwayURIs = ImmutableList.of(); private ImmutableList<Team> teams = ImmutableList.of(); private long retryInterval = 5000L; private long minUpdateInterval = 5000L; private long maxUpdateInterval = 30000L; private String statusChannel = "status"; private String updateChannel = "update"; private String updatesList = "updates"; private String updatesSet = "updates"; private String controlChannel = "control"; /** * Private constructor used by Jackson */ private Config() { } /** * Create a configuration from the given configuration file. * * Expects the configuration file to be UTF-8 formatted. */ public static Optional<Config> fromConfigurationFile(Path configFile) { try { byte[] config = Files.readAllBytes(configFile); Charset charset = Charset.forName("utf-8"); String configString = charset.decode(ByteBuffer.wrap(config)).toString(); return fromConfigurationString(configString); } catch (IOException e) { LOG.error("Error reading configuration file: {}", configFile, e); return Optional.empty(); } } /** * Create a configuration from the given JSON configuration string. */ public static Optional<Config> fromConfigurationString(String configuration) { ObjectMapper mapper = new ObjectMapper(); mapper.findAndRegisterModules(); try { Config result = mapper.readValue(configuration, Config.class); return Optional.of(result); } catch (IOException e) { LOG.error("Error reading configuration", e); return Optional.empty(); } } /** * Get the track length in meters. */ public double getTrackLength() { return trackLength; } public ImmutableList<ReaderConfig> getReaders() { return readers; } public ReaderConfig getReader(int readerId) { return this.readers.get(readerId); } public int getNbReaders() { return readers.size(); } public ImmutableList<URI> getSpeedwayURIs() { return speedwayURIs; } /** * Get the URI of the Impinj Speedway corresponding * to the reader with the given id. This id ranges from 0 to * getSpeedwayURIs.size() - 1 */ public URI getSpeedwayURI(int readerId) { return speedwayURIs.get(readerId); } public int getNbSpeedways() { return speedwayURIs.size(); } /** * The retry interval for connections in ms. */ public long getRetryInterval() { return retryInterval; } /** * The minimum amount of time in ms between two updates, any * update within this amount of time is ignored. */ public long getMinUpdateInterval() { return minUpdateInterval; } /** * The maximum time in ms to wait for an update before issuing a warning. */ public long getMaxUpdateInterval() { return maxUpdateInterval; } /** * Gets the Redis channel name on which status updates are posted. * * Defaults to "status". * * Generally, the db id will be added to the prefix, because * pubsub channels are not database-specific in Redis. */ public String getStatusChannel() { return statusChannel; } /** * The prefix of the channel where the reader announces new updates. * * This prefix defaults to "update". Generally, the db id will be added * to the prefix, because if multiple readers would use the same Redis * instance (e.g. for testing purposes), these would collide, because * pubsub channels are not database-specific. */ public String getUpdateChannel() { return updateChannel; } /** * The prefix of the channel where an entity in the system receives control messages. * * This defaults to "control". Generally, the db id will be added to this prefix, * because pubsub channels are not database-specific in Redis. */ public String getControlChannel() { return controlChannel; } /** * The name of the list where readers push their updates on. * * Defaults to "updates". */ public String getUpdatesList() { return updatesList; } /** * The name of the set in which updates are stored in the processor. */ public String getUpdatesSet() { return updatesSet; } /** * The teams, with team number and name. */ public ImmutableList<Team> getTeams() { return teams; } // TODO: Maybe find some other solution? private static Config currentConfig; public static void setCurrentConfig(Config config) { currentConfig = config; } public static Config getCurrentConfig() { return currentConfig; } }