This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new 7c5b8d8b fix(mcp-server-contributions): remove bundle and component 
resources
7c5b8d8b is described below

commit 7c5b8d8bceb4dc0f766f8062aed89776634ba277
Author: Robert Munteanu <[email protected]>
AuthorDate: Fri Mar 13 13:30:40 2026 +0100

    fix(mcp-server-contributions): remove bundle and component resources
    
    The OsgiBundleDiagnosticContribution should be enough for diagnosing 
OSGi-related issues
---
 .../impl/contribs/BundleResourceContribution.java  | 142 ---------------------
 .../mcp/server/impl/contribs/BundleState.java      |  57 ---------
 .../contribs/ComponentResourceContribution.java    | 125 ------------------
 3 files changed, 324 deletions(-)

diff --git 
a/mcp-server-contributions/src/main/java/org/apache/sling/mcp/server/impl/contribs/BundleResourceContribution.java
 
b/mcp-server-contributions/src/main/java/org/apache/sling/mcp/server/impl/contribs/BundleResourceContribution.java
deleted file mode 100644
index 1d37db39..00000000
--- 
a/mcp-server-contributions/src/main/java/org/apache/sling/mcp/server/impl/contribs/BundleResourceContribution.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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.sling.mcp.server.impl.contribs;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import io.modelcontextprotocol.server.McpStatelessServerFeatures;
-import 
io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncCompletionSpecification;
-import 
io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncResourceSpecification;
-import 
io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncResourceTemplateSpecification;
-import io.modelcontextprotocol.spec.McpSchema;
-import io.modelcontextprotocol.spec.McpSchema.ReadResourceResult;
-import io.modelcontextprotocol.spec.McpSchema.Resource;
-import io.modelcontextprotocol.spec.McpSchema.ResourceTemplate;
-import io.modelcontextprotocol.spec.McpSchema.TextResourceContents;
-import org.apache.sling.mcp.server.spi.McpServerContribution;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-
-@Component
-public class BundleResourceContribution implements McpServerContribution {
-
-    private static final String URI_BUNDLES_ALL = "bundles://all";
-    private static final String RESOURCE_TEMPLATE_BUNDLES_STATE_PREFIX = 
"bundles://state/";
-    private static final String RESOURCE_TEMPLATE_BUNDLES_STATE_PATTERN =
-            RESOURCE_TEMPLATE_BUNDLES_STATE_PREFIX + "{state}";
-
-    private BundleContext ctx;
-
-    @Activate
-    public BundleResourceContribution(BundleContext ctx) {
-        this.ctx = ctx;
-    }
-
-    @Override
-    public List<SyncResourceSpecification> getSyncResourceSpecification() {
-
-        return List.of(new 
McpStatelessServerFeatures.SyncResourceSpecification(
-                new Resource.Builder()
-                        .name("bundles")
-                        .uri(URI_BUNDLES_ALL)
-                        .description(
-                                "List all OSGi bundles with symbolic name, 
version, and state. Fragment bundles are marked with [Fragment]")
-                        .mimeType("text/plain")
-                        .build(),
-                (context, request) -> {
-                    String bundleInfo =
-                            
Stream.of(ctx.getBundles()).map(this::describe).collect(Collectors.joining("\n"));
-
-                    TextResourceContents contents = new 
TextResourceContents(URI_BUNDLES_ALL, "text/plain", bundleInfo);
-
-                    return new McpSchema.ReadResourceResult(List.of(contents));
-                }));
-    }
-
-    @Override
-    public List<SyncResourceTemplateSpecification> 
getSyncResourceTemplateSpecification() {
-        return List.of(new 
McpStatelessServerFeatures.SyncResourceTemplateSpecification(
-                new ResourceTemplate.Builder()
-                        .uriTemplate(RESOURCE_TEMPLATE_BUNDLES_STATE_PATTERN)
-                        .name("bundles")
-                        .build(),
-                (context, request) -> {
-                    String requestedState = 
request.uri().substring(RESOURCE_TEMPLATE_BUNDLES_STATE_PREFIX.length());
-                    try {
-                        BundleState bundleState = 
BundleState.valueOf(requestedState.toUpperCase(Locale.ENGLISH));
-                        if (!bundleState.isValid()) {
-                            throw new IllegalArgumentException("Invalid bundle 
state: " + requestedState);
-                        }
-                        String bundleInfo = Arrays.stream(ctx.getBundles())
-                                .filter(b -> b.getState() == 
bundleState.getState())
-                                .map(this::describe)
-                                .collect(Collectors.joining("\n"));
-
-                        TextResourceContents contents =
-                                new TextResourceContents(request.uri(), 
"text/plain", bundleInfo);
-
-                        return new ReadResourceResult(List.of(contents));
-                    } catch (IllegalArgumentException e) {
-                        return new ReadResourceResult(List.of(new 
TextResourceContents(
-                                request.uri(), "text/plain", "Invalid bundle 
state requested: " + requestedState)));
-                    }
-                }));
-    }
-
-    @Override
-    public List<SyncCompletionSpecification> getSyncCompletionSpecification() {
-
-        return List.of(new 
McpStatelessServerFeatures.SyncCompletionSpecification(
-                new McpSchema.ResourceReference("ref/resource", 
RESOURCE_TEMPLATE_BUNDLES_STATE_PATTERN),
-                (context, request) -> {
-
-                    // expect argument name to always be "state"
-                    String requestedState = request.argument().value();
-                    List<String> states = Stream.of(BundleState.values())
-                            .filter(BundleState::isValid)
-                            .map(s -> s.name().toLowerCase(Locale.ENGLISH))
-                            .toList();
-                    if (requestedState != null && !requestedState.isEmpty()) {
-                        states = states.stream()
-                                .filter(s -> 
s.startsWith(requestedState.toLowerCase(Locale.ENGLISH)))
-                                .toList();
-                    }
-                    return new McpSchema.CompleteResult(
-                            new 
McpSchema.CompleteResult.CompleteCompletion(states, states.size(), false));
-                }));
-    }
-
-    private String describe(Bundle b) {
-        boolean isFragment = 
Optional.ofNullable(b.adapt(BundleRevision.class)).stream()
-                .map(br -> (br.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0)
-                .findAny()
-                .orElse(false);
-        String additionalInfo = isFragment ? " [Fragment]" : "";
-        return "Bundle " + b.getSymbolicName() + additionalInfo + " (version " 
+ b.getVersion() + ") is in state "
-                + BundleState.fromState(b.getState()) + " (" + b.getState() + 
")";
-    }
-}
diff --git 
a/mcp-server-contributions/src/main/java/org/apache/sling/mcp/server/impl/contribs/BundleState.java
 
b/mcp-server-contributions/src/main/java/org/apache/sling/mcp/server/impl/contribs/BundleState.java
deleted file mode 100644
index 29e5bba8..00000000
--- 
a/mcp-server-contributions/src/main/java/org/apache/sling/mcp/server/impl/contribs/BundleState.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.sling.mcp.server.impl.contribs;
-
-import org.osgi.framework.Bundle;
-
-/**
- * Enum representing OSGi bundle states.
- */
-public enum BundleState {
-    UNINSTALLED(Bundle.UNINSTALLED),
-    INSTALLED(Bundle.INSTALLED),
-    RESOLVED(Bundle.RESOLVED),
-    STARTING(Bundle.STARTING),
-    STOPPING(Bundle.STOPPING),
-    ACTIVE(Bundle.ACTIVE),
-    UNKNOWN(-1);
-
-    private final int state;
-
-    BundleState(int state) {
-        this.state = state;
-    }
-
-    public static BundleState fromState(int state) {
-        for (BundleState bs : values()) {
-            if (bs.state == state) {
-                return bs;
-            }
-        }
-        return UNKNOWN;
-    }
-
-    public boolean isValid() {
-        return this != UNKNOWN;
-    }
-
-    public int getState() {
-        return state;
-    }
-}
diff --git 
a/mcp-server-contributions/src/main/java/org/apache/sling/mcp/server/impl/contribs/ComponentResourceContribution.java
 
b/mcp-server-contributions/src/main/java/org/apache/sling/mcp/server/impl/contribs/ComponentResourceContribution.java
deleted file mode 100644
index e0c18bce..00000000
--- 
a/mcp-server-contributions/src/main/java/org/apache/sling/mcp/server/impl/contribs/ComponentResourceContribution.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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.sling.mcp.server.impl.contribs;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Locale;
-import java.util.stream.Collectors;
-
-import io.modelcontextprotocol.server.McpStatelessServerFeatures;
-import 
io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncResourceSpecification;
-import 
io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncResourceTemplateSpecification;
-import io.modelcontextprotocol.spec.McpSchema;
-import io.modelcontextprotocol.spec.McpSchema.ReadResourceResult;
-import io.modelcontextprotocol.spec.McpSchema.Resource;
-import io.modelcontextprotocol.spec.McpSchema.ResourceTemplate;
-import io.modelcontextprotocol.spec.McpSchema.TextResourceContents;
-import org.apache.sling.mcp.server.spi.McpServerContribution;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.runtime.ServiceComponentRuntime;
-import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO;
-
-@Component
-public class ComponentResourceContribution implements McpServerContribution {
-
-    private static String getStateString(int state) {
-        return switch (state) {
-            case 1 -> "UNSATISFIED_CONFIGURATION";
-            case 2 -> "UNSATISFIED_REFERENCE";
-            case 4 -> "SATISFIED";
-            case 8 -> "ACTIVE";
-            case 16 -> "REGISTERED";
-            case 32 -> "FACTORY";
-            case 64 -> "DISABLED";
-            case 128 -> "ENABLING";
-            case 256 -> "ENABLED";
-            case 512 -> "DISABLING";
-            default -> "UNKNOWN";
-        };
-    }
-
-    @Reference
-    private ServiceComponentRuntime scr;
-
-    @Activate
-    public ComponentResourceContribution() {}
-
-    @Override
-    public List<SyncResourceSpecification> getSyncResourceSpecification() {
-
-        return List.of(new 
McpStatelessServerFeatures.SyncResourceSpecification(
-                new Resource.Builder()
-                        .name("component")
-                        .uri("component://")
-                        .description("OSGi component status")
-                        .mimeType("text/plain")
-                        .build(),
-                (context, request) -> {
-                    Collection<ComponentDescriptionDTO> components = 
scr.getComponentDescriptionDTOs();
-                    String componentInfo = components.stream()
-                            .map(c -> {
-                                String state = 
scr.getComponentConfigurationDTOs(c).stream()
-                                        .map(config -> 
getStateString(config.state))
-                                        .collect(Collectors.joining(", "));
-                                return "Component " + c.name + " is in 
state(s): " + state;
-                            })
-                            .collect(Collectors.joining("\n"));
-
-                    TextResourceContents contents =
-                            new TextResourceContents("component://", 
"text/plain", componentInfo);
-
-                    return new McpSchema.ReadResourceResult(List.of(contents));
-                }));
-    }
-
-    @Override
-    public List<SyncResourceTemplateSpecification> 
getSyncResourceTemplateSpecification() {
-        return List.of(new 
McpStatelessServerFeatures.SyncResourceTemplateSpecification(
-                new ResourceTemplate.Builder()
-                        .uriTemplate("components://state/{state}")
-                        .name("components")
-                        .build(),
-                (context, request) -> {
-                    String componentInfo = "";
-                    String uri = request.uri().toLowerCase(Locale.ENGLISH);
-
-                    if (uri.startsWith("components://state/")) {
-                        String requestedState = 
uri.substring("components://state/".length());
-                        Collection<ComponentDescriptionDTO> components = 
scr.getComponentDescriptionDTOs();
-
-                        componentInfo = components.stream()
-                                .flatMap(c -> 
scr.getComponentConfigurationDTOs(c).stream()
-                                        .filter(config -> 
getStateString(config.state)
-                                                .toLowerCase(Locale.ENGLISH)
-                                                .equals(requestedState))
-                                        .map(config -> "Component " + c.name + 
" is in state: "
-                                                + 
getStateString(config.state)))
-                                .collect(Collectors.joining("\n"));
-                    }
-
-                    TextResourceContents contents =
-                            new TextResourceContents(request.uri(), 
"text/plain", componentInfo);
-
-                    return new ReadResourceResult(List.of(contents));
-                }));
-    }
-}

Reply via email to