Package at.molindo.esi4j.core.impl

Source Code of at.molindo.esi4j.core.impl.DefaultStore

/**
* Copyright 2010 Molindo GmbH
*
* 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 at.molindo.esi4j.core.impl;

import java.util.Map;
import java.util.Map.Entry;

import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.cluster.settings.ClusterDynamicSettings;
import org.elasticsearch.cluster.settings.DynamicSettings;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.settings.IndexDynamicSettings;
import org.elasticsearch.node.internal.InternalNode;

import at.molindo.esi4j.core.Esi4JClient;
import at.molindo.esi4j.core.Esi4JIndex;
import at.molindo.esi4j.core.Esi4JStore;
import at.molindo.esi4j.core.internal.InternalIndex;
import at.molindo.utils.data.StringUtils;

public class DefaultStore implements Esi4JStore {

  private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultStore.class);

  private static final long INDEX_CREATION_TIMEOUT_SECONDS = 30;

  private final Esi4JClient _client;

  private final String _indexName;

  private Esi4JIndex _index;

  public DefaultStore(Esi4JClient client, String indexName) {
    if (client == null) {
      throw new NullPointerException("client");
    }
    if (indexName == null) {
      throw new NullPointerException("indexName");
    }
    _client = client;
    _indexName = indexName;
  }

  @Override
  public Esi4JClient getClient() {
    return _client;
  }

  @Override
  public String getIndexName() {
    return _indexName;
  }

  public Esi4JIndex getIndex() {
    return _index;
  }

  @Override
  public void setIndex(Esi4JIndex index) {
    if (index == null) {
      throw new NullPointerException("index");
    }
    if (index != _index) {
      if (_index != null) {
        throw new IllegalStateException("already assigned to another index");
      }
      init(_index = index);
    }
  }

  /**
   * called after assigning a store to a new index
   *
   * @param index
   *            the new index (same as {@link #_index})
   */
  protected void init(Esi4JIndex index) {
    // create index

    assertIndex(index);
    _client.addStore(this);
  }

  void assertIndex(Esi4JIndex index) {
    IndicesExistsResponse existsResponse = _client.getClient().admin().indices().prepareExists(_indexName)
        .execute().actionGet();

    if (!existsResponse.isExists()) {
      // create index
      CreateIndexRequestBuilder request = _client.getClient().admin().indices().prepareCreate(_indexName);

      Settings settings = getStoreSettings(index);
      if (settings != null) {
        request.setSettings(settings);
      }

      CreateIndexResponse response = request
          .setTimeout(TimeValue.timeValueSeconds(INDEX_CREATION_TIMEOUT_SECONDS)).execute().actionGet();

      if (!response.isAcknowledged()) {
        log.warn("index creation not acknowledged within " + INDEX_CREATION_TIMEOUT_SECONDS + " seconds");
      }

      // TODO newly created. auto rebuild?

    } else {
      // update settings
      Settings settings = getStoreSettings(index);
      if (settings != null && settings.getAsMap().size() > 0) {

        Settings storeSettings = toDynamicSettings(settings);

        _client.getClient().admin().indices().prepareUpdateSettings(_indexName).setSettings(storeSettings)
            .execute().actionGet();

        ClusterStateResponse state = _client.getClient().admin().cluster().prepareState()
            .setFilterIndices(_indexName).setFilterAll().setFilterMetaData(false).execute().actionGet();

        Settings indexSettings = state.getState().getMetaData().getIndices().get(_indexName).getSettings();

        for (Entry<String, String> e : settings.getAsMap().entrySet()) {
          String key = e.getKey();
          String localValue = e.getValue();
          String indexValue = indexSettings.get(key.startsWith("index.") ? key : "index." + key);
          if (!StringUtils.equals(localValue, indexValue)) {
            // TODO make behavior configurable: fail or warn
            log.warn("could not update value for settings key '" + key + "' from ('" + indexValue
                + "' to '" + localValue + "') - delete and rebuild index " + _indexName);
          }
        }

        // TODO reset previously set settings to their defaults
        // TODO try closing index to update settings
      }
    }
  }

  private Settings toDynamicSettings(Settings settings) {
    // FIXME TransportClient?
    InternalNode node = (InternalNode) ((NodeClient) getClient()).getNode();

    DynamicSettings indexDynamicSettings = node.injector().getInstance(DynamicSettingsBean.class)
        .getIndexDynamicSettings();

    ImmutableSettings.Builder dynamicSettings = ImmutableSettings.builder();

    for (Map.Entry<String, String> e : settings.getAsMap().entrySet()) {
      if (indexDynamicSettings.hasDynamicSetting(e.getKey())) {
        String error = indexDynamicSettings.validateDynamicSetting(e.getKey(), e.getValue());
        if (error == null) {
          dynamicSettings.put(e.getKey(), e.getValue());
        } else {
          // TODO better error handling
          throw new IllegalArgumentException("index setting " + e.getKey() + " has invalid value '"
              + e.getValue() + " (" + error + ")");
        }
      }
    }

    return dynamicSettings.build();
  }

  private Settings getStoreSettings(Esi4JIndex index) {
    Settings indexSettings = ((InternalIndex) index).getSettings();
    if (indexSettings == null) {
      return null;
    }
    ImmutableSettings.Builder builder = ImmutableSettings.settingsBuilder();
    for (Entry<String, String> e : indexSettings.getAsMap().entrySet()) {
      if (e.getKey().startsWith("index.")) {
        builder.put(e.getKey(), e.getValue());
      }
    }
    return builder.build();
  }

  @Override
  public <T> T execute(StoreOperation<T> operation) {
    if (_index == null) {
      throw new IllegalStateException("store not assigned to an index");
    }
    return operation.execute(_client.getClient(), _indexName);
  }

  @Override
  public void close() {
    _client.removeStore(this);
  }

  public static final class DynamicSettingsBean {

    private final DynamicSettings _clusterDynamicSettings;
    private final DynamicSettings _indexDynamicSettings;

    @Inject
    public DynamicSettingsBean(@ClusterDynamicSettings DynamicSettings clusterDynamicSettings,
        @IndexDynamicSettings DynamicSettings indexDynamicSettings) {

      _clusterDynamicSettings = clusterDynamicSettings;
      _indexDynamicSettings = indexDynamicSettings;
    }

    public DynamicSettings getClusterDynamicSettings() {
      return _clusterDynamicSettings;
    }

    public DynamicSettings getIndexDynamicSettings() {
      return _indexDynamicSettings;
    }

  }
}
TOP

Related Classes of at.molindo.esi4j.core.impl.DefaultStore

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.