Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Temptative solution for basic annotation inspection #621

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions demo-output.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@
codeSnip: " 1 package io.jeffchao.template.server;\n 2 \n 3 import java.io.IOException;\n 4 import java.io.OutputStream;\n 5 import java.net.InetSocketAddress;\n 6 \n 7 import com.sun.net.httpserver.HttpExchange;\n 8 import com.sun.net.httpserver.HttpHandler;\n 9 import com.sun.net.httpserver.HttpServer;\n10 \n11 public class Server {\n12 \n13 public static void main(String[] args) throws IOException {\n14 String portString = System.getenv(\"PORT\");\n15 int port = portString == null ? 8080 : Integer.valueOf(portString);\n16 HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);\n17 server.createContext(\"/\", new MyHandler());"
lineNumber: 7
variables:
containerName: ""
file: file:///examples/gradle-multi-project-example/template-server/src/main/java/io/jeffchao/template/server/Server.java
kind: Module
name: com.sun.net.httpserver.HttpExchange
Expand All @@ -380,6 +381,7 @@
codeSnip: "14 String portString = System.getenv(\"PORT\");\n15 int port = portString == null ? 8080 : Integer.valueOf(portString);\n16 HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);\n17 server.createContext(\"/\", new MyHandler());\n18 server.setExecutor(null); // creates a default executor\n19 server.start();\n20 }\n21 \n22 static class MyHandler implements HttpHandler {\n23 @Override\n24 public void handle(HttpExchange t) throws IOException {\n25 String response = \"Hello from Gradle!\";\n26 t.sendResponseHeaders(200, response.length());\n27 OutputStream os = t.getResponseBody();\n28 os.write(response.getBytes());\n29 os.close();\n30 }\n31 }\n32 }\n"
lineNumber: 24
variables:
containerName: MyHandler
file: file:///examples/gradle-multi-project-example/template-server/src/main/java/io/jeffchao/template/server/Server.java
kind: Method
name: handle
Expand All @@ -394,6 +396,7 @@
codeSnip: " 1 package io.konveyor.util;\n 2 \n 3 import java.io.File;\n 4 \n 5 public class FileReader {\n 6 public static boolean fileExists() {\n 7 File file = new File(\"/test\");\n 8 return true;\n 9 }\n10 }\n"
lineNumber: 3
variables:
containerName: ""
file: file:///examples/inclusion-tests/src/main/java/io/konveyor/util/FileReader.java
kind: Module
name: java.io.File
Expand All @@ -403,6 +406,7 @@
codeSnip: " 1 package io.konveyor.util;\n 2 \n 3 import java.io.File;\n 4 \n 5 public class FileReader {\n 6 public static boolean fileExists() {\n 7 File file = new File(\"/test\");\n 8 return true;\n 9 }\n10 }\n"
lineNumber: 7
variables:
containerName: FileReader
file: file:///examples/inclusion-tests/src/main/java/io/konveyor/util/FileReader.java
kind: Method
name: fileExists
Expand Down Expand Up @@ -488,6 +492,7 @@
codeSnip: " 1 package com.example.apps;\n 2 \n 3 import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition;\n 4 \n 5 public class App \n 6 {\n 7 \n 8 /**\n 9 * {@link CustomResourceDefinition}\n10 * @param args\n11 */\n12 public static void main( String[] args )\n13 {"
lineNumber: 3
variables:
containerName: ""
file: file:///examples/java/example/src/main/java/com/example/apps/App.java
kind: Module
name: io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition
Expand All @@ -497,6 +502,7 @@
codeSnip: " 4 \n 5 public class App \n 6 {\n 7 \n 8 /**\n 9 * {@link CustomResourceDefinition}\n10 * @param args\n11 */\n12 public static void main( String[] args )\n13 {\n14 CustomResourceDefinition crd = new CustomResourceDefinition();\n15 System.out.println( crd );\n16 \n17 GenericClass<String> element = new GenericClass<String>(\"Hello world!\");\n18 element.get();\n19 }\n20 }\n"
lineNumber: 14
variables:
containerName: App
file: file:///examples/java/example/src/main/java/com/example/apps/App.java
kind: Method
name: main
Expand All @@ -511,6 +517,7 @@
codeSnip: " 4 \n 5 public class App \n 6 {\n 7 \n 8 /**\n 9 * {@link CustomResourceDefinition}\n10 * @param args\n11 */\n12 public static void main( String[] args )\n13 {\n14 CustomResourceDefinition crd = new CustomResourceDefinition();\n15 System.out.println( crd );\n16 \n17 GenericClass<String> element = new GenericClass<String>(\"Hello world!\");\n18 element.get();\n19 }\n20 }\n"
lineNumber: 14
variables:
containerName: App
file: file:///examples/java/example/src/main/java/com/example/apps/App.java
kind: Method
name: main
Expand All @@ -520,6 +527,7 @@
codeSnip: " 1 package com.example.apps;\n 2 \n 3 import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition;\n 4 \n 5 public class App \n 6 {\n 7 \n 8 /**\n 9 * {@link CustomResourceDefinition}\n10 * @param args\n11 */\n12 public static void main( String[] args )\n13 {"
lineNumber: 3
variables:
containerName: ""
file: file:///examples/java/example/src/main/java/com/example/apps/App.java
kind: Module
name: io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition
Expand All @@ -535,6 +543,7 @@
lineNumber: 18
variables:
VariableName: element
containerName: App
file: file:///examples/java/example/src/main/java/com/example/apps/App.java
kind: Method
name: main
Expand Down Expand Up @@ -604,6 +613,7 @@
codeSnip: " 1 package com.example.apps;\n 2 \n 3 import javax.ejb.SessionBean;\n 4 import javax.ejb.Singleton;\n 5 \n 6 @Singleton\n 7 public abstract class Bean implements SessionBean {\n 8 \n 9 }\n"
lineNumber: 6
variables:
containerName: Bean
file: file:///examples/java/example/src/main/java/com/example/apps/Bean.java
kind: Class
name: Singleton
Expand All @@ -613,6 +623,7 @@
codeSnip: " 1 package com.example.apps;\n 2 \n 3 import javax.ejb.SessionBean;\n 4 import javax.ejb.Singleton;\n 5 \n 6 @Singleton\n 7 public abstract class Bean implements SessionBean {\n 8 \n 9 }\n"
lineNumber: 7
variables:
containerName: Bean.java
file: file:///examples/java/example/src/main/java/com/example/apps/Bean.java
kind: Class
name: Bean
Expand All @@ -627,6 +638,7 @@
codeSnip: " 1 package com.example.apps;\n 2 \n 3 import javax.ejb.SessionBean;\n 4 import javax.ejb.Singleton;\n 5 \n 6 @Singleton\n 7 public abstract class Bean implements SessionBean {\n 8 \n 9 }\n"
lineNumber: 6
variables:
containerName: Bean
file: file:///examples/java/example/src/main/java/com/example/apps/Bean.java
kind: Class
name: Singleton
Expand All @@ -636,6 +648,7 @@
codeSnip: " 1 package com.example.apps;\n 2 \n 3 import javax.ejb.SessionBean;\n 4 import javax.ejb.Singleton;\n 5 \n 6 @Singleton\n 7 public abstract class Bean implements SessionBean {\n 8 \n 9 }\n"
lineNumber: 7
variables:
containerName: Bean.java
file: file:///examples/java/example/src/main/java/com/example/apps/Bean.java
kind: Class
name: Bean
Expand Down Expand Up @@ -899,6 +912,22 @@
matchingXML: ""
effort: 1
insights:
java-annotation-inspection-01:
description: |
This rule looks for a certain class annotated with a certain annotation
labels:
- tag=Java Operator SDK
incidents:
- uri: file:///examples/java/example/src/main/java/com/example/apps/Bean.java
message: ""
codeSnip: " 1 package com.example.apps;\n 2 \n 3 import javax.ejb.SessionBean;\n 4 import javax.ejb.Singleton;\n 5 \n 6 @Singleton\n 7 public abstract class Bean implements SessionBean {\n 8 \n 9 }\n"
lineNumber: 7
variables:
containerName: Bean
file: file:///examples/java/example/src/main/java/com/example/apps/Bean.java
kind: Class
name: Singleton
package: com.example.apps
java-downloaded-maven-artifact:
description: |
This rule tests the application downloaded from maven artifact
Expand All @@ -910,6 +939,7 @@
codeSnip: " 1 package io.javaoperatorsdk.operator.sample;\n 2 \n 3 import io.fabric8.kubernetes.client.KubernetesClient;\n 4 import io.javaoperatorsdk.operator.Operator;\n 5 import io.javaoperatorsdk.operator.api.config.ConfigurationService;\n 6 import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;\n 7 import io.quarkus.runtime.Quarkus;\n 8 import io.quarkus.runtime.QuarkusApplication;\n 9 import io.quarkus.runtime.annotations.QuarkusMain;\n10 import javax.inject.Inject;\n11 \n12 @QuarkusMain\n13 public class QuarkusOperator implements QuarkusApplication {\n14 @Inject"
lineNumber: 4
variables:
containerName: ""
file: file:///java-project/src/main/java/io/javaoperatorsdk/operator/sample/QuarkusOperator.java
kind: Module
name: io.javaoperatorsdk.operator.Operator
Expand All @@ -919,6 +949,7 @@
codeSnip: " 7 import io.quarkus.runtime.Quarkus;\n 8 import io.quarkus.runtime.QuarkusApplication;\n 9 import io.quarkus.runtime.annotations.QuarkusMain;\n10 import javax.inject.Inject;\n11 \n12 @QuarkusMain\n13 public class QuarkusOperator implements QuarkusApplication {\n14 @Inject\n15 KubernetesClient client;\n16 @Inject\n17 Operator operator;\n18 @Inject\n19 ConfigurationService configuration;\n20 @Inject\n21 CustomServiceController controller;\n22 \n23 public static void main(String... args) {\n24 Quarkus.run(QuarkusOperator.class, args);\n25 }\n26 \n27 public int run(String... args) throws Exception {"
lineNumber: 17
variables:
containerName: QuarkusOperator
file: file:///java-project/src/main/java/io/javaoperatorsdk/operator/sample/QuarkusOperator.java
kind: Field
name: operator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"

Expand All @@ -21,6 +22,8 @@ const (
KIND_EXTRA_KEY = "kind"
SYMBOL_NAME_KEY = "name"
FILE_KEY = "file"
PACKAGE = "package"
CONTAINER_NAME = "containerName"
)

func (p *javaServiceClient) filterVariableDeclaration(symbols []protocol.WorkspaceSymbol) ([]provider.IncidentContext, error) {
Expand Down Expand Up @@ -91,6 +94,38 @@ func (p *javaServiceClient) filterDefault(symbols []protocol.WorkspaceSymbol) ([
return incidents, nil
}

func (p *javaServiceClient) filterAnnotated(cond *javaCondition, symbols []protocol.WorkspaceSymbol) ([]provider.IncidentContext, error) {
incidents := []provider.IncidentContext{}
for _, symbol := range symbols {
incident, err := p.convertToIncidentContext(symbol)
if err != nil {
return nil, err
}
// TODO: problem: for kind == METHOD || kind == CLASS, the containerName returns name of the method or the class, which is fine, but when
// kind == FIELD we would probably want to look for the type of the field, not the name. That is not possible atm
kind := strings.ToLower(incident.Variables[KIND_EXTRA_KEY].(string))
name := incident.Variables[CONTAINER_NAME].(string)
pkg := incident.Variables[PACKAGE].(string)
pattern := regexp.MustCompile(cond.Referenced.Pattern)
if kind == strings.ToLower(cond.Referenced.Location) {
// pattern for annotated classes or methods could be a regex
if kind == "class" {
// for classes, we need the fully qualified name (package + class name)
fqn := strings.Join([]string{pkg, name}, ".")
if pattern.Match([]byte(fqn)) {
incidents = append(incidents, incident)
}
} else if kind == "method" || kind == "field" {
if pattern.Match([]byte(name)) {
incidents = append(incidents, incident)
}
}
}
}
return incidents, nil

}

// TODO: we will probably want to filter symbols bassed on if in any way the method is being used in the code directly.
// This will need to be part of a "filtration" concept that windup has. Searching partiular subsets of things (just the application, applicatoin + corp libraries and the everything.)
// Today this is just giving everything.
Expand Down Expand Up @@ -152,7 +187,8 @@ func (p *javaServiceClient) convertToIncidentContext(symbol protocol.WorkspaceSy
KIND_EXTRA_KEY: symbolKindToString(symbol.Kind),
SYMBOL_NAME_KEY: symbol.Name,
FILE_KEY: string(u),
"package": n,
PACKAGE: n,
CONTAINER_NAME: symbol.ContainerName,
},
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,13 @@ type javaCondition struct {
}

type referenceCondition struct {
Pattern string `yaml:"pattern"`
Location string `yaml:"location"`
Pattern string `yaml:"pattern"`
Location string `yaml:"location"`
Annotated annotatedCondition `yaml:"annotated""`
}

type annotatedCondition struct {
Pattern string `yaml:"pattern"`
}

func NewJavaProvider(log logr.Logger, lspServerName string, contextLines int) *javaProvider {
Expand Down Expand Up @@ -291,6 +296,7 @@ func (p *javaProvider) Init(ctx context.Context, log logr.Logger, config provide
"-Djava.net.useSystemProxies=true",
"-configuration",
"./",
//"--jvm-arg=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:1044",
"-data",
workspace,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"os/exec"
"path/filepath"
"reflect"
"regexp"
"strings"
"sync"
Expand Down Expand Up @@ -51,14 +52,24 @@ func (p *javaServiceClient) Evaluate(ctx context.Context, cap string, conditionI
return provider.ProviderEvaluateResponse{}, fmt.Errorf("unable to get query info: %v", err)
}

if cond.Referenced.Pattern == "" {
// if "annotated" is present, do look for the annotation instead and then filter out according to the
// original location and reference
location := cond.Referenced.Location
pattern := cond.Referenced.Pattern
isAnnotated := !reflect.DeepEqual(cond.Referenced.Annotated, annotatedCondition{})
if isAnnotated {
location = "annotation"
pattern = cond.Referenced.Annotated.Pattern
}

if pattern == "" {
return provider.ProviderEvaluateResponse{}, fmt.Errorf("provided query pattern empty")
}
symbols := p.GetAllSymbols(ctx, cond.Referenced.Pattern, cond.Referenced.Location)
symbols := p.GetAllSymbols(ctx, pattern, location)
p.log.V(5).Info("Symbols retrieved", "symbols", symbols)

incidents := []provider.IncidentContext{}
switch locationToCode[strings.ToLower(cond.Referenced.Location)] {
switch locationToCode[strings.ToLower(location)] {
case 0:
// Filter handle for type, find all the referneces to this type.
incidents, err = p.filterDefault(symbols)
Expand All @@ -69,7 +80,11 @@ func (p *javaServiceClient) Evaluate(ctx context.Context, cap string, conditionI
case 3:
incidents, err = p.filterConstructorSymbols(ctx, symbols)
case 4:
incidents, err = p.filterDefault(symbols)
if isAnnotated {
incidents, err = p.filterAnnotated(cond, symbols)
} else {
incidents, err = p.filterDefault(symbols)
}
case 7:
incidents, err = p.filterMethodSymbols(symbols)
case 8:
Expand Down
15 changes: 14 additions & 1 deletion rule-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,17 @@
ruleID: java-downloaded-maven-artifact
when:
java.referenced:
pattern: io.javaoperatorsdk.operator.Operator
pattern: io.javaoperatorsdk.operator.Operator
- category: mandatory
description: |
This rule looks for a certain class annotated with a certain annotation
tag:
- Java Operator SDK
ruleID: java-annotation-inspection-01
when:
java.referenced:
pattern: com.example.apps*
location: CLASS
annotated:
pattern: javax.ejb.SessionBean

Loading