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

✨ add ability to pass maven coordinate in location #617

Merged
merged 2 commits into from
Jun 13, 2024
Merged
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
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the classifier mandatory in the URL?

Copy link
Contributor Author

@pranavgaikwad pranavgaikwad Jun 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmle yeah, in the hub UI, we have four fields including classifier (defaulted to JAR). I think I will default to JAR too if one isn't specified

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmle done, defaulting to jar now

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
Loading