Unable to create camel salesforce endpoint - java

I am trying to connect to salesforce using Apache Camel salesforce component.
Here is a very simple route I am trying to start:
#Override
public void configure() throws Exception {
from("salesforce:event/Case__e")
.to("mock:end");
}
When trying to start it I am getting an obvious error saying I did not specify a client id:
Caused by: java.lang.IllegalArgumentException: clientId must be specified
at org.apache.camel.util.ObjectHelper.notNull(ObjectHelper.java:149) ~[camel-util-3.16.0.jar:3.16.0]
at org.apache.camel.component.salesforce.SalesforceLoginConfig.validate(SalesforceLoginConfig.java:238) ~[camel-salesforce-3.16.0.jar:3.16.0]
That makes perfectly sense as according to Camel docs clentId parameter must be specified. To address this I am specifying a clientId as below:
#Override
public void configure() throws Exception {
from("salesforce:event/Case__e?clientId=xyz")
.to("mock:end");
}
When trying to start the route this time I am getting a rather strange error complaining about clientId being an unknown parameter:
Failed to resolve endpoint: salesforce://event/Case__e?clientId=xyz due to: There are 1 parameters that couldn't be set on the endpoint.
Check the uri if the parameters are spelt correctly and that they are properties of the endpoint.
Unknown parameters=[{clientId=xyz}]
Not sure what I am doing wrong and how should I address this.
Thank you in advance for your inputs.

Your problem is related to the fact that clientId is a component option so it must be configured at the component level while you try to configure it like it was a query parameter / an endpoint option which cannot work.
Depending on the runtime that you use, the way to configure a component may change but the idea remains the same.
For example, assuming that you use an application.properties to configure your application, the configuration of your salesforce component would look like this:
In application.properties
# Salesforce credentials
camel.component.salesforce.login-config.client-id=<Your Client ID>
camel.component.salesforce.login-config.client-secret=<Your Client Secret>
camel.component.salesforce.login-config.refresh-token=<Your Refresh Token>
...
Here is a salesforce example https://github.com/apache/camel-examples/blob/main/examples/salesforce-consumer/

Related

How to create an IAM User using apache camel?

I have a camel rest api. I was trying to create an IAM User using apache camel framework. The code is like so ->
.post("iam-create-user")
.route()
.process(new Processor(){
#Override
public void process(Exchange exchange) throws Exception {
exchange.getIn().setHeader("CamelAwsIAMUsername", "new-user");
})
.to("aws2-iam://current-user?accessKey=insert&secretKey=insert&operation=createUser")
.endRest();
I am getting this error java.lang.NullPointerException: null. What is the correct way of doing this? It shows in the camel docs to use a URL like so to("aws2-iam://test?iamClient=#amazonIAMClient&operation=createUser"). What do we put as iamClient?
The iamClient reported in the example (#amazonIAMClient) is an instance of IAMClient you'll need to put in the Camel registry with a bind name amazonIAMClient.
I think you need to specify region as aws-global for this particular component.
Maybe add the full stack trace of your error.

How to access kerberos SPNEGO authenticated resource using spring rest template

I am running into issues while trying to access kerberos SPNEGO authenticated resource using spring rest client. I am using KerberosRestTemplate.
From the docs
Leave keyTabLocation and userPrincipal empty if you want to use cached ticket.
But while I try with invoking the parameterless constructor
this.kerberosRestTemplate = new KerberosRestTemplate();
And try to access to the protected resource it fails with the following error:
org.springframework.web.client.RestClientException: Error running rest call; nested exception is java.lang.IllegalArgumentException: Null name not allowed
at org.springframework.security.kerberos.client.KerberosRestTemplate.doExecute(KerberosRestTemplate.java:196)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:538)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:245)
Caused by: java.lang.IllegalArgumentException: Null name not allowed
at sun.security.krb5.PrincipalName.<init>(PrincipalName.java:356) ~[?:1.7.0_67]
at javax.security.auth.kerberos.KerberosPrincipal.<init>(KerberosPrincipal.java:123) ~[?:1.7.0_67]
at org.springframework.security.kerberos.client.KerberosRestTemplate.doExecute(KerberosRestTemplate.java:182)
What am I doing wrong here?
Please try these spring-security-kerberos. I think you are missing basic configuration which can be achieved either via xml or java configuration based .
Can also try following options:
Use loginOptions if you want to customise Krb5LoginModule options.
Use a customised httpClient.
Just call the constructor with null for keyTabLocation and any non-empty string for userPrincipal, like this:
KerberosRestTemplate restTemplate = new KerberosRestTemplate(null,"-");

How to get applicationContextPath in dropwizard 1.0.0

We are using server configuration in yml file which looks like as below
server:
type: simple
connector:
type: http
port: 8061
applicationContextPath: /administration
adminContextPath: /admin
#disable the registration of default Jersey ExceptionMappers
registerDefaultExceptionMappers: false
I want to get "applicationContextPath" when I start my dropwizard service.
I am trying to get it using
environment.getApplicationContext().getContextPath();
but I am getting "/" i.e. default value. Is there anyway to get this.
In order get applicationContextPath we need to get ServerFactory from Configuration and parse it to SimpleServerFactory as below:
((SimpleServerFactory) getConfiguration().getServerFactory()).getApplicationContextPath()
This works for me:
#Override
public void run(CustomAppConfiguration customAppConfiguration , Environment environment) throws Exception {
DefaultServerFactory factory = (DefaultServerFactory) customAppConfiguration .getServerFactory();
System.out.println("CONTEXT PATH: "+factory.getApplicationContextPath());
...
}
If it's in your config file and you want to just read the value in as it exist in your config.yml, then I'd suggest making it part of your Configuration class. Values in your config can always be accessed this way regardless of whether dropwizard uses and treats those key/values in special manner internally.
The following worked for me in dropwizard 1.0.0:
MyApp.java:
public class MyApp extends Application<MyConfig> {
//...
#Override
public void run(MyConfig configuration, Environment environment) throws Exception {
System.out.println(configuration.contextPath);
//...
MyConfig.java
public class MyConfig extends Configuration {
//...
#JsonProperty("applicationContextPath")
public String contextPath;
//...
If I understood your question correctly what you can do in Dropwizard version 1.3.8 if you are using simple server (without https) you can get applicationContextPath in following way:
server:
type: simple
rootPath: /*
applicationContextPath: /administration
adminContextPath: /admin
connector:
type: http
port: 8080
More info about rootPath can be found in Dropwizard Configuration Reference. So if you want to access:
Application REST endpoint /books (which is value of GET,
POST or similar annotation in one of your Resource class methods) you can
type URL like this http://localhost:8080/administration/books
Metrics (only accessible via admin context path) of your Dropwizard application then you create URL like this: http://localhost:8080/admin/metrics
Hope that helps. Cheers!

pathParameters documentation exception (urlTemplate not found)

When using pathParameters to document the URI path parameters like below
#Test
public void documentGetRouteById() throws Exception {
this.mockMvc.perform(get("/route/{id}", "FooBar")).andExpect(status().isOk())
.andDo(document("api-getRouteById",
pathParameters(parameterWithName("id").description("die Routen ID"))));
}
I get the following excpetion
java.lang.IllegalArgumentException: urlTemplate not found. Did you use RestDocumentationRequestBuilders to build the request?
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.restdocs.request.PathParametersSnippet.extractUrlTemplate(PathParametersSnippet.java:95)
at org.springframework.restdocs.request.PathParametersSnippet.extractActualParameters(PathParametersSnippet.java:82)
at org.springframework.restdocs.request.AbstractParametersSnippet.verifyParameterDescriptors(AbstractParametersSnippet.java:77)
at org.springframework.restdocs.request.AbstractParametersSnippet.createModel(AbstractParametersSnippet.java:65)
at org.springframework.restdocs.request.PathParametersSnippet.createModel(PathParametersSnippet.java:67)
at org.springframework.restdocs.snippet.TemplatedSnippet.document(TemplatedSnippet.java:64)
at org.springframework.restdocs.mockmvc.RestDocumentationResultHandler.handle(RestDocumentationResultHandler.java:101)
at org.springframework.test.web.servlet.MockMvc$1.andDo(MockMvc.java:158)
I am pretty sure I did the test setup like explained here.
What could I probably have done wrong?
(Spring REST docs version is 1.0.0.BUILD-SNAPSHOT)
The exception message is trying to point you in the right direction:
urlTemplate not found. Did you use RestDocumentationRequestBuilders to build the request?
You need to use RestDocumentationRequestBuilders so that Spring REST Docs can capture the URL and extract the parameters from it. This is mentioned in the documentation where it says:
To make the path parameters available for documentation, the request must be built using one of the methods on RestDocumentationRequestBuilders rather than MockMvcRequestBuilders.
Replacing your static import of MockMvcRequestBuilders.get with one for RestDocumentationRequestBuilders.get should resolve the problem.

Sample SAML Java Config. Project, Broken From the Start

I pulled in the example Java configuration project for Spring's SAML extension. No commits seem to have been made to the project for about six months as of my writing this question. I have not done anything to this project except for run maven package against it.
I then run the application in Spring Tool Suite as a Spring Boot Application and the application runs; however, the application does not run without error and the application endpoint is inaccessible (resulting in am error message): "ERROR: Something went wrong in the authentication process".
I haven't registered any certificates, etc (and may very well need to). There are no instructions provided with the GitHub project for starting or working with the application. I have intentionally not posted the guts of the project as I have left it unmodified.
INFORMATION ON THE ERROR
From Chrome Dev. Tools, I can see a 500 Internal Server Error returned from the request to the localhost:8080 application. So, the issue is definitely with the sample application (or something that I have not done).
The following error is logged to the console on application deployment (I've included both an image and the text as the text is proving difficult to format):
Text:
[2015-08-20 14:41:40.551] boot - 9908 INFO [localhost-startStop-1]
--- HttpMethodDirector: I/O exception (javax.net.ssl.SSLPeerUnverifiedException) caught when processing
request: SSL peer failed hostname validation for name: 46.4.112.4
[2015-08-20 14:41:40.551] boot - 9908 INFO [localhost-startStop-1]
--- HttpMethodDirector: Retrying request
[2015-08-20 14:41:40.795] boot - 9908 ERROR [localhost-startStop-1] --- HTTPMetadataProvider:
Error retrieving metadata from https://idp.ssocircle.com/idp-meta.xml
javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname
validation for name: 46.4.112.4
at org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.verifyHostname(TLSProtocolSocketFactory.java:233)
at
org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory.createSocket(TLSProtocolSocketFactory.java:194)
I have visited the url endpoint provided by ssocircle and the metadata is exposed.
If I visit the /saml/metadata endpoint of the service provider and get some helpful information: an org.opensaml.saml2.metadata.provider.MetadataProviderException exception. The description if which is "No IDP was configured, please update included metadata with at least one IDP"; however, the source of this may be the above described error.
QUESTION
Am I missing something that is readily apparent to start the example application? In other words, what does this error tell me that I need to be investigating? Or, as it is "non-breaking", do I ignore it?
WHY I'M ASKING
The documentation surrounding the deployment of the Sample Java Configuration application is minimal (as in "non-existant"). The self-documentation only provides "hints", such as the following:
// IDP Metadata configuration - paths to metadata of IDPs in circle of trust is here
// Do no forget to call initialize method on providers
#Bean
#Qualifier("metadata")
public CachingMetadataManager metadata() throws MetadataProviderException {
List<MetadataProvider> providers = new ArrayList<MetadataProvider>();
providers.add(ssoCircleExtendedMetadataProvider());
return new CachingMetadataManager(providers);
}
I am certain there is something I am not doing, particularly since I have not done anything in the deployment of the application except for the run of the mvn package, described above.
The problem occurs due to the sample application's utilization of a deprecated constructor - a deprecation whose warning was explicitly suppressed - for the HTTPMetadataProvider (a fix I will commit, shortly). In configuring the ExtendedMetadataDelegate, the two-parametered constructor is utilized:
#Bean
#Qualifier("idp-ssocircle")
public ExtendedMetadataDelegate ssoCircleExtendedMetadataProvider() throws MetadataProviderException {
#SuppressWarnings({ "deprecation"})
HTTPMetadataProvider httpMetadataProvider = new HTTPMetadataProvider("https://idp.ssocircle.com/idp-meta.xml", 5000);
// other config.s...
}
If replaced with the non-deprecated constructor that takes a java.util.Timer and an org.apache.commons.httpclient.HttpClient (in addition to the metadata url), the sample application works, beautifully, and no errors are logged.
Additional Non-OP-related Information
I had to do the below to get the Sample SAML app to run
After removing the deprecated constructor, I recommend doing two things:
Follow the steps outlined in 4.2.6 of the documentation, i.e. treat the application during setup as the XML-configured application. All the steps need to be taken to "register" the metada.The application will be unable to register its metadata with the current Java configuration (see below; point no. 2)
Change the default configurations in class WebSecurityConfig (read detail, below)
Configuration Change
In the configuration of the ExtendedMetadataDelegate bean ssoCircleExtendedMetadataProvider, change the ExtendedMetadataDelegate's property values as follows:
// code....
extendedMetadataDelegate.setMetadataTrustCheck(true);
extendedMetadataDelegate.setMetadataRequireSignature(false);
// code....
In the ExtendedMetadata bean (different from above), change the property values as below:
// code....
extendedMetadata.setIdpDiscoveryEnabled(true);
extendedMetadata.setSignMetadata(false);
// code....
"Disclaimer"
Whether or not this should be used in production, I do not know; however, it seems to better reflect both the XML-based configuration and resulting metadata of the XML-configured Service Provider example referenced in the SAML Spring Documentation
Just some hints:
I met this exception when I was trying to set up the HTTP-Artifact profile.
There is a hostnameVerifier in org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory (openws-1.5.1) and a verifyHostname() processing before OpenSAML tries to create socket to connect to other host.
I configured sslHostnameVerification to "allowAll" in org.springframework.security.saml.metadata.ExtendedMetadata, the allowed values are "default", "defaultAndLocalhost", "strict", and "allowAll".
It seems in your case, this exception was thrown when the SP (your saml sample) was trying to download the metadata.xml from IdP (ssocircle). The best way to figure out what is happening is to debug when and where the hostnameVerifier was set.
Or you can try set sslHostnameVerification to "allowAll" in the SSOCircle's ExtendedMetadataDelegate's ExtendedMetadata to have a try first..
checkout this answer: It basically describes a plugin I recently released that allows you to configure Spring Boot and Spring Security SAML this way:
#SpringBootApplication
#EnableSAMLSSO
public class SpringBootSecuritySAMLDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSecuritySAMLDemoApplication.class, args);
}
#Configuration
public static class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
}
#Configuration
public static class MyServiceProviderConfig extends ServiceProviderConfigurerAdapter {
#Override
public void configure(ServiceProviderSecurityBuilder serviceProvider) throws Exception {
serviceProvider
.metadataGenerator()
.entityId("localhost-demo")
.and()
.sso()
.defaultSuccessURL("/home")
.idpSelectionPageURL("/idpselection")
.and()
.logout()
.defaultTargetURL("/")
.and()
.metadataManager()
.metadataLocations("classpath:/idp-ssocircle.xml")
.refreshCheckInterval(0)
.and()
.extendedMetadata()
.idpDiscoveryEnabled(true)
.and()
.keyManager()
.privateKeyDERLocation("classpath:/localhost.key.der")
.publicKeyPEMLocation("classpath:/localhost.cert");
}
}
}
There are a couple Demo apps integrated with SSO Circle

Categories