Skip to content

Commit

Permalink
✨ add ability to pass maven coordinate in location (#617)
Browse files Browse the repository at this point in the history
Fixes #554

---------

Signed-off-by: Pranav Gaikwad <[email protected]>
  • Loading branch information
pranavgaikwad authored Jun 13, 2024
1 parent e2284ce commit b5c166d
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 2 deletions.
9 changes: 9 additions & 0 deletions demo-dep-output.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2473,3 +2473,12 @@
- konveyor.io/dep-source=open-source
- konveyor.io/language=java
prefix: file:///root/.m2/repository/org/yaml/snakeyaml/1.30
- fileURI: io/javaoperatorsdk/operator/sample
provider: java
dependencies:
- name: io.javaoperatorsdk.operator.sample
version: 0.0.0
labels:
- konveyor.io/dep-source=open-source
- konveyor.io/language=java
prefix: file://java-project/src/main/io/javaoperatorsdk/operator/sample
27 changes: 26 additions & 1 deletion demo-output.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Backend=Golang
- Infra=Kubernetes
- Java
- Java Operator SDK
- Language=Golang
- License=Apache
violations:
Expand Down Expand Up @@ -898,6 +899,30 @@
matchingXML: ""
effort: 1
insights:
java-downloaded-maven-artifact:
description: |
This rule tests the application downloaded from maven artifact
labels:
- tag=Java Operator SDK
incidents:
- uri: file:///java-project/src/main/java/io/javaoperatorsdk/operator/sample/QuarkusOperator.java
message: ""
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:
file: file:///java-project/src/main/java/io/javaoperatorsdk/operator/sample/QuarkusOperator.java
kind: Module
name: io.javaoperatorsdk.operator.Operator
package: io.javaoperatorsdk.operator.sample
- uri: file:///java-project/src/main/java/io/javaoperatorsdk/operator/sample/QuarkusOperator.java
message: ""
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:
file: file:///java-project/src/main/java/io/javaoperatorsdk/operator/sample/QuarkusOperator.java
kind: Field
name: operator
package: io.javaoperatorsdk.operator.sample
multiple-actions-001:
description: ""
labels:
Expand Down Expand Up @@ -1043,7 +1068,7 @@
errors:
error-rule-001: |-
unable to get query info: yaml: unmarshal errors:
line 9: cannot unmarshal !!map into string
line 10: cannot unmarshal !!map into string
unmatched:
- file-002
- lang-ref-002
Expand Down
2 changes: 1 addition & 1 deletion docs/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Here's an example config for `java` provider that is currently in-tree and does
}
```

The `location` can be a path to the application's source code or to a binary JAR, WAR, or EAR file.
The `location` can be a path to the application's source code or to a binary JAR, WAR, or EAR file. Optionally, coordinates to a maven artifact can be provided as input in the format `mvn://<group-id>:<artifact-id>:<version>:<classifier>@<path>`. The field `<path>` is optional, it specifies a local path where the artifact will be downloaded. If not specified, provider will use the current working directory to download it.

The `java` provider also takes following options in `providerSpecificConfig`:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const (
WebArchive = ".war"
EnterpriseArchive = ".ear"
ClassFile = ".class"
MvnURIPrefix = "mvn://"
)

// provider specific config keys
Expand Down Expand Up @@ -220,6 +221,52 @@ func (p *javaProvider) Init(ctx context.Context, log logr.Logger, config provide
var returnErr error
// each service client should have their own context
ctx, cancelFunc := context.WithCancel(ctx)
// location can be a coordinate to a remote mvn artifact
if strings.HasPrefix(config.Location, MvnURIPrefix) {
mvnUri := strings.Replace(config.Location, MvnURIPrefix, "", 1)
// URI format is <group>:<artifact>:<version>:<classifier>@<path>
// <path> is optional & points to a local path where it will be downloaded
mvnCoordinates, destPath, _ := strings.Cut(mvnUri, "@")
mvnCoordinatesParts := strings.Split(mvnCoordinates, ":")
if mvnCoordinates == "" || len(mvnCoordinatesParts) < 3 {
cancelFunc()
return nil, fmt.Errorf("invalid maven coordinates in location %s, must be in format mvn://<group>:<artifact>:<version>:<classifier>@<path>", config.Location)
}
outputDir := "."
if destPath != "" {
if stat, err := os.Stat(destPath); err != nil || !stat.IsDir() {
cancelFunc()
return nil, fmt.Errorf("output path does not exist or not a directory")
}
outputDir = destPath
}
mvnOptions := []string{
"dependency:copy",
fmt.Sprintf("-Dartifact=%s", mvnCoordinates),
fmt.Sprintf("-DoutputDirectory=%s", outputDir),
}
if mavenSettingsFile != "" {
mvnOptions = append(mvnOptions, "-s", mavenSettingsFile)
}
log.Info("downloading maven artifact", "artifact", mvnCoordinates, "options", mvnOptions)
cmd := exec.CommandContext(ctx, "mvn", mvnOptions...)
cmd.Dir = outputDir
if err := cmd.Run(); err != nil {
cancelFunc()
return nil, fmt.Errorf("error downloading java artifact %s - %w", mvnUri, err)
}
downloadedPath := filepath.Join(outputDir,
fmt.Sprintf("%s.jar", strings.Join(mvnCoordinatesParts[1:3], "-")))
if len(mvnCoordinatesParts) == 4 {
downloadedPath = filepath.Join(outputDir,
fmt.Sprintf("%s.%s", strings.Join(mvnCoordinatesParts[1:3], "-"), strings.ToLower(mvnCoordinatesParts[3])))
}
if _, err := os.Stat(downloadedPath); err != nil {
return nil, fmt.Errorf("failed to download maven artifact to path %s - %w", downloadedPath, err)
}
config.Location = downloadedPath
}

extension := strings.ToLower(path.Ext(config.Location))
switch extension {
case JavaArchive, WebArchive, EnterpriseArchive:
Expand Down
10 changes: 10 additions & 0 deletions provider_container_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@
"bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar"
},
"analysisMode": "source-only"
},
{
"location": "mvn://io.javaoperatorsdk:quarkus:1.6.2:jar",
"providerSpecificConfig": {
"lspServerName": "java",
"lspServerPath": "/jdtls/bin/jdtls",
"depOpenSourceLabelsFile": "/usr/local/etc/maven.default.index",
"bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar"
},
"analysisMode": "full"
}
]
},
Expand Down
10 changes: 10 additions & 0 deletions provider_local_external_images.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@
"bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar"
},
"analysisMode": "source-only"
},
{
"location": "mvn://io.javaoperatorsdk:quarkus:1.6.2:jar",
"providerSpecificConfig": {
"lspServerName": "java",
"lspServerPath": "/jdtls/bin/jdtls",
"depOpenSourceLabelsFile": "/usr/local/etc/maven.default.index",
"bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar"
},
"analysisMode": "full"
}
]
},
Expand Down
10 changes: 10 additions & 0 deletions provider_pod_local_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@
"bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar"
},
"analysisMode": "source-only"
},
{
"location": "mvn://io.javaoperatorsdk:quarkus:1.6.2:jar",
"providerSpecificConfig": {
"lspServerName": "java",
"lspServerPath": "/jdtls/bin/jdtls",
"depOpenSourceLabelsFile": "/usr/local/etc/maven.default.index",
"bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar"
},
"analysisMode": "full"
}
]
},
Expand Down
9 changes: 9 additions & 0 deletions rule-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -321,3 +321,12 @@
when:
java.referenced:
pattern: com.sun.net.httpserver.HttpExchange
- category: mandatory
description: |
This rule tests the application downloaded from maven artifact
tag:
- Java Operator SDK
ruleID: java-downloaded-maven-artifact
when:
java.referenced:
pattern: io.javaoperatorsdk.operator.Operator

0 comments on commit b5c166d

Please sign in to comment.