modified few classes

This commit is contained in:
Pratik Das
2020-09-21 21:05:38 +04:00
parent 778a3d1d6f
commit 2e3d9a03b6
14 changed files with 194 additions and 172 deletions

View File

@@ -7,9 +7,10 @@ metadata:
spec:
ports:
- name: http
port: 8000
port: 8080
targetPort: 8080
selector:
app: usersignup-service
app: usersignup
---
apiVersion: apps/v1
@@ -28,12 +29,18 @@ spec:
spec:
containers:
- name: usersignupservice
image: usersignupservice:1.0
image: pratikdas/usersignupservice:1.0
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8000
port: 8080
initialDelaySeconds: 15
periodSeconds: 5
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
periodSeconds: 5

View File

@@ -37,11 +37,21 @@
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/com.jayway.jsonpath/json-path -->
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
<!-- Micrometer Prometheus registry -->
<dependency>
<groupId>io.micrometer</groupId>

View File

@@ -1,38 +0,0 @@
/**
*
*/
package io.pratik.healthcheck.usersignup;
import java.util.Set;
import org.springframework.boot.actuate.health.SimpleStatusAggregator;
import org.springframework.boot.actuate.health.Status;
import org.springframework.stereotype.Component;
/**
* @author Pratik Das
*
*/
@Component
public class ApplicationHealthAggregator extends SimpleStatusAggregator{
@Override
public Status getAggregateStatus(Status... statuses) {
// TODO Auto-generated method stub
return super.getAggregateStatus(statuses);
}
@Override
public Status getAggregateStatus(Set<Status> statuses) {
if(statuses != null) {
for (Status status : statuses) {
if(status.equals(Status.DOWN)) {
return Status.DOWN;//
}
}
}
return Status.UP;
}
}

View File

@@ -0,0 +1,32 @@
package io.pratik.healthcheck.usersignup;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthContributor;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
@Component("Database")
public class DatabaseHealthContributor implements HealthIndicator, HealthContributor {
@Autowired
private DataSource ds;
@Override
public Health health() {
try(Connection conn = ds.getConnection();){
Statement stmt = conn.createStatement();
stmt.execute("select FIRST_NAME,LAST_NAME,MOBILE,EMAIL from USERS");
} catch (SQLException ex) {
return Health.outOfService().withException(ex).build();
}
return Health.up().build();
}
}

View File

@@ -0,0 +1,63 @@
/**
*
*/
package io.pratik.healthcheck.usersignup;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.CompositeHealthContributor;
import org.springframework.boot.actuate.health.HealthContributor;
import org.springframework.boot.actuate.health.NamedContributor;
import org.springframework.stereotype.Component;
/**
* @author Pratik Das
*
*/
@Component("FetchUsersAPI")
public class FetchUsersAPIHealthContributor
implements CompositeHealthContributor {
private Map<String, HealthContributor>
contributors = new LinkedHashMap<>();
@Autowired
public FetchUsersAPIHealthContributor(
UrlShortenerServiceHealthIndicator
urlShortenerServiceHealthContributor,
DatabaseHealthContributor
databaseHealthContributor) {
super();
// First check if URL shortener service is reachable with
// Health Indicator of URL shortener service
contributors.put("urlShortener",
urlShortenerServiceHealthContributor);
// Check if USERS table used in the API can be queried with
//Health Indicator of Database
contributors.put("database",
databaseHealthContributor);
}
/**
* return list of health contributors
*/
@Override
public Iterator<NamedContributor<HealthContributor>>
iterator() {
return contributors.entrySet().stream()
.map((entry) ->
NamedContributor.of(entry.getKey(),
entry.getValue())).iterator();
}
@Override
public HealthContributor getContributor(String name) {
return contributors.get(name);
}
}

View File

@@ -1,96 +0,0 @@
/**
*
*/
package io.pratik.healthcheck.usersignup;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthContributor;
import org.springframework.boot.actuate.health.HealthContributorRegistry;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.NamedContributor;
import org.springframework.boot.actuate.health.Status;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
/**
* @author Pratik Das
*
*/
@Component("FetchUsersAPI")
@Slf4j
public class FetchUsersAPIHealthIndicator implements HealthIndicator {
private static final String URL = "https://cleanuri.com/api/v1/shorten";
@Autowired
private DataSource ds;
@Override
public Health health() {
Health dbHealth = dbIsHealthy();
Health serviceHealth = externalServiceIsHealthy();
if(Status.UP.equals(dbHealth.getStatus())) {
if(Status.UP.equals(serviceHealth.getStatus())) {
return Health.up().build();
}else {
return serviceHealth;
}
}else {
return dbHealth;
}
}
private Health dbIsHealthy() {
try(Connection conn = ds.getConnection();){
Statement stmt = conn.createStatement();
stmt.execute("select FIRST_NAME,LAST_NAME,MOBILE,EMAIL from USER");
} catch (SQLException ex) {
return Health.outOfService().withException(ex).build();
}
return Health.up().build();
}
private Health externalServiceIsHealthy() {
// check if url shortener service url is reachable
try {
URL url = new URL(URL);
int port = url.getPort();
if (port == -1) {
port = url.getDefaultPort();
}
try (Socket socket = new Socket(url.getHost(), port)) {
} catch (IOException e) {
log.warn("Failed to connect to : {}", URL);
return Health.down().withDetail("error", e.getMessage()).build();
}
} catch (MalformedURLException e1) {
log.warn("Invalid URL: {}",URL);
return Health.down().withDetail("error", e1.getMessage()).build();
}
return Health.up().build();
}
}

View File

@@ -0,0 +1,54 @@
/**
*
*/
package io.pratik.healthcheck.usersignup;
import reactor.netty.http.client.HttpClient;
import java.util.concurrent.TimeUnit;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import com.jayway.jsonpath.JsonPath;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import reactor.core.publisher.Mono;
import reactor.netty.tcp.TcpClient;
/**
* @author Pratik Das
*
*/
public final class URLHelper {
public static String shortenURL(final String longURL) {
WebClient webClient = getWebClient("https://cleanuri.com");
Mono<String> apiResponse = webClient.post().uri("/api/v1/shorten")
.body(BodyInserters.fromMultipartData("url", longURL))
.retrieve()
.bodyToMono(String.class);
String jsonResponse = apiResponse.block();
String shortenedURL = JsonPath.read(jsonResponse, "$.result_url");
return shortenedURL;
}
private static WebClient getWebClient(final String baseUrl) {
TcpClient tcpClient = TcpClient.create().option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
.doOnConnected(connection -> {
connection.addHandlerLast(new ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS));
connection.addHandlerLast(new WriteTimeoutHandler(5000, TimeUnit.MILLISECONDS));
});
WebClient client = WebClient.builder()
.baseUrl(baseUrl)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient))).build();
return client;
}
}

View File

@@ -3,10 +3,7 @@
*/
package io.pratik.healthcheck.usersignup;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthContributor;
@@ -28,24 +25,11 @@ public class UrlShortenerServiceHealthIndicator implements HealthIndicator, Heal
@Override
public Health health() {
// check if url shortener service url is reachable
try {
URL url = new URL(URL);
int port = url.getPort();
if (port == -1) {
port = url.getDefaultPort();
}
try (Socket socket = new Socket(url.getHost(), port)) {
} catch (IOException e) {
log.warn("Failed to connect to : {}", URL);
return Health.down().withDetail("error", e.getMessage()).build();
}
} catch (MalformedURLException e1) {
log.warn("Invalid URL: {}",URL);
try (Socket socket = new Socket(new java.net.URL(URL).getHost(),80)) {
} catch (Exception e1) {
log.warn("Failed to connect to : {}",URL);
return Health.down().withDetail("error", e1.getMessage()).build();
}
return Health.up().build();
}
}

View File

@@ -7,7 +7,6 @@ import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -20,7 +19,6 @@ import lombok.NoArgsConstructor;
@Builder
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name="USERS")
public class User {
@@ -30,5 +28,19 @@ public class User {
private String mobile;
private String email;
private String status;
private String profileURL;
public User(String firstName, String lastName, String mobile, String email, String status, String profileURL) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.mobile = mobile;
this.email = email;
this.status = status;
this.profileURL = profileURL==null?null:URLHelper.shortenURL(profileURL);
}
}

View File

@@ -22,16 +22,11 @@ public class UserController {
@GetMapping("/users")
public List<User> getUsers() {
List<User> users = userService.getUsers();
return users;
return userService.getUsers();
}
@PostMapping("users")
public ResponseEntity<String> addUser(@RequestBody User user) {
userService.addUser(user);
BodyBuilder response = ResponseEntity.status(HttpStatus.CREATED);
@@ -40,10 +35,8 @@ public class UserController {
@PostMapping("users/activate")
public ResponseEntity<String> activateUser(@RequestBody User user) {
userService.addUser(user);
BodyBuilder response = ResponseEntity.status(HttpStatus.OK);
return response.build();
}

View File

@@ -29,7 +29,7 @@ public class UserService {
}
public List<User> getUsers() {
//
return userRepository.findAll();
}

View File

@@ -20,7 +20,7 @@ public class UsersignupApplication {
InitializingBean populateUsers() {
return () -> {
userRepository.deleteAll();
userRepository.save(User.builder().firstName("Roger").lastName("Federer").build());
userRepository.save(User.builder().firstName("Roger").lastName("Federer").profileURL("http://linkin.com/576567").build());
userRepository.save(User.builder().firstName("Rafal").lastName("Nadal").build());
userRepository.save(User.builder().firstName("Novak").lastName("Djokovik").build());
};

View File

@@ -4,5 +4,6 @@ CREATE TABLE USERS (
FIRST_NAME VARCHAR(250) NOT NULL,
LAST_NAME VARCHAR(250) NOT NULL,
MOBILE VARCHAR(250) NULL,
EMAIL VARCHAR(250) NULL
EMAIL VARCHAR(250) NULL,
PROFILE_URL VARCHAR(250) NULL
);