| /* |
| 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 trait |
| |
| import ( |
| "errors" |
| "fmt" |
| "io/ioutil" |
| "os" |
| "path" |
| "path/filepath" |
| "strconv" |
| "strings" |
| |
| "github.com/apache/camel-k/pkg/util/kubernetes" |
| |
| corev1 "k8s.io/api/core/v1" |
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
| |
| "github.com/apache/camel-k/pkg/gzip" |
| |
| "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" |
| "github.com/apache/camel-k/pkg/util/defaults" |
| "github.com/apache/camel-k/pkg/util/maven" |
| ) |
| |
| type restDslTrait struct { |
| BaseTrait `property:",squash"` |
| } |
| |
| func newRestDslTrait() *restDslTrait { |
| return &restDslTrait{ |
| BaseTrait: newBaseTrait("rest-dsl"), |
| } |
| } |
| |
| func (t *restDslTrait) Configure(e *Environment) (bool, error) { |
| if t.Enabled != nil && !*t.Enabled { |
| return false, nil |
| } |
| |
| if e.Integration == nil { |
| return false, nil |
| } |
| |
| for _, resource := range e.Integration.Spec.Resources { |
| if resource.Type == v1alpha1.ResourceTypeOpenAPI { |
| return e.IntegrationInPhase(v1alpha1.IntegrationPhaseInitialization), nil |
| } |
| } |
| |
| return false, nil |
| } |
| |
| func (t *restDslTrait) Apply(e *Environment) error { |
| if len(e.Integration.Spec.Resources) == 0 { |
| return nil |
| } |
| |
| root := os.TempDir() |
| tmpDir, err := ioutil.TempDir(root, "rest-dsl") |
| if err != nil { |
| return err |
| } |
| |
| defer os.RemoveAll(tmpDir) |
| |
| for i, resource := range e.Integration.Spec.Resources { |
| if resource.Type != v1alpha1.ResourceTypeOpenAPI { |
| continue |
| } |
| |
| tmpDir = path.Join(tmpDir, strconv.Itoa(i)) |
| err := os.MkdirAll(tmpDir, os.ModePerm) |
| if err != nil { |
| return err |
| } |
| |
| content := []byte(resource.Content) |
| if resource.Compression { |
| content, err = gzip.UncompressBase64(content) |
| if err != nil { |
| return err |
| } |
| } |
| |
| in := path.Join(tmpDir, "openapi-spec.json") |
| out := path.Join(tmpDir, "openapi-dsl.xml") |
| |
| err = ioutil.WriteFile(in, content, 0644) |
| if err != nil { |
| return err |
| } |
| |
| project, err := t.generateMavenProject(e) |
| if err != nil { |
| return err |
| } |
| |
| mc := maven.NewContext(tmpDir, project) |
| mc.LocalRepository = e.Platform.Spec.Build.LocalRepository |
| mc.Timeout = e.Platform.Spec.Build.Maven.Timeout.Duration |
| mc.AddArgument("-Dopenapi.spec=" + in) |
| mc.AddArgument("-Ddsl.out=" + out) |
| |
| settings, err := kubernetes.ResolveValueSource(e.C, e.Client, e.Integration.Namespace, &e.Platform.Spec.Build.Maven.Settings) |
| if err != nil { |
| return err |
| } |
| if settings != "" { |
| mc.SettingsContent = []byte(settings) |
| } |
| |
| err = maven.Run(mc) |
| if err != nil { |
| return err |
| } |
| |
| content, err = ioutil.ReadFile(out) |
| if err != nil { |
| return err |
| } |
| |
| if resource.Compression { |
| c, err := gzip.CompressBase64(content) |
| if err != nil { |
| return nil |
| } |
| |
| content = c |
| } |
| |
| generatedContentName := fmt.Sprintf("%s-openapi-%03d", e.Integration.Name, i) |
| generatedSourceName := strings.TrimSuffix(resource.Name, filepath.Ext(resource.Name)) + ".xml" |
| generatedSources := make([]v1alpha1.SourceSpec, 0, len(e.Integration.Status.GeneratedSources)) |
| |
| if e.Integration.Status.GeneratedSources != nil { |
| // |
| // Filter out the previously generated source |
| // |
| for _, x := range e.Integration.Status.GeneratedSources { |
| if x.Name != generatedSourceName { |
| generatedSources = append(generatedSources, x) |
| } |
| } |
| } |
| |
| // |
| // Add an additional source that references the config map |
| // |
| generatedSources = append(generatedSources, v1alpha1.SourceSpec{ |
| DataSpec: v1alpha1.DataSpec{ |
| Name: generatedSourceName, |
| ContentRef: generatedContentName, |
| Compression: resource.Compression, |
| }, |
| Language: v1alpha1.LanguageXML, |
| }) |
| |
| // |
| // Store the generated rest xml in a separate config map in order |
| // not to pollute the integration with generated data |
| // |
| cm := corev1.ConfigMap{ |
| TypeMeta: metav1.TypeMeta{ |
| Kind: "ConfigMap", |
| APIVersion: "v1", |
| }, |
| ObjectMeta: metav1.ObjectMeta{ |
| Name: generatedContentName, |
| Namespace: e.Integration.Namespace, |
| Labels: map[string]string{ |
| "camel.apache.org/integration": e.Integration.Name, |
| }, |
| Annotations: map[string]string{ |
| "camel.apache.org/source.language": string(v1alpha1.LanguageXML), |
| "camel.apache.org/source.name": resource.Name, |
| "camel.apache.org/source.compression": strconv.FormatBool(resource.Compression), |
| "camel.apache.org/source.generated": "true", |
| "camel.apache.org/source.type": string(v1alpha1.ResourceTypeOpenAPI), |
| }, |
| }, |
| Data: map[string]string{ |
| "content": string(content), |
| }, |
| } |
| |
| e.Integration.Status.GeneratedSources = generatedSources |
| e.Resources.Add(&cm) |
| } |
| |
| return nil |
| } |
| |
| func (t *restDslTrait) generateMavenProject(e *Environment) (maven.Project, error) { |
| if e.CamelCatalog == nil { |
| return maven.Project{}, errors.New("unknown camel catalog") |
| } |
| |
| p := maven.NewProjectWithGAV("org.apache.camel.k.integration", "camel-k-rest-dsl-generator", defaults.Version) |
| p.Build = &maven.Build{ |
| DefaultGoal: "generate-resources", |
| Plugins: []maven.Plugin{ |
| { |
| GroupID: "org.apache.camel.k", |
| ArtifactID: "camel-k-maven-plugin", |
| Version: e.RuntimeVersion, |
| Executions: []maven.Execution{ |
| { |
| Phase: "generate-resources", |
| Goals: []string{ |
| "generate-rest-xml", |
| }, |
| }, |
| }, |
| Dependencies: []maven.Dependency{ |
| { |
| GroupID: "org.apache.camel", |
| ArtifactID: "camel-swagger-rest-dsl-generator", |
| Version: e.CamelCatalog.Version, |
| }, |
| }, |
| }, |
| }, |
| } |
| |
| return p, nil |
| } |