blob: e09e7998ae32b91477d93886ed1f69247bfcab72 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jackrabbit.oak.segment.azure.util;
import static org.apache.jackrabbit.oak.segment.azure.util.AzureConfigurationParserUtils.AzureConnectionKey.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
/**
* Utility class for parsing Oak Segment Azure configuration (e.g. connection
* string, container name, uri, etc.) from custom encoded String or Azure
* standard URI.
*/
public class AzureConfigurationParserUtils {
public enum AzureConnectionKey {
DEFAULT_ENDPOINTS_PROTOCOL("DefaultEndpointsProtocol"),
ACCOUNT_NAME("AccountName"),
ACCOUNT_KEY("AccountKey"),
BLOB_ENDPOINT("BlobEndpoint"),
CONTAINER_NAME("ContainerName"),
DIRECTORY("Directory");
private String text;
AzureConnectionKey(String text) {
this.text = text;
}
public String text() {
return text;
}
}
public static final String KEY_CONNECTION_STRING = "connectionString";
public static final String KEY_CONTAINER_NAME = "containerName";
public static final String KEY_ACCOUNT_NAME = "accountName";
public static final String KEY_STORAGE_URI = "storageUri";
public static final String KEY_DIR = "directory";
private AzureConfigurationParserUtils() {
// prevent instantiation
}
/**
*
* @param conn
* the connection string
* @return <code>true</code> if this is a custom encoded Azure connection
* String, <code>false</code> otherwise
*/
public static boolean isCustomAzureConnectionString(String conn) {
return conn.contains(DEFAULT_ENDPOINTS_PROTOCOL.text());
}
/**
* Parses a custom encoded connection string of the form (line breaks added for
* clarity):
* <br><br>
* <b>DefaultEndpointsProtocol</b>=http;<b>AccountName</b>=devstoreaccount1;
* <b>AccountKey</b>=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;
* <b>BlobEndpoint</b>=http://127.0.0.1:10000/devstoreaccount1;<br>
* <b>ContainerName</b>=mycontainer;<br>
* <b>Directory</b>=mydir
* <br><br>
* where the first three lines in the string represent a standard Azure
* Connection String and the last two lines are Oak Segment Azure specific
* arguments. Please note that all configuration keys are semicolon separated, except for the last entry. The order
* of keys is not important.
*
* @param conn
* the connection string
* @return parsed configuration map containing the Azure <b>connectionString</b>,
* <b>containerName</b> and <b>dir</b> (key names in bold)
*/
public static Map<String, String> parseAzureConfigurationFromCustomConnection(String conn) {
Map<AzureConnectionKey, String> tempConfig = new HashMap<>();
String[] connKeys = conn.split(";");
for (AzureConnectionKey key : AzureConnectionKey.values()) {
for (String connKey : connKeys) {
if (connKey.toLowerCase().startsWith(key.text().toLowerCase())) {
tempConfig.put(key, connKey.substring(connKey.indexOf("=") + 1));
}
}
}
StringBuilder connectionString = new StringBuilder();
connectionString.append(DEFAULT_ENDPOINTS_PROTOCOL.text()).append("=").append(tempConfig.get(DEFAULT_ENDPOINTS_PROTOCOL)).append(";");
connectionString.append(ACCOUNT_NAME.text()).append("=").append(tempConfig.get(ACCOUNT_NAME)).append(";");
connectionString.append(ACCOUNT_KEY.text()).append("=").append(tempConfig.get(ACCOUNT_KEY)).append(";");
connectionString.append(BLOB_ENDPOINT.text()).append("=").append(tempConfig.get(BLOB_ENDPOINT)).append(";");
Map<String, String> config = new HashMap<>();
config.put(KEY_CONNECTION_STRING, connectionString.toString());
config.put(KEY_CONTAINER_NAME, tempConfig.get(CONTAINER_NAME));
config.put(KEY_DIR, tempConfig.get(DIRECTORY));
return config;
}
/**
* Parses a standard Azure URI in the format
* <b>https</b>://<b>myaccount</b>.blob.core.windows.net/<b>container</b>/<b>repo</b>,
*
* @param uriStr
* the Azure URI as string
* @return parsed configuration map containing <b>accountName</b>, <b>storageUri</b> and <b>dir</b>
* (key names in bold)
*/
public static Map<String, String> parseAzureConfigurationFromUri(String uriStr) {
Map<String, String> config = new HashMap<>();
URI uri = null;
try {
uri = new URI(uriStr);
} catch (URISyntaxException e) {
throw new IllegalStateException(e);
}
String host = uri.getHost();
String path = uri.getPath();
String scheme = uri.getScheme();
int lastSlashPosPath = path.lastIndexOf('/');
int dotPosHost = host.indexOf(".");
String accountName = host.substring(0, dotPosHost);
String container = path.substring(0, lastSlashPosPath);
String storageUri = scheme + "://" + host + container;
String dir = path.substring(lastSlashPosPath + 1);
config.put(KEY_ACCOUNT_NAME, accountName);
config.put(KEY_STORAGE_URI, storageUri);
config.put(KEY_DIR, dir);
return config;
}
}