/** Check the storage dir and add groups*/ void initGroups(RaftGroup group) { final Optional<RaftGroup> raftGroup = Optional.ofNullable(group); final Optional<RaftGroupId> raftGroupId = raftGroup.map(RaftGroup::getGroupId); RaftServerConfigKeys.storageDirs(properties).parallelStream() .forEach((dir) -> Optional.ofNullable(dir.listFiles()) .map(Arrays::stream).orElse(Stream.empty()) .filter(File::isDirectory) .forEach(sub -> { try { LOG.info("{}: found a subdirectory {}", getId(), sub); final RaftGroupId groupId = RaftGroupId.valueOf(UUID.fromString(sub.getName())); if (!raftGroupId.filter(groupId::equals).isPresent()) { addGroup(RaftGroup.valueOf(groupId)); } } catch (Throwable t) { LOG.warn(getId() + ": Failed to initialize the group directory " + sub.getAbsolutePath() + ". Ignoring it", t); } })); raftGroup.ifPresent(this::addGroup); }
/** * Sets the value to <code>raft.server.storage.dir</code> via * RaftServerConfigKeys and also verifies the same via RaftServerConfigKeys. */ @Test public void testStorageDirs() { final File testDir = new File( rootTestDir.get(), UUID.randomUUID().toString()); final List<File> directories = new ArrayList<>(); IntStream.range(0, 10).mapToObj((i) -> new File(testDir, Integer.toString(i))).forEach(directories::add); RaftProperties properties = new RaftProperties(); RaftServerConfigKeys.setStorageDirs(properties, directories); final List<File> storageDirs = RaftServerConfigKeys.storageDirs(properties); final List<String> expectedDirs = directories.stream() .map(File::getAbsolutePath).collect(Collectors.toList()); final List<String> actualDirs = storageDirs.stream() .map(File::getAbsolutePath).collect(Collectors.toList()); actualDirs.removeAll(expectedDirs); Assert.assertEquals(directories.size(), storageDirs.size()); Assert.assertEquals(0, actualDirs.size()); } }
ServerState(RaftPeerId id, RaftGroup group, RaftProperties prop, RaftServerImpl server, StateMachine stateMachine) throws IOException { this.selfId = id; this.server = server; RaftConfiguration initialConf = RaftConfiguration.newBuilder() .setConf(group.getPeers()).build(); configurationManager = new ConfigurationManager(initialConf); LOG.info("{}: {}", id, configurationManager); // use full uuid string to create a subdirectory final File dir = chooseStorageDir(RaftServerConfigKeys.storageDirs(prop), group.getGroupId().getUuid().toString()); storage = new RaftStorage(dir, RaftServerConstants.StartupOption.REGULAR); snapshotManager = new SnapshotManager(storage, id); long lastApplied = initStatemachine(stateMachine, group.getGroupId()); // On start the leader is null, start the clock now leaderId = null; this.lastNoLeaderTime = Timestamp.currentTime(); this.leaderElectionTimeoutMs = RaftServerConfigKeys.leaderElectionTimeout(prop).toIntExact(TimeUnit.MILLISECONDS); // we cannot apply log entries to the state machine in this step, since we // do not know whether the local log entries have been committed. log = initLog(id, prop, lastApplied, this::setRaftConf); RaftLog.Metadata metadata = log.loadMetadata(); currentTerm = metadata.getTerm(); votedFor = metadata.getVotedFor(); stateMachineUpdater = new StateMachineUpdater(stateMachine, server, log, lastApplied, prop); }