功能区LB / OAuth2RestTemplate

时间:2015-01-22 01:21:27

标签: spring-boot spring-cloud

我正在尝试调用负载均衡器来访问服务实例,以便在我的配置类中构建OAuth2RestTemplate访问令牌uri,但由于某种原因,我在实例化bean时不断获得异常。有没有人遇到过这个问题?或者也许可能有一些见解?

工厂方法'restTemplate'抛出异常;嵌套异常是java.lang.IllegalStateException:无法找到服务的ILoadBalancer:service

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'restTemplate' defined in class path resource [com/apop/services/config/rest/RestConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.oauth2.client.OAuth2RestTemplate]: Factory method 'serviceRestTemplate' threw exception; nested exception is java.lang.IllegalStateException: Unable to locate ILoadBalancer for service: service

此处还有我的服务和配置类:

@Service
public class ServiceIntegration implements Service, Serializable {


@Resource(name = "serviceRestTemplate")
OAuth2RestTemplate serviceRestTemplate;

@Autowired
private LoadBalancerClient balancerClient;

@Value("${service}")
private String service;

private ResponseExceptionHelper responseExceptionHelper = new ResponseExceptionHelper();

public ResponseExceptionHelper getResponseExceptionHelper() {
    return responseExceptionHelper;
}

public void setResponseExceptionHelper(
        ResponseExceptionHelper responseExceptionHelper) {
    this.responseExceptionHelper = responseExceptionHelper;
}

/**
 * @param payload
 * @param path
 * @param method
 * @return
 * @throws ResponseException
 */
private String execute(OAuth2RestTemplate restTemplate, String endPoint, String payload, HttpMethod method)
        throws ResponseException {
    HttpHeaders headers = new HttpHeaders();

    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<String> requestEntity = new HttpEntity<String>(payload, headers);

    String response = null;
    try {

        ServiceInstance serviceInstance = balancerClient.choose(service);
        String uri = String.format("http://%s:%s/%s", serviceInstance.getHost(), serviceInstance.getPort(), service) + endPoint;
        ResponseEntity<String> responseEntity = restTemplate.exchange(uri, method, requestEntity, String.class);
        if (responseEntity != null) {
            response = responseEntity.getBody();
        }
    } catch (Exception e) {
        logger.error(error, e);
        throw e;
    }

    logger.info(response);
    return response;
}

}

配置:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class RestConfiguration {


@Value("${service}")
private String service;


@Value("${token.service.endpoint}")
private String tokenServiceEndpoint;


@Value("${clientId}")
private String clientId;

@Value("${clientSecret}")
private String clientSecret;

@Value("${grant}")
private String grant;

@Autowired
private LoadBalancerClient balancerClient;


@Bean
public OAuth2RestTemplate serviceRestTemplate() {
    ClientCredentialsResourceDetails resources = getClientDetails();
    OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resources, new DefaultOAuth2ClientContext());
    return restTemplate;
}


public ClientCredentialsResourceDetails getClientDetails() {
    ServiceInstance serviceInstance = balancerClient.choose(service);
    String uri = String.format("http://%s:%s/%s", serviceInstance.getHost(), serviceInstance.getPort(), legacyService) + tokenServiceEndpoint;

    ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
    resource.setAccessTokenUri(uri);
    resource.setClientSecret(clientId);
    resource.setClientId(clientSecret);
    resource.setGrantType(grant);
    return resource;
}

}

1 个答案:

答案 0 :(得分:0)

您正尝试在服务目录可用之前在@Bean定义中进行服务发现(因此超级早)。最好在正常RibbonInterceptor中使用OAuth2RestTemplate(如RibbonAutoConfiguration中所示)。