У меня есть проект eclispe maven, основанный на сервисах Azure. Я хочу запустить его на клиентской машине из другой страны, поэтому у вас есть другой часовой пояс.
Когда я устанавливаю eclipse на свой компьютер и запускаю все службы, все работает нормально. Но когда я добавил войну в папку apache, после ее запуска она выдавала ошибку, например:
Make sure the value of Authorization header is formed correctly including the signature.
at com.microsoft.azure.storage.StorageException.translateException(StorageException.java:)
Я пришел к этой ссылке, и я думаю, что у меня такая же ошибка:
StorageException для azure blob с java
Скажите, пожалуйста, как решить эту проблему и как сделать тактику "медленной", как указано в ответе предоставленной ссылки.
Вот код: (См. Код в другом цикле от первого метода. Это код, связанный с blob.)
@Override
public JSONObject syncFiles(JSONObject jsonInput) throws InvalidKeyException, URISyntaxException {
if (jsonInput.containsKey("accountName")) {
CloudFileClient fileClient = null;
String storageConnectionString = "DefaultEndpointsProtocol=https;AccountName="
+ jsonInput.get("accountName") + ";" + "AccountKey=" + jsonInput.get("accountKey");
System.out.println(storageConnectionString);
CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);
JSONObject jsonOutput = new JSONObject();
ArrayList fileList = new ArrayList<>();
try {
// fileClient =
// FileClientProvider.getFileClientReference(jsonOutput);
fileClient = storageAccount.createCloudFileClient();
String directoryName = jsonInput.get("directoryStructure").toString();
String[] directoryNameArray = directoryName.split("\\s*/\\s*");
System.out.println(directoryNameArray.length);
CloudFileShare share = fileClient.getShareReference(directoryNameArray[0].toLowerCase()
.replaceAll("[-+.^:,!@#$%&*()_~']", "").replaceAll("\\s+", ""));
if (share.createIfNotExists()) {
System.out.println("New share created named as " + directoryNameArray[0].toLowerCase()
.replaceAll("[-+.^:,!@#$%&*()_~']", "").replaceAll("\\s+", ""));
}
CloudFileDirectory rootDir = share.getRootDirectoryReference();
for (int i = 0; i < directoryNameArray.length; i++) {
String directoryToCreate = directoryNameArray[i];
CloudFileDirectory directory = rootDir.getDirectoryReference(directoryToCreate);
String directoryNameToListFiles = directory.getName();
if (i == directoryNameArray.length - 1) {
for (ListFileItem fileItem : directory.listFilesAndDirectories()) {
boolean isDirectory;
if (isDirectory = fileItem.getClass() == CloudFileDirectory.class) {
System.out.println("Directory Exists Here");
} else {
System.out.println("Name with files :" + fileItem.getUri().toString());
String downloadLocation = "/home/zcon/AzureDownloadedFiles";
String fileName[] = fileItem.getUri().toString().split("\\s*/\\s*");
for (int j = 0; j < fileName.length; j++) {
if (j == fileName.length - 1) {
String fileNameWithExtension = fileName[j];
File f = new File(downloadLocation + "/" + fileNameWithExtension);
String DownloadTo = f.toString();
f.createNewFile();
CloudFile cloudFile = directory
.getFileReference(fileNameWithExtension.replaceAll("%20", " "));
System.out.println("fileName===========" + fileNameWithExtension);
String tokenKey = testFileSAS(share, cloudFile);
cloudFile.downloadToFile(DownloadTo);
fileList.add(fileItem.getUri().toString() + "?" + tokenKey);
f.delete();
}
}
}
}
}
rootDir = directory;
}
ArrayList fileNamesList = new ArrayList<>();
for (int i = 0; i < fileList.size(); i++) {
String fileName[] = fileList.get(i).toString().split("\\s*/\\s*");
for (int j = 0; j < fileName.length; j++) {
if (j == fileName.length - 1) {
String fileNameReturn = fileName[j];
String[] fileNameReturnArray = fileNameReturn.split("\\.");
fileNamesList.add(fileNameReturnArray[0].replace("%20", " "));
}
}
}
jsonOutput.put("fileNamesList", fileNamesList);
jsonOutput.put("fileList", fileList);
jsonOutput.put("status", "successful");
} catch (Exception e) {
System.out.println("Exception is " + e.toString());
jsonOutput.put("status", "unsuccessful");
jsonOutput.put("exception", e.toString());
e.printStackTrace();
}
return jsonOutput;
} else {
CloudBlobClient blobClient = null;
String storageConnectionString = "DefaultEndpointsProtocol=https;AccountName="
+ jsonInput.get("blobAccountName") + ";" + "AccountKey=" + jsonInput.get("blobAccountKey");
System.out.println(storageConnectionString);
CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);
JSONObject jsonOutput = new JSONObject();
ArrayList fileList = new ArrayList<>();
ArrayList fileNamesList = new ArrayList<>();
ArrayList blobItemList = new ArrayList<>();
try {
blobClient = storageAccount.createCloudBlobClient();
String directoryName = jsonInput.get("directoryStructure").toString();
String[] directoryNameArray = directoryName.split("\\s*/\\s*");
CloudBlobContainer container = blobClient.getContainerReference(directoryNameArray[0].toLowerCase()
.replaceAll("[-+.^:,!@#$%&*()_~']", "").replaceAll("\\s+", ""));
if (container.createIfNotExists()) {
System.out.println("New share created named as " + directoryNameArray[0].toLowerCase()
.replaceAll("[-+.^:,!@#$%&*()_~']", "").replaceAll("\\s+", ""));
}
// CloudBlockBlob blob =
// container.getBlockBlobReference(jsonInput.get("directoryStructure")+"/"+jsonInput.get("fileToCopy"));
CloudBlobDirectory directoryOfFile = container
.getDirectoryReference(jsonInput.get("directoryStructure").toString());
for (ListBlobItem blobItem : directoryOfFile.listBlobs()) {
// System.out.println(blobItem.getUri());
// fileList.add(blobItem.getUri());
blobItemList.add(blobItem);
}
for(int q= 0; q<blobItemList.size(); q++){
if(blobItemList.get(q).getClass()==CloudBlobDirectory.class)
{
blobItemList.remove(q);
}
}
System.out.println(blobItemList);
for (int l = 0; l < blobItemList.size(); l++) {
CloudBlob blob = (CloudBlob) blobItemList.get(l);
if (blob.getUri().toString().contains("Temp.txt")) {
System.out.println("Temp file was skipped");
} else {
String tokenKey = testBlobSaS(blob, container);
fileList.add(blob.getUri().toString() + "?" + tokenKey);
}
}
System.out.println("size of blobItemList is=============" + blobItemList.size());
for (int k = 0; k < fileList.size(); k++) {
String fileItem = fileList.get(k).toString();
String fileName[] = fileItem.split("\\s*/\\s*");
for (int j = 0; j < fileName.length; j++) {
if (j == fileName.length - 1) {
String fileNameWithExtension = fileName[j];
String[] parts = fileNameWithExtension.split("\\?");
System.out.println("fileName===========" + fileNameWithExtension);
fileNamesList.add(parts[0].replace("%20", " "));
}
}
}
jsonOutput.put("fileList", fileList);
jsonOutput.put("fileNamesList", fileNamesList);
jsonOutput.put("status", "successful");
System.out.println(fileList);
return jsonOutput;
} catch (Exception e) {
System.out.println("Exception is " + e.toString());
jsonOutput.put("status", "unsuccessful");
jsonOutput.put("exception", e.toString());
e.printStackTrace();
}
return jsonOutput;
}
}
Способ создания BlobSAS:
@Test
// @Category(SlowTests.class)
public String testBlobSaS(CloudBlob blob, CloudBlobContainer container) throws InvalidKeyException,
IllegalArgumentException, StorageException, URISyntaxException, InterruptedException {
SharedAccessBlobPolicy sp = createSharedAccessBlobPolicy(
EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.LIST), 100);
BlobContainerPermissions perms = new BlobContainerPermissions();
perms.getSharedAccessPolicies().put("readperm", sp);
container.uploadPermissions(perms);
// Thread.sleep(30000);
String sas = blob.generateSharedAccessSignature(sp, null);
CloudBlockBlob sasBlob = new CloudBlockBlob(
new URI(blob.getUri().toString() + "?" + blob.generateSharedAccessSignature(null, "readperm")));
sasBlob.download(new ByteArrayOutputStream());
// do not give the client and check that the new blob client has the
// correct perms
CloudBlob blobFromUri = new CloudBlockBlob(
PathUtility.addToQuery(blob.getStorageUri(), blob.generateSharedAccessSignature(null, "readperm")));
assertEquals(StorageCredentialsSharedAccessSignature.class.toString(),
blobFromUri.getServiceClient().getCredentials().getClass().toString());
// create credentials from sas
StorageCredentials creds = new StorageCredentialsSharedAccessSignature(
blob.generateSharedAccessSignature(null, "readperm"));
CloudBlobClient bClient = new CloudBlobClient(sasBlob.getServiceClient().getStorageUri(), creds);
CloudBlockBlob blobFromClient = bClient.getContainerReference(blob.getContainer().getName())
.getBlockBlobReference(blob.getName());
assertEquals(StorageCredentialsSharedAccessSignature.class.toString(),
blobFromClient.getServiceClient().getCredentials().getClass().toString());
assertEquals(bClient, blobFromClient.getServiceClient());
return sas;
}
Способ создания политики доступа общего доступа:
private final static SharedAccessBlobPolicy createSharedAccessBlobPolicy(EnumSet<SharedAccessBlobPermissions> sap,
int expireTimeInSeconds) {
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
cal.setTime(new Date());
cal.add(Calendar.YEAR, expireTimeInSeconds);
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
policy.setPermissions(sap);
policy.setSharedAccessExpiryTime(cal.getTime());
return policy;
}
Какие изменения я должен сделать здесь?
Раньше я сталкивался с подобной проблемой. Что вам нужно сделать, сделайте свой код удобным для всех часовых поясов, таких как GMT, IST, EST и т.д. Потому что, когда вы загружаете войну на сервере другой страны, ваш код должен быть "умным", чтобы понять часовой пояс этой страны !
Итак, вот что вы можете сделать:
Шаг 1:
В третьей части кода попробуйте заменить "UTC" на часовой пояс вашего клиентского компьютера, например GMT, EST и т.д.
Если это работает (и я уверен, что он будет работать нормально), идите
Шаг 2:
Прежде всего, мы будем кодировать что-то, что дает вам текущий часовой пояс в String, например, "Indian Standard Time" или "European Standard Time" и т.д.
Затем мы выберем только первые буквы из всех слов и создадим строку типа "IST" или "EST".
Наконец, мы передадим эту строку в месте, где вы написали "UTC" в третьей части вашего кода.
Итак, вот код:
private final static SharedAccessBlobPolicy createSharedAccessBlobPolicy(EnumSet<SharedAccessBlobPermissions> sap,
int expireTimeInSeconds) {
Calendar now = Calendar.getInstance();
TimeZone timeZone = now.getTimeZone();
System.out.println("Current TimeZone is : " + timeZone.getDisplayName());
String x = timeZone.getDisplayName();
String[] myName = x.split(" ");
String s = "";
ArrayList zoneArray = new ArrayList<>();
char zone = 0;
for (int i = 0; i < myName.length; i++) {
s = myName[i];
System.out.print(s.charAt(0));
zone = s.charAt(0);
zoneArray.add(zone);
}
String timeZoneCurrent = s;
String timeZoneDynamic = zoneArray.toString().replace(",", "").replace(" ", "").replace("[", "").replace("]",
"");
System.out.println("Value of S==========" + timeZoneDynamic);
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone(timeZoneDynamic));
cal.setTime(new Date());
cal.add(Calendar.YEAR, expireTimeInSeconds);
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
policy.setPermissions(sap);
policy.setSharedAccessExpiryTime(cal.getTime());
return policy;
}
В этом случае timeZoneDynamic имеет такие значения, как "IST", "GMT" и т.д. Эта логика должна работать. Если есть какие-либо ошибки, опубликуйте его в редакции. Надеюсь, что это сработает.
По моему опыту, проблема была вызвана неправильным кодом в методе private final static SharedAccessBlobPolicy createSharedAccessBlobPolicy
чтобы получить время UTC через Calendar
.
В качестве ссылки, вот мой пример кода, чтобы получить время UTC с помощью Calendar
.
Calendar cal = Calendar.getInstance() ;
// Get the time zone offset
int zoneOffset = cal.get(Calendar.ZONE_OFFSET);
// Get the daylight-saving time offset
int dstOffset = cal.get(Calendar.DST_OFFSET);
// Reduce these offsets above from local time to get UTC time
cal.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
System.out.println(cal.getTime());
Затем, чтобы добавить время истечения времени, чтобы получить окончательное время.
Без кода трудно сказать, однако есть вероятность, что время на клиенте или на сервере не находится в utc или неправильно преобразовано.
Проверьте время и время работы аппарата. Если они совпадают, проверьте свой код, если используется время utc или местное время.