/* * Copyright 2013 Jive Software, Inc * * 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.jivesoftware.os.amza.deployable; import com.google.common.collect.Sets; import com.jivesoftware.os.amza.api.AmzaInterner; import com.jivesoftware.os.amza.api.ring.RingMember; import com.jivesoftware.os.amza.api.scan.RowsChanged; import com.jivesoftware.os.amza.embed.AmzaConfig; import com.jivesoftware.os.amza.embed.EmbedAmzaServiceInitializer; import com.jivesoftware.os.amza.lab.pointers.LABPointerIndexConfig; import com.jivesoftware.os.amza.service.AmzaServiceInitializer; import com.jivesoftware.os.amza.service.stats.AmzaStats; import com.jivesoftware.os.jive.utils.ordered.id.JiveEpochTimestampProvider; import com.jivesoftware.os.jive.utils.ordered.id.SnowflakeIdPacker; import com.jivesoftware.os.routing.bird.deployable.Deployable; import com.jivesoftware.os.routing.bird.deployable.DeployableHealthCheckRegistry; import com.jivesoftware.os.routing.bird.deployable.ErrorHealthCheckConfig; import com.jivesoftware.os.routing.bird.deployable.InstanceConfig; import com.jivesoftware.os.routing.bird.endpoints.base.FullyOnlineVersion; import com.jivesoftware.os.routing.bird.endpoints.base.HasUI; import com.jivesoftware.os.routing.bird.endpoints.base.HasUI.UI; import com.jivesoftware.os.routing.bird.endpoints.base.LoadBalancerHealthCheckEndpoints; import com.jivesoftware.os.routing.bird.health.api.HealthChecker; import com.jivesoftware.os.routing.bird.health.api.HealthFactory; import com.jivesoftware.os.routing.bird.health.api.ScheduledMinMaxHealthCheckConfig; import com.jivesoftware.os.routing.bird.health.checkers.DiskFreeHealthChecker; import com.jivesoftware.os.routing.bird.health.checkers.FileDescriptorCountHealthChecker; import com.jivesoftware.os.routing.bird.health.checkers.GCLoadHealthChecker; import com.jivesoftware.os.routing.bird.health.checkers.GCPauseHealthChecker; import com.jivesoftware.os.routing.bird.health.checkers.LoadAverageHealthChecker; import com.jivesoftware.os.routing.bird.health.checkers.ServiceStartupHealthCheck; import com.jivesoftware.os.routing.bird.health.checkers.SystemCpuHealthChecker; import com.jivesoftware.os.routing.bird.http.client.HttpDeliveryClientHealthProvider; import com.jivesoftware.os.routing.bird.http.client.HttpRequestHelperUtils; import com.jivesoftware.os.routing.bird.server.util.Resource; import java.io.File; import java.util.Arrays; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicReference; import org.merlin.config.defaults.LongDefault; import org.merlin.config.defaults.StringDefault; public class AmzaMain { public static void main(String[] args) throws Exception { new AmzaMain().run(args); } interface DiskFreeCheck extends ScheduledMinMaxHealthCheckConfig { @StringDefault("disk>free") @Override public String getName(); @LongDefault(80) @Override public Long getMax(); } public void run(String[] args) throws Exception { ServiceStartupHealthCheck serviceStartupHealthCheck = new ServiceStartupHealthCheck(); try { final Deployable deployable = new Deployable(args); HealthFactory.initialize(deployable::config, new DeployableHealthCheckRegistry(deployable)); deployable.addManageInjectables(HasUI.class, new HasUI(Arrays.asList(new UI("Amza", "main", "/amza/ui")))); deployable.addHealthCheck(new GCPauseHealthChecker(deployable.config(GCPauseHealthChecker.GCPauseHealthCheckerConfig.class))); deployable.addHealthCheck(new GCLoadHealthChecker(deployable.config(GCLoadHealthChecker.GCLoadHealthCheckerConfig.class))); deployable.addHealthCheck(new SystemCpuHealthChecker(deployable.config(SystemCpuHealthChecker.SystemCpuHealthCheckerConfig.class))); deployable.addHealthCheck(new LoadAverageHealthChecker(deployable.config(LoadAverageHealthChecker.LoadAverageHealthCheckerConfig.class))); deployable.addHealthCheck( new FileDescriptorCountHealthChecker(deployable.config(FileDescriptorCountHealthChecker.FileDescriptorCountHealthCheckerConfig.class))); deployable.addHealthCheck(serviceStartupHealthCheck); deployable.addErrorHealthChecks(deployable.config(ErrorHealthCheckConfig.class)); InstanceConfig instanceConfig = deployable.config(InstanceConfig.class); AtomicReference<Callable<Boolean>> isAmzaReady = new AtomicReference<>(() -> false); deployable.addManageInjectables(FullyOnlineVersion.class, (FullyOnlineVersion) () -> { if (serviceStartupHealthCheck.startupHasSucceeded() && isAmzaReady.get().call()) { return instanceConfig.getVersion(); } else { return null; } }); deployable.buildManageServer().start(); AmzaConfig amzaConfig = deployable.config(AmzaConfig.class); String[] workingDirs = amzaConfig.getWorkingDirs().split(","); File[] paths = new File[workingDirs.length]; for (int i = 0; i < workingDirs.length; i++) { paths[i] = new File(workingDirs[i].trim()); } HealthFactory.scheduleHealthChecker(DiskFreeCheck.class, config1 -> (HealthChecker) new DiskFreeHealthChecker(config1, paths)); final AmzaServiceInitializer.AmzaServiceConfig amzaServiceConfig = new AmzaServiceInitializer.AmzaServiceConfig(); amzaServiceConfig.checkIfCompactionIsNeededIntervalInMillis = amzaConfig.getCheckIfCompactionIsNeededIntervalInMillis(); amzaServiceConfig.numberOfTakerThreads = amzaConfig.getNumberOfTakerThreads(); amzaServiceConfig.workingDirectories = workingDirs; amzaServiceConfig.asyncFsyncIntervalMillis = amzaConfig.getAsyncFsyncIntervalMillis(); amzaServiceConfig.useMemMap = amzaConfig.getUseMemMap(); amzaServiceConfig.systemReadyInitConcurrencyLevel = amzaConfig.getSystemReadyInitConcurrencyLevel(); amzaServiceConfig.ackWatersVerboseLogTimeouts = amzaConfig.getAckWatersVerboseLogTimeouts(); amzaServiceConfig.takeSlowThresholdInMillis = amzaConfig.getTakeSlowThresholdInMillis(); amzaServiceConfig.takeReofferMaxElectionsPerHeartbeat = amzaConfig.getTakeReofferMaxElectionsPerHeartbeat(); amzaServiceConfig.takeCyaIntervalInMillis = amzaConfig.getTakeCyaIntervalInMillis(); amzaServiceConfig.maxUpdatesBeforeDeltaStripeCompaction = amzaConfig.getMaxUpdatesBeforeDeltaStripeCompaction(); amzaServiceConfig.tombstoneCompactionFactor = amzaConfig.getTombstoneCompactionFactor(); amzaServiceConfig.rebalanceIfImbalanceGreaterThanNBytes = amzaConfig.getRebalanceIfImbalanceGreaterThanNBytes(); amzaServiceConfig.rebalanceableEveryNMillis = amzaConfig.getRebalanceableEveryNMillis(); amzaServiceConfig.interruptBlockingReadsIfLingersForNMillis = amzaConfig.getInterruptBlockingReadsIfLingersForNMillis(); amzaServiceConfig.rackDistributionEnabled = amzaConfig.getRackDistributionEnabled(); amzaServiceConfig.hangupAvailableRowsAfterUnresponsiveMillis = amzaConfig.getHangupAvailableRowsAfterUnresponsiveMillis(); amzaServiceConfig.pongIntervalMillis = amzaConfig.getPongIntervalMillis(); amzaServiceConfig.rowsTakerLimit = amzaConfig.getRowsTakerLimit(); amzaServiceConfig.flushHighwatersAfterNUpdates = amzaConfig.getFlushHighwatersAfterNUpdates(); amzaServiceConfig.deltaUseHighwaterTxId = amzaConfig.getDeltaUseHighwaterTxId(); AmzaStats amzaSystemStats = new AmzaStats(); AmzaStats amzaStats = new AmzaStats(); AmzaInterner amzaInterner = new AmzaInterner(); SnowflakeIdPacker idPacker = new SnowflakeIdPacker(); JiveEpochTimestampProvider timestampProvider = new JiveEpochTimestampProvider(); LABPointerIndexConfig labConfig = deployable.config(LABPointerIndexConfig.class); String blacklist = amzaConfig.getBlacklistRingMembers(); Set<RingMember> blacklistRingMembers = Sets.newHashSet(); for (String b : blacklist != null ? blacklist.split("\\s*,\\s*") : new String[0]) { if (b != null) { String trimmedB = b.trim(); if (!trimmedB.isEmpty()) { blacklistRingMembers.add(new RingMember(trimmedB)); } } } HttpDeliveryClientHealthProvider clientHealthProvider = new HttpDeliveryClientHealthProvider(instanceConfig.getInstanceKey(), HttpRequestHelperUtils.buildRequestHelper(false, false, null, instanceConfig.getRoutesHost(), instanceConfig.getRoutesPort()), instanceConfig.getConnectionsHealth(), 5_000, 100); EmbedAmzaServiceInitializer.Lifecycle lifecycle = new EmbedAmzaServiceInitializer().initialize(deployable, clientHealthProvider, instanceConfig.getInstanceName(), instanceConfig.getInstanceKey(), instanceConfig.getServiceName(), instanceConfig.getDatacenter(), instanceConfig.getRack(), instanceConfig.getHost(), instanceConfig.getMainPort(), instanceConfig.getMainServiceAuthEnabled(), instanceConfig.getClusterName(), amzaServiceConfig, labConfig, amzaSystemStats, amzaStats, amzaInterner, idPacker, timestampProvider, blacklistRingMembers, true, true, (RowsChanged changes) -> { }); File staticResourceDir = new File(System.getProperty("user.dir")); System.out.println("Static resources rooted at " + staticResourceDir.getAbsolutePath()); Resource sourceTree = new Resource(staticResourceDir) .addResourcePath("resources/static") .setDirectoryListingAllowed(false) .setContext("/static"); deployable.addResource(sourceTree); lifecycle.startAmzaService(); lifecycle.startRoutingBirdAmzaDiscovery(); deployable.addEndpoints(LoadBalancerHealthCheckEndpoints.class); deployable.addNoAuth("/health/check"); deployable.buildServer().start(); clientHealthProvider.start(); isAmzaReady.set(lifecycle::isReady); serviceStartupHealthCheck.success(); } catch (Throwable t) { serviceStartupHealthCheck.info("Encountered the following failure during startup.", t); } } }