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

com.marklogic.appdeployer.command.forests.DistributedReplicaBuilderStrategy Maven / Gradle / Ivy

Go to download

Java client for the MarkLogic REST Management API and for deploying applications to MarkLogic

There is a newer version: 5.0.0
Show newest version
/*
 * Copyright (c) 2023 MarkLogic Corporation
 *
 * 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 com.marklogic.appdeployer.command.forests;

import com.marklogic.appdeployer.AppConfig;
import com.marklogic.mgmt.api.forest.Forest;
import com.marklogic.mgmt.api.forest.ForestReplica;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class DistributedReplicaBuilderStrategy extends AbstractReplicaBuilderStrategy {

	/**
	 * Distributes the replicas throughout the cluster.
	 */
	public void buildReplicas(List forests, ForestPlan forestPlan, AppConfig appConfig,
		List replicaDataDirectories, ForestNamingStrategy fns)
	{
		final String databaseName = forestPlan.getDatabaseName();
		final List hostNames = forestPlan.getReplicaHostNames();
		final int replicaCount = forestPlan.getReplicaCount();

		HashMap> hostToForests = new HashMap<>();

		for (Forest f : forests) {
			String host = f.getHost();
			if (hostToForests.containsKey(host)) {
				hostToForests.get(host).add(f);
			}
			else {
				ArrayList hostForests = new ArrayList<>();
				hostForests.add(f);
				hostToForests.put(host, hostForests);
			}
		}

		for (String host : hostToForests.keySet()) {
			logger.info("Determining replicas for host: " + host);

			// availableHosts will be the hosts that we can put a forest's replicas on, which excludes the host where
			// the forest lives. We also want to have the hosts in different order as we assign replicas to hosts, so
			// that we don't overload any of them. So if we have five hosts, and we're looking to build replicas for
			// the forests on host 2, this list will be [host3, host4, host5, host1].
			List availableHosts = new ArrayList<>();
			int hostIndex = hostNames.indexOf(host);
			if (hostIndex != -1 && hostIndex < hostNames.size()) {
				availableHosts.addAll(hostNames.subList(hostIndex + 1, hostNames.size()));
			}
			availableHosts.addAll(hostNames.subList(0, hostIndex));
			final int availableHostCount = availableHosts.size();
			logger.info("Available hosts for replicas: " + availableHosts);

			int hostPointer = 0;

			for (Forest currForest : hostToForests.get(host)) {
				List replicas = new ArrayList<>();
				int dataDirectoryPointer = replicaDataDirectories.indexOf(currForest.getDataDirectory());

				for (int i = 1; i <= replicaCount; i++) {
					ForestReplica replica = new ForestReplica();
					replica.setReplicaName(fns.getReplicaName(databaseName, currForest.getForestName(), i, appConfig));
					replicas.add(replica);

					int replicaHostPointer = hostPointer + i - 1;
					if (replicaHostPointer >= availableHostCount) {
						// Must do a modulo here in the event that there are more primary forests per host than number of hosts
						replicaHostPointer %= availableHostCount;
					}
					replica.setHost(availableHosts.get(replicaHostPointer));
					logger.info(format("Built replica '%s' for forest '%s' on host '%s'", replica.getReplicaName(), currForest.getForestName(), replica.getHost()));

					dataDirectoryPointer++;
					if (dataDirectoryPointer == replicaDataDirectories.size()) {
						dataDirectoryPointer = 0;
					}

					final String dataDir = replicaDataDirectories.get(dataDirectoryPointer);
					if (dataDir != null && dataDir.trim().length() > 0) {
						replica.setDataDirectory(dataDir);
					}

					configureReplica(replica, databaseName, appConfig);
				}

				currForest.setForestReplica(replicas);

				++hostPointer;

				if (hostPointer == availableHostCount) {
					hostPointer = 0;
				}

			}
		}

	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy