1+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+ // SPDX-License-Identifier: Apache-2.0
3+
4+ package com .java .inspector ;
5+
6+ import org .slf4j .Logger ;
7+ import org .slf4j .LoggerFactory ;
8+ import software .amazon .awssdk .services .inspector2 .Inspector2Client ;
9+ import software .amazon .awssdk .services .inspector2 .model .BatchGetAccountStatusRequest ;
10+ import software .amazon .awssdk .services .inspector2 .model .BatchGetAccountStatusResponse ;
11+ import software .amazon .awssdk .services .inspector2 .model .AccountState ;
12+ import software .amazon .awssdk .services .inspector2 .model .ResourceState ;
13+ import software .amazon .awssdk .services .inspector2 .model .State ;
14+ import software .amazon .awssdk .services .inspector2 .model .ListFindingsRequest ;
15+ import software .amazon .awssdk .services .inspector2 .model .ListFindingsResponse ;
16+ import software .amazon .awssdk .services .inspector2 .model .Finding ;
17+ import software .amazon .awssdk .services .inspector2 .model .ListUsageTotalsRequest ;
18+ import software .amazon .awssdk .services .inspector2 .model .ListUsageTotalsResponse ;
19+ import software .amazon .awssdk .services .inspector2 .model .UsageTotal ;
20+ import software .amazon .awssdk .services .inspector2 .model .Inspector2Exception ;
21+ import software .amazon .awssdk .services .inspector2 .paginators .ListFindingsIterable ;
22+ import software .amazon .awssdk .services .inspector2 .paginators .ListUsageTotalsIterable ;
23+ import java .util .List ;
24+ import java .util .ArrayList ;
25+
26+ // snippet-start:[inspector.java2.hello.main]
27+ /**
28+ * Before running this Java V2 code example, set up your development
29+ * environment, including your credentials.
30+ *
31+ * For more information, see the following documentation topic:
32+ *
33+ * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
34+ */
35+ public class HelloInspector {
36+ private static final Logger logger = LoggerFactory .getLogger (HelloInspector .class );
37+ public static void main (String [] args ) {
38+ logger .info (" Hello Amazon Inspector!" );
39+ try (Inspector2Client inspectorClient = Inspector2Client .builder ()
40+ .build ()) {
41+
42+ logger .info ("Checking Inspector account status..." );
43+ checkAccountStatus (inspectorClient );
44+ logger .info ("" );
45+
46+ logger .info ("Checking for recent findings..." );
47+ listRecentFindings (inspectorClient );
48+ logger .info ("" );
49+
50+ logger .info ("Checking usage totals..." );
51+ showUsageTotals (inspectorClient );
52+ logger .info ("" );
53+
54+ logger .info ("The Hello Inspector example completed successfully." );
55+
56+ } catch (Inspector2Exception e ) {
57+ logger .info (" Error: {}" , e .getMessage ());
58+ logger .info (" Troubleshooting:" );
59+ logger .info ("1. Verify AWS credentials are configured" );
60+ logger .info ("2. Check IAM permissions for Inspector2" );
61+ logger .info ("3. Ensure Inspector2 is enabled in your account" );
62+ logger .info ("4. Verify you're using a supported region" );
63+ }
64+ }
65+
66+ /**
67+ * Checks the account status using the provided Inspector2Client.
68+ * This method sends a request to retrieve the account status and prints the details of each account's resource states.
69+ *
70+ * @param inspectorClient The Inspector2Client used to interact with the AWS Inspector service.
71+ */
72+ public static void checkAccountStatus (Inspector2Client inspectorClient ) {
73+ try {
74+ BatchGetAccountStatusRequest request = BatchGetAccountStatusRequest .builder ().build ();
75+ BatchGetAccountStatusResponse response = inspectorClient .batchGetAccountStatus (request );
76+
77+ List <AccountState > accounts = response .accounts ();
78+ if (accounts == null || accounts .isEmpty ()) {
79+ logger .info (" No account information returned." );
80+ return ;
81+ }
82+
83+ for (AccountState account : accounts ) {
84+ logger .info (" Account: " + account .accountId ());
85+ ResourceState resources = account .resourceState ();
86+ if (resources == null ) {
87+ System .out .println (" No resource state data available." );
88+ continue ;
89+ }
90+
91+ logger .info (" Resource States:" );
92+ printState ("EC2" , resources .ec2 ());
93+ printState ("ECR" , resources .ecr ());
94+ printState ("Lambda" , resources .lambda ());
95+ printState ("Lambda Code" , resources .lambdaCode ());
96+ System .out .println ();
97+ }
98+
99+ } catch (Inspector2Exception e ) {
100+ System .err .println (" Failed to retrieve account status: " + e .awsErrorDetails ().errorMessage ());
101+ }
102+ }
103+
104+ public static void printState (String name , State state ) {
105+ if (state == null ) {
106+ logger .info (" - {} : (no data)" , name );
107+ return ;
108+ }
109+ String err = state .errorMessage () != null ? " (Error: " + state .errorMessage () + ")" : "" ;
110+ logger .info (" - {}: {}{}" , name , state .status (), err );
111+ }
112+
113+ /**
114+ * Lists recent findings from AWS Inspector2 using the synchronous client with a paginator.
115+ *
116+ * @param inspectorClient an instance of {@link Inspector2Client} used to call AWS Inspector2
117+ * @throws Inspector2Exception if there is an error communicating with the Inspector2 service
118+ */
119+ /**
120+ * Lists up to 10 recent findings from AWS Inspector2 using the synchronous client.
121+ *
122+ * <p>This method retrieves findings in pages and logs details for each finding,
123+ * including title, severity, status, and last observed time. Only the first
124+ * 10 findings are logged, even if more exist.
125+ *
126+ * @param inspectorClient an instance of {@link Inspector2Client} used to call AWS Inspector2
127+ * @throws Inspector2Exception if there is an error communicating with the Inspector2 service
128+ */
129+ public static void listRecentFindings (Inspector2Client inspectorClient ) {
130+ final int MAX_FINDINGS = 10 ;
131+ int totalLogged = 0 ;
132+
133+ try {
134+ // Build initial request with page size
135+ ListFindingsRequest request = ListFindingsRequest .builder ()
136+ .maxResults (MAX_FINDINGS )
137+ .build ();
138+
139+ // Paginator returns an iterable over responses
140+ ListFindingsIterable responses = inspectorClient .listFindingsPaginator (request );
141+
142+ for (ListFindingsResponse response : responses ) {
143+ List <Finding > findings = response .findings ();
144+ if (findings == null || findings .isEmpty ()) {
145+ continue ;
146+ }
147+
148+ for (Finding finding : findings ) {
149+ if (totalLogged >= MAX_FINDINGS ) {
150+ break ;
151+ }
152+
153+ logger .info (" Title: {}" , finding .title ());
154+ logger .info (" Severity: {}" , finding .severity ());
155+ logger .info (" Status: {}" , finding .status ());
156+ logger .info (" Last Observed: {}" , finding .lastObservedAt ());
157+ logger .info ("" );
158+
159+ totalLogged ++;
160+ }
161+
162+ if (totalLogged >= MAX_FINDINGS ) {
163+ break ;
164+ }
165+ }
166+
167+ if (totalLogged == 0 ) {
168+ logger .info (" No findings found." );
169+ } else {
170+ logger .info (" Displayed {} recent finding(s)." , totalLogged );
171+ }
172+
173+ } catch (Inspector2Exception e ) {
174+ logger .info (" Error listing findings: {}" , e .awsErrorDetails ().errorMessage ());
175+ }
176+ }
177+
178+
179+ /**
180+ * Displays the usage totals for the Inspector2 service.
181+ *
182+ * @param inspectorClient the {@code Inspector2Client} used to make the API call to
183+ * retrieve the usage totals.
184+ *
185+ * @throws Inspector2Exception if there is an error while retrieving the usage totals.
186+ * The error message is printed to the standard error output.
187+ */
188+ public static void showUsageTotals (Inspector2Client inspectorClient ) {
189+ try {
190+ logger .info ("Listing usage totals using paginator..." );
191+ ListUsageTotalsRequest request = ListUsageTotalsRequest .builder ()
192+ .maxResults (10 )
193+ .build ();
194+
195+ // Create paginator.
196+ ListUsageTotalsIterable paginator = inspectorClient .listUsageTotalsPaginator (request );
197+ List <UsageTotal > allTotals = new ArrayList <>();
198+
199+ // Iterate through all pages.
200+ for (ListUsageTotalsResponse response : paginator ) {
201+ List <UsageTotal > totals = response .totals ();
202+ if (totals != null && !totals .isEmpty ()) {
203+ allTotals .addAll (totals );
204+ }
205+ }
206+
207+ // Display results.
208+ if (allTotals .isEmpty ()) {
209+ logger .info (" No usage data available yet." );
210+ logger .info (" Usage data appears after Inspector has been active for some time." );
211+ } else {
212+ logger .info (" Usage Totals (Last 30 days):" );
213+ for (UsageTotal total : allTotals ) {
214+ logger .info (" Account: {}" , total .accountId ());
215+ if (total .usage () != null && !total .usage ().isEmpty ()) {
216+ total .usage ().forEach (u -> {
217+ logger .info (" - {}: {}" , u .type (), u .total ());
218+
219+ if (u .estimatedMonthlyCost () != null ) {
220+ logger .info (" Estimated Monthly Cost: {} {}" , u .estimatedMonthlyCost (), u .currency ());
221+ }
222+ });
223+ }
224+ logger .info ("" );
225+ }
226+ }
227+
228+ } catch (Inspector2Exception e ) {
229+ logger .info (" Error getting usage totals: {}" , e .awsErrorDetails ().errorMessage ());
230+ throw e ;
231+ } catch (Exception e ) {
232+ throw new RuntimeException ("Unexpected error while listing usage totals: " + e .getMessage (), e );
233+ }
234+ }
235+ }
236+ // snippet-end:[inspector.java2.hello.main]
0 commit comments