Skip to content

Commit

Permalink
Provide mechanism to configure each extension on a separate level
Browse files Browse the repository at this point in the history
Signed-off-by: Yannic Klem <yannic.klem@bosch.io>
  • Loading branch information
Yannic92 committed Jul 8, 2022
1 parent 17d452c commit 9d36ce5
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.ditto.base.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import org.eclipse.ditto.base.service.DittoExtensionPoint.ExtensionId.ExtensionIdConfig;
import org.eclipse.ditto.internal.utils.akka.AkkaClassLoader;

import akka.actor.AbstractExtensionId;
import akka.actor.ActorSystem;
import akka.actor.ExtendedActorSystem;
import akka.actor.Extension;

public final class DittoExtensionIds implements Extension {

static final ExtensionId INSTANCE = new ExtensionId();
private final Map<ExtensionIdConfig<?>, DittoExtensionPoint.ExtensionId<?>> extensionIds = new HashMap<>();

public <T extends Extension> DittoExtensionPoint.ExtensionId<T> computeIfAbsent(
final ExtensionIdConfig<T> extensionIdConfig,
final Function<ExtensionIdConfig<T>, DittoExtensionPoint.ExtensionId<T>> extensionIdCreator) {
final DittoExtensionPoint.ExtensionId<T> extensionId =
(DittoExtensionPoint.ExtensionId<T>) extensionIds.get(extensionIdConfig);
if (extensionId == null) {
final DittoExtensionPoint.ExtensionId<T> newExtensionId = extensionIdCreator.apply(extensionIdConfig);
extensionIds.put(extensionIdConfig, newExtensionId);
return newExtensionId;
} else {
return extensionId;
}
}

public static DittoExtensionIds get(final ActorSystem actorSystem) {
return INSTANCE.get(actorSystem);
}

static final class ExtensionId extends AbstractExtensionId<DittoExtensionIds> {

@Override
public DittoExtensionIds createExtension(final ExtendedActorSystem system) {

return AkkaClassLoader.instantiate(system, DittoExtensionIds.class,
DittoExtensionIds.class.getCanonicalName(),
List.of(),
List.of());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@

import java.util.List;

import javax.annotation.Nullable;

import org.eclipse.ditto.internal.utils.akka.AkkaClassLoader;

import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;

import akka.actor.AbstractExtensionId;
import akka.actor.ActorSystem;
import akka.actor.ExtendedActorSystem;
Expand All @@ -34,31 +39,60 @@ public interface DittoExtensionPoint extends Extension {
*/
abstract class ExtensionId<T extends Extension> extends AbstractExtensionId<T> {

private final Class<T> parentClass;
private final ExtensionIdConfig<T> extensionIdConfig;

/**
* Returns the {@code ExtensionId} for the implementation that should be loaded.
*
* @param parentClass the class of the extensions for which an implementation should be loaded.
* @param extensionIdConfig configuration for the extension ID.
*/
public ExtensionId(final Class<T> parentClass) {
this.parentClass = parentClass;
protected ExtensionId(final ExtensionIdConfig<T> extensionIdConfig) {
this.extensionIdConfig = extensionIdConfig;
}

@Override
public T createExtension(final ExtendedActorSystem system) {
return AkkaClassLoader.instantiate(system, parentClass,
return AkkaClassLoader.instantiate(system, extensionIdConfig.parentClass,
getImplementation(system),
List.of(ActorSystem.class),
List.of(system));
List.of(ActorSystem.class, Config.class),
List.of(system, extensionIdConfig.extensionConfig));
}

protected String getImplementation(final ExtendedActorSystem actorSystem) {
return actorSystem.settings().config().getString(getConfigPath());
if (extensionIdConfig.extensionClass == null) {
return actorSystem.settings().config().getString(getConfigPath());
} else {
return extensionIdConfig.extensionClass;
}
}

protected abstract String getConfigPath();

public record ExtensionIdConfig<T extends Extension>(Class<T> parentClass,
@Nullable String extensionClass,
Config extensionConfig) {

public static <T extends Extension> ExtensionIdConfig<T> of(
final Class<T> parentClass,
final Config config) {

@Nullable final String extensionClass;
final Config extensionConfig;
if (config.hasPath("extension-class")) {
extensionClass = config.getString("extension-class");
} else {
extensionClass = null;
}
if (config.hasPath("extension-config")) {
extensionConfig = config.getConfig("extension-config");
} else {
extensionConfig = ConfigFactory.empty();
}
return new ExtensionIdConfig<>(parentClass, extensionClass, extensionConfig);
}
}

}

}

0 comments on commit 9d36ce5

Please sign in to comment.