Skip to content

Commit 59c6e7c

Browse files
authored
Merge pull request #22 from rok4/develop
Release 1.1.2
2 parents 6bc5466 + 04688ae commit 59c6e7c

19 files changed

+223
-49
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
build
2-
dist
2+
dist
3+
.vscode

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## 1.1.2
2+
3+
### [Changed]
4+
5+
* Le test d'existence d'un objet ou d'un fichier n'est plus une lecture de 1 octet mais une implémentation spécifique à chaque type
6+
* Les TMS et les styles sont cherchés sur le stockage avec et sans extension JSON
7+
8+
### [Fixed]
9+
10+
* Table
11+
* Correction d'une typo dans l'écriture du metadata.json : filedsCount -> fieldsCount
12+
* Style
13+
* La valeur de nodata en sortie d'un style est la première valeur de la palette (et non la couleur pour la valeur 0)
14+
115
## 1.1.1
216

317
### [Fixed]

include/rok4/storage/Context.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,9 @@ class Context {
170170
* \~french \brief Précise si l'objet demandé existe dans ce contexte
171171
* \param[in] name Nom de l'objet dont on veut savoir l'existence
172172
* \~english \brief Precise if provided object exists in this context
173-
* \param[in] name Object's name whose existency is asked
173+
* \param[in] name Object's name whose existence is asked
174174
*/
175-
bool exists(std::string name) {
176-
uint8_t test;
177-
return (read(&test, 0, 1, name) == 1);
178-
}
175+
virtual bool exists(std::string name) = 0;
179176

180177
/**
181178
* \~french \brief Précise si le contexte est connecté

include/rok4/style/Style.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ private :
285285
*/
286286
int getNodata (int** nodata) {
287287
if (palette && palette->getColoursMap() && ! palette->getColoursMap()->empty()) {
288-
Colour c = palette->getColour(0);
288+
Colour c = palette->getColoursMap()->begin()->second;
289289
if (palette->isNoAlpha()) {
290290
(*nodata) = new int[3];
291291
(*nodata)[0] = c.r;

include/rok4/utils/Cache.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ class TmsBook {
727727
d = directory;
728728
}
729729

730-
std::string tms_path = d + "/" + id + ".json";
730+
std::string tms_path = d + "/" + id;
731731

732732
TileMatrixSet* tms = new TileMatrixSet(tms_path);
733733
if ( ! tms->isOk() ) {
@@ -894,7 +894,7 @@ class StyleBook {
894894
d = directory;
895895
}
896896

897-
std::string style_path = d + "/" + id + ".json";
897+
std::string style_path = d + "/" + id;
898898

899899
Style* style = new Style(style_path, inspire);
900900
if ( ! style->isOk() ) {

include/rok4/utils/Configuration.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,11 @@ class Configuration
110110

111111
std::string id;
112112

113-
unsigned int idBegin=file.rfind ( "/" );
113+
size_t idBegin=file.rfind ( "/" );
114114
if ( idBegin == std::string::npos ) {
115115
idBegin=0;
116116
}
117-
unsigned int idEnd=file.rfind ( extension );
117+
size_t idEnd=file.rfind ( extension );
118118
if ( idEnd == std::string::npos ) {
119119
idEnd=file.size();
120120
}

include/rok4/utils/Table.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class Table
7979
res << ",\"geometry\":\"" << geometry << "\"";
8080
res << ",\"maxzoom\":\"" << max << "\"";
8181
res << ",\"minzoom\":\"" << min << "\"";
82-
res << ",\"filedsCount\":\"" << attributes.size() << "\"";
82+
res << ",\"fieldsCount\":\"" << attributes.size() << "\"";
8383
res << ",\"fields\":{";
8484
for (int i = 0; i < attributes.size(); i++) {
8585
if (i != 0) {

src/storage/Context.cpp

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -80,39 +80,31 @@ eContextType fromString ( std::string strct ) {
8080

8181
void split_path(std::string path, ContextType::eContextType& type, std::string& fo, std::string& tray) {
8282

83-
std::stringstream ss(path);
84-
std::string token;
85-
char delim = ':';
86-
std::getline(ss, token, delim);
87-
std::string storage_type = token;
88-
89-
90-
if (storage_type != path) {
91-
// Un type de stockage a été précisé, on l'enlève pour passer à la suite
83+
size_t pos = path.find ( "://" );
84+
if ( pos == std::string::npos ) {
85+
// Il n'y a pas de préfixe de stockage, on considère le mode fichier
86+
type = ContextType::FILECONTEXT;
87+
} else {
88+
std::string storage_type = path.substr ( 0, pos );
9289
type = ContextType::fromString(storage_type);
9390
if (type == ContextType::UNKNOWN) {
9491
type = ContextType::FILECONTEXT;
9592
}
96-
path.erase(0, storage_type.length() + 3);
97-
} else {
98-
type = ContextType::FILECONTEXT;
93+
path = path.erase ( 0, storage_type.length() + 3);
9994
}
10095

101-
10296
if (type == ContextType::FILECONTEXT) {
10397
// Dans le cas d'un stockage fichier, le nom du fichier est l'ensemble et on ne définit pas de contenant
10498
fo = path;
99+
tray = "";
105100
return;
106101
}
107102

108103
// Dans le cas d'un stockage objet, on sépare le contenant du nom de l'objet
109-
ss = std::stringstream(path);
110-
delim = '/';
111-
std::getline(ss, token, delim);
112-
tray = token;
104+
pos = path.find ( "/" );
105+
tray = path.substr ( 0, pos );
106+
fo = path.substr ( pos + 1, std::string::npos );
113107

114-
path.erase(0, tray.length() + 1);
115-
fo = path;
116108
return;
117109
}
118110

src/storage/FileContext.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,8 @@ std::string FileContext::getPath(std::string name) {
200200
return root_dir + name;
201201
}
202202

203+
bool FileContext::exists(std::string name) {
204+
BOOST_LOG_TRIVIAL(debug) << "Exists (FILE) ? " << getPath(name);
205+
struct stat buffer;
206+
return (stat (getPath(name).c_str(), &buffer) == 0);
207+
}

src/storage/FileContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ class FileContext : public Context {
150150

151151
bool connection();
152152

153+
bool exists(std::string name);
154+
153155
void closeConnection() {
154156
connected = false;
155157
}

src/storage/S3Context.cpp

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,6 @@ bool S3Context::openToWrite(std::string name) {
438438

439439
bool S3Context::closeToWrite(std::string name) {
440440

441-
442441
std::map<std::string, std::vector<char>*>::iterator it1 = writingBuffers.find ( name );
443442
if ( it1 == writingBuffers.end() ) {
444443
BOOST_LOG_TRIVIAL(error) << "The S3 writing buffer with name " << name << "does not exist, cannot flush it";
@@ -528,4 +527,78 @@ bool S3Context::closeToWrite(std::string name) {
528527
writingBuffers.erase(it1);
529528

530529
return true;
530+
}
531+
532+
bool S3Context::exists(std::string name) {
533+
534+
BOOST_LOG_TRIVIAL(debug) << "Exists (S3) ? " << getPath(name);
535+
536+
CURLcode res;
537+
struct curl_slist *list = NULL;
538+
539+
CURL* curl = CurlPool::getCurlEnv();
540+
541+
std::string fullUrl = url + "/" + bucket_name + "/" + name;
542+
543+
time_t current;
544+
545+
time(&current);
546+
struct tm * ptm = gmtime ( &current );
547+
548+
static char gmt_time[40];
549+
sprintf(
550+
gmt_time, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT",
551+
wday_name[ptm->tm_wday], ptm->tm_mday, mon_name[ptm->tm_mon], 1900 + ptm->tm_year,
552+
ptm->tm_hour, ptm->tm_min, ptm->tm_sec
553+
);
554+
555+
std::string content_type = "application/octet-stream";
556+
std::string resource = "/" + bucket_name + "/" + name;
557+
std::string stringToSign = "HEAD\n\n" + content_type + "\n" + std::string(gmt_time) + "\n" + resource;
558+
std::string signature = getAuthorizationHeader(stringToSign);
559+
560+
// Constitution du header
561+
562+
char hd_host[256];
563+
sprintf(hd_host, "Host: %s", host.c_str());
564+
list = curl_slist_append(list, hd_host);
565+
566+
char d[100];
567+
sprintf(d, "Date: %s", gmt_time);
568+
list = curl_slist_append(list, d);
569+
570+
char ct[50];
571+
sprintf(ct, "Content-Type: %s", content_type.c_str());
572+
list = curl_slist_append(list, ct);
573+
574+
char auth[512];
575+
sprintf(auth, "Authorization: AWS %s:%s", key.c_str(), signature.c_str());
576+
577+
list = curl_slist_append(list, auth);
578+
579+
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
580+
curl_easy_setopt(curl, CURLOPT_URL, fullUrl.c_str());
581+
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "HEAD");
582+
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
583+
if(ssl_no_verify){
584+
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
585+
}
586+
587+
res = curl_easy_perform(curl);
588+
589+
curl_slist_free_all(list);
590+
591+
if( CURLE_OK != res) {
592+
BOOST_LOG_TRIVIAL(error) << "Cannot test object existence from S3 : " << bucket_name + "/" + name;
593+
BOOST_LOG_TRIVIAL(error) << curl_easy_strerror(res);
594+
return false;
595+
}
596+
597+
long http_code = 0;
598+
curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code);
599+
if (http_code >= 200 && http_code <= 299) {
600+
return true;
601+
} else {
602+
return false;
603+
}
531604
}

src/storage/S3Context.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ class S3Context : public Context {
185185
* \~english \brief Get public URL #public_url and constitute the HTTP header #authHdr
186186
*/
187187
bool connection();
188+
189+
bool exists(std::string name);
188190

189191
void closeConnection() {
190192
connected = false;

src/storage/SwiftContext.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,3 +617,49 @@ std::string SwiftContext::getPath(std::string racine,int x,int y,int pathDepth){
617617
std::string SwiftContext::getPath(std::string name) {
618618
return container_name + "/" + name;
619619
}
620+
621+
622+
bool SwiftContext::exists(std::string name) {
623+
624+
BOOST_LOG_TRIVIAL(debug) << "Exists (SWIFT) ? " << getPath(name);
625+
626+
if (! connected) {
627+
BOOST_LOG_TRIVIAL(error) << "Try to test object existence using the unconnected swift context " << container_name;
628+
return false;
629+
}
630+
631+
CURLcode res;
632+
struct curl_slist *list = NULL;
633+
CURL* curl = CurlPool::getCurlEnv();
634+
635+
std::string fullUrl;
636+
fullUrl = public_url + "/" + container_name + "/" + name;
637+
638+
list = curl_slist_append(list, token.c_str());
639+
640+
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
641+
curl_easy_setopt(curl, CURLOPT_URL, fullUrl.c_str());
642+
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "HEAD");
643+
if(ssl_no_verify){
644+
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
645+
}
646+
647+
res = curl_easy_perform(curl);
648+
649+
curl_slist_free_all(list);
650+
651+
if( CURLE_OK != res) {
652+
BOOST_LOG_TRIVIAL(error) << "Cannot test object existence from SWIFT : " << container_name + "/" + name;
653+
BOOST_LOG_TRIVIAL(error) << curl_easy_strerror(res);
654+
return false;
655+
}
656+
657+
long http_code = 0;
658+
curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code);
659+
if (http_code >= 200 && http_code <= 299) {
660+
return true;
661+
} else {
662+
return false;
663+
}
664+
665+
}

src/storage/SwiftContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ class SwiftContext : public Context{
244244
*/
245245
bool connection();
246246

247+
bool exists(std::string name);
248+
247249
/**
248250
* \~french \brief Returne le jeton d'authentification #token
249251
* \~english \brief Returns authentification token #token

src/storage/ceph/CephPoolContext.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,4 +329,23 @@ std::string CephPoolContext::getPath(std::string racine,int x,int y,int pathDept
329329

330330
std::string CephPoolContext::getPath(std::string name) {
331331
return pool_name + "/" + name;
332+
}
333+
334+
bool CephPoolContext::exists(std::string name) {
335+
336+
BOOST_LOG_TRIVIAL(debug) << "Exists (CEPH) ? " << getPath(name);
337+
338+
if (! connected) {
339+
BOOST_LOG_TRIVIAL(error) << "Try to test object existence using the unconnected ceph pool context " << pool_name;
340+
return false;
341+
}
342+
343+
uint64_t fullSize;
344+
time_t time;
345+
int ret = rados_stat(io_ctx, name.c_str(), &fullSize, &time);
346+
if (ret < 0) {
347+
return false;
348+
} else {
349+
return true;
350+
}
332351
}

src/storage/ceph/CephPoolContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ class CephPoolContext : public Context {
139139
*/
140140
bool connection();
141141

142+
bool exists(std::string name);
143+
142144
/**
143145
* \~french \brief Nettoie les objets librados
144146
* \~english \brief Clean librados objects

src/style/Palette.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,3 +318,4 @@ Colour Palette::getColour ( double index ) {
318318
return tmp;
319319
}
320320

321+

0 commit comments

Comments
 (0)