package doge;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.ResourceProcessor;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableConfigurationProperties
@EnableHystrix
@EnableEurekaClient
public class AccountApplication extends RepositoryRestMvcConfiguration {
@Override
protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(Account.class);
}
public static void main(String[] args) {
SpringApplication.run(AccountApplication.class, args);
}
}
@Component
class AccountResourceProcessor implements ResourceProcessor<Resource<Account>> {
private final DogeClient dogeClient;
@Autowired
public AccountResourceProcessor(DogeClient dogeClient) {
this.dogeClient = dogeClient;
}
@Override
public Resource<Account> process(Resource<Account> accountResource) {
Link dogeLink = this.dogeClient.buildDogeLink(
accountResource.getContent());
if (null != dogeLink)
accountResource.add(dogeLink);
return accountResource;
}
}
@Component
class DogeClient {
private String dogeServiceName = "doges";
private final DiscoveryClient discoveryClient;
@Autowired
public DogeClient(DiscoveryClient discoveryClient) {
this.discoveryClient = discoveryClient;
}
public Link defaultDogeLink(Account account) {
return null;
}
@HystrixCommand(fallbackMethod = "defaultDogeLink")
public Link buildDogeLink(Account account) {
InstanceInfo instance = discoveryClient.getNextServerFromEureka(dogeServiceName, false);
String url = UriComponentsBuilder.fromHttpUrl(instance.getHomePageUrl() + "/doges/{key}/photos")
.buildAndExpand(Long.toString(account.getId())).toUriString();
return new Link(url, "doges");
}
}
@RepositoryRestResource
interface AccountRepository extends JpaRepository<Account, Long> {
}
@Entity
class Account {
public String getUsername() {
return username;
}
public Long getId() {
return id;
}
@Id
@GeneratedValue
private Long id;
private String username;
Account() { // JPA only
}
public Account(String username) {
this.username = username;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("User{");
sb.append("id=").append(id);
sb.append(", username='").append(username).append('\'');
sb.append('}');
return sb.toString();
}
}