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

org.apache.solr.cloud.autoscaling.AutoScaling Maven / Gradle / Ivy

There is a newer version: 9.7.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.solr.cloud.autoscaling;

import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.lucene.store.AlreadyClosedException;
import org.apache.solr.client.solrj.cloud.SolrCloudManager;
import org.apache.solr.client.solrj.cloud.autoscaling.TriggerEventType;
import org.apache.solr.common.util.Utils;
import org.apache.solr.core.SolrResourceLoader;

public class AutoScaling {

  /**
   * Implementation of this interface is used for processing events generated by a trigger.
   */
  public interface TriggerEventProcessor {

    /**
     * This method is executed for events produced by {@link Trigger#run()}.
     *
     * @param event a subclass of {@link TriggerEvent}
     * @return true if the processor was ready to perform actions on the event, false
     * otherwise. If false was returned then callers should assume the event was discarded.
     */
    boolean process(TriggerEvent event);
  }

  /**
   * Interface for a Solr trigger. Each trigger implements Runnable and Closeable interface. A trigger
   * is scheduled using a {@link java.util.concurrent.ScheduledExecutorService} so it is executed as
   * per a configured schedule to check whether the trigger is ready to fire. The {@link AutoScaling.Trigger#setProcessor(AutoScaling.TriggerEventProcessor)}
   * method should be used to set a processor which is used by implementation of this class whenever
   * ready.
   * 

* As per the guarantees made by the {@link java.util.concurrent.ScheduledExecutorService} a trigger * implementation is only ever called sequentially and therefore need not be thread safe. However, it * is encouraged that implementations be immutable with the exception of the associated listener * which can be get/set by a different thread than the one executing the trigger. Therefore, implementations * should use appropriate synchronization around the listener. *

* When a trigger is ready to fire, it calls the {@link TriggerEventProcessor#process(TriggerEvent)} event * with the proper trigger event object. If that method returns false then it should be interpreted to mean * that Solr is not ready to process this trigger event and therefore we should retain the state and fire * at the next invocation of the run() method. */ public interface Trigger extends Closeable, Runnable { /** * Trigger name. */ String getName(); /** * Event type generated by this trigger. */ TriggerEventType getEventType(); /** Returns true if this trigger is enabled. */ boolean isEnabled(); /** Trigger properties. */ Map getProperties(); /** Number of seconds to wait between fired events ("waitFor" property). */ int getWaitForSecond(); /** Actions to execute when event is fired. */ List getActions(); /** Set event processor to call when event is fired. */ void setProcessor(TriggerEventProcessor processor); /** Get event processor. */ TriggerEventProcessor getProcessor(); /** Return true when this trigger is closed and cannot be used. */ boolean isClosed(); /** Set internal state of this trigger from another instance. */ void restoreState(Trigger old); /** Save internal state of this trigger in ZooKeeper. */ void saveState(); /** Restore internal state of this trigger from ZooKeeper. */ void restoreState(); /** * Called when trigger is created but before it's initialized or scheduled for use. * This method should also verify that the trigger configuration parameters are correct. It may * be called multiple times. * @param properties configuration properties * @throws TriggerValidationException contains details of invalid configuration parameters. */ void configure(SolrResourceLoader loader, SolrCloudManager cloudManager, Map properties) throws TriggerValidationException; /** * Called before a trigger is scheduled. Any heavy object creation or initialisation should * be done in this method instead of the Trigger's constructor. */ void init() throws Exception; } /** * Factory to produce instances of {@link Trigger}. */ public static abstract class TriggerFactory implements Closeable { protected boolean isClosed = false; public abstract Trigger create(TriggerEventType type, String name, Map props) throws TriggerValidationException; @Override public void close() throws IOException { synchronized (this) { isClosed = true; } } } /** * Default implementation of {@link TriggerFactory}. */ public static class TriggerFactoryImpl extends TriggerFactory { private final SolrCloudManager cloudManager; private final SolrResourceLoader loader; public TriggerFactoryImpl(SolrResourceLoader loader, SolrCloudManager cloudManager) { Objects.requireNonNull(cloudManager); Objects.requireNonNull(loader); this.cloudManager = cloudManager; this.loader = loader; } @Override public synchronized Trigger create(TriggerEventType type, String name, Map props) throws TriggerValidationException { if (isClosed) { throw new AlreadyClosedException("TriggerFactory has already been closed, cannot create new triggers"); } if (type == null) { throw new IllegalArgumentException("Trigger type must not be null"); } if (name == null || name.isEmpty()) { throw new IllegalArgumentException("Trigger name must not be empty"); } Trigger t; switch (type) { case NODEADDED: t = new NodeAddedTrigger(name); break; case NODELOST: t = new NodeLostTrigger(name); break; case SEARCHRATE: t = new SearchRateTrigger(name); break; case METRIC: t = new MetricTrigger(name); break; case SCHEDULED: t = new ScheduledTrigger(name); break; case INDEXSIZE: t = new IndexSizeTrigger(name); break; default: throw new IllegalArgumentException("Unknown event type: " + type + " in trigger: " + name); } t.configure(loader, cloudManager, props); return t; } } public static final String AUTO_ADD_REPLICAS_TRIGGER_NAME = ".auto_add_replicas"; public static final String AUTO_ADD_REPLICAS_TRIGGER_DSL = " {" + " 'name' : '" + AUTO_ADD_REPLICAS_TRIGGER_NAME + "'," + " 'event' : 'nodeLost'," + " 'waitFor' : -1," + " 'enabled' : true," + " 'actions' : [" + " {" + " 'name':'auto_add_replicas_plan'," + " 'class':'solr.AutoAddReplicasPlanAction'" + " }," + " {" + " 'name':'execute_plan'," + " 'class':'solr.ExecutePlanAction'" + " }" + " ]" + " }"; public static final Map AUTO_ADD_REPLICAS_TRIGGER_PROPS = (Map) Utils.fromJSONString(AUTO_ADD_REPLICAS_TRIGGER_DSL); public static final String SCHEDULED_MAINTENANCE_TRIGGER_NAME = ".scheduled_maintenance"; public static final String SCHEDULED_MAINTENANCE_TRIGGER_DSL = " {" + " 'name' : '" + SCHEDULED_MAINTENANCE_TRIGGER_NAME + "'," + " 'event' : 'scheduled'," + " 'startTime' : 'NOW'," + " 'every' : '+1DAY'," + " 'enabled' : true," + " 'actions' : [" + " {" + " 'name':'inactive_shard_plan'," + " 'class':'solr.InactiveShardPlanAction'" + " }," + " {" + " 'name':'inactive_markers_plan'," + " 'class':'solr.InactiveMarkersPlanAction'" + " }," + " {" + " 'name':'execute_plan'," + " 'class':'solr.ExecutePlanAction'" + " }" + " ]" + " }"; public static final Map SCHEDULED_MAINTENANCE_TRIGGER_PROPS = (Map) Utils.fromJSONString(SCHEDULED_MAINTENANCE_TRIGGER_DSL); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy