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

com.composum.ai.backend.slingbase.impl.SlingCaConfigPluginImpl Maven / Gradle / Ivy

Go to download

Common Functionality for Composum AI specific to Sling but would be useable in both Composum and AEM and similar.

There is a newer version: 1.2.1
Show newest version
package com.composum.ai.backend.slingbase.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.caconfig.ConfigurationBuilder;
import org.jetbrains.annotations.NotNull;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.composum.ai.backend.base.service.chat.GPTConfiguration;
import com.composum.ai.backend.slingbase.AIConfigurationPlugin;
import com.composum.ai.backend.slingbase.model.GPTPermissionConfiguration;
import com.composum.ai.backend.slingbase.model.GPTPromptLibrary;
import com.composum.ai.backend.slingbase.model.OpenAIConfig;

/**
 * Reads configurations using Sling context aware configuration.
 * Higher precedence than {@link OsgiAIConfigurationPluginImpl}.
 */
@Component(
        property = Constants.SERVICE_RANKING + ":Integer=1000"
)
@Designate(ocd = SlingCaConfigPluginImpl.Config.class)
public class SlingCaConfigPluginImpl implements AIConfigurationPlugin {

    private static final Logger LOG = LoggerFactory.getLogger(SlingCaConfigPluginImpl.class);
    private boolean enabled;

    @Override
    @Nullable
    public List allowedServices(@NotNull SlingHttpServletRequest request, @NotNull String contentPath) {
        if (!enabled) {
            return null;
        }
        LOG.debug("allowedServices({}, {})", request.getResource().getPath(), contentPath);
        Resource resource = determineResource(request.getResourceResolver(), request.getResource(), contentPath);
        if (resource == null) {
            return null;
        }

        ConfigurationBuilder confBuilder = Objects.requireNonNull(resource.adaptTo(ConfigurationBuilder.class));
        Collection configs = confBuilder.asCollection(GPTPermissionConfiguration.class);
        LOG.debug("found configs: {}", configs);
        return configs.isEmpty() ? null : new ArrayList<>(configs);
    }

    @Nullable
    @Override
    public GPTConfiguration getGPTConfiguration(@Nonnull ResourceResolver resourceResolver, @Nonnull String contentPath) throws IllegalArgumentException {
        if (!enabled) {
            return null;
        }
        LOG.debug("getGPTConfiguration({}, {})", contentPath);
        Resource resource = determineResource(resourceResolver, null, contentPath);
        if (resource == null) {
            return null;
        }

        ConfigurationBuilder confBuilder = Objects.requireNonNull(resource.adaptTo(ConfigurationBuilder.class));
        OpenAIConfig config = confBuilder.as(OpenAIConfig.class);
        GPTConfiguration result = null;
        if (StringUtils.isNotBlank(config.openAiApiKey())) {
            result = new GPTConfiguration(config.openAiApiKey(), config.openAiOrganizationId(), null);
        }
        LOG.debug("found key: {}", result);
        return result;
    }

    @Nullable
    @Override
    public GPTPromptLibrary getGPTPromptLibraryPaths(@NotNull SlingHttpServletRequest request, @Nullable String contentPath) {
        if (!enabled || contentPath == null) {
            return null;
        }
        LOG.debug("getGPTPromptLibraryPaths({}, {})", request.getResource().getPath(), contentPath);
        Resource resource = determineResource(request.getResourceResolver(), request.getResource(), contentPath);
        if (resource == null) {
            return null;
        }

        ConfigurationBuilder confBuilder = Objects.requireNonNull(resource.adaptTo(ConfigurationBuilder.class));
        GPTPromptLibrary config = confBuilder.as(GPTPromptLibrary.class);
        LOG.debug("found config: {}", config);
        return config;
    }

    /**
     * Determines the resource to use for the given request and content path.
     */
    @Nullable
    private static Resource determineResource(@Nonnull ResourceResolver resolver, @Nullable Resource requestResource, @Nonnull String contentPath) {
        Resource resource = requestResource;
        if (StringUtils.isNotBlank(contentPath)) {
            contentPath = contentPath.replace("_jcr_content", "jcr:content");
            resource = resolver.getResource(contentPath);
        }
        if (resource == null) {
            LOG.warn("No resource found for path {}", contentPath);
            return null;
        }
        if (!resource.getPath().startsWith("/content/")) {
            LOG.debug("Path {} is not a /content/ path", resource.getPath());
            return null;
        }
        return resource;
    }

    @Activate
    @Modified
    public void activate(Config config) {
        LOG.info("Activated with configuration {}", config);
        this.enabled = config.enabled();
    }

    @Deactivate
    public void deactivate() {
        LOG.info("Deactivated.");
        this.enabled = false;
    }

    @ObjectClassDefinition(name = "Composum AI SlingCaConfig Plugin", description = "Allows enabling / disabling the Sling Context Aware Configuration of the Composum AI.")
    public @interface Config {

        @AttributeDefinition(name = "Enabled", description = "Whether the Sling Context Aware Configuration of the Composum AI is enabled.")
        boolean enabled() default true;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy