使用 Spring Boot 和 Cloud Foundry 的 Off Platform Sybase 连接

Off Platform Sybase connection using Spring Boot and Cloud Foundry

我正在尝试在我的应用程序中创建一个平台外的 sybase 连接。 我正在使用 Spring 启动并且还在 CF 上创建了一个用户提供的服务。 我需要创建或使用什么扩展 classes 才能实现此目的? 我已经使用 OracleServiceInfo 和 OracleServiceInfoCreator class 完成了 oracle 连接。 但是没有 SybaseServiceInfo class.

以下是ups的详情

{
   "credentials": {
     "hostname": "host",
     "jdbcUrl": "jdbc:sybase://username:password@host:port/name",
     "name": "name",
     "password": "password",
     "port": "port",
     "uri": "sybase://username:password@host:port/name",
     "username": "username"
   },
   "label": "user-provided",
   "name": "SYBDB",
   "syslog_drain_url": "",
   "tags": []
 }

我是 CF 新手。任何帮助都会很棒。

在查看 Scott Fredrick 的回复后,我采取了以下提到的步骤:

我创建了一个 ServiceInfoCreator class 和一个 ServiceInfo class,如下所述:

ServiceInfoCreator

import java.util.Map;

import org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator;
import org.springframework.cloud.cloudfoundry.Tags;
import org.springframework.context.annotation.Profile;

@Profile({ "cloud" })
public class SybaseServiceInfoCreator extends
        CloudFoundryServiceInfoCreator<SQLDBServiceInfo> {

    public SybaseServiceInfoCreator(Tags tags, String[] uriSchemes) {
        super(new Tags(), "sybase");
        // TODO Auto-generated constructor stub
    }

    @Override
    public SQLDBServiceInfo createServiceInfo(Map<String, Object> serviceData) {
        // TODO Auto-generated method stub
        @SuppressWarnings("unchecked")
        Map<String, String> credentials = (Map<String, String>) serviceData
                .get("credentials");

        String id = serviceData.get("name").toString();
        String uri = credentials.get("uri");


        return new SQLDBServiceInfo(id, uri);
    }


}

服务信息

import org.springframework.cloud.service.UriBasedServiceInfo;

public class SQLDBServiceInfo extends UriBasedServiceInfo {

    public SQLDBServiceInfo(String id, String uriString) {
        super(id, uriString);
        // TODO Auto-generated constructor stub
    }




}

我在 META-INF/Services/org 中输入了一个条目。springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator

com.x.y.SybaseServiceInfoCreator

但是当我推送应用程序时出现以下错误:

2015-04-20T16:28:59.85+0530 [App/0]   ERR       ... 190 more
2015-04-20T16:28:59.85+0530 [App/0]   ERR Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.C
loud]: Factory method 'cloud' threw exception; nested exception is java.util.ServiceConfigurationError: org.springframework.cloud.CloudConnector: Provider or
g.springframework.cloud.cloudfoundry.CloudFoundryConnector could not be instantiated
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrat
egy.java:189)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorRes
olver.java:588)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       ... 202 more
2015-04-20T16:28:59.85+0530 [App/0]   ERR Caused by: java.util.ServiceConfigurationError: org.springframework.cloud.CloudConnector: Provider org.springframew
ork.cloud.cloudfoundry.CloudFoundryConnector could not be instantiated
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at java.util.ServiceLoader.fail(ServiceLoader.java:232)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at java.util.ServiceLoader.access0(ServiceLoader.java:185)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at java.util.ServiceLoader.next(ServiceLoader.java:480)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at org.springframework.cloud.CloudFactory.scanCloudConnectors(CloudFactory.java:91)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at org.springframework.cloud.CloudFactory.<init>(CloudFactory.java:35)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at com.x.y.config.CloudAdminConfig.cloud(CloudAdminConfig.java:56)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at java.lang.reflect.Method.invoke(Method.java:483)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrat
egy.java:162)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       ... 203 more
2015-04-20T16:28:59.85+0530 [App/0]   ERR Caused by: java.util.ServiceConfigurationError: org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreat
or: Provider com.x.y.config.SybaseServiceInfoCreator could not be instantiated
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at java.util.ServiceLoader.fail(ServiceLoader.java:232)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at java.util.ServiceLoader.access0(ServiceLoader.java:185)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
2015-04-20T16:28:59.85+0530 [App/0]   ERR       at java.util.ServiceLoader.next(ServiceLoader.java:480)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at org.springframework.cloud.AbstractCloudConnector.scanServiceInfoCreators(AbstractCloudConnector.java:53)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at org.springframework.cloud.AbstractCloudConnector.<init>(AbstractCloudConnector.java:33)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at org.springframework.cloud.cloudfoundry.CloudFoundryConnector.<init>(CloudFoundryConnector.java:32)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at java.lang.Class.newInstance(Class.java:438)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       ... 213 more
2015-04-20T16:28:59.86+0530 [App/0]   ERR Caused by: java.lang.InstantiationException: com.x.y.config.SybaseServiceInfoCreator
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at java.lang.Class.newInstance(Class.java:423)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       ... 224 more
2015-04-20T16:28:59.86+0530 [App/0]   ERR Caused by: java.lang.NoSuchMethodException: com.x.y.config.SybaseServiceInfoCreator.<init>()
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at java.lang.Class.getConstructor0(Class.java:3074)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       at java.lang.Class.newInstance(Class.java:408)
2015-04-20T16:28:59.86+0530 [App/0]   ERR       ... 225 more
2015-04-20T16:29:02.38+0530 [DEA]     OUT Instance (index 0) failed to start accepting connections
2015-04-20T16:29:02.39+0530 [API]     OUT App instance exited with guid e946c9db-afdc-459a-bd01-ff718a5900db payload: {"cc_partition"=>"default", "droplet"=>
"e946c9db-afdc-459a-bd01-ff718a5900db", "version"=>"aeb7dbc8-e856-445b-80f1-0ff56339e1f5", "instance"=>"3efe1b541e2a4c6eb6aaecd7daac1143", "index"=>0, "reaso
n"=>"CRASHED", "exit_status"=>1, "exit_description"=>"app instance exited", "crash_timestamp"=>1429527542}

不确定我搞砸了什么。

还有提示找不到开头的ServiceInfoCreator

2015-04-20T18:04:59.98+0530 [App/0]   OUT 2015-04-20 12:34:59.988  WARN 33 --- [           main] o.c.r.o.s.cloud.AbstractCloudConnector   : No suitable servi
ce info creator found for service SYBDB Did you forget to add a ServiceInfoCreator?

Spring Cloud Connectors 是提供您提到的 OracleServiceInfoOracleServiceInfoCreator 类 的项目。如您所说,Spring Cloud Connectors 不支持 Sybase 数据库连接。所以,你有两个选择:

1) 扩展 Spring 云连接器以通过用户提供的服务支持 Sybase 连接。可以找到编写此类扩展的文档 here and here。这些扩展 类 可以在您的项目中或在单独的库中,它们不需要成为核心 SCC 项目的一部分即可供您使用。

2) 使用 vcap 属性,当 Spring Boot 在 Cloud Foundry 上检测到某个应用 运行 时,它会自动添加到环境中。您可以做一些简单的事情,例如在 Spring bean 上包含一个 @Value("${vcap.services.sybase.credentials.jdbcUrl}") 注释,然后使用该值创建一个 DataSource bean。有关详细信息,请参阅 here

第二个选择要简单得多,是一个很好的起点。如果您只有一个应用程序将使用这种类型的连接,那么这可能就足够了。如果您需要在多个应用程序中使用这种类型的连接,那么在第一个选项中编写 SCC 扩展并使其成为可重用的库将是更好的选择。

Thanks.That 似乎是问题所在。 这就是我现在创建 类 的方式 ServiceInfoCreator

@Profile({ "cloud" })
public class SybaseServiceInfoCreator extends
        RelationalServiceInfoCreator<SybaseServiceInfo> {

    public SybaseServiceInfoCreator() {
        super(new Tags(), "sybase");
        }

    @Override
    public SybaseServiceInfo createServiceInfo(String id, String uri) {
        // TODO Auto-generated method stub

        return new SybaseServiceInfo(id, uri, "sybase");
    }

    }

服务信息

@Profile({ "cloud" })
@ServiceInfo.ServiceLabel("sybase")
public class SybaseServiceInfo extends RelationalServiceInfo {

     public SybaseServiceInfo(String id, String url, String uri) {
            super(id, validateUrl(url), uri);
        }
        private static String validateUrl(String url) {
            if (parse(url).getHost() == null) {
                throw new IllegalArgumentException("The URL " + url
                        + " does not appear to contain a hostname - are you missing a trailing slash?");
            }

            return url;
        }

        private static URI parse(String url) {
            try {
                return new URI(url);
            } catch (URISyntaxException e) {
                throw new IllegalArgumentException(e);
            }
        }

        @Override
        public String getJdbcUrl() {
            return String.format("jdbc:%s:Tds:%s:%d/%s",
                    jdbcUrlDatabaseType,getHost(), getPort(), getPath());
        }


}