Search code examples
javakubernetesfabric8

javax.ws.rs.WebApplicationException: HTTP 404 the server could not find the requested resource


I have been using the fabric8's Java Kubernetes Client API to build an application which creates Kubernetes replication controllers, as follows.

import io.fabric8.kubernetes.api.KubernetesClient;
import io.fabric8.kubernetes.api.KubernetesFactory;
import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.api.model.resource.Quantity;
import io.fabric8.kubernetes.client.KubernetesClientException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.stratos.kubernetes.client.interfaces.ReplicationControllerClientAPIInterface;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ReplicationControllerClientAPI implements ReplicationControllerClientAPIInterface {

    private final KubernetesClient kubernetesClient;

    private static final Log LOG = LogFactory.getLog(ReplicationControllerClientAPI.class);

    public ReplicationControllerClientAPI(String endpointURL) {
        kubernetesClient = new KubernetesClient(new KubernetesFactory(endpointURL));
        System.out.println(endpointURL);
    }

    public void createReplicationController(String replicationControllerID, String selectorLabel,
            int replicas, String containerName, String dockerImage, int cpu, int memory,
            List<ContainerPort> ports) throws KubernetesClientException {

        try {
            int memoryInMB = 1024 * 1024 * memory;
            if (LOG.isDebugEnabled()) {
                LOG.debug(String.format("Creating kubernetes replication-controller: [rc-id] %s "
                                + "[container-name] %s [docker-image] %s "
                                + "[cpu] %d [memory] %d MB [ports] %s",
                        replicationControllerID, containerName, dockerImage, cpu, memoryInMB, ports));
            }

            // Create replication-controller definition
            ReplicationController replicationController = new ReplicationController();

            replicationController.setApiVersion(ReplicationController.ApiVersion.V_1);
            replicationController.setKind(KubernetesConstantsExtended.KIND_REPLICATION_CONTROLLER);

            ObjectMeta replicationControllerMetaData = new ObjectMeta();
            replicationControllerMetaData.setName(replicationControllerID);
            replicationController.setMetadata(replicationControllerMetaData);

            ReplicationControllerSpec replicationControllerSpec = new ReplicationControllerSpec();
            replicationControllerSpec.setReplicas(replicas);

            // Setup label selectors for the replication controller
            Map<String, String> selectors = new HashMap<String, String>();
            selectors.put(KubernetesConstantsExtended.LABEL_NAME_REPLICATION_CONTROLLER, selectorLabel);
            replicationControllerSpec.setSelector(selectors);

            PodTemplateSpec podTemplateSpec = new PodTemplateSpec();

            ObjectMeta podMetaData = new ObjectMeta();
            podMetaData.setLabels(selectors);
            podTemplateSpec.setMetadata(podMetaData);

            PodSpec podSpec = new PodSpec();

            List<Container> containers = new ArrayList<Container>();
            // Create container definition
            Container container = new Container();
            container.setName(containerName);
            container.setImage(dockerImage);
            // Set resource limits
            ResourceRequirements resources = new ResourceRequirements();
            Map<String, Quantity> limits = new HashMap<String, Quantity>();
            limits.put(KubernetesConstants.RESOURCE_CPU, new Quantity(String.valueOf(cpu)));
            limits.put(KubernetesConstants.RESOURCE_MEMORY, new Quantity(String.valueOf(memoryInMB)));
            resources.setLimits(limits);
            container.setResources(resources);
            // Add container definition to the list of containers
            containers.add(container);

            podSpec.setContainers(containers);

            // Add Pod Spec to the Pod Template Spec
            podTemplateSpec.setSpec(podSpec);
            // Add Pod Template Spec to the ReplicationController Spec
            replicationControllerSpec.setTemplate(podTemplateSpec);
            // Add Replication Controller Spec to the Replication Controller instance
            replicationController.setSpec(replicationControllerSpec);

            // Create the replication-controller
            kubernetesClient.createReplicationController(replicationController);
        } catch (Exception e) {
            String message = String.format("Could not create kubernetes replication-controller: "
                    + "[rc-id] %s", replicationControllerID);
            LOG.error(message, e);
            throw new KubernetesClientException(message, e);
        }
    }

    public ReplicationController getReplicationController(String replicationControllerID)
            throws KubernetesClientException {
        try {
            return kubernetesClient.getReplicationController(replicationControllerID);
        } catch (Exception e) {
            String message = String.format("Could not retrieve kubernetes replication-controller"
                    + ": [rc-id] %s", replicationControllerID);
            LOG.error(message, e);
            throw new KubernetesClientException(message, e);
        }
    }

    public ReplicationControllerList getReplicationControllers()
            throws KubernetesClientException {
        try {
            return kubernetesClient.getReplicationControllers();
        } catch (Exception e) {
            String message = String.format("Could not retrieve kubernetes replication-controllers");
            LOG.error(message, e);
            throw new KubernetesClientException(message, e);
        }
    }

    public void deleteReplicationController(String replicationControllerID)
            throws KubernetesClientException {
        try {
            kubernetesClient.deleteReplicationController(replicationControllerID);
        } catch (Exception e) {
            String message = String.format("Could not delete kubernetes replication-controller"
                    + ": [rc-id] %s", replicationControllerID);
            LOG.error(message, e);
            throw new KubernetesClientException(message, e);
        }
    }
}

When I am executing the above code, I find that the application is throwing out the following exception.

javax.ws.rs.WebApplicationException: HTTP 404 the server could not find the requested resource
    at io.fabric8.kubernetes.api.ExceptionResponseMapper.fromResponse(ExceptionResponseMapper.java:44)
    at io.fabric8.kubernetes.api.ExceptionResponseMapper.fromResponse(ExceptionResponseMapper.java:35)
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.checkResponse(ClientProxyImpl.java:302)
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.handleResponse(ClientProxyImpl.java:725)
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.doChainedInvocation(ClientProxyImpl.java:683)
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.invoke(ClientProxyImpl.java:224)
    at com.sun.proxy.$Proxy18.createReplicationController(Unknown Source)
    at io.fabric8.kubernetes.api.KubernetesClient.createReplicationController(KubernetesClient.java:460)
    at io.fabric8.kubernetes.api.KubernetesClient.createReplicationController(KubernetesClient.java:450)
    at org.apache.stratos.kubernetes.client.ReplicationControllerClientAPI.createReplicationController(ReplicationControllerClientAPI.java:108)
    at org.apache.stratos.kubernetes.client.ReplicationControllerTestSuite.createReplicationController(ReplicationControllerTestSuite.java:44)
    at org.apache.stratos.kubernetes.client.ReplicationControllerTestExecutor.main(ReplicationControllerTestExecutor.java:22)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

Exception in thread "main" io.fabric8.kubernetes.client.KubernetesClientException: Could not create kubernetes replication-controller: [rc-id] helloworldrc
    at org.apache.stratos.kubernetes.client.ReplicationControllerClientAPI.createReplicationController(ReplicationControllerClientAPI.java:113)
    at org.apache.stratos.kubernetes.client.ReplicationControllerTestSuite.createReplicationController(ReplicationControllerTestSuite.java:44)
    at org.apache.stratos.kubernetes.client.ReplicationControllerTestExecutor.main(ReplicationControllerTestExecutor.java:22)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: javax.ws.rs.WebApplicationException: HTTP 404 the server could not find the requested resource
    at io.fabric8.kubernetes.api.ExceptionResponseMapper.fromResponse(ExceptionResponseMapper.java:44)
    at io.fabric8.kubernetes.api.ExceptionResponseMapper.fromResponse(ExceptionResponseMapper.java:35)
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.checkResponse(ClientProxyImpl.java:302)
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.handleResponse(ClientProxyImpl.java:725)
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.doChainedInvocation(ClientProxyImpl.java:683)
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.invoke(ClientProxyImpl.java:224)
    at com.sun.proxy.$Proxy18.createReplicationController(Unknown Source)
    at io.fabric8.kubernetes.api.KubernetesClient.createReplicationController(KubernetesClient.java:460)
    at io.fabric8.kubernetes.api.KubernetesClient.createReplicationController(KubernetesClient.java:450)
    at org.apache.stratos.kubernetes.client.ReplicationControllerClientAPI.createReplicationController(ReplicationControllerClientAPI.java:108)
    ... 7 more

Process finished with exit code 1

I have setup the endpoint URL of the KubernetesClient to http://127.0.0.1:8080 as I am running Kubernetes locally via Docker for testing purposes. I followed several previous posts related to similar issues but none of them seem to help me in this case.

I have set up the following environmental variables in my .bashrc.

export KUBERNETES_SERVICE_HOST=127.0.0.1
export KUBERNETES_SERVICE_PORT=8080

The following code samples are used to setup the KubernetesClient in my application.

private final ReplicationControllerClientAPIInterface REPLICATION_CONTROLLER_CLIENT;

    public ReplicationControllerTestSuite() {
        REPLICATION_CONTROLLER_CLIENT = new ReplicationControllerClientAPI("http://"
                + ReplicationControllerTestConstants.KUBERNETES_SERVICE_HOST + ":"
                + ReplicationControllerTestConstants.KUBERNETES_SERVICE_PORT);

//        REPLICATION_CONTROLLER_CLIENT = new ReplicationControllerClientAPI("http://localhost:8080");
    }

    public void createReplicationController(int replicas) {
        List<ContainerPort> exposedPorts = new ArrayList<ContainerPort>();
        ContainerPort port = new ContainerPort();
        port.setContainerPort(ReplicationControllerTestConstants.EXPOSED_PORT);
        exposedPorts.add(port);

        REPLICATION_CONTROLLER_CLIENT.createReplicationController(
                ReplicationControllerTestConstants.REPLICATION_CONTROLLER_ID, ReplicationControllerTestConstants.SELECTOR_LABEL,
                replicas, ReplicationControllerTestConstants.CONTAINER_NAME, ReplicationControllerTestConstants.DEFAULT_DOCKER_IMAGE,
                ReplicationControllerTestConstants.CPU_CORES, ReplicationControllerTestConstants.MEMORY_ALLOCATION, exposedPorts);
    }

The constants in the above code refer to the following:

    protected static final String KUBERNETES_SERVICE_HOST = "127.0.0.1";
    protected static final String KUBERNETES_SERVICE_PORT = "8080";
    protected static final String SELECTOR_LABEL = "helloworld";
    protected static final String REPLICATION_CONTROLLER_ID = "helloworldrc";
    // Container specific
    protected static final String DEFAULT_DOCKER_IMAGE = "helloworld";
    protected static final String CONTAINER_NAME = "helloworld";
    protected static final int CPU_CORES = 1;
    protected static final int MEMORY_ALLOCATION = 512;
    protected static final int EXPOSED_PORT = 8080;

Any help with regards to this issue is highly appreciated as my knowledge on REST API and Kubernetes is limited.


Solution

  • I managed to fix the above issue by avoiding the use of https://github.com/apache/stratos which is one dependency I am using in my code. I intended to use its already created capabilities such as KubernetesClientException in my code but the above issue seem to pop up due to this dependency.

    But, I am not entirely sure about the reason behind the particular issue.