spring-cloud / spring-cloud-connectors Goto Github PK
View Code? Open in Web Editor NEWLibrary to let cloud applications connect to services
License: Apache License 2.0
Library to let cloud applications connect to services
License: Apache License 2.0
The ServiceConnectorCreator
interface needs suitable Javadocs on the get
methods. I think I understand what they're supposed to return, but it's not specifically stated.
While playing with spring-cloud and spring boot, I configured my app for cloud foundry, but then when I wanted to run locally, I wanted spring-boot's autoconfigure to kick in and not worry about configuring each service (there are several) to use a different configuration mechanism than boot's (ie LocalConfigConnector.
I created a passthrough connector that extended LocalConfigConnector:
public class NotCFConfigConnector extends LocalConfigConnector {
private EnvironmentAccessor env = new EnvironmentAccessor();
@Override
public boolean isInMatchingCloud() {
return env.getEnvValue("VCAP_APPLICATION") == null;
}
@Override
protected List<UriBasedServiceData> getServicesData() {
return Collections.emptyList();
}
}
Ideally, something that recognizes it is a boot app and perhaps a configurable condition for isInMatchingCloud (I was considering not in a particular spring profile), get's the id from boot configuration and potentially implement getServicesData from boot configuration. I wasn't as concerned about that because of boot auto config support for rabbit/amqp.
I started down this route, but because the config connectors didn't have access to the spring context or environment, I stopped.
The service bindings for rabbit would have to adapt (they they did for mysql already I believe)?
Hi there,
I am currently trying to get a rabbitmq/cloudfoundry sample running. I checked it out from https://github.com/cloudfoundry-samples/rabbitmq-cloudfoundry-samples, did a mvn package
and a cf push
. Afterwards the log was a follows:
Using manifest file /Users/user/Development/oss/cloudfoundry/rabbitmq-cloudfoundry/spring/manifest.yml
Creating app rabbitmq-spring in org demo / space development as admin...
OK
Creating route rabbitmq-spring-butlerlike-chippie.X.X.X.X.xip.io...
OK
Binding rabbitmq-spring-butlerlike-chippie.X.X.X.X.xip.io to rabbitmq-spring...
OK
Uploading rabbitmq-spring...
Uploading app files from: /Users/user/Development/oss/cloudfoundry/rabbitmq-cloudfoundry/spring/target/rabbitmq-spring-1.0-SNAPSHOT.war
Uploading 7M, 39 files
OK
Binding service cs-rabbitmq to app rabbitmq-spring in org demo / space development as admin...
OK
Starting app rabbitmq-spring in org demo / space development as admin...
OK
-----> Downloaded app package (7.5M)
-----> Java Buildpack source: system
-----> Downloading Open JDK 1.7.0_55 from http://download.run.pivotal.io/openjdk/lucid/x86_64/openjdk-1.7.0_55.tar.gz (3.2s)
Expanding Open JDK to .java-buildpack/open_jdk (1.5s)
-----> Downloading Spring Auto Reconfiguration 0.8.9 from http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.8.9.jar (0.5s)
Modifying /WEB-INF/web.xml for Auto Reconfiguration
-----> Downloading Tomcat 7.0.53 from http://download.run.pivotal.io/tomcat/tomcat-7.0.53.tar.gz (0.9s)
Expanding Tomcat to .java-buildpack/tomcat (0.1s)
-----> Downloading Buildpack Tomcat Support 1.1.1 from http://download.run.pivotal.io/tomcat-buildpack-support/tomcat-buildpack-support-1.1.1.jar (0.0s)
-----> Uploading droplet (46M)
0 of 1 instances running, 1 starting
1 of 1 instances running
App started
Showing health and status for app rabbitmq-spring in org demo / space development as admin...
OK
requested state: started
instances: 0/1
usage: 512M x 1 instances
urls: rabbitmq-spring-butlerlike-chippie.X.X.X.X.xip.io
state since cpu memory disk
#0 running 2014-04-29 09:56:20 PM 0.0% 332.9M of 512M 105.6M of 1G
But, when I call the app, I get the following exception:
java.lang.NullPointerException
org.springframework.cloud.util.StandardUriInfoFactory.createUri(StandardUriInfoFactory.java:20)
org.springframework.cloud.service.UriBasedServiceInfo.<init>(UriBasedServiceInfo.java:26)
org.springframework.cloud.service.common.RabbitServiceInfo.<init>(RabbitServiceInfo.java:21)
org.springframework.cloud.cloudfoundry.RabbitServiceInfoCreator.createServiceInfo(RabbitServiceInfoCreator.java:26)
org.springframework.cloud.cloudfoundry.RabbitServiceInfoCreator.createServiceInfo(RabbitServiceInfoCreator.java:12)
org.springframework.cloud.AbstractCloudConnector.getServiceInfo(AbstractCloudConnector.java:61)
org.springframework.cloud.AbstractCloudConnector.getServiceInfos(AbstractCloudConnector.java:40)
org.springframework.cloud.Cloud.getServiceInfos(Cloud.java:89)
org.springframework.cloud.Cloud.getServiceInfos(Cloud.java:105)
org.springframework.cloud.service.AbstractCloudServiceConnectorFactory.afterPropertiesSet(AbstractCloudServiceConnectorFactory.java:77)
org.springframework.cloud.config.xml.CloudServiceIntroducer.postProcessBeanFactory(AbstractCloudServiceFactoryParser.java:82)
org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694)
org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:684)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:461)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:599)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:518)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
javax.servlet.GenericServlet.init(GenericServlet.java:158)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:683)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:745)
This makes me wonder, cause the service instances seem to have a uri. As can be seen here:
...
"entity": {
"app_guid": "25c1f438-4a3b-492e-ad3e-c4aa1bdcca1a",
"service_instance_guid": "4028160a-4671-43d6-91a6-7b46c528a53e",
"credentials": {
"name": "6c4fefbb-8eb4-43a8-bcb1-464c5d8df8e6",
"hostname": "172.24.100.141",
"host": "172.24.100.141",
"port": 15001,
"admin_port": 25001,
"vhost": "v3cf7fb9e401d4b298e5b591356436d14",
"username": "uZgv8BVGa0Uxz",
"user": "uZgv8BVGa0Uxz",
"password":"[PRIVATE DATA HIDDEN]",
"pass": "pyfNeGLeVdUdQ",
"url": "amqp://uZgv8BVGa0Uxz:[email protected]:15001/v3cf7fb9e401d4b298e5b591356436d14"
},
...
My configuration for rabbit looks like this:
...
<!-- Obtain a connection to the RabbitMQ via cloudfoundry-runtime: -->
<cloud:rabbit-connection-factory id="connectionFactory"/>
<!-- Set up the AmqpTemplate/RabbitTemplate: -->
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory"/>
<!-- Request that queues, exchanges and bindings be automatically
declared on the broker: -->
<rabbit:admin connection-factory="connectionFactory"/>
<!-- Declare the "messages" queue: -->
<rabbit:queue name="messages" durable="true"/>
..
Son any idea what's wrong here? CF Build is the latest, as well as for services contrib. CLI is 6.1 and Spring is 3.2.
Currently if a New Relic service is bound to an application using Spring Cloud, the application will fail to start with the following exception:
Caused by: org.springframework.cloud.CloudException: No suitable service info creator found
at org.springframework.cloud.cloudfoundry.CloudFoundryConnector.getServiceInfo(CloudFoundryConnector.java:66)
at org.springframework.cloud.cloudfoundry.CloudFoundryConnector.getServiceInfos(CloudFoundryConnector.java:53)
at org.springframework.cloud.Cloud.getServiceInfos(Cloud.java:86)
at org.springframework.cloud.Cloud.getServiceInfo(Cloud.java:73)
Tags are 'pivotal' and 'cassandra'
I am using the Cloud.getServiceConnector API to get an instance of MongoServiceInfo in a non-spring app deployed to CF but the API is throwing an exception saying no suitable ServiceConnectorCreator found. When I call cloud.getServiceInfo() I see the service in the list with the correct id and I can cast it to an an instance of MongoServiceInfo. Any idea why I would be getting this error?
The dependencies on spring-rabbit
, spring-data-mongodb
and spring-data-redis
are marked as optional, but AbstractCloudConfig
has a hard linker dependency on them. It might be possible to do some trickery like Spring Boot does with nested classes and conditions that look for the class, but in the meantime, it is probably easiest to remove the "optional".
I'm glad to see the main Spring projects including BOM POMs now, but I don't know how to create one in Gradle (other than the obvious fragile XML template file). It would be very helpful to have one for Spring Cloud, especially for testing live applications against development versions of SC.
The Heroku test suite manually re-asserts identical URI parameters on its service definitions instead of having these in a single place. (This is actually common to all URI-based creators, and it would be lovely to have abstract test functionality available to submodules, but I think that would require a separate cloud-test
module.)
Looks like the latest MongoDb service on CF does not expose the uri anymore. This field is now called url
"system_env_json": {
"VCAP_SERVICES": {
"mongodb-2.2": [
{
"name": "jbehave-reports",
"label": "mongodb-2.2",
"tags": [
"nosql",
"document"
],
"plan": "default",
"credentials": {
"hostname": "x",
"host": "x",
"port": 10002,
"username": "6d55a686-de4f-4df1-87e8-8a6052c3cdad",
"password": "543caa18-52f8-49ac-ae74-28f91ec32898",
"name": "0eb9d144-4851-4f79-9758-f5c97b1b6e45",
"db": "db",
"url": "mongodb://6d55a686-de4f-4df1-87e8-8a6052c3cdad:543caa18-52f8-49ac-ae74-28f91ec32898@x:10002/db"
}
}
]
}
Therefore this fails:
We have deployed the latest mongodb from the cf-services-contrib.
I have a simple Spring app. I've included cloud:service-scan/ in my config. I have a simple user-provided service:
name=jibberish
label=user-provided
tags=[]
credentials={aaa=aaa, bbb=bbb, ccc=ccc}
syslog_drain_url=
When I try to run my app on run.pivotal.io I get:
ERROR: org.springframework.web.servlet.DispatcherServlet - Context initialization failed
org.springframework.cloud.CloudException: Error registering service factory
at org.springframework.cloud.config.CloudServicesScanner.registerServiceBean(CloudServicesScanner.java:97)
at org.springframework.cloud.config.CloudServicesScanner.registerServiceBeans(CloudServicesScanner.java:86)
at org.springframework.cloud.config.CloudServicesScanner.postProcessBeanFactory(CloudServicesScanner.java:79)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:265)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:177)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:609)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:643)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:606)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:657)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:525)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:466)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1193)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1088)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5176)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5460)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1120)
at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1678)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.ClassCastException: org.springframework.cloud.service.BaseServiceInfo cannot be cast to org.springframework.cloud.service.common.RelationalServiceInfo
at org.springframework.cloud.service.relational.DataSourceCreator.create(DataSourceCreator.java:23)
at org.springframework.cloud.Cloud.getServiceConnector(Cloud.java:235)
at org.springframework.cloud.Cloud.getServiceConnector(Cloud.java:128)
at org.springframework.cloud.service.AbstractCloudServiceConnectorFactory.createService(AbstractCloudServiceConnectorFactory.java:93)
at org.springframework.cloud.service.AbstractCloudServiceConnectorFactory.createInstance(AbstractCloudServiceConnectorFactory.java:89)
at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:134)
at org.springframework.cloud.service.AbstractCloudServiceConnectorFactory.afterPropertiesSet(AbstractCloudServiceConnectorFactory.java:84)
at org.springframework.cloud.config.CloudServicesScanner.registerServiceBean(CloudServicesScanner.java:94)
... 29 more
The code seems to want to coerce this user-provided service into a data source of some kind, which causes an error.
Removing cloud:service-scan/ eliminates the error. Unbinding the service also eliminates the error. The cloud:service-scan/ works fine with built-in services, it just objects to this loosely-defined user-provided one.
thx,
k
I am trying to use Spring Cloud within a Spring Boot application and I am deploying this to BlueMix. BlueMix has a an ElephantSQL and Clear DB as services in its catalog. When I bind either of these services to my Spring Boot application and call connectionFactory().dataSource() in my AbstractCloudConfig implementation I am getting an exception saying " No unique service matching interface javax.sql.DataSource found. Expected 1, found 0". After reading the code in CloudFoundryServiceInfoCreator.accept it looks like it will look for whatever tag name is passed into the constructor in a property called tags in the service details or it will look at the service label to see if it begins with the tag. If neither of these are true for the ElephantSQL and Clear DB services, could this result in the error I am seeing?
I don't understand what these are for. Something to do with structured CF service definitions?
Tags are 'pivotal' and 'neo4j'
(Looks like an FAE has already started working on this, so we should check with @scottfrederick before working on this)
Some of the Spring infrastructure, especially MongoDataAutoConfiguration
, expects a bean of type Mongo
to be registered. The MongoDbFactoryCreator
creates a MongoClient
(extends Mongo
) instance along the way to creating the MongoDbFactory
but does not expose it, causing the autoconfiguration to fail and abort container startup.
It looks like if a cloud:data-source element is present, but no service is bound, the error printed is cryptic and doesn't point to the real issue.
It should have printed an error along the following lines:
Cannot create bean corresponding to <cloud:data-source>; no relational service is bound to the application"
(In this context, database driver was missing, too)
2013-12-04 16:53:18,239 ERROR [ContextLoader] [main] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error registering service factory; nested exception is java.util.NoSuchElementException
at org.springframework.cloud.config.xml.CloudServiceIntroducer.postProcessBeanFactory(AbstractCloudServiceFactoryParser.java:90)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:686)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:676)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:451)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
at org.apache.catalina.core.StandardService.start(StandardService.java:525)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: java.util.NoSuchElementException
at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:375)
at java.util.LinkedHashMap$ValueIterator.next(LinkedHashMap.java:388)
at org.springframework.cloud.service.AbstractCloudServiceConnectorFactory.afterPropertiesSet(AbstractCloudServiceConnectorFactory.java:73)
at org.springframework.cloud.config.xml.CloudServiceIntroducer.postProcessBeanFactory(AbstractCloudServiceFactoryParser.java:82)
... 21 more
We need to publish xsd files to http://www.springframework.org/schema/cloud/spring-cloud.xsd
I am trying to access user provided services in my VCAP_SERVICE environment var. I see the ups connector but that seems to expect the user provided service to just have a URI. In my case I also have a username and password. Is there any other helper classes I can use to access this service?
The high-performance Tomcat DataSource is infinitely preferable to DBCP (and to the Tomcat re-jarred version that Spring Cloud currently falls back to if available). If it is on the classpath it should be used in preference.
My current code is extending AbstractMongoConfiguration
, supplying connection details and registering custom converters to the superclass, which creates the Spring Data objects (specifically the MongoTemplate
, MappingMongoConverter
, and MongoMappingContext
) from the information provided.
How can I convert this to having Spring Cloud inject the MongoDB connection? Should I subclass AbstractCloudConfig
, register connectionFactory().mongoDbFactory()
as a bean, and then autowire that bean into my AbstractMongoConfiguration
as its factory?
This is a breaking change, but the @ServiceScan
annotation is extremely generic, providing little clue as to what "services" are involved and inviting collisions from other Things That Could Scan For Services.
You had erroneously mentioned @CloudScan
in another issue; this would be a much clearer annotation. Perhaps bridge it as a meta-annotation and deprecate @ServiceScan
?
Currently, the url returned from PostgresqlServiceInfo.getJdbcUrl()
isn't directly usable. There are two problems with it.
The current implementation of this method simply prepends the URI from VCAP_SERVICES
with jdbc:
. The result is something like:
postgres://username:[email protected]:5432/username =>
jdbc:postgres://username:[email protected]:5432/username
However, as described here, the correct sheme is actually jdbc:postgresql
. This can be verified by pushing an app that does something like this:
BoneCPDataSource dataSource = new BoneCPDataSource();
dataSource.setDriverClass(Driver.class.getCanonicalName());
dataSource.setJdbcUrl(serviceInfo.getJdbcUrl());
dataSource.setUsername(serviceInfo.getUserName());
dataSource.setPassword(serviceInfo.getPassword());
The output will reflect the problem:
java.sql.SQLException: No suitable driver found for jdbc:postgres://username:[email protected]:5432/username
at java.sql.DriverManager.getConnection(DriverManager.java:604)
at java.sql.DriverManager.getConnection(DriverManager.java:221)
The current implementation uses the hostname VCAP_SERVICES
without stripping credentials off of it. The postgresql JDBC driver cannot tolerate this.
However, as described here, the correct hostname cannot have credentials attached to it. This can be verified by pushing an app that does something like this:
BoneCPDataSource dataSource = new BoneCPDataSource();
dataSource.setDriverClass(Driver.class.getCanonicalName());
dataSource.setJdbcUrl(serviceInfo.getJdbcUrl().replace(":postgres:", ":postgresql:");
dataSource.setUsername(serviceInfo.getUserName());
dataSource.setPassword(serviceInfo.getPassword());
The output will reflect the problem:
Caused by: java.net.UnknownHostException: username:[email protected]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
An example solution might look like the following:
String.format("jdbc:postgresql://%s:%d/%s", serviceInfo.getHost(), serviceInfo.getPort(),
serviceInfo.getUserName());
Currently, the DataSource
creation logic prefers org.apache.commons.dbcp.BasicDataSource
, then its Tomcat equivalent, and then falls back to Spring's SimpleDriverDataSource
. We can improve this logic by abstracting pool creation that can also allow utilizing other pools such as BoneCP
Currently, we are shading in the whole jackson library thus increasing the jar file size.
The current code uses SPRING_CLOUD_APP_NAME
to identify an application name from within Heroku, but the API refers to the value in question as appId()
. Keep as a wart or breaking-change to a consistent SPRING_CLOUD_APP_ID
?
Note that the way I determine whether the local connector should activate is to look for spring.cloud.appId
; if we extend that to an environment scan, the values would semantically mean the same thing, but the current logic would get a false-positive on the local connector, so that would need to be addressed somehow.
Currently there is no getter for scheme, despite that fact that it is parsed out by the java.util.URI class. Please add. Thx.
Why does the method signature not have a throws declaration for the CloudException? I realize that CloudException is a runtime exception and it is not required but it seems like you would want users to always make sure they handle this exception properly.
On startup, I notice that getServiceInfos()
gets called multiple times; apparently, it gets called once to identify the service names, and then it gets called again to specifically retrieve each service by name. The implementation in AbstractCloudConnector
delegates to getServicesData()
, which in all the connectors rebuilds the entire cloud context. I think that getServiceInfos()
should cache the result before returning; is there a reason not to do this?
Hey,
I tried to create a custom service that should be interpreted as a MySQL service. I checked the sources and found out, that the term "mysql" needs to be in the tags array. So this is what I did to create the service:
โ cf create-service
1: p-mysql , via
2: p-mysql-custom , via
3: user-provided , via
What kind?> 3
Name?> upsi-mysql
What credential parameters should applications use to connect to this service instance?
(e.g. hostname, port, password)> tags, name, label, credentials
tags> ["mysql"]
name> upsi-mysql
label> upsi-mysql
credentials> {"hostname":"a.b.c.d","port":3306,"name":"name","username":"user","password":"pass","uri":"mysql://user:[email protected]:3306/schema?reconnect=true","jdbcUrl":"jdbc:mysql://user:[email protected]:3306/schema"}
Creating service upsi-mysql... OK
But this service bound to an app will prevent it from getting staged. What would be the correct way to create a user defined that will be correctly recognized by spring-cloud?
In org.springframework.cloud.cloudfoundry.RelationalServiceInfoCreator, the following keys are assumed for the service binding:
In v2 of CloudFoundry service broker the keys used for the binding are specified differently:
http://docs.cloudfoundry.com/docs/running/architecture/services/writing-service.html#binding
I suggest the name of the keys should be aligned.
Tags are ["riak-cs","s3"]
Tags are 'pivotal' and 'memcached'
My app does this ("postgresql" is the name of the service instance), using spring-cloud 0.9.1:
@Bean
@Profile("cloud")
public DataSource dataSource() {
CloudFactory cloudFactory = new CloudFactory();
Cloud cloud = cloudFactory.getCloud();
return cloud.getServiceConnector("postgresql", DataSource.class, null);
}
and I see this:
Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class 'org.postgresql.Driver' for connect URL 'jdbc:postgres://wftjxbes:[email protected]:5432/wftjxbes'
at org.apache.commons.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1452)
at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
at demo.Application.run(Application.java:76)
at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:495)
... 10 more
Caused by: java.sql.SQLException: No suitable driver
at java.sql.DriverManager.getDriver(DriverManager.java:289)
at org.apache.commons.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1437)
... 14 more
I think Postgresql does not allow the user credentials embedded in the URL. Is that the problem?
Hi,
In project "spring-cloud-spring-service-connector", the object AbstractCloudConfig imports classes from "spring-data-redis", "spring-data-mongodb" and "spring-data-rabbitmq". Therefore it is impossible to extend it to create a DataSource, without adding useless dependencies.
Thanks, regards,
Gauthier
I just faceplanted into CF's inability to (AFAICT) set tags on user-provided services, meaning Spring Cloud won't pick them up. However, the MongoDB handler, at least, simply provides credentials in credentials.uri
. Any possibility of rolling over to just inspecting those URIs instead of routing them through tag filtering?
A sample VCAP_SERVICES:
{
"p-hd":[
{
"name":"phd1",
"label":"p-hd",
"tags":[
],
"plan":"Standard",
"credentials":{
"hadoop_username":"u295594b875749a",
"hdfs":{
"configuration":{
"fs.defaultFS":"hdfs://10.68.44.228:8020"
},
"directory":"/user/u295594b8757f49a"
},
"yarn":{
"configuration":{
"yarn.resourcemanager.address":"10.68.44.229:8032",
"mapreduce.framework.name":"yarn",
"yarn.resourcemanager.scheduler.address":"10.68.44.229:8030",
"mapreduce.job.working.dir":"/user/u295594b8757f49a/work",
"yarn.app.mapreduce.am.staging-dir":"/user/u295594b8757f49a/staging"
}
},
"hawq":{
"uri":"jdbc:postgres://10.68.44.230:5432/default;username=u295594b8757f49a;password=2281f1d7-7d0b-4c79-5ac5-2bdcc811bfde"
},
"gemfirexd":{
"uri":"jdbc:gemfirexd://10.68.44.231:1527/;user=u295594b8757f49a;password=234795ab-322b-43ef-5df6-e90ef74cfa8e"
}
}
}
]
}
I'm very interested in using Spring Cloud to configure my application (which I'm planning to push to Cloud Foundry), and it would be extremely convenient to be able to use Spring Cloud to handle development configuration as well. Would you be interested in adding a connector that implemented the connector wiring via some local hand-configured means such as a properties file?
Tags are 'pivotal' and 'elasticsearch'
It appears but isn't directly discussed in the docs that the minimum Java version for the project is 1.6. I'd love to use StandardCharsets
but will deal with that gaping hole in the API for 1.6 if needed.
Since DataSource
and its subclasses are in spring-service-connector
, unless user adds the latter as a dependency, creating DataSource
connector is not possible. Unlike other connector types (MongoDbFactory
), DataSource
doesn't have any inherent dependency on Spring. Thus, it should be possible to move its creation in the core
iself.
The tricky part is allowing the use of connection pool (which currently uses Spring classes such as BeanWrapper
).
MongoDB specifies replica sets using multiple hostname:port pairs in that section of its URI. Spring Data MongoDB does support replica sets, but Spring Cloud Connectors currently hard-maps the incoming service spec onto a URI
. I am preparing for a production deployment and would like to point my client at both of my replicas, but the current design may need some major rework to make that happen.
Hi,
I tried to connect to MongoDB today, with the latest release of the MongoDB Driver (2.12.3 against 2.2, Spring Data MongoDB 1.5.4, CF-Service-Release v5 with MongoDB 2.2). During the connection I get an exception, which results in a exception:
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches AnyServerSelector{} after 10000 ms
com.mongodb.BaseCluster.getServer(BaseCluster.java:87)
com.mongodb.DBTCPConnector.getServer(DBTCPConnector.java:654)
com.mongodb.DBTCPConnector.access$300(DBTCPConnector.java:39)
com.mongodb.DBTCPConnector$MyPort.getConnection(DBTCPConnector.java:503)
com.mongodb.DBTCPConnector$MyPort.get(DBTCPConnector.java:451)
com.mongodb.DBTCPConnector.authenticate(DBTCPConnector.java:624)
com.mongodb.DBApiLayer.doAuthenticate(DBApiLayer.java:195)
com.mongodb.DB.authenticateCommandHelper(DB.java:765)
com.mongodb.DB.authenticate(DB.java:721)
org.springframework.data.mongodb.core.MongoDbUtils.doGetDB(MongoDbUtils.java:123)
org.springframework.data.mongodb.core.MongoDbUtils.getDB(MongoDbUtils.java:81)
org.springframework.data.mongodb.core.SimpleMongoDbFactory.getDb(SimpleMongoDbFactory.java:145)
org.springframework.data.mongodb.core.SimpleMongoDbFactory.getDb(SimpleMongoDbFactory.java:134)
org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.createIndex(MongoPersistentEntityIndexCreator.java:135)
org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.checkForAndCreateIndexes(MongoPersistentEntityIndexCreator.java:129)
org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.checkForIndexes(MongoPersistentEntityIndexCreator.java:121)
org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.onApplicationEvent(MongoPersistentEntityIndexCreator.java:105)
org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.onApplicationEvent(MongoPersistentEntityIndexCreator.java:46)
org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:98)
org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:333)
org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:307)
org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java:470)
org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:427)
org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:579)
org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:295)
org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java:470)
org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:427)
org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:579)
On my local machine the repositories are running without any issue. Currently digging through the web finding possibly related information. Any suggestions?
We need a hands-on tutorial to be hosted on spring.io.
These logs on startup are distracting and actually I have no idea if it's important or not. If it isn't then maybe they should be at DEBUG?
2013-10-16 16:21:22.118 WARN 31 --- [ main] .s.c.u.ServiceLoaderWithExceptionControl : Failed to load java.util.ServiceConfigurationError: org.springframework.cloud.service.ServiceConnectorCreator: Provider org.springframework.cloud.service.keyval.RedisConnectionFactoryCreator could not be instantiated: java.lang.NoClassDefFoundError: org/springframework/data/redis/connection/RedisConnectionFactory
2013-10-16 16:21:22.120 WARN 31 --- [ main] .s.c.u.ServiceLoaderWithExceptionControl : Failed to load java.util.ServiceConfigurationError: org.springframework.cloud.service.ServiceConnectorCreator: Provider org.springframework.cloud.service.document.MongoDbFactoryCreator could not be instantiated: java.lang.NoClassDefFoundError: com/mongodb/MongoException
2013-10-16 16:21:22.122 WARN 31 --- [ main] .s.c.u.ServiceLoaderWithExceptionControl : Failed to load java.util.ServiceConfigurationError: org.springframework.cloud.service.ServiceConnectorCreator: Provider org.springframework.cloud.service.messaging.RabbitConnectionFactoryCreator could not be instantiated: java.lang.NoClassDefFoundError: org/springframework/amqp/rabbit/connection/ConnectionFactory
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.