I have a spring boot project which interacts with Cloud Foundry
I have the following code:
CloudFoundryController.java:
package com.backend
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.context.ApplicationListener;
import org.cloudfoundry.operations.CloudFoundryOperations;
import org.cloudfoundry.operations.applications.GetApplicationRequest;
import org.cloudfoundry.operations.DefaultCloudFoundryOperations;
import org.cloudfoundry.reactor.DefaultConnectionContext;
import org.cloudfoundry.reactor.TokenProvider;
import org.cloudfoundry.reactor.client.ReactorCloudFoundryClient;
import org.cloudfoundry.reactor.tokenprovider.PasswordGrantTokenProvider;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class BackendApplication implements ApplicationListener<ApplicationFailedEvent> {
private static final Logger logger = LoggerFactory.getLogger(BackendApplication.class);
public static void main(String[] args) {
// Hardcoded Cloud Foundry client configuration
String target = "thisistheurl";
String org = "thisisthename";
String space = "thisisthename";
String user = "thisisthelogin";
String password = "thisisthepass";
try {
// Configure and login to Cloud Foundry
final PasswordGrantTokenProvider tokenProvider = PasswordGrantTokenProvider.builder()
.username(user)
.password(password)
.build();
final DefaultConnectionContext connectionContext = DefaultConnectionContext.builder()
.apiHost(target)
.build();
final ReactorCloudFoundryClient client = ReactorCloudFoundryClient.builder()
.connectionContext(connectionContext)
.tokenProvider(tokenProvider)
.build();
final DefaultCloudFoundryOperations operations = DefaultCloudFoundryOperations.builder()
.cloudFoundryClient(client)
.organization(org)
.space(space)
.build();
operations.applications().list().subscribe(application ->
System.out.printf(" %s%n", application.getName())
);
} catch (Exception e) {
logger.error("Error interacting with Cloud Foundry: " + e.getMessage());
}
}
@Override
private static URL getTargetURL(String target) {
try {
return URI.create(target).toURL();
} catch (MalformedURLException e) {
throw new RuntimeException("The target URL is not valid: " + e.getMessage());
}
}
}
I have the following libraries:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.cloudfoundry</groupId>
<artifactId>cloudfoundry-operations</artifactId>
<version>5.12.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.cloudfoundry</groupId>
<artifactId>cloudfoundry-client-reactor</artifactId>
<version>5.12.1.RELEASE</version>
</dependency>
What i get is: HTTP/1.1 401 Unauthorized
And corresponding exception:
2024-04-21T23:26:04.769+12:00 ERROR 36848 --- [backend] [ry-client-nio-2] cloudfoundry-client.compatibility : An error occurred while checking version compatibility:
org.cloudfoundry.uaa.UaaException: invalid_client: Bad credentials
at org.cloudfoundry.reactor.util.ErrorPayloadMappers.lambda$null$8(ErrorPayloadMappers.java:104) ~[cloudfoundry-client-reactor-5.12.1.RELEASE.jar:na]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Assembly trace from producer [reactor.core.publisher.MonoCacheTime] :
reactor.core.publisher.Mono.checkpoint(Mono.java:2261)
org.cloudfoundry.reactor.tokenprovider.AbstractUaaTokenProvider.token(AbstractUaaTokenProvider.java:330)
Error has been observed at the following site(s):
*__checkpoint() ⇢ at org.cloudfoundry.reactor.tokenprovider.AbstractUaaTokenProvider.token(AbstractUaaTokenProvider.java:330)
*__checkpoint() ⇢ at org.cloudfoundry.reactor.client.v2.info.ReactorInfo.get(ReactorInfo.java:52)
when I perform the following operation:
cf -a thisistheurl -u thisisthelogin -p thisisthepass
it works perfectly, login is working.
However from what i see, the java library does the following:
newlink/v2/info
and obtains authorization_endpoint, which is something like login.thisistheurl
login.thisistheurl/oauth/token
and gets 'unauthorized' which is completely true, as I can't login with my creds through browser (and probably should not be able to.Can anybody help with corrections in my implementation?
The code actually works perfect. I had to check the accuracy in handling the variables. Exact issue is unknow.