Skip to content

Commit

Permalink
[SHIBUI-1253]
Browse files Browse the repository at this point in the history
use file writing service for metadata providers
refactor tests
  • Loading branch information
jj committed May 23, 2019
1 parent 115c53e commit c1a55bf
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public EntityDescriptorFilesScheduledTasks entityDescriptorFilesScheduledTasks(E
@Bean
@ConditionalOnProperty(name = "shibui.metadataProviders.target")
public MetadataProvidersScheduledTasks metadataProvidersScheduledTasks(@Value("${shibui.metadataProviders.target}") final Resource resource, final MetadataResolverService metadataResolverService) {
return new MetadataProvidersScheduledTasks(resource, metadataResolverService);
return new MetadataProvidersScheduledTasks(resource, metadataResolverService, fileWritingService());
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package edu.internet2.tier.shibboleth.admin.ui.scheduled;

import edu.internet2.tier.shibboleth.admin.ui.service.FileWritingService;
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -26,10 +27,12 @@ public class MetadataProvidersScheduledTasks {

private final Resource target;
private final MetadataResolverService metadataResolverService;
private final FileWritingService fileWritingService;

public MetadataProvidersScheduledTasks(Resource target, MetadataResolverService metadataResolverService) {
public MetadataProvidersScheduledTasks(Resource target, MetadataResolverService metadataResolverService, FileWritingService fileWritingService) {
this.target = target;
this.metadataResolverService = metadataResolverService;
this.fileWritingService = fileWritingService;
}

@Scheduled(fixedRateString = "${shibui.metadataProviders.taskRunRate:30000}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package edu.internet2.tier.shibboleth.admin.ui.service;

import org.springframework.core.io.WritableResource;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.DigestInputStream;
Expand All @@ -24,28 +27,49 @@ public FileCheckingFileWritingService(String algorithm) {
@Override
public void write(Path path, String content) throws IOException {
if (Files.exists(path)) {
try {
MessageDigest md = MessageDigest.getInstance(this.algorithm);
try (
InputStream is = Files.newInputStream(path);
DigestInputStream dis = new DigestInputStream(is, md)
) {
byte[] buf = new byte[4096];
while (dis.read(buf) > -1){}
try (InputStream is = Files.newInputStream(path)) {
if (checkContentMatches(is, content)) {
return;
}
byte[] fileDigest = md.digest();
byte[] contentDigest = md.digest(content.getBytes());
if (Arrays.equals(fileDigest, contentDigest)) {
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
writeContent(path, content);
}

@Override
public void write(WritableResource resource, String content) throws IOException {
if (resource.exists()) {
try (InputStream is = resource.getInputStream()) {
if (checkContentMatches(is, content)) {
return;
}
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
writeContent(path, content.getBytes());
writeContent(resource, content);
}

private boolean checkContentMatches(InputStream inputStream, String content) throws NoSuchAlgorithmException, IOException {
MessageDigest md = MessageDigest.getInstance(this.algorithm);
try (DigestInputStream dis = new DigestInputStream(inputStream, md)) {
byte[] buf = new byte[4096];
while (dis.read(buf) > -1) {}
}
byte[] fileDigest = md.digest();
byte[] contentDigest = md.digest(content.getBytes());
return Arrays.equals(fileDigest, contentDigest);
}

void writeContent(Path path, byte[] bytes) throws IOException {
Files.write(path, bytes);
void writeContent(Path path, String content) throws IOException {
Files.write(path, content.getBytes());
}

void writeContent(WritableResource resource, String content) throws IOException {
try (OutputStream os = resource.getOutputStream()) {
os.write(content.getBytes());
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package edu.internet2.tier.shibboleth.admin.ui.service;

import org.springframework.core.io.WritableResource;

import java.io.IOException;
import java.nio.file.Path;

Expand All @@ -9,11 +11,20 @@
*/
public interface FileWritingService {
/**
* write the file
* Write content to a file
*
* @param path target file Path
* @param content content to write
* @throws IOException
*/
void write(Path path, String content) throws IOException;

/**
* Write content to a writeable resource
*
* @param resource
* @param content
* @throws IOException
*/
void write(WritableResource resource, String content) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
package edu.internet2.tier.shibboleth.admin.ui.service

import org.springframework.core.io.PathResource
import org.springframework.core.io.WritableResource
import spock.lang.Specification

import java.nio.file.Files
import java.nio.file.Path
import java.security.NoSuchAlgorithmException

class FileCheckingFileWritingServiceTests extends Specification {
def writer = Spy(FileCheckingFileWritingService)

def file1 = Files.createTempFile('test1', '.txt')
def file2 = Files.createTempFile('test2', '.txt')
Path file

def "test bad algorithm"() {
WritableResource resource

def setup() {
file = Files.createTempFile('test1', '.txt')
resource = new PathResource(file)
}

def 'test bad algorithm'() {
setup:
def badWriter = new FileCheckingFileWritingService('badAlGoreRhythm')

Expand All @@ -23,31 +32,65 @@ class FileCheckingFileWritingServiceTests extends Specification {
assert ex.cause instanceof NoSuchAlgorithmException
}

def "test a single write"() {
def 'test a single write to a Path'() {
when:
writer.write(file, 'testme')

then:
1 * writer.writeContent(file, 'testme')
assert file.text == 'testme'
}

def 'test writes with changed content to a Path'() {
when:
writer.write(file, 'testme')
writer.write(file, 'anothertest')

then:
1 * writer.writeContent(file, 'testme')
1 * writer.writeContent(file, 'anothertest')
assert file.text == 'anothertest'
}

def 'test writes with unchanged content, should only write once to a Path'() {
when:
(1..5).each {
writer.write(file, 'testme2')
}

then:
1 * writer.writeContent(file, 'testme2')
assert file.text == 'testme2'
}

def 'test a single write to a WriteableResource'() {
when:
writer.write(file1, 'testme')
writer.write(resource, 'testme')

then:
1 * writer.writeContent(file1, 'testme'.bytes)
1 * writer.writeContent(resource, 'testme')
assert resource.getFile().text == 'testme'
}

def "test writes with changed content"() {
def 'test write with changed content to a WritableResource'() {
when:
writer.write(file2, 'testme')
writer.write(file2, 'anothertest')
writer.write(resource, 'testme')
writer.write(resource, 'anothertest')

then:
1 * writer.writeContent(file2, 'testme'.bytes)
1 * writer.writeContent(file2, 'anothertest'.bytes)
1 * writer.writeContent(resource, 'testme')
1 * writer.writeContent(resource, 'anothertest')
assert resource.getFile().text == 'anothertest'
}

def "test writes with unchanged content, should only write once"() {
def 'test writes with unchanged content, should only write once to a WriteableResource'() {
when:
(1..5).each {
writer.write(file1, 'testme')
writer.write(resource, 'testme2')
}

then:
1 * writer.writeContent(file1, 'testme'.bytes)
1 * writer.writeContent(resource, 'testme2')
assert resource.getFile().text == 'testme2'
}
}

0 comments on commit c1a55bf

Please sign in to comment.