<|start_filename|>karavan-app/src/main/java/org/apache/camel/karavan/api/IntegrationResource.java<|end_filename|>
/*
 * 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.camel.karavan.api;

import io.vertx.core.Vertx;
import org.apache.camel.karavan.service.CamelKService;
import org.apache.camel.karavan.service.FileSystemService;
import org.apache.camel.karavan.service.GitService;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.microprofile.config.inject.ConfigProperty;

import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Path("/integration")
public class IntegrationResource {

    private static final String GITOPS_MODE = "gitops";
    private static final String SERVERLESS_MODE = "serverless";

    @ConfigProperty(name = "karavan.mode", defaultValue = "local")
    String mode;

    @Inject
    Vertx vertx;

    @Inject
    GitService gitService;

    @Inject
    FileSystemService fileSystemService;

    @Inject
    CamelKService camelKService;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Map<String, String> getList(@HeaderParam("username") String username) throws GitAPIException, IOException {
        switch (mode){
            case SERVERLESS_MODE:
                return camelKService.getIntegrationList();
            case GITOPS_MODE:
                String dir = gitService.pullIntegrations(username);
                return fileSystemService.getIntegrationList(dir).stream().collect(Collectors.toMap(s -> s, s-> ""));
            default:
                return fileSystemService.getIntegrationList().stream().collect(Collectors.toMap(s -> s, s-> ""));
        }
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/{name}")
    public String getYaml(@HeaderParam("username") String username, @PathParam("name") String name) throws GitAPIException, IOException {
        switch (mode){
            case SERVERLESS_MODE:
                return camelKService.getIntegration(name);
            case GITOPS_MODE:
                String dir = gitService.pullIntegrations(username);
                return fileSystemService.getFile(dir, name);
            default:
                return fileSystemService.getIntegrationsFile(name);
        }
    }

    @POST
    @Produces(MediaType.TEXT_PLAIN)
    @Consumes(MediaType.TEXT_PLAIN)
    @Path("/{name}")
    public String save(@HeaderParam("username") String username, @PathParam("name") String name, String yaml) throws GitAPIException, IOException, URISyntaxException {
        switch (mode){
            case SERVERLESS_MODE:
                camelKService.applyIntegration(name, yaml);
                break;
            case GITOPS_MODE:
                gitService.save(username, name, yaml);
                break;
            default:
                fileSystemService.saveIntegrationsFile(name, yaml);
                break;
        }
        return yaml;
    }

    @PATCH
    @Produces(MediaType.TEXT_PLAIN)
    @Consumes(MediaType.TEXT_PLAIN)
    @Path("/{name}")
    public String publish(@HeaderParam("username") String username, @PathParam("name") String name, String yaml) throws GitAPIException, IOException, URISyntaxException {
        if (mode.equals(GITOPS_MODE)) {
            gitService.save(username, name, yaml);
            gitService.publish(username, name);
        }
        return yaml;
    }

    @DELETE
    @Path("/{name}")
    public void delete(@HeaderParam("username") String username, @PathParam("name") String name) throws GitAPIException, IOException, URISyntaxException {
        switch (mode){
            case SERVERLESS_MODE:
                camelKService.deleteIntegration(name);
                break;
            case GITOPS_MODE:
                gitService.delete(username, name);
                break;
            default:
                fileSystemService.deleteIntegration(name);
                break;
        }
    }
}

<|start_filename|>karavan-app/src/main/java/org/apache/camel/karavan/service/CamelKService.java<|end_filename|>
/*
 * 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.camel.karavan.service;

import io.fabric8.camelk.client.CamelKClient;
import io.fabric8.camelk.client.DefaultCamelKClient;
import io.fabric8.camelk.v1.Integration;
import io.fabric8.camelk.v1.IntegrationList;
import io.fabric8.camelk.v1.SourceSpec;
import io.vertx.core.Vertx;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.jboss.logging.Logger;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@ApplicationScoped
public class CamelKService {

    private CamelKClient camelk = new DefaultCamelKClient();

    private static final String header =
            "apiVersion: camel.apache.org/v1\n" +
            "kind: Integration\n" +
            "metadata:\n" +
            "  name: %s\n" +
            "spec:\n" +
            "  flows:\n";

    @Inject
    Vertx vertx;

    private static final Logger LOGGER = Logger.getLogger(CamelKService.class.getName());

    public Map<String, String> getIntegrationList() throws IOException {
        IntegrationList list = camelk.v1().integrations().inNamespace(getNamespace()).list();
        return list.getItems().stream()
                .collect(Collectors.toMap(i -> i.getMetadata().getName(),i -> i.getStatus().getPhase()));
    }

    public String getIntegration(String name) throws IOException {
        StringBuilder result = new StringBuilder(String.format(header, name));
        Integration i = camelk.v1().integrations().inNamespace(getNamespace()).withName(name).get();
        Optional<SourceSpec> spec = i.getStatus().getGeneratedSources().stream()
                .filter(s -> s.getContent() != null && !s.getContent().isEmpty())
                .findFirst();
        if (spec.isPresent()){
            String content = spec.get().getContent().lines().map(s -> "    ".concat(s)).collect(Collectors.joining("\n"));
            result.append(content);
        }
        System.out.println(result.toString());
        return result.toString();
    }

    public String getNamespace() throws IOException {
        try {
            return Files.readString(Paths.get("/var/run/secrets/kubernetes.io/serviceaccount/namespace"));
        } catch (Exception e){
            return "karavan";
        }
    }

    public List<String> getIntegrationList(String folder) {
        return vertx.fileSystem().readDirBlocking(Paths.get(folder).toString())
                .stream()
                .filter(s -> s.endsWith(".yaml"))
                .map(s -> {
                    String[] parts = s.split(Pattern.quote(File.separator));
                    return parts[parts.length - 1];
                }).collect(Collectors.toList());
    }

    public void applyIntegration(String name, String yaml) throws GitAPIException, IOException {
        Integration i = camelk.v1().integrations().load(new ByteArrayInputStream(yaml.getBytes())).get();
        camelk.v1().integrations().createOrReplace(i);
    }

    public Boolean deleteIntegration(String name) throws IOException {
        Integration i = camelk.v1().integrations().inNamespace(getNamespace()).withName(name).get();
        return camelk.v1().integrations().delete(i);
    }


}


<|start_filename|>karavan-app/src/main/java/org/apache/camel/karavan/api/KameletResources.java<|end_filename|>
/*
 * 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.camel.karavan.api;

import io.vertx.core.Vertx;
import org.eclipse.microprofile.config.inject.ConfigProperty;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Path("/kamelet")
public class KameletResources {

    @ConfigProperty(name = "karavan.folder.kamelets-buildin")
    String kameletsBuildin;

    @ConfigProperty(name = "karavan.folder.kamelets-custom")
    String kameletsCustom;

    @Inject
    Vertx vertx;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<String> getList() {
        List<String> kameletList = getList(kameletsBuildin);
        if (Files.exists(Paths.get(kameletsCustom))) {
            List<String> customKameletList = getList(kameletsCustom);
            kameletList.addAll(customKameletList);
        }
        return kameletList;
    }

    public List<String> getList(String folder) {
        return vertx.fileSystem().readDirBlocking(Paths.get(folder).toString())
                .stream()
                .filter(s -> s.endsWith(".yaml"))
                .map(s -> {
                    String[] parts = s.split(Pattern.quote(File.separator));
                    return parts[parts.length - 1];
                }).collect(Collectors.toList());
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/{name}")
    public String getYaml(@PathParam("name") String name) {
        if (Files.exists(Paths.get(kameletsBuildin, name))) {
            return vertx.fileSystem().readFileBlocking(Paths.get(kameletsBuildin, name).toString()).toString();
        } else {
            return vertx.fileSystem().readFileBlocking(Paths.get(kameletsCustom, name).toString()).toString();
        }
    }
}
