Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
FROM openjdk:8-jdk-alpine as builder

ARG WORKDIR="/app"

WORKDIR ${WORKDIR}

COPY build.gradle gradlew settings.gradle ${WORKDIR}/
COPY gradle ${WORKDIR}/gradle
# The task `gradle dependencies` will list the dependencies and download them as a side-effect.
RUN ./gradlew --no-daemon clean dependencies --configuration runtime
COPY . ${WORKDIR}
RUN ./gradlew --no-daemon bootJar


FROM openjdk:8-jdk-alpine

ARG WORKDIR="/app"

WORKDIR ${WORKDIR}

EXPOSE 8000

CMD ["java", "-jar", "tinyurlapi-0.0.1-SNAPSHOT.jar"]

ENV JAVA_TOOL_OPTIONS "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=2"

COPY --from=builder ${WORKDIR}/build/libs/*.jar ${WORKDIR}/
23 changes: 22 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
version: '3.4'

services:

tinyurl:
build: .
ports:
- 8000:8000
links:
- cassandra
- kgs


cassandra:
image: cassandra
ports:
Expand All @@ -10,4 +20,15 @@ services:
volumes:
- "./src/main/resources/cassandra-init.sh:/cassandra-init.sh"
- "./src/main/resources/import.cql:/import.cql"
command: "sh /cassandra-init.sh"
command: "sh /cassandra-init.sh"

redis:
image: redis:alpine

kgs:
image: victuxbb/tinyurlkgs
environment:
KGS_REDIS_HOST: redis
KGS_KEYS_LENGTH: 3
links:
- redis
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.victuxbb.systemdesigns.tinyurlapi.application;

import com.victuxbb.systemdesigns.tinyurlapi.domain.shorturl.ShortURL;
import com.victuxbb.systemdesigns.tinyurlapi.domain.shorturl.ShortURLRepository;
import reactor.core.publisher.Mono;

public class RedirectShortURL {
private final ShortURLRepository shortURLRepository;

public RedirectShortURL(ShortURLRepository shortURLRepository) {
this.shortURLRepository = shortURLRepository;
}

public Mono<ShortURL> redirect(String key) {
return this.shortURLRepository.find(key);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.victuxbb.systemdesigns.tinyurlapi.domain.shorturl;

import com.victuxbb.systemdesigns.tinyurlapi.domain.kgs.URLKey;
import reactor.core.publisher.Mono;

public interface ShortURLRepository {
Mono<ShortURL> save(ShortURL url);
Mono<Void> delete(URLKey urlKey);
Mono<ShortURL> save(ShortURL url);

Mono<ShortURL> find(String key);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.victuxbb.systemdesigns.tinyurlapi.infrastructure.bootstrap.configuration;

import com.victuxbb.systemdesigns.tinyurlapi.application.CreateShortURL;
import com.victuxbb.systemdesigns.tinyurlapi.application.RedirectShortURL;
import com.victuxbb.systemdesigns.tinyurlapi.domain.kgs.KGSRepository;
import com.victuxbb.systemdesigns.tinyurlapi.domain.shorturl.ShortURLRepository;
import org.springframework.context.annotation.Bean;
Expand All @@ -9,6 +10,11 @@
@Configuration
public class ApplicationConfiguration {

@Bean
public RedirectShortURL redirectShortURL(ShortURLRepository shortURLRepository){
return new RedirectShortURL(shortURLRepository);
}

@Bean
public CreateShortURL createShortURL(ShortURLRepository shortURLRepository, KGSRepository kgsRepository) {
return new CreateShortURL(shortURLRepository, kgsRepository);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package com.victuxbb.systemdesigns.tinyurlapi.infrastructure.controller;

import com.victuxbb.systemdesigns.tinyurlapi.application.CreateShortURL;
import com.victuxbb.systemdesigns.tinyurlapi.application.RedirectShortURL;
import com.victuxbb.systemdesigns.tinyurlapi.application.ShortURLRequest;
import com.victuxbb.systemdesigns.tinyurlapi.domain.shorturl.ShortURL;
import java.net.URI;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

Expand All @@ -13,14 +20,26 @@
public class TinyURLController {

private final CreateShortURL createShortURL;
private final RedirectShortURL redirectShortURL;

public TinyURLController(CreateShortURL createShortURL) {
public TinyURLController(CreateShortURL createShortURL,
RedirectShortURL redirectShortURL) {
this.createShortURL = createShortURL;
this.redirectShortURL = redirectShortURL;
}

@PostMapping(path = "/tinyURL")
public Mono<ShortURL> createTinyURL(@RequestBody CreateTinyURLRequest createTinyURLRequest) {
return Mono.fromCallable(() -> new ShortURLRequest(createTinyURLRequest.getOriginalURL()))
.flatMap(createShortURL::create);
}

@RequestMapping(value = "/{key}", method = RequestMethod.GET)
public Mono<ResponseEntity<Void>> redirect(@PathVariable("key") String key) {
return redirectShortURL.redirect(key)
.flatMap(shortURL -> Mono.fromCallable(() -> new URI(shortURL.getOriginalURL())))
.map(uri -> ResponseEntity
.status(HttpStatus.SEE_OTHER)
.location(uri).build());
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
package com.victuxbb.systemdesigns.tinyurlapi.infrastructure.datasource;

import com.victuxbb.systemdesigns.tinyurlapi.domain.kgs.URLKey;
import com.victuxbb.systemdesigns.tinyurlapi.domain.shorturl.ShortURLRepository;
import com.victuxbb.systemdesigns.tinyurlapi.domain.shorturl.ShortURL;
import com.victuxbb.systemdesigns.tinyurlapi.domain.shorturl.ShortURLRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.cassandra.core.ReactiveCassandraOperations;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Mono;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

@Repository
public class CassandraShortURLRepository implements ShortURLRepository {

private final ReactiveCassandraOperations reactiveCassandraOperations;
private final ReactiveCassandraOperations reactiveCassandraOperations;

@Autowired
public CassandraShortURLRepository(ReactiveCassandraOperations reactiveCassandraOperations) {
this.reactiveCassandraOperations = reactiveCassandraOperations;
}
@Autowired
public CassandraShortURLRepository(ReactiveCassandraOperations reactiveCassandraOperations) {
this.reactiveCassandraOperations = reactiveCassandraOperations;
}

@Override
public Mono<ShortURL> save(ShortURL shortUrl) {
return reactiveCassandraOperations.insert(new URL(shortUrl))
.map(URL::toShortURL);
}
@Override
public Mono<ShortURL> save(ShortURL shortUrl) {
return reactiveCassandraOperations.insert(new URL(shortUrl))
.map(URL::toShortURL);
}

@Override
public Mono<Void> delete(URLKey urlKey) {
return Mono.error(new NotImplementedException());
}
@Override public Mono<ShortURL> find(String key) {
//MapId id = id("hash", key);
return reactiveCassandraOperations.selectOneById(key, URL.class)
.map(URL::toShortURL);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.victuxbb.systemdesigns.tinyurlapi.infrastructure.datasource;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.victuxbb.systemdesigns.tinyurlapi.domain.kgs.KGSRepository;
import com.victuxbb.systemdesigns.tinyurlapi.domain.kgs.URLKey;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Repository;
import org.springframework.web.client.RestTemplate;
import reactor.core.publisher.Mono;

@Repository
@Primary
public class HttpKGSRepository implements KGSRepository {
private final RestTemplate restTemplate;

public HttpKGSRepository() {
this.restTemplate = new RestTemplate();
}

@Override public Mono<URLKey> getUniqueKey() {
return Mono.fromCallable(
() -> restTemplate.postForEntity(
"http://kgs:8080/keys_request",
new HttpEntity<>(new KGSRequest(1)),
String[].class
)
)
.map(HttpEntity::getBody)
.map(strings -> new URLKey(strings[0]));
}

@JsonInclude(JsonInclude.Include.NON_NULL)
private class KGSRequest {
@JsonProperty("quantity")
private Integer quantity;

private KGSRequest(Integer quantity) {
this.quantity = quantity;
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.victuxbb.systemdesigns.tinyurlapi.infrastructure.datasource;

import com.victuxbb.systemdesigns.tinyurlapi.domain.shorturl.ShortURL;
import org.springframework.data.annotation.Id;
import org.springframework.data.cassandra.core.cql.PrimaryKeyType;
import org.springframework.data.cassandra.core.mapping.Column;
import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn;
Expand All @@ -11,11 +12,15 @@
@Table("url")
public class URL {
@PrimaryKeyColumn(name = "hash", type = PrimaryKeyType.PARTITIONED)
private final String hash;
@Id
private String hash;
@Column("original_url")
private final String originalURL;
private String originalURL;
@Column("creation_date")
private final LocalDateTime creationDate;
private LocalDateTime creationDate;

public URL() {
}

URL(ShortURL shortUrl) {
hash = shortUrl.getHash();
Expand Down
6 changes: 5 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ spring:
username: cassandra
password: cassandra
keyspace-name: tinyurl
schema-action: create_if_not_exists
schema-action: create_if_not_exists
contact-points: ["cassandra"]

server:
port: 8000
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.victuxbb.systemdesigns.tinyurlapi.domain.kgs.KGSRepository;
import com.victuxbb.systemdesigns.tinyurlapi.domain.kgs.URLKey;
import com.victuxbb.systemdesigns.tinyurlapi.infrastructure.bootstrap.TinyURLAPIApplication;
import com.victuxbb.systemdesigns.tinyurlapi.infrastructure.datasource.InMemoryKGSRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -32,7 +32,7 @@ public class TinyURLControllerTest {
private ObjectMapper objectMapper;

@SpyBean
private InMemoryKGSRepository kgsRepository;
private KGSRepository kgsRepository;

@Test
public void createTinyURL() throws JsonProcessingException {
Expand Down