Initial revision
This commit is contained in:
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
*~
|
||||
#*
|
||||
*#
|
||||
.#*
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.gradle
|
||||
build
|
||||
bin
|
||||
/target/
|
||||
97
README.md
Normal file
97
README.md
Normal file
@@ -0,0 +1,97 @@
|
||||
Integration between [Cloudfoundry](https://github.com/cloudfoundry)
|
||||
and the [Spring Platform](https://github.com/spring-platform).
|
||||
|
||||
Add this project to a Spring Boot REST service and deploy to
|
||||
Cloudfoundry (and use the Actuator for maximum flexibility). It will
|
||||
expose service-broker endpoints automatically (look in /mappings for
|
||||
/v2/*) and you can register it with the Cloud Controller as described
|
||||
here:
|
||||
[http://docs.cloudfoundry.org/services/managing-service-brokers.html](http://docs.cloudfoundry.org/services/managing-service-brokers.html).
|
||||
|
||||
Example script to deploy and register a broker:
|
||||
|
||||
```
|
||||
DOMAIN=mydomain.net
|
||||
cf push app -p target/*.jar --no-start
|
||||
cf env app | grep SPRING_PROFILES_ACTIVE || cf set-env app SPRING_PROFILES_ACTIVE cloud
|
||||
cf env app | grep APPLICATION_DOMAIN || cf set-env app APPLICATION_DOMAIN ${DOMAIN}
|
||||
|
||||
cf services | grep configserver && cf bind app configserver
|
||||
|
||||
cf restart app
|
||||
cf create-service-broker app user secure http://app.${DOMAIN}
|
||||
|
||||
for f in `cf curl /v2/service_plans | grep '\"guid' | sed -e 's/.*: "//' -e 's/".*//'`; do
|
||||
cf curl v2/service_plans/$f -X PUT -d '{"public":true}'
|
||||
done
|
||||
|
||||
cf create-service app free appi
|
||||
```
|
||||
|
||||
At which point you have a service called "app" and a service instance called "appi":
|
||||
|
||||
```
|
||||
$ cf marketplace
|
||||
OK
|
||||
|
||||
service plans description
|
||||
app free Singleton service app
|
||||
$ cf services
|
||||
Getting services in org default / space development as admin...
|
||||
OK
|
||||
|
||||
name service plan bound apps
|
||||
appi app free
|
||||
```
|
||||
|
||||
Your application can define a configuration property
|
||||
`application.domain` (defaults to "cfapps.io") which will be used to
|
||||
construct the credentials for any app that binds to your service. Or
|
||||
it can define the URI directly using
|
||||
`cloudfoundry.service.definition.metadata.uri`.
|
||||
|
||||
You can change some other basic metadata by setting config properties:
|
||||
|
||||
* `cloudfoundry.service.definition.*` is bound to a
|
||||
`ServiceDefinition` (defined in spring-boot-cf-service-broker) which
|
||||
has optional setters for plans and metadata.
|
||||
|
||||
* `cloudfoundry.service.broker.*` is bound to an internal bean. It has
|
||||
optional setters for "name" (the service name), "description" (user
|
||||
friendly description) and "prefix" (used to create a unique id from
|
||||
the name).
|
||||
|
||||
An app which binds to your service will get credentials that contain a
|
||||
"uri" property linking to your service. A Spring Boot app can bind to
|
||||
that through the `vcap.services.[service].credentials.uri` environment
|
||||
property.
|
||||
|
||||
If your service also has a
|
||||
[Eureka core](https://github.com/Netflix/eureka) dependency, and you
|
||||
can expose it as a Eureka service, then any service which registers
|
||||
with Eureka will also become a Cloudfoundry service. Example app with
|
||||
Eureka server (include jersey 1.13 to get the JAX-RS dependencies):
|
||||
|
||||
```
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
public class Application extends WebMvcConfigurerAdapter {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean jersey() {
|
||||
FilterRegistrationBean bean = new FilterRegistrationBean();
|
||||
bean.setFilter(new ServletContainer());
|
||||
bean.addInitParameter("com.sun.jersey.config.property.WebPageContentRegex",
|
||||
"(/|/(flex/|images/|js/|css/|jsp/|admin/|v2/catalog|v2/service_instances).*)");
|
||||
bean.addInitParameter("com.sun.jersey.config.property.packages",
|
||||
"com.sun.jersey;com.netflix");
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
75
pom.xml
Normal file
75
pom.xml
Normal file
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.platform</groupId>
|
||||
<artifactId>spring-platform-cloudfoundry</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>spring-platform-cloudfoundry</name>
|
||||
<description>Spring Patform Cloudfoundry integration project</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.1.5.BUILD-SNAPSHOT</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.platform</groupId>
|
||||
<artifactId>spring-platform-netflix</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.platform</groupId>
|
||||
<artifactId>spring-platform-netflix-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cloudfoundry</groupId>
|
||||
<artifactId>spring-boot-cf-service-broker</artifactId>
|
||||
<version>2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-servlet</artifactId>
|
||||
<version>1.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.7</java.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.cloudfoundry.community.servicebroker.model.Catalog;
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceDefinition;
|
||||
import org.cloudfoundry.community.servicebroker.service.BeanCatalogService;
|
||||
import org.cloudfoundry.community.servicebroker.service.CatalogService;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.appinfo.InstanceInfo.ActionType;
|
||||
import com.netflix.eureka.lease.LeaseManager;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class CatalogLeaseManager implements LeaseManager<InstanceInfo>, LeaseManagerLite,
|
||||
CatalogService {
|
||||
|
||||
private Map<String, ServiceDefinition> definitions = new HashMap<String, ServiceDefinition>();
|
||||
|
||||
private List<ServiceDefinition> values = new ArrayList<ServiceDefinition>();
|
||||
|
||||
public CatalogLeaseManager(InstanceInfo config) {
|
||||
register(config, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Catalog getCatalog() {
|
||||
return new Catalog(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceDefinition getServiceDefinition(String serviceId) {
|
||||
return new BeanCatalogService(getCatalog()).getServiceDefinition(serviceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(InstanceInfo info, boolean isReplication) {
|
||||
register(info, 0, isReplication);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(InstanceInfo info, int leaseDuration, boolean isReplication) {
|
||||
if (!definitions.containsKey(info.getAppName())) {
|
||||
ServiceDefinition definition = getServiceDefinition(info);
|
||||
definitions.put(info.getAppName(), definition);
|
||||
values.add(definition);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(String appName, String id, boolean isReplication) {
|
||||
ServiceDefinition definition = definitions.remove(appName);
|
||||
if (definition != null) {
|
||||
values.remove(definition);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renew(String appName, String id, boolean isReplication) {
|
||||
if (definitions.containsKey(appName)) {
|
||||
definitions.get(appName).getMetadata()
|
||||
.put("timestamp", System.currentTimeMillis());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evict() {
|
||||
Collection<ServiceDefinition> definitions = new ArrayList<ServiceDefinition>(
|
||||
this.definitions.values());
|
||||
for (ServiceDefinition definition : definitions) {
|
||||
InstanceInfo info = (InstanceInfo) definition.getMetadata().get("info");
|
||||
if (info.getActionType() == ActionType.DELETED) {
|
||||
cancel(info.getAppName(), info.getId(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ServiceDefinition getServiceDefinition(InstanceInfo info) {
|
||||
String name = info.getAppName().toLowerCase();
|
||||
ServiceDefinition definition = new FreeServiceDefinitionFactory("eureka-").create(name, "Eureka-brokered service");
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("info", (Object) info);
|
||||
map.put("uri", info.getHomePageUrl());
|
||||
map.put("timestamp", System.currentTimeMillis());
|
||||
definition.setMetadata(map);
|
||||
return definition;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.cloudfoundry.community.servicebroker.model.Plan;
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceDefinition;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class FreeServiceDefinitionFactory {
|
||||
|
||||
private final String prefix;
|
||||
|
||||
public FreeServiceDefinitionFactory() {
|
||||
this("");
|
||||
}
|
||||
|
||||
public FreeServiceDefinitionFactory(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public ServiceDefinition create(String name, String description) {
|
||||
return new ServiceDefinition(getId(name), name, description, true, getPlans(name));
|
||||
}
|
||||
|
||||
private List<Plan> getPlans(String appName) {
|
||||
Plan plan = new Plan(getId(appName + "-free"), "free",
|
||||
"This is a default service plan. All services are created equally.",
|
||||
getServiceDefinitionMetadata(appName), true);
|
||||
return new ArrayList<Plan>(Arrays.asList(plan));
|
||||
}
|
||||
|
||||
private Map<String, Object> getServiceDefinitionMetadata(String appName) {
|
||||
Map<String, Object> sdMetadata = new HashMap<String, Object>();
|
||||
sdMetadata.put("displayName", appName + "-service");
|
||||
sdMetadata.put("longDescription", "Platform Service for " + appName);
|
||||
sdMetadata.put("providerDisplayName", "Pivotal");
|
||||
sdMetadata.put("documentationUrl", "https://github.com/spring-platform");
|
||||
sdMetadata.put("supportUrl", "https://github.com/spring-platform");
|
||||
return sdMetadata;
|
||||
}
|
||||
|
||||
protected String getId(String name) {
|
||||
try {
|
||||
String id = DigestUtils.md5DigestAsHex((prefix + name).getBytes("UTF-8"));
|
||||
return id;
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public interface LeaseManagerLite {
|
||||
|
||||
void register(final InstanceInfo info, final boolean isReplication);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class PiggybackMethodInterceptor implements MethodInterceptor {
|
||||
|
||||
private Object delegate;
|
||||
private Class<?>[] types;
|
||||
|
||||
public PiggybackMethodInterceptor(Object delegate, Class<?>... types) {
|
||||
this.delegate = delegate;
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
Object result = invocation.proceed();
|
||||
invokeAfter(invocation.getMethod(), invocation.getArguments());
|
||||
return result;
|
||||
}
|
||||
|
||||
private void invokeAfter(Method method, Object[] arguments) throws Exception {
|
||||
for (Class<?> type : types) {
|
||||
Method target = getTarget(type, method);
|
||||
if (target != null) {
|
||||
target.invoke(delegate, arguments);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Method getTarget(Class<?> type, Method method) {
|
||||
Method target = ReflectionUtils.findMethod(type, method.getName(),
|
||||
method.getParameterTypes());
|
||||
if (target != null) {
|
||||
return target;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.cloudfoundry.community.servicebroker.config.BrokerApiVersionConfig;
|
||||
import org.cloudfoundry.community.servicebroker.model.Catalog;
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceDefinition;
|
||||
import org.cloudfoundry.community.servicebroker.service.BeanCatalogService;
|
||||
import org.cloudfoundry.community.servicebroker.service.CatalogService;
|
||||
import org.cloudfoundry.community.servicebroker.service.ServiceInstanceBindingService;
|
||||
import org.cloudfoundry.community.servicebroker.service.ServiceInstanceService;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.platform.netflix.eureka.EurekaRegistryAvailableEvent;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider;
|
||||
import com.netflix.eureka.PeerAwareInstanceRegistry;
|
||||
import com.netflix.eureka.lease.LeaseManager;
|
||||
|
||||
/**
|
||||
* Autoconfiguration providing simple service-broker endpoints and Netflix eureka server
|
||||
* features. The service-broker endpoints will be enabled if <a
|
||||
* href="https://github.com/cloudfoundry-community/spring-boot-cf-service-broker"
|
||||
* >spring-boot-cf-service-broker</a> is on the classpath. By default they just make the
|
||||
* current app into a service brooker for itself. The Eureka features will be added if <a
|
||||
* href="https://github.com/Netflix/eureka">ereka-core</a> is on the classpath. When
|
||||
* active any Eureka services registered using native Netflix APIs will be available as
|
||||
* Cloudfoundry services. They consist of an interceptor for the {@link LeaseManager} that
|
||||
* manages the {@link Catalog} of Cloudfoundry servvices.
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = { "demo", "org.cloudfoundry.community.servicebroker" }, excludeFilters = {
|
||||
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = BrokerApiVersionConfig.class),
|
||||
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = BeanCatalogService.class) })
|
||||
@ConditionalOnClass(ServiceInstanceRepository.class)
|
||||
@ConditionalOnWebApplication
|
||||
public class ServiceBrokerAutoConfiguration {
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingClass(name="com.netflix.eureka.PeerAwareInstanceRegistry")
|
||||
@ConditionalOnMissingBean(CatalogService.class)
|
||||
protected static class CatalogConfiguration {
|
||||
|
||||
@Autowired
|
||||
private BrokerProperties broker;
|
||||
|
||||
@Bean
|
||||
public BeanCatalogService catalogService() {
|
||||
return new BeanCatalogService(catalog());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Catalog catalog() {
|
||||
return new Catalog(Arrays.asList(serviceDefinition()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties("cloudfoundry.service.definition")
|
||||
public ServiceDefinition serviceDefinition() {
|
||||
return new FreeServiceDefinitionFactory(broker.getPrefix()).create(broker.getName(),
|
||||
broker.getDescription());
|
||||
}
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties("cloudfoundry.server.broker")
|
||||
public static class BrokerProperties {
|
||||
private String prefix;
|
||||
@Value("${spring.application.name:application}")
|
||||
private String name;
|
||||
private String description;
|
||||
public String getPrefix() {
|
||||
return prefix==null ? name + "-" : prefix;
|
||||
}
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getDescription() {
|
||||
return description == null ? "Singleton service app" : description;
|
||||
}
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(PeerAwareInstanceRegistry.class)
|
||||
protected static class EurekaCatalogConfiguration {
|
||||
|
||||
@Bean
|
||||
public CatalogLeaseManager catalogLeaseManager(EurekaInstanceConfig config) {
|
||||
InstanceInfo info = new EurekaConfigBasedInstanceInfoProvider(config).get();
|
||||
return new CatalogLeaseManager(info);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(PeerAwareInstanceRegistry.class)
|
||||
protected static class Initializer implements
|
||||
ApplicationListener<EurekaRegistryAvailableEvent> {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private CatalogLeaseManager leaseManager;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(EurekaRegistryAvailableEvent event) {
|
||||
ProxyFactory factory = new ProxyFactory(
|
||||
PeerAwareInstanceRegistry.getInstance());
|
||||
factory.addAdvice(new PiggybackMethodInterceptor(leaseManager,
|
||||
LeaseManager.class, LeaseManagerLite.class));
|
||||
factory.setProxyTargetClass(true);
|
||||
Field field = ReflectionUtils.findField(PeerAwareInstanceRegistry.class,
|
||||
"instance");
|
||||
try {
|
||||
// Awful ugly hack to work around lack of DI in eureka
|
||||
field.setAccessible(true);
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||
ReflectionUtils.setField(field, null, factory.getProxy());
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException("Cannot modify instance registry", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ServiceInstanceService.class)
|
||||
public SimpleServiceInstanceService serviceInstanceService(
|
||||
ServiceInstanceRepository repository) {
|
||||
return new SimpleServiceInstanceService(repository);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ServiceInstanceBindingService.class)
|
||||
public SimpleServiceInstanceBindingService serviceInstanceBindingService(
|
||||
CatalogService catalog, ServiceInstanceBindingRepository repository) {
|
||||
return new SimpleServiceInstanceBindingService(catalog, repository);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ServiceInstanceRepository.class)
|
||||
public SimpleServiceInstanceRepository serviceInstanceRepository(
|
||||
CatalogService catalog) {
|
||||
List<ServiceDefinition> definitions = catalog.getCatalog()
|
||||
.getServiceDefinitions();
|
||||
ServiceDefinition definition = definitions.iterator().next();
|
||||
return new SimpleServiceInstanceRepository(definition.getId());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ServiceInstanceBindingRepository.class)
|
||||
public SimpleServiceInstanceBindingRepository serviceInstanceBindingRepository(
|
||||
CatalogService catalog) {
|
||||
List<ServiceDefinition> definitions = catalog.getCatalog()
|
||||
.getServiceDefinitions();
|
||||
ServiceDefinition definition = definitions.iterator().next();
|
||||
return new SimpleServiceInstanceBindingRepository(definition.getId());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker;
|
||||
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceInstanceBinding;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public interface ServiceInstanceBindingRepository {
|
||||
|
||||
ServiceInstanceBinding findOne(String bindingId);
|
||||
|
||||
void delete(String id);
|
||||
|
||||
void save(ServiceInstanceBinding binding);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceInstance;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public interface ServiceInstanceRepository {
|
||||
|
||||
List<ServiceInstance> findAll();
|
||||
|
||||
ServiceInstance findOne(String serviceInstanceId);
|
||||
|
||||
void save(ServiceInstance instance);
|
||||
|
||||
void delete(String id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker;
|
||||
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceInstanceBinding;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class SimpleServiceInstanceBindingRepository implements ServiceInstanceBindingRepository {
|
||||
|
||||
private String serviceDefinitionId;
|
||||
|
||||
public SimpleServiceInstanceBindingRepository(String serviceDefinitionId) {
|
||||
this.serviceDefinitionId = serviceDefinitionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstanceBinding findOne(String id) {
|
||||
return new ServiceInstanceBinding(id, serviceDefinitionId, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(ServiceInstanceBinding instance) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String id) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.cloudfoundry.community.servicebroker.exception.ServiceBrokerException;
|
||||
import org.cloudfoundry.community.servicebroker.exception.ServiceInstanceBindingExistsException;
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceDefinition;
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceInstance;
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceInstanceBinding;
|
||||
import org.cloudfoundry.community.servicebroker.service.CatalogService;
|
||||
import org.cloudfoundry.community.servicebroker.service.ServiceInstanceBindingService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Simple impl to bind services.
|
||||
*
|
||||
* @author sgreenberg@gopivotal.com
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class SimpleServiceInstanceBindingService implements ServiceInstanceBindingService {
|
||||
|
||||
private ServiceInstanceBindingRepository repository;
|
||||
private CatalogService catalog;
|
||||
@Value("${application.domain:cfapps.io}")
|
||||
private String applicationDomain;
|
||||
|
||||
@Autowired
|
||||
public SimpleServiceInstanceBindingService(CatalogService catalog,
|
||||
ServiceInstanceBindingRepository repository) {
|
||||
this.catalog = catalog;
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstanceBinding createServiceInstanceBinding(String bindingId,
|
||||
ServiceInstance serviceInstance, String serviceId, String planId,
|
||||
String appGuid) throws ServiceInstanceBindingExistsException,
|
||||
ServiceBrokerException {
|
||||
|
||||
ServiceInstanceBinding binding = repository.findOne(bindingId);
|
||||
if (binding != null && binding.getAppGuid()!=null) {
|
||||
throw new ServiceInstanceBindingExistsException(binding);
|
||||
}
|
||||
|
||||
if (!isBindingPermitted(serviceInstance, serviceId, planId, appGuid)) {
|
||||
throw new ServiceBrokerException(
|
||||
"Binding is not permitted for this plan, app and service");
|
||||
}
|
||||
|
||||
binding = new ServiceInstanceBinding(bindingId, serviceInstance.getId(),
|
||||
getCredentials(serviceInstance, serviceId), null, appGuid);
|
||||
repository.save(binding);
|
||||
|
||||
return binding;
|
||||
}
|
||||
|
||||
protected boolean isBindingPermitted(ServiceInstance serviceInstance,
|
||||
String serviceId, String planId, String appGuid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected Map<String, Object> getCredentials(ServiceInstance instance,
|
||||
String serviceId) {
|
||||
Map<String, Object> credentials = new HashMap<String, Object>();
|
||||
credentials.put("uri", findUriFromService(serviceId));
|
||||
credentials.put("domain", applicationDomain);
|
||||
return credentials;
|
||||
}
|
||||
|
||||
protected String findUriFromService(String serviceId) {
|
||||
ServiceDefinition definition = catalog.getServiceDefinition(serviceId);
|
||||
if (definition != null && definition.getId().equals(serviceId)) {
|
||||
String uri = (String) definition.getMetadata().get("uri");
|
||||
if (uri != null) {
|
||||
return uri;
|
||||
}
|
||||
return "http://" + definition.getName() + "." + applicationDomain;
|
||||
}
|
||||
throw new IllegalStateException("Cannot locate service in catalog: " + serviceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstanceBinding getServiceInstanceBinding(String id) {
|
||||
return repository.findOne(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstanceBinding deleteServiceInstanceBinding(String id)
|
||||
throws ServiceBrokerException {
|
||||
ServiceInstanceBinding binding = getServiceInstanceBinding(id);
|
||||
if (binding != null) {
|
||||
repository.delete(id);
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceInstance;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class SimpleServiceInstanceRepository implements ServiceInstanceRepository {
|
||||
|
||||
private String serviceDefinitionId;
|
||||
|
||||
public SimpleServiceInstanceRepository(String serviceDefinitionId) {
|
||||
// TODO: add dashboard URL
|
||||
this.serviceDefinitionId = serviceDefinitionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInstance> findAll() {
|
||||
return new ArrayList<ServiceInstance>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance findOne(String serviceInstanceId) {
|
||||
return new ServiceInstance(serviceInstanceId, serviceDefinitionId, null, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(ServiceInstance instance) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String id) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.cloudfoundry.community.servicebroker.exception.ServiceBrokerException;
|
||||
import org.cloudfoundry.community.servicebroker.exception.ServiceInstanceExistsException;
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceDefinition;
|
||||
import org.cloudfoundry.community.servicebroker.model.ServiceInstance;
|
||||
import org.cloudfoundry.community.servicebroker.service.ServiceInstanceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SimpleServiceInstanceService implements ServiceInstanceService {
|
||||
|
||||
private ServiceInstanceRepository repository;
|
||||
|
||||
@Autowired
|
||||
public SimpleServiceInstanceService(ServiceInstanceRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInstance> getAllServiceInstances() {
|
||||
return repository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance createServiceInstance(ServiceDefinition service,
|
||||
String serviceInstanceId, String planId, String organizationGuid,
|
||||
String spaceGuid)
|
||||
throws ServiceInstanceExistsException, ServiceBrokerException {
|
||||
ServiceInstance instance = repository.findOne(serviceInstanceId);
|
||||
if (instance != null && instance.getOrganizationGuid()!=null) {
|
||||
throw new ServiceInstanceExistsException(instance);
|
||||
}
|
||||
instance = new ServiceInstance(serviceInstanceId, service.getId(),
|
||||
planId, organizationGuid, spaceGuid, null);
|
||||
repository.save(instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ServiceInstance getServiceInstance(String id) {
|
||||
return repository.findOne(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance deleteServiceInstance(String id) throws ServiceBrokerException {
|
||||
ServiceInstance instance = repository.findOne(id);
|
||||
repository.delete(id);
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
||||
2
src/main/resources/META-INF/spring.factories
Normal file
2
src/main/resources/META-INF/spring.factories
Normal file
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.platform.cloudfoundry.broker.ServiceBrokerAutoConfiguration
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker.sample;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.embedded.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
import com.sun.jersey.spi.container.servlet.ServletContainer;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
public class Application extends WebMvcConfigurerAdapter {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean jersey() {
|
||||
FilterRegistrationBean bean = new FilterRegistrationBean();
|
||||
bean.setFilter(new ServletContainer());
|
||||
bean.addInitParameter("com.sun.jersey.config.property.WebPageContentRegex",
|
||||
"(/|/(flex/|images/|js/|css/|jsp/|admin/|v2/catalog|v2/service_instances).*)");
|
||||
bean.addInitParameter("com.sun.jersey.config.property.packages",
|
||||
"com.sun.jersey;com.netflix");
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.platform.cloudfoundry.broker.sample;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
@WebAppConfiguration
|
||||
public class ApplicationTests {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
15
src/test/resources/application.yml
Normal file
15
src/test/resources/application.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
debug: true
|
||||
spring:
|
||||
application:
|
||||
name: eureka
|
||||
management:
|
||||
context-path: /admin
|
||||
eureka:
|
||||
server:
|
||||
waitTimeInMsWhenSyncEmpty: 1000
|
||||
client:
|
||||
serviceUrl:
|
||||
defaultZone: http://localhost:8080/v2/
|
||||
default.defaultZone: http://localhost:8080/v2/
|
||||
registerWithEureka: false
|
||||
fetchRegistry: false
|
||||
Reference in New Issue
Block a user