Skip to content
Merged
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
11 changes: 11 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.799</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.4.0-b180830.0359</version>
</dependency>

</dependencies>


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.justinefactory.cloud.communication.access;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.justinefactory.sending.exceptions.AwsSecurityCredentialsException;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

import static com.justinefactory.util.PathToResources.getPathToResource;

public class AwsSecurityCredentials {

private final String ACCESS_KEY_ID;
private final String SECRET_ACCESS_KEY;


public AwsSecurityCredentials() throws AwsSecurityCredentialsException {
List<String> securityInfo = getAccessKeys();
ACCESS_KEY_ID = securityInfo.get(0);
SECRET_ACCESS_KEY = securityInfo.get(1);
}


public AWSCredentials getCredentials() {
return new BasicAWSCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY);
}


private List<String> getAccessKeys() throws AwsSecurityCredentialsException {
try {
Path path = getPathToResource("AwsRootKey.csv");
return Files.readAllLines(path);
} catch (Throwable e) {
throw new AwsSecurityCredentialsException(e, "Trouble while acquiring security credentials.");
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.justinefactory.cloud.communication.clients;

import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.internal.S3DirectSpi;
import com.justinefactory.cloud.communication.access.AwsSecurityCredentials;

public interface AwsClient {

S3DirectSpi buildClient(Regions region, AwsSecurityCredentials awsSecurityCredentials);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.justinefactory.cloud.communication.clients;

import com.amazonaws.AmazonClientException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.justinefactory.cloud.communication.access.AwsSecurityCredentials;

public class AwsS3Client implements AwsClient {

@Override
public AmazonS3 buildClient(Regions region, AwsSecurityCredentials awsSecurityCredentials) {
try {
return AmazonS3ClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(awsSecurityCredentials.getCredentials()))
.withRegion(region)
.build();
} catch (Throwable e) {
throw new AmazonClientException("Trouble while building an AWSS3 client.", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.justinefactory.cloud.communication.distribution;

import com.amazonaws.HttpMethod;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.justinefactory.domain.AwsInfo;

import java.util.Date;
import java.time.Instant;

public class PresignedUrlRequest {

public GeneratePresignedUrlRequest generateRequest(AwsInfo info, Instant expiration) {
Date expirationDate = Date.from(expiration);
return new GeneratePresignedUrlRequest(info.getBucketName(), info.getKeyName())
.withMethod(HttpMethod.GET)
.withExpiration(expirationDate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.justinefactory.cloud.communication.distribution;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.AmazonS3;
import com.justinefactory.domain.AwsInfo;
import com.justinefactory.util.TimeCalculator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.net.URL;
import java.time.Duration;
import java.time.Instant;

public class ServerObjectDownloadByUrlCreator {

private final TimeCalculator timeCalculator;
private final PresignedUrlRequest urlRequest;
private final Logger logger = LogManager.getLogger(this.getClass());

public ServerObjectDownloadByUrlCreator(TimeCalculator timeCalculator, PresignedUrlRequest urlRequest) {
this.timeCalculator = timeCalculator;
this.urlRequest = urlRequest;

}


public URL createAccessWithPresignedUrl(AmazonS3 client, AwsInfo info, Duration duration) {
try {
Instant expiration = timeCalculator.calculateExpirationTime(Instant.now(), duration);
URL url = client.generatePresignedUrl(urlRequest.generateRequest(info, expiration));
logger.debug("Creating URL {} to the object {} - success", url, info.getURI());
return url;
} catch (AmazonServiceException e) {
logger.warn("Trouble while creating URL to the object {} due to an error in the request.", info.getURI(), e);
throw new AmazonServiceException("Trouble while creating URL to the object " + info.getURI() + " due to an error in the request.", e);
} catch (SdkClientException e) {
logger.warn("Trouble while creating URL to the object {} due to an error in service connection.", info.getURI(), e);
throw new SdkClientException("Trouble while creating URL to the object " + info.getURI() + " due to an error in service connection.", e);
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.justinefactory.cloud.communication.distribution.service;

import com.amazonaws.services.s3.AmazonS3;
import com.justinefactory.cloud.communication.distribution.ServerObjectDownloadByUrlCreator;
import com.justinefactory.domain.AwsInfo;
import com.justinefactory.reading.exceptions.ContentReadingException;
import com.justinefactory.sending.service.ContentSendingService;
import com.justinefactory.stats.exceptions.StatsCalculatingException;
import com.justinefactory.writing.domain.ContentStorage;
import com.justinefactory.writing.exceptions.ContentWritingException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.lang.invoke.MethodHandles;
import java.time.Duration;

public class CloudObjectsManagementService<RawContent, Content> {

private final ContentSendingService<RawContent, Content, ContentStorage<String>> sendingService;
private final ServerObjectDownloadByUrlCreator urlCreator;
private static final Logger logger = LogManager.getLogger(MethodHandles.lookup().lookupClass());

public CloudObjectsManagementService(ContentSendingService<RawContent, Content, ContentStorage<String>> sendingService, ServerObjectDownloadByUrlCreator urlCreator) {
logger.debug("Creating, sending and management of server objects - initialization");
this.sendingService = sendingService;
this.urlCreator = urlCreator;
}

public void manageContent(AmazonS3 client, AwsInfo info, Duration duration) throws ContentWritingException, StatsCalculatingException, ContentReadingException {
sendingService.sendContent();
urlCreator.createAccessWithPresignedUrl(client, info, duration);
logger.debug("Creating, sending and management of server objects - success");
}
}
40 changes: 40 additions & 0 deletions src/main/java/com/justinefactory/domain/AwsInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.justinefactory.domain;

import java.net.URI;
import java.util.UUID;

public class AwsInfo implements WritingInfo {

private final URI uri;
private final UUID id;
private final String bucketName;
private final String keyName;


public AwsInfo(String bucketName, String keyName) {
this.bucketName = bucketName;
this.keyName = keyName;
uri = URI.create("s3://" + this.bucketName + "/" + this.keyName);
id = UUID.randomUUID();
}


@Override
public URI getURI() {
return uri;
}

@Override
public UUID getId() {
return id;
}

public String getBucketName() {
return bucketName;
}

public String getKeyName() {
return keyName;
}

}
29 changes: 0 additions & 29 deletions src/main/java/com/justinefactory/domain/PathData.java

This file was deleted.

39 changes: 39 additions & 0 deletions src/main/java/com/justinefactory/domain/PathInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.justinefactory.domain;

import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

public class PathInfo implements WritingInfo {

private final Path path;
private final URI uri;
private final UUID id;

public PathInfo(Path filePath) {
path = filePath;
uri = path.toUri();
id = UUID.randomUUID();
}

public PathInfo(URI u) {
uri = u;
path = Paths.get(uri);
id = UUID.randomUUID();
}

@Override
public URI getURI() {
return uri;
}

@Override
public UUID getId() {
return id;
}

public Path getPath() {
return path;
}
}
12 changes: 12 additions & 0 deletions src/main/java/com/justinefactory/domain/WritingInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.justinefactory.domain;

import java.net.URI;
import java.util.UUID;

public interface WritingInfo {

URI getURI();

UUID getId();

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.justinefactory.reading.readers;

import com.justinefactory.domain.PathData;
import com.justinefactory.domain.PathInfo;
import com.justinefactory.reading.exceptions.ContentReadingException;
import com.justinefactory.reading.exceptions.ReadingContentFromFileException;
import com.justinefactory.reading.exceptions.SourceFileIsEmptyException;
Expand All @@ -12,36 +12,38 @@
import java.io.Reader;
import java.lang.invoke.MethodHandles;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static com.justinefactory.util.FileNotEmptyAndExistChecker.checkIfFileExistsIsNotDirAndNotEmpty;

class CsvContentReader implements ContentReader<String[]> {

private final PathData fileData;
private final PathInfo fileData;
private final Logger logger = LogManager.getLogger(MethodHandles.lookup().lookupClass());

CsvContentReader(PathData fd) {
CsvContentReader(PathInfo fd) {
fileData = fd;
}


@Override
public ContentStorage<String[]> readContent() throws ContentReadingException {
logger.debug("Reading data from file id {}", fileData.getFileId());
if (!checkIfFileExistsIsNotDirAndNotEmpty(fileData.getFilePath())) {
logger.warn("Reading data from file id {} failed. File does not exist or is empty.", fileData.getFileId());
throw new SourceFileIsEmptyException("Reading data from file id " + fileData.getFileId() + " - failed. File does not exist or is empty.");
logger.debug("Reading data from file id {}", fileData.getId());
if (!checkIfFileExistsIsNotDirAndNotEmpty(fileData.getPath())) {
logger.warn("Reading data from file id {} failed. File does not exist or is empty.", fileData.getId());
throw new SourceFileIsEmptyException("Reading data from file id " + fileData.getId() + " - failed. File does not exist or is empty.");
}

try (Reader reader = Files.newBufferedReader(fileData.getFilePath());
try (Reader reader = Files.newBufferedReader(fileData.getPath());
CSVReader csvReader = new CSVReader(reader)
) {
ContentStorage<String[]> rawContent = new ContentStorage<>(csvReader.readAll());
logger.debug("Reading data from file id {} - success.", fileData.getFileId());
logger.debug("Reading data from file id {} - success.", fileData.getId());
return rawContent;
} catch (Throwable e) {
logger.warn("Reading data from file id {} failed.", fileData.getFileId(), e);
throw new ReadingContentFromFileException(e, "Reading data from file id " + fileData.getFileId() + " - failed.");
logger.warn("Reading data from file id {} failed.", fileData.getId(), e);
throw new ReadingContentFromFileException(e, "Reading data from file id " + fileData.getId() + " - failed.");
}
}
}
Expand Down
Loading