Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create S3 grib file's index in local cache #1215

Merged
merged 3 commits into from
Jul 14, 2023
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
163 changes: 163 additions & 0 deletions cdm-test/src/test/java/ucar/nc2/grib/TestGribIndexLocation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package ucar.nc2.grib;

import static com.google.common.truth.Truth.assertThat;

import java.io.File;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import thredds.filesystem.MFileOS;
import thredds.inventory.CollectionUpdateType;
import thredds.inventory.MFile;
import ucar.nc2.util.DiskCache2;

@RunWith(Parameterized.class)
public class TestGribIndexLocation {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private static final String DATA_DIR = "../grib/src/test/data/";
private static final String INDEX_DIR = "../grib/src/test/data/index/";

@Parameterized.Parameters(name = "{0}")
public static List<Object[]> getTestParameters() {
return Arrays.asList(new Object[][] {

{"radar_national.grib1"},

{"cosmo-eu.grib2"},

});
}

private final String filename;
private final String indexFilename;
private final boolean isGrib1;

public TestGribIndexLocation(String filename) {
this.filename = filename;
this.indexFilename = filename + GribIndex.GBX9_IDX;
this.isGrib1 = filename.endsWith(".grib1");
}

@Rule
public final TemporaryFolder tempCacheFolder = new TemporaryFolder();

@Rule
public final TemporaryFolder tempFolder = new TemporaryFolder();

@Before
public void setCacheLocation() {
System.getProperties().setProperty("nj22.cache", tempCacheFolder.getRoot().getPath());
}

@After
public void unsetCacheLocation() {
System.clearProperty("nj22.cache");
}

@Test
public void shouldCreateIndexInLocationOfDataFile() throws IOException {
useCache(false);

final MFile copiedFile = new MFileOS(copyToTempFolder(DATA_DIR + filename).getPath());

final GribIndex index =
GribIndex.readOrCreateIndexFromSingleFile(isGrib1, copiedFile, CollectionUpdateType.always, logger);
assertThat(index).isNotNull();
assertThat(index.getNRecords()).isNotEqualTo(0);

assertTempFolderHasSize(2);
assertTempFolderHas(copiedFile.getName() + GribIndex.GBX9_IDX);
}

@Test
public void shouldUseIndexInLocationOfDataFile() throws IOException {
useCache(false);

final MFile copiedFile = new MFileOS(copyToTempFolder(DATA_DIR + filename).getPath());
final File copiedIndexFile = copyToTempFolder(INDEX_DIR + indexFilename);
assertThat(copiedIndexFile.setLastModified(0)).isTrue();

final GribIndex index =
GribIndex.readOrCreateIndexFromSingleFile(isGrib1, copiedFile, CollectionUpdateType.nocheck, logger);
assertThat(index).isNotNull();
assertThat(index.getNRecords()).isNotEqualTo(0);

assertTempFolderHasSize(2);
assertTempFolderHas(copiedFile.getName() + GribIndex.GBX9_IDX);
assertThat(copiedIndexFile.lastModified()).isEqualTo(0);
}

@Test
public void shouldCreateIndexInDefaultCache() throws IOException {
final DiskCache2 diskCache = useCache(true);

final MFile copiedFile = new MFileOS(copyToTempFolder(DATA_DIR + filename).getPath());

final GribIndex index =
GribIndex.readOrCreateIndexFromSingleFile(isGrib1, copiedFile, CollectionUpdateType.always, logger);
assertThat(index).isNotNull();
assertThat(index.getNRecords()).isNotEqualTo(0);

assertTempFolderHasSize(1);
assertThat(diskCache.getCacheFile(copiedFile.getPath() + GribIndex.GBX9_IDX).exists()).isTrue();
}

@Test
public void shouldReuseCachedIndex() throws IOException {
final DiskCache2 diskCache = useCache(true);

final MFile copiedFile = new MFileOS(copyToTempFolder(DATA_DIR + filename).getPath());

final GribIndex index =
GribIndex.readOrCreateIndexFromSingleFile(isGrib1, copiedFile, CollectionUpdateType.always, logger);
assertThat(index).isNotNull();
assertThat(diskCache.getCacheFile(copiedFile.getPath() + GribIndex.GBX9_IDX).exists()).isTrue();
final long cacheLastModified = diskCache.getCacheFile(copiedFile.getPath() + GribIndex.GBX9_IDX).lastModified();

final GribIndex rereadIndex =
GribIndex.readOrCreateIndexFromSingleFile(isGrib1, copiedFile, CollectionUpdateType.never, logger);
assertThat(rereadIndex).isNotNull();
final File rereadCachedIndex = diskCache.getCacheFile(copiedFile.getPath() + GribIndex.GBX9_IDX);
assertThat(rereadCachedIndex.lastModified()).isEqualTo(cacheLastModified);
}

// Helper functions
static DiskCache2 useCache(boolean useCache) {
final DiskCache2 diskCache = GribIndexCache.getDiskCache2();
diskCache.setNeverUseCache(!useCache);
diskCache.setAlwaysUseCache(useCache);
return diskCache;
}

private File copyToTempFolder(String filename) throws IOException {
final File file = new File(filename);
final File copiedFile = new File(tempFolder.getRoot(), file.getName());
Files.copy(file.toPath(), copiedFile.toPath());
assertTempFolderHas(copiedFile.getName());
return copiedFile;
}

private void assertTempFolderHas(String filename) {
final File[] filesInFolder = tempFolder.getRoot().listFiles();
assertThat(filesInFolder).isNotNull();
assertThat(Arrays.stream(filesInFolder).anyMatch(file -> file.getName().equals(filename))).isTrue();
}

private void assertTempFolderHasSize(int size) {
final File[] filesInFolder = tempFolder.getRoot().listFiles();
assertThat(filesInFolder).isNotNull();
assertThat(filesInFolder.length).isEqualTo(size);
}
}
110 changes: 110 additions & 0 deletions cdm-test/src/test/java/ucar/nc2/grib/TestGribIndexLocationS3.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package ucar.nc2.grib;

import static com.google.common.truth.Truth.assertThat;
import static ucar.nc2.grib.TestGribIndexLocation.useCache;

import java.io.File;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import thredds.inventory.CollectionUpdateType;
import thredds.inventory.MFile;
import thredds.inventory.s3.MFileS3;
import ucar.nc2.util.DiskCache2;

@RunWith(Parameterized.class)
public class TestGribIndexLocationS3 {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private static final String BUCKET = "cdms3:thredds-test-data";
private static final String S3_DIR_WITHOUT_INDEX = BUCKET + "?" + "test-grib-without-index/";
private static final String FRAGMENT = "#delimiter=/";

@Parameterized.Parameters(name = "{0}")
public static List<Object[]> getTestParameters() {
return Arrays.asList(new Object[][] {

{"radar_national.grib1", ""},

{"radar_national.grib1", FRAGMENT},

{"cosmo-eu.grib2", ""},

{"cosmo-eu.grib2", FRAGMENT},

});
}

private final String filename;
private final String indexFilename;
private final boolean isGrib1;

public TestGribIndexLocationS3(String filename, String fragment) {
this.filename = filename + fragment;
this.indexFilename = filename + GribIndex.GBX9_IDX;
this.isGrib1 = filename.endsWith(".grib1");
}

@Rule
public final TemporaryFolder tempCacheFolder = new TemporaryFolder();

@Rule
public final TemporaryFolder tempFolder = new TemporaryFolder();

@Before
public void setCacheLocation() {
System.getProperties().setProperty("nj22.cache", tempCacheFolder.getRoot().getPath());
}

@After
public void unsetCacheLocation() {
System.clearProperty("nj22.cache");
}

@Test
public void shouldCreateIndexInDefaultCache() throws IOException {
final DiskCache2 diskCache = useCache(true);

// Check that index file does not exist
final MFile s3FileIndex = new MFileS3(S3_DIR_WITHOUT_INDEX + indexFilename);
assertThat(s3FileIndex.exists()).isFalse();

final MFile s3File = new MFileS3(S3_DIR_WITHOUT_INDEX + filename);

final GribIndex index =
GribIndex.readOrCreateIndexFromSingleFile(isGrib1, s3File, CollectionUpdateType.always, logger);
assertThat(index).isNotNull();
assertThat(index.getNRecords()).isNotEqualTo(0);

assertThat(diskCache.getCacheFile(s3File.getPath() + GribIndex.GBX9_IDX).exists()).isTrue();
}

@Test
public void shouldReuseCachedIndex() throws IOException {
final DiskCache2 diskCache = useCache(true);

final MFile s3File = new MFileS3(S3_DIR_WITHOUT_INDEX + filename);

final GribIndex index =
GribIndex.readOrCreateIndexFromSingleFile(isGrib1, s3File, CollectionUpdateType.always, logger);
assertThat(index).isNotNull();
assertThat(diskCache.getCacheFile(s3File.getPath() + GribIndex.GBX9_IDX).exists()).isTrue();
final long cacheLastModified = diskCache.getCacheFile(s3File.getPath() + GribIndex.GBX9_IDX).lastModified();

final GribIndex rereadIndex =
GribIndex.readOrCreateIndexFromSingleFile(isGrib1, s3File, CollectionUpdateType.never, logger);
assertThat(rereadIndex).isNotNull();
final File rereadCachedIndex = diskCache.getCacheFile(s3File.getPath() + GribIndex.GBX9_IDX);
assertThat(rereadCachedIndex.lastModified()).isEqualTo(cacheLastModified);
}
}
3 changes: 2 additions & 1 deletion grib/src/main/java/ucar/nc2/grib/grib1/Grib1Index.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.google.protobuf.ByteString;
import java.nio.charset.StandardCharsets;
import thredds.inventory.CollectionUpdateType;
import ucar.nc2.NetcdfFiles;
import ucar.nc2.grib.GribIndex;
import ucar.nc2.grib.GribIndexCache;
import ucar.nc2.stream.NcStream;
Expand Down Expand Up @@ -185,7 +186,7 @@ public boolean makeIndex(String filename, RandomAccessFile dataRaf) throws IOExc
rootBuilder.setFilename(filename);

if (dataRaf == null) { // open if dataRaf not already open
raf = RandomAccessFile.acquire(filename);
raf = NetcdfFiles.getRaf(filename, -1);
dataRaf = raf;
}

Expand Down
3 changes: 2 additions & 1 deletion grib/src/main/java/ucar/nc2/grib/grib2/Grib2Index.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.google.protobuf.ByteString;
import java.nio.charset.StandardCharsets;
import thredds.inventory.CollectionUpdateType;
import ucar.nc2.NetcdfFiles;
import ucar.nc2.grib.GribIndex;
import ucar.nc2.grib.GribIndexCache;
import ucar.nc2.stream.NcStream;
Expand Down Expand Up @@ -221,7 +222,7 @@ public boolean makeIndex(String filename, RandomAccessFile dataRaf) throws IOExc
rootBuilder.setFilename(filename);

if (dataRaf == null) {
raf = RandomAccessFile.acquire(filename);
raf = NetcdfFiles.getRaf(filename, -1);
dataRaf = raf;
}

Expand Down
Binary file added grib/src/test/data/index/cosmo-eu.grib2.gbx9
Binary file not shown.
Binary file added grib/src/test/data/index/radar_national.grib1.gbx9
Binary file not shown.