io.fabric8.elasticsearch.plugin.KibanaUserReindexAction Maven / Gradle / Ivy
/**
* Copyright (C) 2015 Red Hat, 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 io.fabric8.elasticsearch.plugin;
import java.io.IOException;
import java.util.Map;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse.FieldMappingMetaData;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.get.MultiGetResponse.Failure;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.ActionFilter;
import org.elasticsearch.action.support.ActionFilterChain;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.io.stream.BytesStreamInput;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.index.get.GetField;
import org.elasticsearch.index.get.GetResult;
public class KibanaUserReindexAction implements ActionFilter, ConfigurationSettings {
private final ESLogger logger;
private final String kibanaIndex;
private Boolean enabled;
@Inject
public KibanaUserReindexAction(final Settings settings, final ClusterService clusterService, final Client client) {
this.enabled = settings.getAsBoolean(OPENSHIFT_KIBANA_REWRITE_ENABLED_FLAG, OPENSHIFT_KIBANA_REWRITE_ENABLED_DEFAULT);
this.logger = Loggers.getLogger(KibanaUserReindexAction.class);
this.kibanaIndex = settings.get(KIBANA_CONFIG_INDEX_NAME, DEFAULT_USER_PROFILE_PREFIX);
if ( enabled )
logger.debug("Initializing KibanaUserReindexAction");
}
@Override
public int order() {
// We want this to be the last in the chain
return Integer.MAX_VALUE;
}
@Override
public void apply(String action, ActionRequest request,
ActionListener listener, ActionFilterChain chain) {
chain.proceed(action, request, listener);
}
@Override
public void apply(String action, ActionResponse response,
ActionListener listener, ActionFilterChain chain) {
if ( enabled ) {
logger.debug("Response with Action '{}' and class '{}'", action, response.getClass());
if ( containsKibanaUserIndex(response) ) {
if ( response instanceof IndexResponse ) {
final IndexResponse ir = (IndexResponse) response;
String index = getIndex(ir);
response = new IndexResponse(index, ir.getType(), ir.getId(), ir.getVersion(), ir.isCreated());
}
else if ( response instanceof GetResponse ) {
response = new GetResponse(buildNewResult((GetResponse) response));
}
else if ( response instanceof DeleteResponse ) {
final DeleteResponse dr = (DeleteResponse) response;
String index = getIndex(dr);
response = new DeleteResponse(index, dr.getType(), dr.getId(), dr.getVersion(), dr.isFound());
}
else if ( response instanceof MultiGetResponse ) {
final MultiGetResponse mgr = (MultiGetResponse) response;
MultiGetItemResponse[] responses = new MultiGetItemResponse[mgr.getResponses().length];
int index = 0;
for ( MultiGetItemResponse item : mgr.getResponses() ) {
GetResponse itemResponse = item.getResponse();
Failure itemFailure = item.getFailure();
GetResponse getResponse = (itemResponse != null) ? new GetResponse(buildNewResult(itemResponse)) : null;
Failure failure = (itemFailure != null) ? buildNewFailure(itemFailure) : null;
responses[index] = new MultiGetItemResponse(getResponse, failure);
index++;
}
response = new MultiGetResponse(responses);
}
else if ( response instanceof GetFieldMappingsResponse ) {
final GetFieldMappingsResponse gfmResponse = (GetFieldMappingsResponse) response;
ImmutableMap>> mappings = gfmResponse.mappings();
String index = "";
for ( String key : mappings.keySet() ) {
index = key;
if ( isKibanaUserIndex(index) ) {
index = kibanaIndex;
}
}
BytesStreamOutput bso = new BytesStreamOutput();
try {
MappingResponseRemapper remapper = new MappingResponseRemapper();
remapper.updateMappingResponse(bso, index, mappings);
BytesStreamInput input = new BytesStreamInput(bso.bytes());
response.readFrom(input);
} catch (IOException e) {
logger.error("Error while rewriting GetFieldMappingsResponse", e);
}
}
}
}
chain.proceed(action, response, listener);
}
private GetResult buildNewResult(GetResponse response) {
String index = getIndex(response);
String replacedIndex = response.getIndex();
//Check for .kibana.* in the source
BytesReference replacedContent = null;
if ( ! response.isSourceEmpty() ) {
String source = response.getSourceAsBytesRef().toUtf8();
String replaced = source.replaceAll(replacedIndex, index);
replacedContent = new BytesArray(replaced);
}
//Check for .kibana.* in the fields
Map responseFields = response.getFields();
for ( String key : responseFields.keySet() ) {
GetField replacedField = responseFields.get(key);
for ( Object o : replacedField.getValues() ) {
if ( o instanceof String ) {
String value = (String) o;
if ( value.contains(replacedIndex) ) {
replacedField.getValues().remove(o);
replacedField.getValues().add(value.replaceAll(replacedIndex, index));
}
}
}
}
GetResult getResult = new GetResult(index, response.getType(), response.getId(), response.getVersion(),
response.isExists(),
replacedContent,
response.getFields());
return getResult;
}
private Failure buildNewFailure(Failure failure) {
String index = failure.getIndex();
String message = failure.getMessage();
if ( isKibanaUserIndex(index) ) {
message = message.replace(index, kibanaIndex);
index = kibanaIndex;
}
return new Failure(index, failure.getType(), failure.getId(), message);
}
private boolean isKibanaUserIndex(String index) {
return (index.startsWith(kibanaIndex) && !index.equalsIgnoreCase(kibanaIndex));
}
private String getIndex(ActionResponse response) {
String index = "";
if ( response instanceof IndexResponse )
index = ((IndexResponse) response).getIndex();
else if ( response instanceof GetResponse )
index = ((GetResponse)response).getIndex();
else if ( response instanceof DeleteResponse )
index = ((DeleteResponse)response).getIndex();
if ( isKibanaUserIndex(index) ) {
index = kibanaIndex;
}
return index;
}
private boolean containsKibanaUserIndex(ActionResponse response) {
String index = "";
if ( response instanceof MultiGetResponse ) {
for ( MultiGetItemResponse item : ((MultiGetResponse)response).getResponses() ) {
GetResponse itemResponse = item.getResponse();
Failure itemFailure = item.getFailure();
if ( itemResponse == null ) {
if ( isKibanaUserIndex(itemFailure.getIndex()) )
return true;
}
else {
if ( isKibanaUserIndex(itemResponse.getIndex()) )
return true;
}
}
return false;
}
if ( response instanceof IndexResponse )
index = ((IndexResponse) response).getIndex();
else if ( response instanceof GetResponse )
index = ((GetResponse)response).getIndex();
else if ( response instanceof DeleteResponse )
index = ((DeleteResponse)response).getIndex();
else if ( response instanceof GetFieldMappingsResponse) {
ImmutableMap>> mappings = ((GetFieldMappingsResponse)response).mappings();
for ( String key : mappings.keySet() )
index = key;
}
return isKibanaUserIndex(index);
}
/*
* Courtesy of GetFieldMappingsResponse.writeTo
*/
private static class MappingResponseRemapper extends ActionResponse implements ToXContent {
ESLogger logger = Loggers.getLogger(MappingResponseRemapper.class);
public void updateMappingResponse(StreamOutput out, String index, ImmutableMap>> mappings) throws IOException {
super.writeTo(out);
out.writeVInt(mappings.size());
for (Map.Entry>> indexEntry : mappings.entrySet()) {
out.writeString(index);
out.writeVInt(indexEntry.getValue().size());
for (Map.Entry> typeEntry : indexEntry.getValue().entrySet()) {
out.writeString(typeEntry.getKey());
out.writeVInt(typeEntry.getValue().size());
for (Map.Entry fieldEntry : typeEntry.getValue().entrySet()) {
out.writeString(fieldEntry.getKey());
FieldMappingMetaData fieldMapping = fieldEntry.getValue();
out.writeString(fieldMapping.fullName());
// below replaces logic of out.writeBytesReference(fieldMapping.source);
Map map = fieldMapping.sourceAsMap();
XContentBuilder builder = XContentBuilder.builder(JsonXContent.jsonXContent);
builder.map(map).close();
out.writeBytesReference(builder.bytes());
}
}
}
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params)
throws IOException {
return null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy