sync & commit in greenwich
parent
12b9091583
commit
980bc3fd7a
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.dubbo.metadata.repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
|
||||
/**
|
||||
* metadata service instance selector.
|
||||
*
|
||||
* @author <a href="mailto:liuxx-u@outlook.com">liuxx</a>
|
||||
*/
|
||||
public interface MetadataServiceInstanceSelector {
|
||||
|
||||
/**
|
||||
* choose a service instance to get metadata.
|
||||
* @param serviceInstances all service instance
|
||||
* @return the service instance to get metadata
|
||||
*/
|
||||
Optional<ServiceInstance> choose(List<ServiceInstance> serviceInstances);
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 com.alibaba.cloud.sentinel.datasource;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
*/
|
||||
public interface SentinelDataSourceConstants {
|
||||
|
||||
String PROPERTY_PREFIX = "spring.cloud.sentinel";
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba</artifactId>
|
||||
<version>2.1.1.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-alibaba-sidecar</artifactId>
|
||||
<name>Spring Cloud Alibaba Sidecar</name>
|
||||
<description>An easy way to integrate polyglot apps for Spring Cloud Alibaba.</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.sidecar;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* @author www.itmuch.com
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(SidecarProperties.class)
|
||||
public class SidecarAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SidecarHealthIndicator sidecarHealthIndicator(
|
||||
SidecarProperties sidecarProperties, RestTemplate restTemplate) {
|
||||
return new SidecarHealthIndicator(sidecarProperties, restTemplate);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SidecarHealthChecker sidecarHealthChecker(
|
||||
SidecarDiscoveryClient sidecarDiscoveryClient,
|
||||
SidecarHealthIndicator sidecarHealthIndicator,
|
||||
SidecarProperties sidecarProperties, ConfigurableEnvironment environment) {
|
||||
SidecarHealthChecker cleaner = new SidecarHealthChecker(sidecarDiscoveryClient,
|
||||
sidecarHealthIndicator, sidecarProperties, environment);
|
||||
cleaner.check();
|
||||
return cleaner;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.sidecar;
|
||||
|
||||
/**
|
||||
* @author www.itmuch.com
|
||||
*/
|
||||
public interface SidecarDiscoveryClient {
|
||||
|
||||
/**
|
||||
* register instance.
|
||||
* @param applicationName applicationName
|
||||
* @param ip ip
|
||||
* @param port port
|
||||
*/
|
||||
void registerInstance(String applicationName, String ip, Integer port);
|
||||
|
||||
/**
|
||||
* deregister instance.
|
||||
* @param applicationName applicationName
|
||||
* @param ip ip
|
||||
* @param port port
|
||||
*/
|
||||
void deregisterInstance(String applicationName, String ip, Integer port);
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.sidecar;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
/**
|
||||
* @author www.itmuch.com
|
||||
*/
|
||||
public class SidecarHealthChecker {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SidecarHealthChecker.class);
|
||||
|
||||
private final SidecarDiscoveryClient sidecarDiscoveryClient;
|
||||
|
||||
private final HealthIndicator healthIndicator;
|
||||
|
||||
private final SidecarProperties sidecarProperties;
|
||||
|
||||
private final ConfigurableEnvironment environment;
|
||||
|
||||
public SidecarHealthChecker(SidecarDiscoveryClient sidecarDiscoveryClient,
|
||||
HealthIndicator healthIndicator, SidecarProperties sidecarProperties,
|
||||
ConfigurableEnvironment environment) {
|
||||
this.sidecarDiscoveryClient = sidecarDiscoveryClient;
|
||||
this.healthIndicator = healthIndicator;
|
||||
this.sidecarProperties = sidecarProperties;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public void check() {
|
||||
Schedulers.single().schedulePeriodically(() -> {
|
||||
String ip = sidecarProperties.getIp();
|
||||
Integer port = sidecarProperties.getPort();
|
||||
|
||||
Status status = healthIndicator.health().getStatus();
|
||||
String applicationName = environment.getProperty("spring.application.name");
|
||||
|
||||
if (status.equals(Status.UP)) {
|
||||
this.sidecarDiscoveryClient.registerInstance(applicationName, ip, port);
|
||||
log.debug(
|
||||
"Health check success. register this instance. applicationName = {}, ip = {}, port = {}, status = {}",
|
||||
applicationName, ip, port, status);
|
||||
}
|
||||
else {
|
||||
log.warn(
|
||||
"Health check failed. unregister this instance. applicationName = {}, ip = {}, port = {}, status = {}",
|
||||
applicationName, ip, port, status);
|
||||
this.sidecarDiscoveryClient.deregisterInstance(applicationName, ip, port);
|
||||
}
|
||||
|
||||
}, 0, sidecarProperties.getHealthCheckInterval(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.sidecar;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* @author www.itmuch.com
|
||||
*/
|
||||
public class SidecarHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
private final SidecarProperties sidecarProperties;
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
public SidecarHealthIndicator(SidecarProperties sidecarProperties,
|
||||
RestTemplate restTemplate) {
|
||||
this.sidecarProperties = sidecarProperties;
|
||||
this.restTemplate = restTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
try {
|
||||
URI uri = this.sidecarProperties.getHealthCheckUrl();
|
||||
if (uri == null) {
|
||||
builder.up();
|
||||
return;
|
||||
}
|
||||
|
||||
ResponseEntity<Map<String, Object>> exchange = this.restTemplate.exchange(uri,
|
||||
HttpMethod.GET, null,
|
||||
new ParameterizedTypeReference<Map<String, Object>>() {
|
||||
});
|
||||
|
||||
Map<String, Object> map = exchange.getBody();
|
||||
|
||||
if (map == null) {
|
||||
this.getWarning(builder);
|
||||
return;
|
||||
}
|
||||
Object status = map.get("status");
|
||||
if (status instanceof String) {
|
||||
builder.status(status.toString());
|
||||
}
|
||||
else {
|
||||
this.getWarning(builder);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
builder.down().withDetail("error", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void getWarning(Health.Builder builder) {
|
||||
builder.unknown().withDetail("warning", "no status field in response");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.sidecar;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
* @author www.itmuch.com
|
||||
*/
|
||||
@ConfigurationProperties("sidecar")
|
||||
@Validated
|
||||
public class SidecarProperties {
|
||||
|
||||
/**
|
||||
* polyglot service's ip.
|
||||
*/
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* polyglot service's port.
|
||||
*/
|
||||
@NotNull
|
||||
@Max(65535)
|
||||
@Min(1)
|
||||
private Integer port;
|
||||
|
||||
/**
|
||||
* polyglot service's health check url. this endpoint must return json and the format
|
||||
* must follow spring boot actuator's health endpoint. eg. {"status": "UP"}.
|
||||
*/
|
||||
private URI healthCheckUrl;
|
||||
|
||||
/**
|
||||
* interval of health check.
|
||||
*/
|
||||
private long healthCheckInterval = 30000L;
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
public Integer getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(Integer port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public URI getHealthCheckUrl() {
|
||||
return healthCheckUrl;
|
||||
}
|
||||
|
||||
public void setHealthCheckUrl(URI healthCheckUrl) {
|
||||
this.healthCheckUrl = healthCheckUrl;
|
||||
}
|
||||
|
||||
public long getHealthCheckInterval() {
|
||||
return healthCheckInterval;
|
||||
}
|
||||
|
||||
public void setHealthCheckInterval(long healthCheckInterval) {
|
||||
this.healthCheckInterval = healthCheckInterval;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.sidecar.consul;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.cloud.sidecar.SidecarAutoConfiguration;
|
||||
import com.alibaba.cloud.sidecar.SidecarDiscoveryClient;
|
||||
import com.alibaba.cloud.sidecar.SidecarProperties;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
|
||||
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
|
||||
import org.springframework.cloud.consul.discovery.HeartbeatProperties;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulManagementRegistrationCustomizer;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulRegistrationCustomizer;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistryAutoConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author www.itmuch.com
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(ConsulServiceRegistryAutoConfiguration.class)
|
||||
@AutoConfigureBefore({ ConsulAutoServiceRegistrationAutoConfiguration.class,
|
||||
SidecarAutoConfiguration.class })
|
||||
public class SidecarConsulAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public ConsulAutoRegistration consulRegistration(
|
||||
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
|
||||
ConsulDiscoveryProperties properties, ApplicationContext applicationContext,
|
||||
ObjectProvider<List<ConsulRegistrationCustomizer>> registrationCustomizers,
|
||||
ObjectProvider<List<ConsulManagementRegistrationCustomizer>> managementRegistrationCustomizers,
|
||||
HeartbeatProperties heartbeatProperties,
|
||||
SidecarProperties sidecarProperties) {
|
||||
return SidecarConsulAutoRegistration.registration(
|
||||
autoServiceRegistrationProperties, properties, applicationContext,
|
||||
registrationCustomizers.getIfAvailable(),
|
||||
managementRegistrationCustomizers.getIfAvailable(), heartbeatProperties,
|
||||
sidecarProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SidecarDiscoveryClient sidecarDiscoveryClient(
|
||||
ConsulDiscoveryProperties properties, ConsulServiceRegistry serviceRegistry,
|
||||
ConsulAutoRegistration registration) {
|
||||
return new SidecarConsulDiscoveryClient(properties, serviceRegistry,
|
||||
registration);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.sidecar.consul;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.cloud.sidecar.SidecarProperties;
|
||||
import com.ecwid.consul.v1.agent.model.NewService;
|
||||
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
|
||||
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
|
||||
import org.springframework.cloud.consul.discovery.HeartbeatProperties;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulManagementRegistrationCustomizer;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulRegistrationCustomizer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* @author www.itmuch.com
|
||||
*/
|
||||
public class SidecarConsulAutoRegistration extends ConsulAutoRegistration {
|
||||
|
||||
public SidecarConsulAutoRegistration(NewService service,
|
||||
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
|
||||
ConsulDiscoveryProperties properties, ApplicationContext context,
|
||||
HeartbeatProperties heartbeatProperties,
|
||||
List<ConsulManagementRegistrationCustomizer> managementRegistrationCustomizers) {
|
||||
super(service, autoServiceRegistrationProperties, properties, context,
|
||||
heartbeatProperties, managementRegistrationCustomizers);
|
||||
}
|
||||
|
||||
public static ConsulAutoRegistration registration(
|
||||
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
|
||||
ConsulDiscoveryProperties properties, ApplicationContext context,
|
||||
List<ConsulRegistrationCustomizer> registrationCustomizers,
|
||||
List<ConsulManagementRegistrationCustomizer> managementRegistrationCustomizers,
|
||||
HeartbeatProperties heartbeatProperties,
|
||||
SidecarProperties sidecarProperties) {
|
||||
|
||||
NewService service = new NewService();
|
||||
String appName = getAppName(properties, context.getEnvironment());
|
||||
service.setId(getInstanceId(sidecarProperties, context.getEnvironment()));
|
||||
if (!properties.isPreferAgentAddress()) {
|
||||
service.setAddress(sidecarProperties.getIp());
|
||||
}
|
||||
service.setName(normalizeForDns(appName));
|
||||
service.setTags(createTags(properties));
|
||||
|
||||
// set health check, use alibaba sidecar self's port rather than polyglot app's
|
||||
// port.
|
||||
service.setPort(
|
||||
Integer.valueOf(context.getEnvironment().getProperty("server.port")));
|
||||
setCheck(service, autoServiceRegistrationProperties, properties, context,
|
||||
heartbeatProperties);
|
||||
|
||||
service.setPort(sidecarProperties.getPort());
|
||||
|
||||
ConsulAutoRegistration registration = new ConsulAutoRegistration(service,
|
||||
autoServiceRegistrationProperties, properties, context,
|
||||
heartbeatProperties, managementRegistrationCustomizers);
|
||||
customize(registrationCustomizers, registration);
|
||||
return registration;
|
||||
}
|
||||
|
||||
public static String getInstanceId(SidecarProperties sidecarProperties,
|
||||
Environment environment) {
|
||||
return String.format("%s-%s-%s",
|
||||
environment.getProperty("spring.application.name"),
|
||||
sidecarProperties.getIp(), sidecarProperties.getPort());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.sidecar.consul;
|
||||
|
||||
import com.alibaba.cloud.sidecar.SidecarDiscoveryClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry;
|
||||
|
||||
/**
|
||||
* @author www.itmuch.com
|
||||
*/
|
||||
public class SidecarConsulDiscoveryClient implements SidecarDiscoveryClient {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(SidecarConsulDiscoveryClient.class);
|
||||
|
||||
private final ConsulDiscoveryProperties properties;
|
||||
|
||||
private final ConsulServiceRegistry serviceRegistry;
|
||||
|
||||
private final ConsulAutoRegistration registration;
|
||||
|
||||
public SidecarConsulDiscoveryClient(ConsulDiscoveryProperties properties,
|
||||
ConsulServiceRegistry serviceRegistry, ConsulAutoRegistration registration) {
|
||||
this.properties = properties;
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
this.registration = registration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerInstance(String applicationName, String ip, Integer port) {
|
||||
|
||||
if (!this.properties.isRegister()) {
|
||||
log.debug("Registration disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
serviceRegistry.register(registration);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregisterInstance(String applicationName, String ip, Integer port) {
|
||||
if (!this.properties.isRegister() || !this.properties.isDeregister()) {
|
||||
return;
|
||||
}
|
||||
serviceRegistry.deregister(registration);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.sidecar.nacos;
|
||||
|
||||
import com.alibaba.cloud.nacos.NacosDiscoveryAutoConfiguration;
|
||||
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
|
||||
import com.alibaba.cloud.sidecar.SidecarAutoConfiguration;
|
||||
import com.alibaba.cloud.sidecar.SidecarDiscoveryClient;
|
||||
import com.alibaba.cloud.sidecar.SidecarProperties;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author www.itmuch.com
|
||||
*/
|
||||
@Configuration
|
||||
@AutoConfigureBefore({ NacosDiscoveryAutoConfiguration.class,
|
||||
SidecarAutoConfiguration.class })
|
||||
@ConditionalOnClass(NacosDiscoveryProperties.class)
|
||||
public class SidecarNacosAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SidecarNacosDiscoveryProperties sidecarNacosDiscoveryProperties(
|
||||
SidecarProperties sidecarProperties) {
|
||||
return new SidecarNacosDiscoveryProperties(sidecarProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SidecarDiscoveryClient sidecarDiscoveryClient(
|
||||
SidecarNacosDiscoveryProperties sidecarNacosDiscoveryProperties) {
|
||||
return new SidecarNacosDiscoveryClient(sidecarNacosDiscoveryProperties);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.sidecar.nacos;
|
||||
|
||||
import com.alibaba.cloud.sidecar.SidecarDiscoveryClient;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author www.itmuch.com
|
||||
*/
|
||||
public class SidecarNacosDiscoveryClient implements SidecarDiscoveryClient {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(SidecarNacosDiscoveryClient.class);
|
||||
|
||||
private final SidecarNacosDiscoveryProperties sidecarNacosDiscoveryProperties;
|
||||
|
||||
public SidecarNacosDiscoveryClient(
|
||||
SidecarNacosDiscoveryProperties sidecarNacosDiscoveryProperties) {
|
||||
this.sidecarNacosDiscoveryProperties = sidecarNacosDiscoveryProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerInstance(String applicationName, String ip, Integer port) {
|
||||
try {
|
||||
this.sidecarNacosDiscoveryProperties.namingServiceInstance()
|
||||
.registerInstance(applicationName, ip, port);
|
||||
}
|
||||
catch (NacosException e) {
|
||||
log.warn("nacos exception happens", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregisterInstance(String applicationName, String ip, Integer port) {
|
||||
try {
|
||||
this.sidecarNacosDiscoveryProperties.namingServiceInstance()
|
||||
.deregisterInstance(applicationName, ip, port);
|
||||
}
|
||||
catch (NacosException e) {
|
||||
log.warn("nacos exception happens", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.cloud.sidecar.nacos;
|
||||
|
||||
import java.net.SocketException;
|
||||
|
||||
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
|
||||
import com.alibaba.cloud.sidecar.SidecarProperties;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* @author itmuch.com
|
||||
*/
|
||||
public class SidecarNacosDiscoveryProperties extends NacosDiscoveryProperties {
|
||||
|
||||
private final SidecarProperties sidecarProperties;
|
||||
|
||||
public SidecarNacosDiscoveryProperties(SidecarProperties sidecarProperties) {
|
||||
this.sidecarProperties = sidecarProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() throws SocketException {
|
||||
super.init();
|
||||
|
||||
String ip = sidecarProperties.getIp();
|
||||
if (StringUtils.isNotBlank(ip)) {
|
||||
this.setIp(ip);
|
||||
}
|
||||
|
||||
Integer port = sidecarProperties.getPort();
|
||||
this.setPort(port);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.alibaba.cloud.sidecar.nacos.SidecarNacosAutoConfiguration,\
|
||||
com.alibaba.cloud.sidecar.SidecarAutoConfiguration,\
|
||||
com.alibaba.cloud.sidecar.consul.SidecarConsulAutoConfiguration
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.alicloud.oss.resource;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.aliyun.oss.model.Bucket;
|
||||
import com.aliyun.oss.model.OSSObject;
|
||||
import com.aliyun.oss.model.ObjectMetadata;
|
||||
import com.aliyun.oss.model.PutObjectResult;
|
||||
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* @author lich
|
||||
*/
|
||||
public class DummyOssClient {
|
||||
|
||||
private Map<String, byte[]> storeMap = new ConcurrentHashMap<>();
|
||||
|
||||
private Map<String, Bucket> bucketSet = new HashMap<>();
|
||||
|
||||
public String getStoreKey(String bucketName, String objectKey) {
|
||||
return String.join(".", bucketName, objectKey);
|
||||
}
|
||||
|
||||
public PutObjectResult putObject(String bucketName, String objectKey,
|
||||
InputStream inputStream) {
|
||||
|
||||
try {
|
||||
byte[] result = StreamUtils.copyToByteArray(inputStream);
|
||||
storeMap.put(getStoreKey(bucketName, objectKey), result);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
inputStream.close();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
return new PutObjectResult();
|
||||
}
|
||||
|
||||
public OSSObject getOSSObject(String bucketName, String objectKey) {
|
||||
byte[] value = storeMap.get(this.getStoreKey(bucketName, objectKey));
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
OSSObject ossObject = new OSSObject();
|
||||
ossObject.setBucketName(bucketName);
|
||||
ossObject.setKey(objectKey);
|
||||
InputStream inputStream = new ByteArrayInputStream(value);
|
||||
ossObject.setObjectContent(inputStream);
|
||||
|
||||
ObjectMetadata objectMetadata = new ObjectMetadata();
|
||||
objectMetadata.setContentLength(value.length);
|
||||
ossObject.setObjectMetadata(objectMetadata);
|
||||
|
||||
return ossObject;
|
||||
}
|
||||
|
||||
public Bucket createBucket(String bucketName) {
|
||||
if (bucketSet.containsKey(bucketName)) {
|
||||
return bucketSet.get(bucketName);
|
||||
}
|
||||
Bucket bucket = new Bucket();
|
||||
bucket.setCreationDate(new Date());
|
||||
bucket.setName(bucketName);
|
||||
bucketSet.put(bucketName, bucket);
|
||||
return bucket;
|
||||
}
|
||||
|
||||
public List<Bucket> bucketList() {
|
||||
return new ArrayList<>(bucketSet.values());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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 com.alibaba.alicloud.oss.resource;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.WritableResource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import static com.alibaba.alicloud.oss.OssConstants.OSS_TASK_EXECUTOR_BEAN_NAME;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* @author lich
|
||||
*/
|
||||
@SpringBootTest
|
||||
@RunWith(SpringRunner.class)
|
||||
public class OssStorageResourceTest {
|
||||
|
||||
/**
|
||||
* Used to test exception messages and types.
|
||||
*/
|
||||
@Rule
|
||||
public ExpectedException expectedEx = ExpectedException.none();
|
||||
|
||||
@Autowired
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
@Autowired
|
||||
private OSS oss;
|
||||
|
||||
@Value("oss://aliyun-test-bucket/")
|
||||
private Resource bucketResource;
|
||||
|
||||
@Value("oss://aliyun-test-bucket/myfilekey")
|
||||
private Resource remoteResource;
|
||||
|
||||
public static byte[] generateRandomBytes(int blen) {
|
||||
byte[] array = new byte[blen];
|
||||
new Random().nextBytes(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceType() {
|
||||
assertThat(remoteResource.getClass()).isEqualTo(OssStorageResource.class);
|
||||
OssStorageResource ossStorageResource = (OssStorageResource) remoteResource;
|
||||
assertThat(ossStorageResource.getFilename()).isEqualTo("myfilekey");
|
||||
assertThat(ossStorageResource.isBucket()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidObject() throws Exception {
|
||||
assertThat(remoteResource.exists()).isEqualTo(true);
|
||||
OssStorageResource ossStorageResource = (OssStorageResource) remoteResource;
|
||||
assertThat(ossStorageResource.bucketExists()).isEqualTo(true);
|
||||
assertThat(remoteResource.contentLength()).isEqualTo(4096L);
|
||||
assertThat(remoteResource.getURI().toString())
|
||||
.isEqualTo("oss://aliyun-test-bucket/myfilekey");
|
||||
assertThat(remoteResource.getFilename()).isEqualTo("myfilekey");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBucketResource() throws Exception {
|
||||
assertThat(bucketResource.exists()).isEqualTo(true);
|
||||
assertThat(((OssStorageResource) this.bucketResource).isBucket()).isEqualTo(true);
|
||||
assertThat(((OssStorageResource) this.bucketResource).bucketExists())
|
||||
.isEqualTo(true);
|
||||
assertThat(bucketResource.getURI().toString())
|
||||
.isEqualTo("oss://aliyun-test-bucket/");
|
||||
assertThat(this.bucketResource.getFilename()).isEqualTo("aliyun-test-bucket");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBucketNotEndingInSlash() {
|
||||
assertThat(
|
||||
new OssStorageResource(this.oss, "oss://aliyun-test-bucket", beanFactory)
|
||||
.isBucket()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecifyPathCorrect() {
|
||||
OssStorageResource ossStorageResource = new OssStorageResource(this.oss,
|
||||
"oss://aliyun-test-bucket/myfilekey", beanFactory, false);
|
||||
assertThat(ossStorageResource.exists()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecifyBucketCorrect() {
|
||||
OssStorageResource ossStorageResource = new OssStorageResource(this.oss,
|
||||
"oss://aliyun-test-bucket", beanFactory, false);
|
||||
|
||||
assertThat(ossStorageResource.isBucket()).isEqualTo(true);
|
||||
assertThat(ossStorageResource.getBucket().getName())
|
||||
.isEqualTo("aliyun-test-bucket");
|
||||
assertThat(ossStorageResource.exists()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBucketOutputStream() throws IOException {
|
||||
this.expectedEx.expect(IllegalStateException.class);
|
||||
this.expectedEx.expectMessage(
|
||||
"Cannot open an output stream to a bucket: 'oss://aliyun-test-bucket/'");
|
||||
((WritableResource) this.bucketResource).getOutputStream();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBucketInputStream() throws IOException {
|
||||
this.expectedEx.expect(IllegalStateException.class);
|
||||
this.expectedEx.expectMessage(
|
||||
"Cannot open an input stream to a bucket: 'oss://aliyun-test-bucket/'");
|
||||
this.bucketResource.getInputStream();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBucketContentLength() throws IOException {
|
||||
this.expectedEx.expect(FileNotFoundException.class);
|
||||
this.expectedEx.expectMessage("OSSObject not existed.");
|
||||
this.bucketResource.contentLength();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBucketFile() throws IOException {
|
||||
this.expectedEx.expect(UnsupportedOperationException.class);
|
||||
this.expectedEx.expectMessage(
|
||||
"oss://aliyun-test-bucket/ cannot be resolved to absolute file path");
|
||||
this.bucketResource.getFile();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBucketLastModified() throws IOException {
|
||||
this.expectedEx.expect(FileNotFoundException.class);
|
||||
this.expectedEx.expectMessage("OSSObject not existed.");
|
||||
this.bucketResource.lastModified();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBucketResourceStatuses() {
|
||||
assertThat(this.bucketResource.isOpen()).isEqualTo(false);
|
||||
assertThat(((WritableResource) this.bucketResource).isWritable())
|
||||
.isEqualTo(false);
|
||||
assertThat(this.bucketResource.exists()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWritable() throws Exception {
|
||||
assertThat(this.remoteResource instanceof WritableResource).isEqualTo(true);
|
||||
WritableResource writableResource = (WritableResource) this.remoteResource;
|
||||
assertThat(writableResource.isWritable()).isEqualTo(true);
|
||||
writableResource.getOutputStream();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWritableOutputStream() throws Exception {
|
||||
String location = "oss://aliyun-test-bucket/test";
|
||||
OssStorageResource resource = new OssStorageResource(this.oss, location,
|
||||
beanFactory, true);
|
||||
OutputStream os = resource.getOutputStream();
|
||||
assertThat(os).isNotNull();
|
||||
|
||||
byte[] randomBytes = generateRandomBytes(1203);
|
||||
String expectedString = new String(randomBytes);
|
||||
|
||||
os.write(randomBytes);
|
||||
os.close();
|
||||
|
||||
InputStream in = resource.getInputStream();
|
||||
|
||||
byte[] result = StreamUtils.copyToByteArray(in);
|
||||
String actualString = new String(result);
|
||||
|
||||
assertThat(actualString).isEqualTo(expectedString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateBucket() {
|
||||
String location = "oss://my-new-test-bucket/";
|
||||
OssStorageResource resource = new OssStorageResource(this.oss, location,
|
||||
beanFactory, true);
|
||||
|
||||
resource.createBucket();
|
||||
|
||||
assertThat(resource.bucketExists()).isEqualTo(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration for the tests.
|
||||
*/
|
||||
@Configuration
|
||||
@Import(OssStorageProtocolResolver.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean(name = OSS_TASK_EXECUTOR_BEAN_NAME)
|
||||
@ConditionalOnMissingBean
|
||||
public ExecutorService ossTaskExecutor() {
|
||||
return new ThreadPoolExecutor(8, 128, 60, TimeUnit.SECONDS,
|
||||
new SynchronousQueue<>());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public static OSS mockOSS() {
|
||||
DummyOssClient dummyOssStub = new DummyOssClient();
|
||||
OSS oss = mock(OSS.class);
|
||||
|
||||
doAnswer(invocation -> dummyOssStub.putObject(invocation.getArgument(0),
|
||||
invocation.getArgument(1), invocation.getArgument(2))).when(oss)
|
||||
.putObject(Mockito.anyString(), Mockito.anyString(),
|
||||
Mockito.any(InputStream.class));
|
||||
|
||||
doAnswer(invocation -> dummyOssStub.getOSSObject(invocation.getArgument(0),
|
||||
invocation.getArgument(1))).when(oss).getObject(Mockito.anyString(),
|
||||
Mockito.anyString());
|
||||
|
||||
doAnswer(invocation -> dummyOssStub.bucketList()).when(oss).listBuckets();
|
||||
|
||||
doAnswer(invocation -> dummyOssStub.createBucket(invocation.getArgument(0)))
|
||||
.when(oss).createBucket(Mockito.anyString());
|
||||
|
||||
// prepare object
|
||||
dummyOssStub.createBucket("aliyun-test-bucket");
|
||||
|
||||
byte[] content = generateRandomBytes(4096);
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(content);
|
||||
dummyOssStub.putObject("aliyun-test-bucket", "myfilekey", inputStream);
|
||||
|
||||
return oss;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
<?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">
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba</artifactId>
|
||||
<version>2.1.1.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-starter-alibaba-sidecar</artifactId>
|
||||
<name>Spring Cloud Starter Alibaba Sidecar</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-sidecar</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
Loading…
Reference in New Issue