diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/CreateNote.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/CreateNote.java new file mode 100644 index 00000000000..871f65c60ee --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/CreateNote.java @@ -0,0 +1,60 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_create_note] +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.ProjectName; +import io.grafeas.v1beta1.Note; +import io.grafeas.v1beta1.vulnerability.Severity; +import io.grafeas.v1beta1.vulnerability.Vulnerability; +import io.grafeas.v1beta1.vulnerability.Vulnerability.Detail; +import java.io.IOException; +import java.lang.InterruptedException; + + +public class CreateNote { + + // Creates and returns a new Note + public static Note createNote(String noteId, String projectId) + throws IOException, InterruptedException { + // String noteId = "my-note"; + // String projectId = "my-project-id"; + final String projectName = ProjectName.format(projectId); + + Note.Builder noteBuilder = Note.newBuilder(); + // Associate the Note with the metadata type + // https://cloud.google.com/container-registry/docs/container-analysis#supported_metadata_types + // Here, we use the type "vulnerability" + Vulnerability.Builder vulBuilder = Vulnerability.newBuilder(); + noteBuilder.setVulnerability(vulBuilder); + // Set additional information specific to your new vulnerability note + Detail.Builder detailsBuilder = Detail.newBuilder(); + detailsBuilder.setDescription("my new vulnerability note"); + vulBuilder.setSeverity(Severity.LOW); + vulBuilder.addDetails(detailsBuilder); + // Build the Note object + Note newNote = noteBuilder.build(); + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + Note result = client.createNote(projectName, noteId, newNote); + return result; + } +} +// [END containeranalysis_create_note] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/CreateOccurrence.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/CreateOccurrence.java new file mode 100644 index 00000000000..ac87f3487ea --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/CreateOccurrence.java @@ -0,0 +1,60 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_create_occurrence] +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.NoteName; +import com.google.containeranalysis.v1beta1.ProjectName; +import io.grafeas.v1beta1.Occurrence; +import io.grafeas.v1beta1.Resource; +import io.grafeas.v1beta1.vulnerability.Details; +import java.io.IOException; +import java.lang.InterruptedException; + +public class CreateOccurrence { + // Creates and returns a new Occurrence associated with an existing Note + public static Occurrence createOccurrence(String resourceUrl, String noteId, + String occProjectId, String noteProjectId) throws IOException, InterruptedException { + // String resourceUrl = "https://gcr.io/project/image@sha256:123"; + // String noteId = "my-note"; + // String occProjectId = "my-project-id"; + // String noteProjectId = "my-project-id"; + final NoteName noteName = NoteName.of(noteProjectId, noteId); + final String occProjectName = ProjectName.format(occProjectId); + + Occurrence.Builder occBuilder = Occurrence.newBuilder(); + occBuilder.setNoteName(noteName.toString()); + // Associate the Occurrence with the metadata type (should match the parent Note's type) + // https://cloud.google.com/container-registry/docs/container-analysis#supported_metadata_types + // Here, we use the type "vulnerability" + Details.Builder detailsBuilder = Details.newBuilder(); + occBuilder.setVulnerability(detailsBuilder); + // Attach the occurrence to the associated image uri + Resource.Builder resourceBuilder = Resource.newBuilder(); + resourceBuilder.setUri(resourceUrl); + occBuilder.setResource(resourceBuilder); + Occurrence newOcc = occBuilder.build(); + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + Occurrence result = client.createOccurrence(occProjectName, newOcc); + return result; + } +} +// [END containeranalysis_create_occurrence] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/DeleteNote.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/DeleteNote.java new file mode 100644 index 00000000000..9a4f92a421d --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/DeleteNote.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_delete_note] +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.NoteName; +import java.io.IOException; +import java.lang.InterruptedException; + +public class DeleteNote { + // Deletes an existing Note from the server + public static void deleteNote(String noteId, String projectId) + throws IOException, InterruptedException { + // String noteId = "my-note"; + // String projectId = "my-project-id"; + final NoteName noteName = NoteName.of(projectId, noteId); + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + client.deleteNote(noteName); + } +} +// [END containeranalysis_delete_note] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/DeleteOccurrence.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/DeleteOccurrence.java new file mode 100644 index 00000000000..47abfa9a7c2 --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/DeleteOccurrence.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_delete_occurrence] +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.OccurrenceName; +import java.io.IOException; +import java.lang.InterruptedException; + +public class DeleteOccurrence { + // Deletes an existing Occurrence from the server + public static void deleteOccurrence(String occurrenceId, String projectId) + throws IOException, InterruptedException { + // String occurrenceId = "123-456-789"; + // String projectId = "my-project-id"; + final OccurrenceName occurrenceName = OccurrenceName.of(projectId, occurrenceId); + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + client.deleteOccurrence(occurrenceName); + } +} +// [END containeranalysis_delete_occurrence] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/GetDiscoveryInfo.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/GetDiscoveryInfo.java new file mode 100644 index 00000000000..4203a3a60d3 --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/GetDiscoveryInfo.java @@ -0,0 +1,44 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_discovery_info] +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.ProjectName; +import io.grafeas.v1beta1.Occurrence; +import java.io.IOException; +import java.lang.InterruptedException; + +public class GetDiscoveryInfo { + // Retrieves and prints the Discovery Occurrence created for a specified image + // The Discovery Occurrence contains information about the initial scan on the image + public static void getDiscoveryInfo(String resourceUrl, String projectId) + throws IOException, InterruptedException { + // String resourceUrl = "https://gcr.io/project/image@sha256:123"; + // String projectId = "my-project-id"; + String filterStr = "kind=\"DISCOVERY\" AND resourceUrl=\"" + resourceUrl + "\""; + final String projectName = ProjectName.format(projectId); + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) { + System.out.println(o); + } + } +} +// [END containeranalysis_discovery_info] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/GetNote.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/GetNote.java new file mode 100644 index 00000000000..23aea0b28a0 --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/GetNote.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_get_note] +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.NoteName; +import io.grafeas.v1beta1.Note; +import java.io.IOException; +import java.lang.InterruptedException; + +public class GetNote { + // Retrieves and prints a specified Note from the server + public static Note getNote(String noteId, String projectId) + throws IOException, InterruptedException { + // String noteId = "my-note"; + // String projectId = "my-project-id"; + final NoteName noteName = NoteName.of(projectId, noteId); + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + Note n = client.getNote(noteName); + System.out.println(n); + return n; + } +} +// [END containeranalysis_get_note] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/GetOccurrence.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/GetOccurrence.java new file mode 100644 index 00000000000..57be93557b3 --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/GetOccurrence.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_get_occurrence] +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.OccurrenceName; +import io.grafeas.v1beta1.Occurrence; +import java.io.IOException; +import java.lang.InterruptedException; + +public class GetOccurrence { + // Retrieves and prints a specified Occurrence from the server + public static Occurrence getOccurrence(String occurrenceId, String projectId) + throws IOException, InterruptedException { + // String occurrenceId = "123-456-789"; + // String projectId = "my-project-id"; + final OccurrenceName occurrenceName = OccurrenceName.of(projectId, occurrenceId); + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + Occurrence occ = client.getOccurrence(occurrenceName); + System.out.println(occ); + return occ; + } +} +// [END containeranalysis_get_occurrence] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/HighVulnerabilitiesForImage.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/HighVulnerabilitiesForImage.java new file mode 100644 index 00000000000..2e99cee0f91 --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/HighVulnerabilitiesForImage.java @@ -0,0 +1,50 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_filter_vulnerability_occurrences] +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.ProjectName; +import io.grafeas.v1beta1.Occurrence; +import io.grafeas.v1beta1.vulnerability.Severity; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +public class HighVulnerabilitiesForImage { + // Retrieve a list of vulnerability occurrences with a severity level of 'HIGH' or greater + public static List findHighSeverityVulnerabilitiesForImage(String resourceUrl, + String projectId) throws IOException { + // String resourceUrl = "https://gcr.io/project/image@sha256:123"; + // String projectId = "my-project-id"; + final String projectName = ProjectName.format(projectId); + String filterStr = String.format("kind=\"VULNERABILITY\" AND resourceUrl=\"%s\"", resourceUrl); + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + LinkedList vulnerabilitylist = new LinkedList(); + for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) { + Severity severity = o.getVulnerability().getSeverity(); + if (severity == Severity.HIGH || severity == Severity.CRITICAL) { + vulnerabilitylist.add(o); + } + } + return vulnerabilitylist; + } +} +// [END containeranalysis_filter_vulnerability_occurrences] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/OccurrencesForImage.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/OccurrencesForImage.java new file mode 100644 index 00000000000..57130203425 --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/OccurrencesForImage.java @@ -0,0 +1,48 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_occurrences_for_image] +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.ProjectName; +import io.grafeas.v1beta1.Occurrence; +import java.io.IOException; +import java.lang.InterruptedException; + +public class OccurrencesForImage { + // Retrieves all the Occurrences associated with a specified image + // Here, all Occurrences are simply printed and counted + public static int getOccurrencesForImage(String resourceUrl, String projectId) + throws IOException, InterruptedException { + // String resourceUrl = "https://gcr.io/project/image@sha256:123"; + // String projectId = "my-project-id"; + final String projectName = ProjectName.format(projectId); + final String filterStr = String.format("resourceUrl=\"%s\"", resourceUrl); + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + int i = 0; + for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) { + // Write custom code to process each Occurrence here + System.out.println(o.getName()); + i = i + 1; + } + return i; + } +} +// [END containeranalysis_occurrences_for_image] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/OccurrencesForNote.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/OccurrencesForNote.java new file mode 100644 index 00000000000..7e6cbce9d8a --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/OccurrencesForNote.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_occurrences_for_note] +import static java.lang.Thread.sleep; + +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.NoteName; +import io.grafeas.v1beta1.ListNoteOccurrencesRequest; +import io.grafeas.v1beta1.Occurrence; +import java.io.IOException; +import java.lang.InterruptedException; + +public class OccurrencesForNote { + // Retrieves all the Occurrences associated with a specified Note + // Here, all Occurrences are printed and counted + public static int getOccurrencesForNote(String noteId, String projectId) + throws IOException, InterruptedException { + // String noteId = "my-note"; + // String projectId = "my-project-id"; + final NoteName noteName = NoteName.of(projectId, noteId); + + ListNoteOccurrencesRequest request = ListNoteOccurrencesRequest.newBuilder() + .setName(noteName.toString()) + .build(); + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + int i = 0; + for (Occurrence o : client.listNoteOccurrences(request).iterateAll()) { + // Write custom code to process each Occurrence here + System.out.println(o.getName()); + i = i + 1; + } + return i; + } +} +// [END containeranalysis_occurrences_for_note] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/PollDiscoveryOccurrenceFinished.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/PollDiscoveryOccurrenceFinished.java new file mode 100644 index 00000000000..069f18d2c73 --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/PollDiscoveryOccurrenceFinished.java @@ -0,0 +1,78 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_poll_discovery_occurrence_finished]i +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.ProjectName; +import io.grafeas.v1beta1.Occurrence; +import io.grafeas.v1beta1.discovery.Discovered.AnalysisStatus; +import java.io.IOException; +import java.lang.InterruptedException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class PollDiscoveryOccurrenceFinished { + // Repeatedly query the Container Analysis API for the latest discovery occurrence until it is + // either in a terminal state, or the timeout value has been exceeded + public static Occurrence pollDiscoveryOccurrenceFinished(String resourceUrl, String projectId, + long timeoutSeconds) throws IOException, TimeoutException, InterruptedException { + // String resourceUrl = "https://gcr.io/project/image@sha256:123"; + // String projectId = "my-project-id"; + // long timeoutSeconds = 30; + final String projectName = ProjectName.format(projectId); + long deadline = System.currentTimeMillis() + timeoutSeconds * 1000; + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + + // find the discovery occurrence using a filter string + Occurrence discoveryOccurrence = null; + String filterStr = "kind=\"DISCOVERY\" AND resourceUrl=\"" + resourceUrl + "\""; + while (discoveryOccurrence == null) { + for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) { + if (o.getDiscovered() != null) { + // there should be only one valid discovery occurrence returned by the given filter + discoveryOccurrence = o; + } + } + TimeUnit.SECONDS.sleep(1); + // check for timeout + if (System.currentTimeMillis() > deadline) { + throw new TimeoutException("discovery occurrence not found"); + } + } + + // wait for discovery occurrence to enter a terminal state + AnalysisStatus status = AnalysisStatus.PENDING; + while (status != AnalysisStatus.FINISHED_SUCCESS + && status != AnalysisStatus.FINISHED_FAILED + && status != AnalysisStatus.FINISHED_UNSUPPORTED) { + // update the occurrence state + discoveryOccurrence = client.getOccurrence(discoveryOccurrence.getName()); + status = discoveryOccurrence.getDiscovered().getDiscovered().getAnalysisStatus(); + TimeUnit.SECONDS.sleep(1); + // check for timeout + if (System.currentTimeMillis() > deadline) { + throw new TimeoutException("discovery occurrence not in terminal state"); + } + } + return discoveryOccurrence; + } +} +// [END containeranalysis_poll_discovery_occurrence_finished] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/PubSub.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/PubSub.java new file mode 100644 index 00000000000..abf1051472c --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/PubSub.java @@ -0,0 +1,91 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_pubsub] +import com.google.cloud.pubsub.v1.AckReplyConsumer; +import com.google.cloud.pubsub.v1.MessageReceiver; +import com.google.cloud.pubsub.v1.Subscriber; +import com.google.cloud.pubsub.v1.SubscriptionAdminClient; +import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.ProjectTopicName; +import com.google.pubsub.v1.PubsubMessage; +import com.google.pubsub.v1.PushConfig; +import com.google.pubsub.v1.Subscription; +import io.grpc.StatusRuntimeException; +import java.io.IOException; +import java.lang.InterruptedException; +import java.util.concurrent.TimeUnit; + +public class PubSub { + // Handle incoming Occurrences using a Cloud Pub/Sub subscription + public static int pubSub(String subId, long timeoutSeconds, String projectId) + throws InterruptedException { + // String subId = "my-occurrence-subscription"; + // long timeoutSeconds = 20; + // String projectId = "my-project-id"; + Subscriber subscriber = null; + MessageReceiverExample receiver = new MessageReceiverExample(); + + try { + // Subscribe to the requested Pub/Sub channel + ProjectSubscriptionName subName = ProjectSubscriptionName.of(projectId, subId); + subscriber = Subscriber.newBuilder(subName, receiver).build(); + subscriber.startAsync().awaitRunning(); + // Sleep to listen for messages + TimeUnit.SECONDS.sleep(timeoutSeconds); + } finally { + // Stop listening to the channel + if (subscriber != null) { + subscriber.stopAsync(); + } + } + // Print and return the number of Pub/Sub messages received + System.out.println(receiver.messageCount); + return receiver.messageCount; + } + + // Custom class to handle incoming Pub/Sub messages + // In this case, the class will simply log and count each message as it comes in + static class MessageReceiverExample implements MessageReceiver { + public int messageCount = 0; + + @Override + public synchronized void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) { + // Every time a Pub/Sub message comes in, print it and count it + System.out.println("Message " + messageCount + ": " + message.getData().toStringUtf8()); + messageCount += 1; + // Acknowledge the message + consumer.ack(); + } + } + + // Creates and returns a Pub/Sub subscription object listening to the Occurrence topic + public static Subscription createOccurrenceSubscription(String subId, String projectId) + throws IOException, StatusRuntimeException, InterruptedException { + // This topic id will automatically receive messages when Occurrences are added or modified + String topicId = "container-analysis-occurrences-v1beta1"; + ProjectTopicName topicName = ProjectTopicName.of(projectId, topicId); + ProjectSubscriptionName subName = ProjectSubscriptionName.of(projectId, subId); + + SubscriptionAdminClient client = SubscriptionAdminClient.create(); + PushConfig config = PushConfig.getDefaultInstance(); + Subscription sub = client.createSubscription(subName, topicName, config, 0); + return sub; + } +} +// [END containeranalysis_pubsub] diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/Samples.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/Samples.java deleted file mode 100644 index c5c69149d4d..00000000000 --- a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/Samples.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright 2018 Google LLC - * - * Licensed 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 com.example.containeranalysis; - -import static java.lang.Thread.sleep; - -import com.google.cloud.devtools.containeranalysis.v1beta1.ContainerAnalysisV1Beta1Client; -import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; -import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client.ListNoteOccurrencesPagedResponse; -import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client.ListOccurrencesPagedResponse; -import com.google.cloud.pubsub.v1.AckReplyConsumer; -import com.google.cloud.pubsub.v1.MessageReceiver; -import com.google.cloud.pubsub.v1.Subscriber; -import com.google.cloud.pubsub.v1.SubscriptionAdminClient; -import com.google.containeranalysis.v1beta1.NoteName; -import com.google.containeranalysis.v1beta1.ProjectName; -import com.google.pubsub.v1.ProjectSubscriptionName; -import com.google.pubsub.v1.ProjectTopicName; -import com.google.pubsub.v1.PubsubMessage; -import com.google.pubsub.v1.PushConfig; -import com.google.pubsub.v1.Subscription; -import io.grafeas.v1beta1.ListNoteOccurrencesRequest; -import io.grafeas.v1beta1.ListOccurrencesRequest; -import io.grafeas.v1beta1.Note; -import io.grafeas.v1beta1.Occurrence; -import io.grafeas.v1beta1.Resource; -import io.grafeas.v1beta1.UpdateNoteRequest; -import io.grafeas.v1beta1.UpdateOccurrenceRequest; -import io.grafeas.v1beta1.vulnerability.Details; -import io.grafeas.v1beta1.vulnerability.Severity; -import io.grafeas.v1beta1.vulnerability.Vulnerability; -import io.grpc.StatusRuntimeException; -import java.io.IOException; -import java.lang.InterruptedException; - -/** - * API usage samples - */ -public class Samples { - - // [START create_note] - /** - * Creates and returns a new vulnerability Note - * @param client The Grafeas client used to perform the API requests. - * @param noteId A user-specified identifier for the Note. - * @param projectId the GCP project the Note will be created under - * @return the newly created Note object - */ - public static Note createNote(GrafeasV1Beta1Client client, String noteId, String projectId) { - Note.Builder noteBuilder = Note.newBuilder(); - Vulnerability.Builder vulBuilder = Vulnerability.newBuilder(); - // Details about the your vulnerability can be added here - // Example: vulBuilder.setSeverity(Severity.CRITICAL); - noteBuilder.setVulnerability(vulBuilder); - Note newNote = noteBuilder.build(); - - final String projectName = ProjectName.format(projectId); - return client.createNote(projectName, noteId, newNote); - } - // [END create_note] - - - // [START create_occurrence] - /** - * Creates and returns a new Occurrence of a previously created vulnerability Note - * @param client The Grafeas client used to perform the API requests. - * @param imageUrl the Container Registry URL associated with the image - * example: "https://gcr.io/project/image@sha256:foo" - * @param noteId the identifier of the Note associated with this Occurrence - * @param occProjectId the GCP project the Occurrence will be created under - * @param noteProjectId the GCP project the associated Note belongs to - * @return the newly created Occurrence object - */ - public static Occurrence createOccurrence(GrafeasV1Beta1Client client, String imageUrl, - String noteId, String occProjectId, String noteProjectId) { - final NoteName noteName = NoteName.of(noteProjectId, noteId); - final String occProjectName = ProjectName.format(occProjectId); - - Occurrence.Builder occBuilder = Occurrence.newBuilder(); - occBuilder.setNoteName(noteName.toString()); - Details.Builder detailsBuilder = Details.newBuilder(); - // Details about the vulnerability instance can be added here - occBuilder.setVulnerability(detailsBuilder); - // Attach the occurrence to the associated image uri - Resource.Builder resourceBuilder = Resource.newBuilder(); - resourceBuilder.setUri(imageUrl); - occBuilder.setResource(resourceBuilder); - Occurrence newOcc = occBuilder.build(); - return client.createOccurrence(occProjectName, newOcc); - } - // [END create_occurrence] - - // [START update_note] - /** - * Pushes an update to a Note that already exists on the server - * @param client The Grafeas client used to perform the API requests. - * @param updated a Note object representing the desired updates to push - * @param noteId the identifier of the existing Note - * @param projectId the GCP project the Note belongs to - */ - public static Note updateNote(GrafeasV1Beta1Client client, Note updated, String noteId, - String projectId) { - final NoteName noteName = NoteName.of(projectId, noteId); - UpdateNoteRequest request = UpdateNoteRequest.newBuilder() - .setName(noteName.toString()) - .setNote(updated) - .build(); - return client.updateNote(request); - } - // [END update_note] - - // [START update_occurrence] - /** - * Pushes an update to an Occurrence that already exists on the server - * @param client The Grafeas client used to perform the API requests. - * @param occurrenceName the name of the Occurrence to delete. - * format: "projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]" - * @param updated an Occurrence object representing the desired updates to push - */ - public static Occurrence updateOccurrence(GrafeasV1Beta1Client client, String occurrenceName, - Occurrence updated) { - UpdateOccurrenceRequest request = UpdateOccurrenceRequest.newBuilder() - .setName(occurrenceName) - .setOccurrence(updated) - .build(); - return client.updateOccurrence(request); - } - // [END update_occurrence] - - // [START delete_note] - /** - * Deletes an existing Note from the server - * @param client The Grafeas client used to perform the API requests. - * @param noteId the identifier of the Note to delete - * @param projectId the GCP project the Note belongs to - */ - public static void deleteNote(GrafeasV1Beta1Client client, String noteId, String projectId) { - final NoteName noteName = NoteName.of(projectId, noteId); - client.deleteNote(noteName); - } - // [END delete_note] - - // [START delete_occurrence] - /** - * Deletes an existing Occurrence from the server - * @param client The Grafeas client used to perform the API requests. - * @param occurrenceName the name of the Occurrence to delete - * format: "projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]" - */ - public static void deleteOccurrence(GrafeasV1Beta1Client client, String occurrenceName) { - client.deleteOccurrence(occurrenceName); - } - // [END delete_occurrence] - - - // [START get_occurrence] - /** - * Retrieves and prints a specified Occurrence from the server - * @param client The Grafeas client used to perform the API requests. - * @param occurrenceName the name of the Occurrence to delete - * format: "projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]" - * @return the requested Occurrence object - */ - public static Occurrence getOccurrence(GrafeasV1Beta1Client client, String occurrenceName) { - Occurrence occ = client.getOccurrence(occurrenceName); - System.out.println(occ); - return occ; - } - // [END get_occurrence] - - // [START get_note] - /** - * Retrieves and prints a specified Note from the server - * @param client The Grafeas client used to perform the API requests. - * @param noteId the Note's unique identifier - * @param projectId the GCP project the Note belongs to - * @return the requested Note object - */ - public static Note getNote(GrafeasV1Beta1Client client, String noteId, String projectId) { - final NoteName noteName = NoteName.of(projectId, noteId); - - Note n = client.getNote(noteName); - System.out.println(n); - return n; - } - // [END get_note] - - // [START discovery_info] - /** - * Retrieves and prints the Discovery Occurrence created for a specified image - * The Discovery Occurrence contains information about the initial scan on the image - * @param client The Grafeas client used to perform the API requests. - * @param imageUrl the Container Registry URL associated with the image - * example: "https://gcr.io/project/image@sha256:foo" - * @param projectId the GCP project the image belongs to - */ - public static void getDiscoveryInfo(GrafeasV1Beta1Client client, String imageUrl, - String projectId) { - String filterStr = "kind=\"DISCOVERY\" AND resourceUrl=\"" + imageUrl + "\""; - final String projectName = ProjectName.format(projectId); - - for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) { - System.out.println(o); - } - } - // [END discovery_info] - - // [START occurrences_for_note] - /** - * Retrieves all the Occurrences associated with a specified Note - * Here, all Occurrences are printed and counted - * @param client The Grafeas client used to perform the API requests. - * @param noteId the Note's unique identifier - * @param projectId the GCP project the Note belongs to - * @return number of Occurrences found - */ - public static int getOccurrencesForNote(GrafeasV1Beta1Client client, String noteId, - String projectId) { - final NoteName noteName = NoteName.of(projectId, noteId); - int i = 0; - - ListNoteOccurrencesRequest request = ListNoteOccurrencesRequest.newBuilder() - .setName(noteName.toString()) - .build(); - for (Occurrence o : client.listNoteOccurrences(request).iterateAll()) { - // Write custom code to process each Occurrence here - System.out.println(o.getName()); - i = i + 1; - } - return i; - } - // [END occurrences_for_note] - - - // [START occurrences_for_image] - /** - * Retrieves all the Occurrences associated with a specified image - * Here, all Occurrences are simply printed and counted - * @param client The Grafeas client used to perform the API requests. - * @param imageUrl the Container Registry URL associated with the image - * example: "https://gcr.io/project/image@sha256:foo" - * @param projectId the GCP project to search for Occurrences in - * @return number of Occurrences found - */ - public static int getOccurrencesForImage(GrafeasV1Beta1Client client, String imageUrl, - String projectId) { - final String filterStr = "resourceUrl=\"" + imageUrl + "\""; - final String projectName = ProjectName.format(projectId); - int i = 0; - - for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) { - // Write custom code to process each Occurrence here - System.out.println(o.getName()); - i = i + 1; - } - return i; - } - // [END occurrences_for_image] - - // [START pubsub] - /** - * Handle incoming Occurrences using a Cloud Pub/Sub subscription - * @param subId the user-specified identifier for the Pub/Sub subscription - * @param timeout the amount of time to listen for Pub/Sub messages (in seconds) - * @param projectId the GCP project the Pub/Sub subscription belongs to - * @return number of Occurrence Pub/Sub messages received before exiting - * @throws InterruptedException on errors with the subscription client - */ - public static int pubSub(String subId, int timeout, String projectId) - throws InterruptedException { - Subscriber subscriber = null; - MessageReceiverExample receiver = new MessageReceiverExample(); - - try { - // Subscribe to the requested Pub/Sub channel - ProjectSubscriptionName subName = ProjectSubscriptionName.of(projectId, subId); - subscriber = Subscriber.newBuilder(subName, receiver).build(); - subscriber.startAsync().awaitRunning(); - // Listen to messages for 'timeout' seconds - for (int i = 0; i < timeout; i++) { - sleep(1000); - } - } finally { - // Stop listening to the channel - if (subscriber != null) { - subscriber.stopAsync(); - } - } - // Print and return the number of Pub/Sub messages received - System.out.println(receiver.messageCount); - return receiver.messageCount; - } - - - /** - * Custom class to handle incoming Pub/Sub messages - * In this case, the class will simply log and count each message as it comes in - */ - static class MessageReceiverExample implements MessageReceiver { - public int messageCount = 0; - - @Override - public synchronized void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) { - // Every time a Pub/Sub message comes in, print it and count it - System.out.println("Message " + messageCount + ": " + message.getData().toStringUtf8()); - messageCount += 1; - // Acknowledge the message - consumer.ack(); - } - } - - /** - * Creates and returns a Pub/Sub subscription object listening to the Occurrence topic - * @param subId the identifier you want to associate with the subscription - * @param projectId the GCP project to create the subscription under - * @throws IOException thrown on errors with the subscription client - * @throws StatusRuntimeException if subscription already exists - * - */ - public static Subscription createOccurrenceSubscription(String subId, String projectId) - throws IOException, StatusRuntimeException { - // This topic id will automatically receive messages when Occurrences are added or modified - String topicId = "container-analysis-occurrences-v1beta1"; - SubscriptionAdminClient client = SubscriptionAdminClient.create(); - PushConfig config = PushConfig.getDefaultInstance(); - ProjectTopicName topicName = ProjectTopicName.of(projectId, topicId); - ProjectSubscriptionName subName = ProjectSubscriptionName.of(projectId, subId); - Subscription sub = client.createSubscription(subName, topicName, config, 0); - return sub; - } - // [END pubsub] -} diff --git a/container-registry/container-analysis/src/main/java/com/example/containeranalysis/VulnerabilityOccurrencesForImage.java b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/VulnerabilityOccurrencesForImage.java new file mode 100644 index 00000000000..2ccf2f465c6 --- /dev/null +++ b/container-registry/container-analysis/src/main/java/com/example/containeranalysis/VulnerabilityOccurrencesForImage.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed 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 com.example.containeranalysis; + +// [START containeranalysis_vulnerability_occurrences_for_image] +import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; +import com.google.containeranalysis.v1beta1.ProjectName; +import io.grafeas.v1beta1.Occurrence; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +public class VulnerabilityOccurrencesForImage { + // Retrieve a list of vulnerability occurrences assoviated with a resource + public static List findVulnerabilityOccurrencesForImage(String resourceUrl, + String projectId) throws IOException { + // String resourceUrl = "https://gcr.io/project/image@sha256:123"; + // String projectId = "my-project-id"; + final String projectName = ProjectName.format(projectId); + String filterStr = String.format("kind=\"VULNERABILITY\" AND resourceUrl=\"%s\"", resourceUrl); + + // Initialize client that will be used to send requests. After completing all of your requests, + // call the "close" method on the client to safely clean up any remaining background resources. + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + LinkedList vulnerabilitylist = new LinkedList(); + for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) { + vulnerabilitylist.add(o); + } + return vulnerabilitylist; + } +} +// [END containeranalysis_vulnerability_occurrences_for_image] diff --git a/container-registry/container-analysis/src/test/java/com/example/containeranalysis/SamplesTest.java b/container-registry/container-analysis/src/test/java/com/example/containeranalysis/SamplesTest.java index 717bacbba6d..b364e23bbb1 100644 --- a/container-registry/container-analysis/src/test/java/com/example/containeranalysis/SamplesTest.java +++ b/container-registry/container-analysis/src/test/java/com/example/containeranalysis/SamplesTest.java @@ -17,22 +17,31 @@ package com.example.containeranalysis; import static java.lang.Thread.sleep; -import static junit.framework.Assert.fail; import static junit.framework.TestCase.assertEquals; import com.google.api.gax.rpc.NotFoundException; import com.google.cloud.devtools.containeranalysis.v1beta1.GrafeasV1Beta1Client; import com.google.cloud.pubsub.v1.Subscriber; import com.google.cloud.pubsub.v1.SubscriptionAdminClient; +import com.google.containeranalysis.v1beta1.NoteName; +import com.google.containeranalysis.v1beta1.ProjectName; import com.google.pubsub.v1.ProjectSubscriptionName; import io.grafeas.v1beta1.Note; import io.grafeas.v1beta1.Occurrence; +import io.grafeas.v1beta1.Resource; +import io.grafeas.v1beta1.discovery.Discovered; +import io.grafeas.v1beta1.discovery.Discovered.AnalysisStatus; +import io.grafeas.v1beta1.discovery.Discovery; import io.grafeas.v1beta1.vulnerability.Details; +import io.grafeas.v1beta1.vulnerability.Severity; import io.grafeas.v1beta1.vulnerability.Vulnerability; import io.grpc.StatusRuntimeException; import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeoutException; import org.junit.After; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -50,7 +59,6 @@ public class SamplesTest { private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); private static final String subId = "CA-Occurrences-" + (new Date()).getTime(); - private static GrafeasV1Beta1Client client; private String noteId; private String imageUrl; private Note noteObj; @@ -60,15 +68,11 @@ public class SamplesTest { @Rule public TestName name = new TestName(); - @BeforeClass - public static void setUpClass() throws Exception { - client = GrafeasV1Beta1Client.create(); - } + @AfterClass public static void tearDownClass() { try { - client.shutdownNow(); SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create(); ProjectSubscriptionName subName = ProjectSubscriptionName.of(PROJECT_ID, subId); subscriptionAdminClient.deleteSubscription(subName); @@ -85,13 +89,13 @@ public void setUp() throws Exception { System.out.println(name.getMethodName()); noteId = "note-" + (new Date()).getTime() + name.getMethodName(); imageUrl = "www." + (new Date()).getTime() + name.getMethodName() + ".com"; - noteObj = Samples.createNote(client, noteId, PROJECT_ID); + noteObj = CreateNote.createNote(noteId, PROJECT_ID); } @After public void tearDown() { try { - Samples.deleteNote(client, noteId, PROJECT_ID); + DeleteNote.deleteNote(noteId, PROJECT_ID); } catch (Exception e) { // these exceptions aren't relevant to the tests System.out.println("TearDown Error: " + e.toString()); @@ -101,90 +105,62 @@ public void tearDown() { @Test public void testCreateNote() throws Exception { // note should have been created as part of set up. verify that it succeeded - Note n = Samples.getNote(client, noteId, PROJECT_ID); + Note n = GetNote.getNote(noteId, PROJECT_ID); assertEquals(n.getName(), noteObj.getName()); } @Test public void testDeleteNote() throws Exception { - Samples.deleteNote(client, noteId, PROJECT_ID); + DeleteNote.deleteNote(noteId, PROJECT_ID); try { - Samples.getNote(client, noteId, PROJECT_ID); + GetNote.getNote(noteId, PROJECT_ID); // above should throw, because note was deleted - fail("note not deleted"); + Assert.fail("note not deleted"); } catch (NotFoundException e) { // test passes } } - @Test - public void testUpdateNote() throws Exception { - String descriptionText = "updated"; - - Note.Builder builder = Note.newBuilder(noteObj); - builder.setShortDescription(descriptionText); - Note returned = Samples.updateNote(client, builder.build(), noteId, PROJECT_ID); - assertEquals(descriptionText, returned.getShortDescription()); - - Note updated = Samples.getNote(client, noteId, PROJECT_ID); - assertEquals(descriptionText, updated.getShortDescription()); - } - @Test public void testCreateOccurrence() throws Exception { - Occurrence o = Samples.createOccurrence(client, imageUrl, noteId, PROJECT_ID, PROJECT_ID); - Occurrence retrieved = Samples.getOccurrence(client, o.getName()); + Occurrence o = CreateOccurrence.createOccurrence(imageUrl, noteId, PROJECT_ID, PROJECT_ID); + String[] nameArr = o.getName().split("/"); + String occId = nameArr[nameArr.length - 1]; + Occurrence retrieved = GetOccurrence.getOccurrence(occId, PROJECT_ID); assertEquals(o.getName(), retrieved.getName()); // clean up - Samples.deleteOccurrence(client, o.getName()); + DeleteOccurrence.deleteOccurrence(occId, PROJECT_ID); } @Test public void testDeleteOccurrence() throws Exception { - Occurrence o = Samples.createOccurrence(client, imageUrl, noteId, PROJECT_ID, PROJECT_ID); + Occurrence o = CreateOccurrence.createOccurrence(imageUrl, noteId, PROJECT_ID, PROJECT_ID); String occName = o.getName(); + String[] nameArr = occName.split("/"); + String occId = nameArr[nameArr.length - 1]; - Samples.deleteOccurrence(client, occName); + DeleteOccurrence.deleteOccurrence(occId, PROJECT_ID); try { - Samples.getOccurrence(client, occName); + GetOccurrence.getOccurrence(occId, PROJECT_ID); // getOccurrence should fail, because occurrence was deleted - fail("failed to delete occurrence"); + Assert.fail("failed to delete occurrence"); } catch (NotFoundException e) { // test passes } } - @Test - public void testUpdateOccurrence() throws Exception { - String typeId = "newType"; - - Occurrence o = Samples.createOccurrence(client, imageUrl, noteId, PROJECT_ID, PROJECT_ID); - - Occurrence.Builder b = Occurrence.newBuilder(o); - Details.Builder d = Details.newBuilder(); - d.setType(typeId); - b.setVulnerability(d); - - Occurrence returned = Samples.updateOccurrence(client, o.getName(), b.build()); - assertEquals(typeId, returned.getVulnerability().getType()); - Occurrence got = Samples.getOccurrence(client, o.getName()); - assertEquals(typeId, got.getVulnerability().getType()); - - // clean up - Samples.deleteOccurrence(client, o.getName()); - } - @Test public void testOccurrencesForImage() throws Exception { int newCount; int tries = 0; - int origCount = Samples.getOccurrencesForImage(client, imageUrl, PROJECT_ID); - final Occurrence o = Samples.createOccurrence(client, imageUrl, noteId, PROJECT_ID, PROJECT_ID); + int origCount = OccurrencesForImage.getOccurrencesForImage(imageUrl, PROJECT_ID); + final Occurrence o = CreateOccurrence.createOccurrence( + imageUrl, noteId, PROJECT_ID, PROJECT_ID); do { - newCount = Samples.getOccurrencesForImage(client, imageUrl, PROJECT_ID); + newCount = OccurrencesForImage.getOccurrencesForImage(imageUrl, PROJECT_ID); sleep(SLEEP_TIME); tries += 1; } while (newCount != 1 && tries < TRY_LIMIT); @@ -192,17 +168,20 @@ public void testOccurrencesForImage() throws Exception { assertEquals(0, origCount); // clean up - Samples.deleteOccurrence(client, o.getName()); + String[] nameArr = o.getName().split("/"); + String occId = nameArr[nameArr.length - 1]; + DeleteOccurrence.deleteOccurrence(occId, PROJECT_ID); } @Test public void testOccurrencesForNote() throws Exception { int newCount; int tries = 0; - int origCount = Samples.getOccurrencesForNote(client, noteId, PROJECT_ID); - final Occurrence o = Samples.createOccurrence(client, imageUrl, noteId, PROJECT_ID, PROJECT_ID); + int origCount = OccurrencesForNote.getOccurrencesForNote(noteId, PROJECT_ID); + final Occurrence o = CreateOccurrence.createOccurrence( + imageUrl, noteId, PROJECT_ID, PROJECT_ID); do { - newCount = Samples.getOccurrencesForNote(client, noteId, PROJECT_ID); + newCount = OccurrencesForNote.getOccurrencesForNote(noteId, PROJECT_ID); sleep(SLEEP_TIME); tries += 1; } while (newCount != 1 && tries < TRY_LIMIT); @@ -210,7 +189,9 @@ public void testOccurrencesForNote() throws Exception { assertEquals(1, newCount); // clean up - Samples.deleteOccurrence(client, o.getName()); + String[] nameArr = o.getName().split("/"); + String occId = nameArr[nameArr.length - 1]; + DeleteOccurrence.deleteOccurrence(occId, PROJECT_ID); } @Test @@ -219,12 +200,12 @@ public void testPubSub() throws Exception { int tries; ProjectSubscriptionName subName = ProjectSubscriptionName.of(PROJECT_ID, subId); try { - Samples.createOccurrenceSubscription(subId, PROJECT_ID); + PubSub.createOccurrenceSubscription(subId, PROJECT_ID); } catch (StatusRuntimeException e) { System.out.println("subscription " + subId + " already exists"); } Subscriber subscriber = null; - Samples.MessageReceiverExample receiver = new Samples.MessageReceiverExample(); + PubSub.MessageReceiverExample receiver = new PubSub.MessageReceiverExample(); subscriber = Subscriber.newBuilder(subName, receiver).build(); subscriber.startAsync().awaitRunning(); @@ -235,7 +216,7 @@ public void testPubSub() throws Exception { // now, we can test adding 3 more occurrences int endVal = startVal + 3; for (int i = startVal; i <= endVal; i++) { - Occurrence o = Samples.createOccurrence(client, imageUrl, noteId, PROJECT_ID, PROJECT_ID); + Occurrence o = CreateOccurrence.createOccurrence(imageUrl, noteId, PROJECT_ID, PROJECT_ID); System.out.println("CREATED: " + o.getName()); tries = 0; do { @@ -245,10 +226,136 @@ public void testPubSub() throws Exception { } while (newCount != i && tries < TRY_LIMIT); System.out.println(receiver.messageCount + " : " + i); assertEquals(i, receiver.messageCount); - Samples.deleteOccurrence(client, o.getName()); + String[] nameArr = o.getName().split("/"); + String occId = nameArr[nameArr.length - 1]; + DeleteOccurrence.deleteOccurrence(occId, PROJECT_ID); } if (subscriber != null) { subscriber.stopAsync(); } } + + @Test + public void testPollDiscoveryOccurrenceFinished() throws Exception { + try { + // expect fail on first try + PollDiscoveryOccurrenceFinished.pollDiscoveryOccurrenceFinished(imageUrl, PROJECT_ID, 5); + Assert.fail("found unexpected discovery occurrence"); + } catch (TimeoutException e) { + // test passes + } + // create discovery note + String discNoteId = "discovery-note-" + (new Date()).getTime(); + NoteName noteName = NoteName.of(PROJECT_ID, discNoteId); + Note.Builder noteBuilder = Note.newBuilder(); + Discovery.Builder discoveryBuilder = Discovery.newBuilder(); + noteBuilder.setDiscovery(discoveryBuilder); + Note newNote = noteBuilder.build(); + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + client.createNote(ProjectName.format(PROJECT_ID), discNoteId, newNote); + + // create discovery occurrence + Occurrence.Builder occBuilder = Occurrence.newBuilder(); + occBuilder.setNoteName(noteName.toString()); + Discovered.Builder discoveredBuilder = Discovered.newBuilder(); + discoveredBuilder.setAnalysisStatus(AnalysisStatus.FINISHED_SUCCESS); + io.grafeas.v1beta1.discovery.Details.Builder detailsBuilder = + io.grafeas.v1beta1.discovery.Details.newBuilder(); + detailsBuilder.setDiscovered(discoveredBuilder); + occBuilder.setDiscovered(detailsBuilder); + Resource.Builder resourceBuilder = Resource.newBuilder(); + resourceBuilder.setUri(imageUrl); + occBuilder.setResource(resourceBuilder); + Occurrence newOcc = occBuilder.build(); + Occurrence result = client.createOccurrence(ProjectName.format(PROJECT_ID), newOcc); + + // poll again + Occurrence found = PollDiscoveryOccurrenceFinished.pollDiscoveryOccurrenceFinished( + imageUrl, PROJECT_ID, 5); + AnalysisStatus foundStatus = found.getDiscovered().getDiscovered().getAnalysisStatus(); + assertEquals(foundStatus, AnalysisStatus.FINISHED_SUCCESS); + + // clean up + String[] nameArr = found.getName().split("/"); + String occId = nameArr[nameArr.length - 1]; + DeleteOccurrence.deleteOccurrence(occId, PROJECT_ID); + DeleteNote.deleteNote(discNoteId, PROJECT_ID); + } + + @Test + public void testFindVulnerabilitiesForImage() throws Exception { + List result = VulnerabilityOccurrencesForImage.findVulnerabilityOccurrencesForImage( + imageUrl, PROJECT_ID); + assertEquals(result.size(), 0); + Occurrence o = CreateOccurrence.createOccurrence(imageUrl, noteId, PROJECT_ID, PROJECT_ID); + int tries = 0; + do { + result = VulnerabilityOccurrencesForImage.findVulnerabilityOccurrencesForImage( + imageUrl, PROJECT_ID); + sleep(SLEEP_TIME); + tries += 1; + } while (result.size() != 1 && tries < TRY_LIMIT); + assertEquals(result.size(), 1); + + // clean up + String[] nameArr = o.getName().split("/"); + String occId = nameArr[nameArr.length - 1]; + DeleteOccurrence.deleteOccurrence(occId, PROJECT_ID); + } + + @Test + public void testFindHighSeverityVulnerabilitiesForImage() throws Exception { + // check before creation + List result = HighVulnerabilitiesForImage.findHighSeverityVulnerabilitiesForImage( + imageUrl, PROJECT_ID); + assertEquals(0, result.size()); + + // create low severity occurrence + Occurrence low; + low = CreateOccurrence.createOccurrence(imageUrl, noteId, PROJECT_ID, PROJECT_ID); + result = HighVulnerabilitiesForImage.findHighSeverityVulnerabilitiesForImage( + imageUrl, PROJECT_ID); + assertEquals(0, result.size()); + + // create high severity note + String vulnNoteId = "discovery-note-" + (new Date()).getTime(); + Note.Builder noteBuilder = Note.newBuilder(); + Vulnerability.Builder vulnBuilder = Vulnerability.newBuilder(); + vulnBuilder.setSeverity(Severity.CRITICAL); + noteBuilder.setVulnerability(vulnBuilder); + Note newNote = noteBuilder.build(); + GrafeasV1Beta1Client client = GrafeasV1Beta1Client.create(); + client.createNote(ProjectName.format(PROJECT_ID), vulnNoteId, newNote); + + // create high severity occurrence + Occurrence.Builder occBuilder = Occurrence.newBuilder(); + NoteName noteName = NoteName.of(PROJECT_ID, vulnNoteId); + occBuilder.setNoteName(noteName.toString()); + Details.Builder detailsBuilder = Details.newBuilder(); + occBuilder.setVulnerability(detailsBuilder); + Resource.Builder resourceBuilder = Resource.newBuilder(); + resourceBuilder.setUri(imageUrl); + occBuilder.setResource(resourceBuilder); + Occurrence critical = occBuilder.build(); + critical = client.createOccurrence(ProjectName.format(PROJECT_ID), critical); + + // check again + int tries = 0; + do { + result = HighVulnerabilitiesForImage.findHighSeverityVulnerabilitiesForImage( + imageUrl, PROJECT_ID); + sleep(SLEEP_TIME); + tries += 1; + } while (result.size() != 1 && tries < TRY_LIMIT); + assertEquals(1, result.size()); + + // clean up + String[] lowNameArr = low.getName().split("/"); + String lowId = lowNameArr[lowNameArr.length - 1]; + DeleteOccurrence.deleteOccurrence(lowId, PROJECT_ID); + String[] nameArr = critical.getName().split("/"); + String occId = nameArr[nameArr.length - 1]; + DeleteOccurrence.deleteOccurrence(occId, PROJECT_ID); + DeleteNote.deleteNote(vulnNoteId, PROJECT_ID); + } }