@@ -83,10 +83,13 @@ public final class ExhortApi implements Api {
8383 public static final String S_API_V5_LICENSES_IDENTIFY = "%s/api/v5/licenses/identify" ;
8484 private static final String TRUSTIFY_DA_LICENSE_CHECK = "TRUSTIFY_DA_LICENSE_CHECK" ;
8585
86- private final String endpoint ;
86+ private String endpoint ;
8787
8888 public String getEndpoint () {
89- return endpoint ;
89+ if (this .endpoint == null ) {
90+ this .endpoint = getExhortUrl ();
91+ }
92+ return this .endpoint ;
9093 }
9194
9295 private final HttpClient client ;
@@ -117,7 +120,6 @@ static HttpClient.Version getHttpVersion() {
117120 commonHookBeginning (true );
118121 this .client = client ;
119122 this .mapper = new ObjectMapper ().disable (DeserializationFeature .FAIL_ON_UNKNOWN_PROPERTIES );
120- this .endpoint = getExhortUrl ();
121123 }
122124
123125 public static HttpClient createHttpClient () {
@@ -346,7 +348,7 @@ public CompletableFuture<AnalysisReport> componentAnalysis(
346348 String exClientTraceId = commonHookBeginning (false );
347349 var manifestPath = Path .of (manifest );
348350 var provider = Ecosystem .getProvider (manifestPath );
349- var uri = URI .create (String .format (S_API_V_5_ANALYSIS , this . endpoint ));
351+ var uri = URI .create (String .format (S_API_V_5_ANALYSIS , getEndpoint () ));
350352 var content = provider .provideComponent ();
351353 commonHookAfterProviderCreatedSbomAndBeforeExhort ();
352354 return getAnalysisReportForComponent (uri , content , exClientTraceId );
@@ -390,7 +392,7 @@ public CompletableFuture<AnalysisReport> componentAnalysis(String manifestFile)
390392 String exClientTraceId = commonHookBeginning (false );
391393 var manifestPath = Path .of (manifestFile );
392394 var provider = Ecosystem .getProvider (manifestPath );
393- var uri = URI .create (String .format (S_API_V_5_ANALYSIS , this . endpoint ));
395+ var uri = URI .create (String .format (S_API_V_5_ANALYSIS , getEndpoint () ));
394396 var content = provider .provideComponent ();
395397 commonHookAfterProviderCreatedSbomAndBeforeExhort ();
396398 return getAnalysisReportForComponent (uri , content , exClientTraceId );
@@ -431,13 +433,21 @@ private HttpRequest buildStackRequest(final String manifestFile, final MediaType
431433 throws IOException {
432434 var manifestPath = Path .of (manifestFile );
433435 var provider = Ecosystem .getProvider (manifestPath );
434- var uri = URI .create (String .format (S_API_V_5_ANALYSIS , this . endpoint ));
436+ var uri = URI .create (String .format (S_API_V_5_ANALYSIS , getEndpoint () ));
435437 var content = provider .provideStack ();
436438 commonHookAfterProviderCreatedSbomAndBeforeExhort ();
437439
438440 return buildRequest (content , uri , acceptType , "Stack Analysis" );
439441 }
440442
443+ @ Override
444+ public String generateSbom (final String manifestFile ) throws IOException {
445+ var manifestPath = Path .of (manifestFile );
446+ var provider = Ecosystem .getProvider (manifestPath );
447+ var content = provider .provideStack ();
448+ return new String (content .buffer , java .nio .charset .StandardCharsets .UTF_8 );
449+ }
450+
441451 @ Override
442452 public CompletableFuture <Map <ImageRef , AnalysisReport >> imageAnalysis (
443453 final Set <ImageRef > imageRefs ) throws IOException {
@@ -510,7 +520,7 @@ <H, T> CompletableFuture<T> performBatchAnalysis(
510520 final String analysisName )
511521 throws IOException {
512522 String exClientTraceId = commonHookBeginning (false );
513- var uri = URI .create (String .format (S_API_V_5_BATCH_ANALYSIS , this . endpoint ));
523+ var uri = URI .create (String .format (S_API_V_5_BATCH_ANALYSIS , getEndpoint () ));
514524 var sboms = sbomsGenerator .get ();
515525 var content =
516526 new Provider .Content (
@@ -572,7 +582,7 @@ public CompletableFuture<ComponentAnalysisResult> componentAnalysisWithLicense(
572582 String exClientTraceId = commonHookBeginning (false );
573583 var manifestPath = Path .of (manifestFile );
574584 var provider = Ecosystem .getProvider (manifestPath );
575- var uri = URI .create (String .format (S_API_V_5_ANALYSIS , this . endpoint ));
585+ var uri = URI .create (String .format (S_API_V_5_ANALYSIS , getEndpoint () ));
576586 var content = provider .provideComponent ();
577587 String sbomJson = new String (content .buffer );
578588 commonHookAfterProviderCreatedSbomAndBeforeExhort ();
@@ -603,7 +613,7 @@ public CompletableFuture<ComponentAnalysisResult> componentAnalysisWithLicense(
603613 */
604614 public CompletableFuture <JsonNode > getLicenseDetails (String spdxId ) {
605615 String encodedId = URLEncoder .encode (spdxId , StandardCharsets .UTF_8 ).replace ("+" , "%20" );
606- URI uri = URI .create (String .format (S_API_V5_LICENSES , this . endpoint , encodedId ));
616+ URI uri = URI .create (String .format (S_API_V5_LICENSES , getEndpoint () , encodedId ));
607617 HttpRequest request = buildGetRequest (uri , "License Details" );
608618
609619 return this .client
@@ -649,7 +659,7 @@ public CompletableFuture<String> identifyLicense(Path licenseFilePath) {
649659 LOG .warning (String .format ("Failed to read license file: %s" , e .getMessage ()));
650660 return CompletableFuture .completedFuture (null );
651661 }
652- URI uri = URI .create (String .format (S_API_V5_LICENSES_IDENTIFY , this . endpoint ));
662+ URI uri = URI .create (String .format (S_API_V5_LICENSES_IDENTIFY , getEndpoint () ));
653663 HttpRequest request =
654664 buildPostRequest (
655665 uri ,
0 commit comments