blob: 7e3fa08303021b2c9167a89afb73a30334557be8 [file] [log] [blame]
/*
* 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.ignite.internal.processors.tracing.configuration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.processors.metastorage.DistributedMetaStorage;
import org.apache.ignite.internal.processors.metastorage.persistence.DistributedMetaStorageImpl;
import org.apache.ignite.spi.tracing.Scope;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.internal.LT;
import org.apache.ignite.spi.tracing.TracingConfigurationCoordinates;
import org.apache.ignite.spi.tracing.TracingConfigurationManager;
import org.apache.ignite.spi.tracing.TracingConfigurationParameters;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Tracing configuration manager implementation that uses distributed meta storage
* in order to store tracing configuration.
*/
public class GridTracingConfigurationManager implements TracingConfigurationManager {
/** */
private static final String TRACING_CONFIGURATION_DISTRIBUTED_METASTORE_KEY_PREFIX =
DistributedMetaStorageImpl.IGNITE_INTERNAL_KEY_PREFIX + "tr.config.";
/** Map with default configurations. */
private static final Map<TracingConfigurationCoordinates, TracingConfigurationParameters> DEFAULT_CONFIGURATION_MAP;
/** */
public static final String WARNING_MSG_METASTORAGE_NOT_AVAILABLE =
"Failed to save tracing configuration to meta storage. Meta storage is not available.";
/** */
public static final String WARNING_MSG_TO_RESET_CONFIG_METASTORAGE_NOT_AVAILABLE =
"Failed to reset tracing configuration for coordinates=[%s] to default. Meta storage is not available.";
/** */
public static final String WARNING_MSG_TO_RESET_ALL_CONFIG_METASTORAGE_NOT_AVAILABLE =
"Failed to reset tracing configuration for scope=[%s] to default. Meta storage is not available.";
/** */
public static final String WARNING_FAILED_TO_RETRIEVE_CONFIG_METASTORAGE_NOT_AVAILABLE =
"Failed to retrieve tracing configuration. Meta storage is not available. Default value will be used.";
static {
Map<TracingConfigurationCoordinates, TracingConfigurationParameters> tmpDfltConfigurationMap = new HashMap<>();
tmpDfltConfigurationMap.put(
new TracingConfigurationCoordinates.Builder(Scope.TX).build(),
TracingConfigurationManager.DEFAULT_TX_CONFIGURATION);
tmpDfltConfigurationMap.put(
new TracingConfigurationCoordinates.Builder(Scope.COMMUNICATION).build(),
TracingConfigurationManager.DEFAULT_COMMUNICATION_CONFIGURATION);
tmpDfltConfigurationMap.put(
new TracingConfigurationCoordinates.Builder(Scope.EXCHANGE).build(),
TracingConfigurationManager.DEFAULT_EXCHANGE_CONFIGURATION);
tmpDfltConfigurationMap.put(
new TracingConfigurationCoordinates.Builder(Scope.DISCOVERY).build(),
TracingConfigurationManager.DEFAULT_DISCOVERY_CONFIGURATION);
DEFAULT_CONFIGURATION_MAP = Collections.unmodifiableMap(tmpDfltConfigurationMap);
}
/** Kernal context. */
@GridToStringExclude
protected final GridKernalContext ctx;
/** Grid logger. */
@GridToStringExclude
protected final IgniteLogger log;
/**
* Constructor.
*
* @param ctx Context.
*/
public GridTracingConfigurationManager(@NotNull GridKernalContext ctx) {
this.ctx = ctx;
log = ctx.log(getClass());
}
/** {@inheritDoc} */
@Override public void set(
@NotNull TracingConfigurationCoordinates coordinates,
@NotNull TracingConfigurationParameters parameters)
{
DistributedMetaStorage metaStore = distributedMetaStorage(
false,
WARNING_MSG_METASTORAGE_NOT_AVAILABLE);
String scopeSpecificKey = TRACING_CONFIGURATION_DISTRIBUTED_METASTORE_KEY_PREFIX + coordinates.scope().name();
boolean configurationSuccessfullyUpdated = false;
try {
while (!configurationSuccessfullyUpdated) {
HashMap<String, TracingConfigurationParameters> existingScopeSpecificTracingConfiguration =
metaStore.read(scopeSpecificKey);
HashMap<String, TracingConfigurationParameters> updatedScopeSpecificTracingConfiguration =
existingScopeSpecificTracingConfiguration != null ?
new HashMap<>(existingScopeSpecificTracingConfiguration) : new
HashMap<>();
updatedScopeSpecificTracingConfiguration.put(coordinates.label(), parameters);
configurationSuccessfullyUpdated = metaStore.compareAndSet(
scopeSpecificKey,
existingScopeSpecificTracingConfiguration,
updatedScopeSpecificTracingConfiguration);
}
}
catch (IgniteCheckedException e) {
log.warning(WARNING_MSG_METASTORAGE_NOT_AVAILABLE, e);
throw new IgniteException(WARNING_MSG_METASTORAGE_NOT_AVAILABLE, e);
}
}
/** {@inheritDoc} */
@Override public @NotNull TracingConfigurationParameters get(
@NotNull TracingConfigurationCoordinates coordinates) {
DistributedMetaStorage metaStore;
try {
metaStore = ctx.distributedMetastorage();
}
catch (Exception e) {
LT.warn(log, WARNING_FAILED_TO_RETRIEVE_CONFIG_METASTORAGE_NOT_AVAILABLE);
// If metastorage in not available — use scope specific default tracing configuration.
return TracingConfigurationManager.super.get(coordinates);
}
if (metaStore == null) {
LT.warn(log, WARNING_FAILED_TO_RETRIEVE_CONFIG_METASTORAGE_NOT_AVAILABLE);
// If metastorage in not available — use scope specific default tracing configuration.
return TracingConfigurationManager.super.get(coordinates);
}
String scopeSpecificKey = TRACING_CONFIGURATION_DISTRIBUTED_METASTORE_KEY_PREFIX + coordinates.scope().name();
HashMap<String, TracingConfigurationParameters> scopeSpecificTracingConfiguration;
try {
scopeSpecificTracingConfiguration = metaStore.read(scopeSpecificKey);
}
catch (IgniteCheckedException e) {
LT.warn(
log,
e,
"Failed to retrieve tracing configuration. Default value will be used.",
false,
true);
// In case of exception during retrieving configuration from metastorage — use scope specific default one.
return TracingConfigurationManager.super.get(coordinates);
}
// If the configuration was not found — use scope specific default one.
if (scopeSpecificTracingConfiguration == null)
return TracingConfigurationManager.super.get(coordinates);
// Retrieving scope + label specific tracing configuration.
TracingConfigurationParameters lbBasedTracingConfiguration =
scopeSpecificTracingConfiguration.get(coordinates.label());
// If scope + label specific was found — use it.
if (lbBasedTracingConfiguration != null)
return lbBasedTracingConfiguration;
// Retrieving scope specific tracing configuration.
TracingConfigurationParameters rawScopedTracingConfiguration = scopeSpecificTracingConfiguration.get(null);
// If scope specific was found — use it.
if (rawScopedTracingConfiguration != null)
return rawScopedTracingConfiguration;
// If neither scope + label specific nor just scope specific configuration was found —
// use scope specific default one.
return TracingConfigurationManager.super.get(coordinates);
}
/** {@inheritDoc} */
@SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType")
@Override public @NotNull Map<TracingConfigurationCoordinates, TracingConfigurationParameters> getAll(
@Nullable Scope scope
) {
DistributedMetaStorage metaStore = distributedMetaStorage(
true,
WARNING_FAILED_TO_RETRIEVE_CONFIG_METASTORAGE_NOT_AVAILABLE);
if (metaStore == null)
return DEFAULT_CONFIGURATION_MAP;
Map<TracingConfigurationCoordinates, TracingConfigurationParameters> res = new HashMap<>();
for (Scope scopeToRetrieve : scope == null ? Scope.values() : new Scope[] {scope}) {
String scopeSpecificKey = TRACING_CONFIGURATION_DISTRIBUTED_METASTORE_KEY_PREFIX + scopeToRetrieve.name();
try {
Map<String, TracingConfigurationParameters> scopeBasedTracingCfg = metaStore.read(scopeSpecificKey);
if (scopeBasedTracingCfg == null) {
res.put(
new TracingConfigurationCoordinates.Builder(scopeToRetrieve).build(),
DEFAULT_CONFIGURATION_MAP.get(
new TracingConfigurationCoordinates.Builder(scopeToRetrieve).build()));
continue;
}
// Null keys encapsulates scope specific configuration.
if (!scopeBasedTracingCfg.containsKey(null)) {
res.put(
new TracingConfigurationCoordinates.Builder(scopeToRetrieve).build(),
DEFAULT_CONFIGURATION_MAP.get(
new TracingConfigurationCoordinates.Builder(scopeToRetrieve).build()));
}
for (Map.Entry<String, TracingConfigurationParameters> entry :
((Map<String, TracingConfigurationParameters>)metaStore.read(scopeSpecificKey)).entrySet()) {
res.put(
new TracingConfigurationCoordinates.Builder(scopeToRetrieve).
withLabel(entry.getKey()).build(),
entry.getValue());
}
}
catch (IgniteCheckedException e) {
LT.warn(log, "Failed to retrieve tracing configuration");
}
}
return res;
}
/** {@inheritDoc} */
@Override public void reset(@NotNull TracingConfigurationCoordinates coordinates) {
DistributedMetaStorage metaStore = distributedMetaStorage(
false,
WARNING_MSG_TO_RESET_CONFIG_METASTORAGE_NOT_AVAILABLE,
coordinates);
String scopeSpecificKey = TRACING_CONFIGURATION_DISTRIBUTED_METASTORE_KEY_PREFIX + coordinates.scope().name();
boolean configurationSuccessfullyUpdated = false;
try {
while (!configurationSuccessfullyUpdated) {
HashMap<String, TracingConfigurationParameters> existingScopeSpecificTracingConfiguration =
metaStore.read(scopeSpecificKey);
if (existingScopeSpecificTracingConfiguration == null) {
// Nothing to do.
return;
}
HashMap<String, TracingConfigurationParameters> updatedScopeSpecificTracingConfiguration =
new HashMap<>(existingScopeSpecificTracingConfiguration);
if (coordinates.label() != null)
updatedScopeSpecificTracingConfiguration.remove(coordinates.label());
else
updatedScopeSpecificTracingConfiguration.remove(null);
configurationSuccessfullyUpdated = metaStore.compareAndSet(
scopeSpecificKey,
existingScopeSpecificTracingConfiguration,
updatedScopeSpecificTracingConfiguration);
}
}
catch (IgniteCheckedException e) {
log.warning(String.format(WARNING_MSG_TO_RESET_CONFIG_METASTORAGE_NOT_AVAILABLE, coordinates));
throw new IgniteException(
String.format(WARNING_MSG_TO_RESET_CONFIG_METASTORAGE_NOT_AVAILABLE, coordinates),
e);
}
}
/** {@inheritDoc} */
@Override public void resetAll(@Nullable Scope scope) throws IgniteException {
DistributedMetaStorage metaStore = distributedMetaStorage(
false,
WARNING_MSG_TO_RESET_ALL_CONFIG_METASTORAGE_NOT_AVAILABLE,
scope);
try {
for (Scope scopeItem : scope == null ? Scope.values() : new Scope[] {scope})
metaStore.remove(TRACING_CONFIGURATION_DISTRIBUTED_METASTORE_KEY_PREFIX + scopeItem.name());
}
catch (IgniteCheckedException e) {
log.warning(String.format(WARNING_MSG_TO_RESET_ALL_CONFIG_METASTORAGE_NOT_AVAILABLE, scope));
throw new IgniteException(
String.format(WARNING_MSG_TO_RESET_ALL_CONFIG_METASTORAGE_NOT_AVAILABLE, scope),
e);
}
}
/**
* Checks if metastore if available and return it.
*
* @param returnNull If {@code true} return null if distributed metastorage isn't available,
* otherwise throw {@code IgniteException}
* @param warningMsg Warning message to be logged and used in {@code IgniteException}
* @param warningMsgFormatArgs Arguments to warning message.
*
* @return Distributed metastorage if it's available.
*/
private DistributedMetaStorage distributedMetaStorage(boolean returnNull, String warningMsg, Object...warningMsgFormatArgs) {
DistributedMetaStorage metaStore;
try {
metaStore = ctx.distributedMetastorage();
}
catch (Exception e) {
log.warning(String.format(warningMsg, warningMsgFormatArgs));
if (returnNull)
return null;
else
throw new IgniteException(String.format(warningMsg, warningMsgFormatArgs), e);
}
if (metaStore == null) {
log.warning(String.format(warningMsg, warningMsgFormatArgs));
if (returnNull)
return null;
else
throw new IgniteException(String.format(warningMsg, warningMsgFormatArgs));
}
return metaStore;
}
}