From 1aecd4fae9df2671d17f7c86f5c988be92fc04b2 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Thu, 14 Nov 2024 18:09:57 +0100 Subject: [PATCH] Fix chaining in Java provider Signed-off-by: Juan Manuel Leflet Estrada --- demo-output.yaml | 14 ++++++++ .../pkg/java_external_provider/provider.go | 1 + .../java_external_provider/service_client.go | 36 +++++++++++++++---- provider/provider.go | 2 +- rule-example.yaml | 17 +++++++++ 5 files changed, 63 insertions(+), 7 deletions(-) diff --git a/demo-output.yaml b/demo-output.yaml index 5bc15d6a..44184ab5 100644 --- a/demo-output.yaml +++ b/demo-output.yaml @@ -998,6 +998,20 @@ kind: Class name: Configuration package: io.konveyor.demo.ordermanagement.config + java-chaining-01: + description: There should only be one instance of this rule + category: mandatory + incidents: + - uri: file:///examples/customers-tomcat-legacy/src/main/java/io/konveyor/demo/ordermanagement/OrderManagementAppInitializer.java + message: | + Sample message. This rule checks that the chaining conditions are working. Should only get a single issue. + codeSnip: " 3 import javax.servlet.ServletContext;\n 4 import javax.servlet.ServletException;\n 5 import javax.servlet.ServletRegistration;\n 6 \n 7 import org.springframework.web.WebApplicationInitializer;\n 8 import org.springframework.web.context.ContextLoaderListener;\n 9 import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;\n10 import org.springframework.web.servlet.DispatcherServlet;\n11 \n12 \n13 public class OrderManagementAppInitializer implements WebApplicationInitializer {\n14 \n15 \t@Override\n16 \tpublic void onStartup(ServletContext container) throws ServletException {\n17 \t\tAnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();\n18 context.setConfigLocation(\"io.konveyor.demo.ordermanagement.config\");\n19 \n20 context.scan(\"io.konveyor.demo.ordermanagement\");\n21 container.addListener(new ContextLoaderListener(context));\n22 \n23 ServletRegistration.Dynamic dispatcher = container" + lineNumber: 13 + variables: + file: file:///examples/customers-tomcat-legacy/src/main/java/io/konveyor/demo/ordermanagement/OrderManagementAppInitializer.java + kind: Class + name: OrderManagementAppInitializer + package: io.konveyor.demo.ordermanagement java-downloaded-maven-artifact: description: | This rule tests the application downloaded from maven artifact diff --git a/external-providers/java-external-provider/pkg/java_external_provider/provider.go b/external-providers/java-external-provider/pkg/java_external_provider/provider.go index d052a2a3..b5f27481 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/provider.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/provider.go @@ -97,6 +97,7 @@ type referenceCondition struct { Pattern string `yaml:"pattern"` Location string `yaml:"location"` Annotated annotated `yaml:"annotated,omitempty" json:"annotated,omitempty"` + Filepaths []string `yaml:"filepaths"` } type annotated struct { diff --git a/external-providers/java-external-provider/pkg/java_external_provider/service_client.go b/external-providers/java-external-provider/pkg/java_external_provider/service_client.go index ed2a6129..84bce600 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/service_client.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/service_client.go @@ -14,6 +14,7 @@ import ( "time" "github.com/go-logr/logr" + "github.com/konveyor/analyzer-lsp/engine" "github.com/konveyor/analyzer-lsp/jsonrpc2" "github.com/konveyor/analyzer-lsp/lsp/protocol" "github.com/konveyor/analyzer-lsp/provider" @@ -53,11 +54,21 @@ func (p *javaServiceClient) Evaluate(ctx context.Context, cap string, conditionI if err != nil { return provider.ProviderEvaluateResponse{}, fmt.Errorf("unable to get query info: %v", err) } + // filepaths get rendered as a string and must be converted + if cond.Referenced.Filepaths != nil { + cond.Referenced.Filepaths = strings.Split(cond.Referenced.Filepaths[0], " ") + } + + condCtx := &engine.ConditionContext{} + err = yaml.Unmarshal(conditionInfo, condCtx) + if err != nil { + return provider.ProviderEvaluateResponse{}, fmt.Errorf("unable to get condition context info: %v", err) + } if cond.Referenced.Pattern == "" { return provider.ProviderEvaluateResponse{}, fmt.Errorf("provided query pattern empty") } - symbols, err := p.GetAllSymbols(ctx, cond.Referenced.Pattern, cond.Referenced.Location, cond.Referenced.Annotated) + symbols, err := p.GetAllSymbols(ctx, *cond) if err != nil { p.log.Error(err, "unable to get symbols", "symbols", symbols, "cap", cap, "conditionInfo", cond) return provider.ProviderEvaluateResponse{}, err @@ -110,19 +121,19 @@ func (p *javaServiceClient) Evaluate(ctx context.Context, cap string, conditionI }, nil } -func (p *javaServiceClient) GetAllSymbols(ctx context.Context, query, location string, annotation annotated) ([]protocol.WorkspaceSymbol, error) { +func (p *javaServiceClient) GetAllSymbols(ctx context.Context, c javaCondition) ([]protocol.WorkspaceSymbol, error) { // This command will run the added bundle to the language server. The command over the wire needs too look like this. // in this case the project is hardcoded in the init of the Langauge Server above // workspace/executeCommand '{"command": "io.konveyor.tackle.ruleEntry", "arguments": {"query":"*customresourcedefinition","project": "java"}}' argumentsMap := map[string]interface{}{ - "query": query, + "query": c.Referenced.Pattern, "project": "java", - "location": fmt.Sprintf("%v", locationToCode[strings.ToLower(location)]), + "location": fmt.Sprintf("%v", locationToCode[strings.ToLower(c.Referenced.Location)]), "analysisMode": string(p.config.AnalysisMode), } - if !reflect.DeepEqual(annotation, annotated{}) { - argumentsMap["annotationQuery"] = annotation + if !reflect.DeepEqual(c.Referenced.Annotated, annotated{}) { + argumentsMap["annotationQuery"] = c.Referenced.Annotated } if p.includedPaths != nil && len(p.includedPaths) > 0 { @@ -152,6 +163,19 @@ func (p *javaServiceClient) GetAllSymbols(ctx context.Context, query, location s } } + if c.Referenced.Filepaths != nil { + // filter according to the given filepaths + var filteredRefs []protocol.WorkspaceSymbol + for _, ref := range refs { + for _, fp := range c.Referenced.Filepaths { + if strings.HasSuffix(ref.Location.Value.(protocol.Location).URI, fp) { + filteredRefs = append(filteredRefs, ref) + } + } + } + return filteredRefs, nil + } + return refs, nil } diff --git a/provider/provider.go b/provider/provider.go index 6dbdb507..be51ffe8 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -611,7 +611,7 @@ func templateCondition(condition []byte, ctx map[string]engine.ChainTemplate) ([ s := strings.ReplaceAll(string(condition), `'{{`, "{{") s = strings.ReplaceAll(s, `}}'`, "}}") - s, err := mustache.Render(s, true, ctx) + s, err := mustache.RenderRaw(s, true, ctx) if err != nil { return nil, err } diff --git a/rule-example.yaml b/rule-example.yaml index a6f563ff..40743bfe 100644 --- a/rule-example.yaml +++ b/rule-example.yaml @@ -402,3 +402,20 @@ elements: - name: basePackages value: "io.konveyor.demo.ordermanagement.repository" +- ruleID: java-chaining-01 + category: mandatory + description: "There should only be one instance of this rule" + message: | + Sample message. This rule checks that the chaining conditions are working. Should only get a single issue. + when: + and: + - java.referenced: + pattern: java.lang.Override + location: ANNOTATION + as: class + ignore: true + - java.referenced: + pattern: org.springframework.web.WebApplicationInitializer + location: IMPLEMENTS_TYPE + filepaths: "{{class.Filepaths}}" + from: class