@Override public void load() { Registration.register( new URIPattern("hbase::zk"), new URIPattern("hbase::zk/:dataset?namespace=default"), new OptionBuilder<DatasetRepository>() { @Override public DatasetRepository getFromOptions(Map<String, String> options) { Configuration conf = HBaseConfiguration.create(DefaultConfiguration.get()); String[] hostsAndPort = parseHostsAndPort(options.get("zk")); conf.set(HConstants.ZOOKEEPER_QUORUM, hostsAndPort[0]); String port = hostsAndPort[1]; if (port != null) { conf.set(HConstants.ZOOKEEPER_CLIENT_PORT, port); } return new HBaseDatasetRepository.Builder().configuration(conf).build(); } }); }
/** * Returns a dataset or view URI encompassing the given constraints. The * referenced {@link Dataset} or {@link View} may be loaded again with * {@link Datasets#load(URI, Class)}. * * @return a dataset or view URI * * @since 0.17.0 */ public URI build() { try { return new URI((isView ? VIEW_SCHEME : DATASET_SCHEME) + ":" + pattern.construct(options).toString()); } catch (URISyntaxException e) { throw new IllegalArgumentException("Could not build URI", e); } } }
/** * Returns true if the {@link java.net.URI} matches this pattern. * * If successful, the variable values are available by calling * {@link #getLastMatch()} (not thread safe). * * @param uri a String to check against this pattern. * @return true if the String matches this pattern */ public boolean matches(URI uri) { return (getMatch(uri) != null); }
public URIPattern(URI uri) { this.pattern = uri; Map<String, String> accumulator = Maps.newHashMap(); if (pattern.isOpaque()) { Iterator<String> pathQuery = PATH_QUERY_SPLITTER .split(pattern.getSchemeSpecificPart()).iterator(); this.patternPath = Iterators.getNext(pathQuery, null); addQuery(Iterators.getNext(pathQuery, null), accumulator); } else { patternPath = pattern.getRawPath(); addQuery(pattern.getRawQuery(), accumulator); addAuthority(pattern, accumulator); } if (pattern.getScheme() != null) { accumulator.put(SCHEME, pattern.getScheme()); } this.defaults = ImmutableMap.copyOf(accumulator); }
@Test public void testSubURI() throws URISyntaxException { URIPattern pattern = new URIPattern("scheme:*sub-uri"); String uri = "scheme:other-scheme:/path/to/data.avro"; Assert.assertTrue(pattern.matches(uri)); Map<String, String> actual = pattern.getMatch(uri); expected.put("uri:scheme", "scheme"); expected.put("sub-uri", "other-scheme:/path/to/data.avro"); Assert.assertEquals(expected, actual); URI constructed = pattern.construct(expected); Assert.assertEquals(URI.create(uri), constructed); }
@Test public void testOpaqueQueryEncoding() throws URISyntaxException { URIPattern pattern = new URIPattern("file:path"); URI original = URI.create("file:path?f1=a,b,a%2Cb"); Map<String, String> match = pattern.getMatch(original); Assert.assertNotNull(match); Assert.assertEquals("a,b,a%2Cb", match.get("f1")); URI constructed = pattern.construct(match); Assert.assertEquals(original, constructed); }
@Test public void testNonAbsoluteExactMatch() throws URISyntaxException { URIPattern pattern = new URIPattern("hive"); String uri = "hive"; Assert.assertTrue(pattern.matches(uri)); }
@Test public void testConstructMissingOptions() throws URISyntaxException { final URIPattern pattern = new URIPattern("scheme:/*path/:name"); TestHelpers.assertThrows("Should reject missing name", IllegalArgumentException.class, new Runnable() { @Override public void run() { Map<String, String> options = Maps.newHashMap(); options.put("path", "a/b/c"); pattern.construct(options); } }); // globs are optional Map<String, String> options = Maps.newHashMap(); options.put("name", "table-name"); URI constructed = pattern.construct(options); Assert.assertEquals(URI.create("scheme:/table-name"), constructed); }
@Test public void testEmptyGlobs() throws URISyntaxException { URIPattern pattern = new URIPattern("file:/a/*path"); Map<String, String> match = pattern.getMatch("file:/a"); Assert.assertNotNull(match); Assert.assertNull(match.get("path")); match = pattern.getMatch("file:/a/"); Assert.assertNotNull(match); Assert.assertEquals("", match.get("path")); match = pattern.getMatch("file:/a//"); Assert.assertNotNull(match); Assert.assertEquals("/", match.get("path")); pattern = new URIPattern("file:/a/*path/:dataset"); match = pattern.getMatch("file:/a//dataset"); Assert.assertNotNull(match); Assert.assertEquals("", match.get("path")); match = pattern.getMatch("file:/a/dataset"); Assert.assertNotNull(match); Assert.assertNull(match.get("path")); pattern = new URIPattern("file:/*path"); match = pattern.getMatch("file:/"); Assert.assertNotNull(match); Assert.assertNull(match.get("path")); }
.split(uri.getRawSchemeSpecificPart()).iterator(); if (!addPath(patternPath, Iterators.getNext(pathQuery, null), result)) { return null; addQuery(Iterators.getNext(pathQuery, null), result); addAuthority(uri, result); if (!addPath(patternPath, uri.getRawPath(), result)) { return null; addQuery(uri.getRawQuery(), result); if (!addComplexMatch(pattern.getFragment(), uri.getFragment(), result)) { return null;
public static Pair<DatasetRepository, Map<String, String>> lookupDatasetUri(URI datasetUri) { String scheme = datasetUri.getScheme(); List<String> schemeMatches = Lists.newArrayList(); for (URIPattern pattern : DATASET_PATTERNS.keySet()) { Map<String, String> match = pattern.getMatch(datasetUri); if (match != null) { return Pair.of(DATASET_PATTERNS.get(pattern).getFromOptions(match), match); } else if (pattern.getScheme() != null && pattern.getScheme().equals(scheme)) { schemeMatches.add(pattern.getPatternString()); } } String message = "Unknown dataset URI pattern: dataset:" + datasetUri; if (schemeMatches.isEmpty()) { // no known patterns for the scheme, maybe jars are missing message += "\nCheck that JARs for " + scheme + " datasets are on the classpath"; } else { // show the known patterns in case it's a simple error message += "\nKnown patterns for " + scheme + ":\n dataset:" + Joiner.on("\n dataset:").join(schemeMatches); } throw new DatasetNotFoundException(message); }
/** * Returns true if the {@link java.net.URI} String matches this pattern. * * If successful, the variable values are available by calling * {@link #getLastMatch()} (not thread safe). * * @param uri a String to check against this pattern. * @return true if the String matches this pattern * @throws URISyntaxException if the String is not a valid URI */ public boolean matches(String uri) throws URISyntaxException { return matches(new URI(uri)); }
!addComplexMatch(patternPart, parts.removeFirst(), storage)) { !addComplexMatch(patternPart, parts.removeLast(), storage)) {
@Test public void testPathGlob() throws URISyntaxException { URIPattern pattern = new URIPattern("file:///*path"); String uri = "file:/path/to/data.avro"; Assert.assertTrue(pattern.matches(uri)); Map<String, String> actual = pattern.getMatch(uri); expected.put("uri:scheme", "file"); expected.put("path", "path/to/data.avro"); Assert.assertEquals(expected, actual); URI constructed = pattern.construct(expected); Assert.assertEquals(URI.create(uri), constructed); }
@Test public void testPathEncoding() throws URISyntaxException { URIPattern pattern = new URIPattern("file:/*path"); URI original = URI.create("file:/a%2Fb/c"); Map<String, String> match = pattern.getMatch(original); Assert.assertNotNull(match); Assert.assertEquals("a%2Fb/c", match.get("path")); URI constructed = pattern.construct(match); Assert.assertEquals(original, constructed); }
@Test public void testNotEnoughPathComponents() throws URISyntaxException { URIPattern pattern = new URIPattern("scheme:*path/:ns/:name"); Assert.assertFalse(pattern.matches("scheme://host:3434/dataset")); }
@Test public void testStaticMatch() throws URISyntaxException { URIPattern pattern = new URIPattern("scheme:static"); String uri = "scheme:static"; Assert.assertTrue(pattern.matches(uri)); Map<String, String> actual = pattern.getMatch(uri); expected.put("uri:scheme", "scheme"); Assert.assertEquals(expected, actual); URI constructed = pattern.construct(expected); Assert.assertEquals(URI.create(uri), constructed); }
@Test public void testOpaquePathEncoding() throws URISyntaxException { URIPattern pattern = new URIPattern("file:*path"); URI original = URI.create("file:a%2Fb/c"); Map<String, String> match = pattern.getMatch(original); Assert.assertNotNull(match); Assert.assertEquals("a%2Fb/c", match.get("path")); URI constructed = pattern.construct(match); Assert.assertEquals(original, constructed); }
@Override public void load() { Registration.register( new URIPattern("hbase::zk"), new URIPattern("hbase::zk/:dataset?namespace=default"), new OptionBuilder<DatasetRepository>() { @Override public DatasetRepository getFromOptions(Map<String, String> options) { Configuration conf = HBaseConfiguration.create(DefaultConfiguration.get()); String[] hostsAndPort = parseHostsAndPort(options.get("zk")); conf.set(HConstants.ZOOKEEPER_QUORUM, hostsAndPort[0]); String port = hostsAndPort[1]; if (port != null) { conf.set(HConstants.ZOOKEEPER_CLIENT_PORT, port); } return new HBaseDatasetRepository.Builder().configuration(conf).build(); } }); }
/** * Returns results from parsing a {@link java.net.URI} with this pattern. * If the URI doesn't match the pattern, this will return null. * * @param uri A URI to match against this URIPattern * @return A Map of the pattern's variable names to values from the parsed URI * @throws URISyntaxException if the String is not a valid URI */ public Map<String, String> getMatch(String uri) throws URISyntaxException { return getMatch(new URI(uri)); }