Skip to content

Commit fbc0bcf

Browse files
committed
Refactoring
1 parent fa2df34 commit fbc0bcf

13 files changed

Lines changed: 362 additions & 289 deletions

src/constants.hpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
Copyright (c) 2016 Snowplow Analytics Ltd. All rights reserved.
3+
4+
This program is licensed to you under the Apache License Version 2.0,
5+
and you may not use this file except in compliance with the Apache License Version 2.0.
6+
You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
8+
Unless required by applicable law or agreed to in writing,
9+
software distributed under the Apache License Version 2.0 is distributed on an
10+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
14+
#ifndef CONSTANTS_H
15+
#define CONSTANTS_H
16+
17+
#include <string>
18+
19+
using namespace std;
20+
21+
const string TRACKER_VERSION_LABEL = "cpp-0.1.0";
22+
23+
// post requests
24+
const string POST_PROTOCOL_VENDOR = "com.snowplowanalytics.snowplow";
25+
const string POST_PROTOCOL_VERSION = "tp2";
26+
const string POST_CONTENT_TYPE = "application/json; charset=utf-8";
27+
28+
// get requests
29+
const string GET_PROTOCOL_PATH = "i";
30+
31+
// schema versions
32+
const string SCHEMA_PAYLOAD_DATA = "iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-4";
33+
const string SCHEMA_CONTEXTS = "iglu:com.snowplowanalytics.snowplow/contexts/jsonschema/1-0-1";
34+
const string SCHEMA_UNSTRUCT_EVENT = "iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0";
35+
const string SCHEMA_SCREEN_VIEW = "iglu:com.snowplowanalytics.snowplow/screen_view/jsonschema/1-0-0";
36+
const string SCHEMA_USER_TIMINGS = "iglu:com.snowplowanalytics.snowplow/timing/jsonschema/1-0-0";
37+
38+
// event types
39+
const string EVENT_STRUCTURED = "se";
40+
const string EVENT_UNSTRUCTURED = "ue";
41+
42+
const string CONTEXT = "co";
43+
const string CONTEXT_ENCODED = "cx";
44+
const string UNSTRUCTURED = "ue_pr";
45+
const string UNSTRUCTURED_ENCODED = "ue_px";
46+
47+
// general
48+
const string SCHEMA = "schema";
49+
const string DATA = "data";
50+
const string EVENT = "e";
51+
const string EID = "eid";
52+
const string TIMESTAMP = "dtm";
53+
const string SENT_TIMESTAMP = "stm";
54+
const string TRUE_TIMESTAMP = "ttm";
55+
const string TRACKER_VERSION = "tv";
56+
const string APP_ID = "aid";
57+
const string SP_NAMESPACE = "tna";
58+
const string PLATFORM = "p";
59+
60+
// subject class
61+
const string UID = "uid";
62+
const string RESOLUTION = "res";
63+
const string VIEWPORT = "vp";
64+
const string COLOR_DEPTH = "cd";
65+
const string TIMEZONE = "tz";
66+
const string LANGUAGE = "lang";
67+
68+
// structured event
69+
const string SE_CATEGORY = "se_ca";
70+
const string SE_ACTION = "se_ac";
71+
const string SE_LABEL = "se_la";
72+
const string SE_PROPERTY = "se_pr";
73+
const string SE_VALUE = "se_va";
74+
75+
// screen view
76+
const string SV_ID = "id";
77+
const string SV_NAME = "name";
78+
79+
// user timing
80+
const string UT_CATEGORY = "category";
81+
const string UT_VARIABLE = "variable";
82+
const string UT_TIMING = "timing";
83+
const string UT_LABEL = "label";
84+
85+
#endif

src/cracked_url.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
Copyright (c) 2016 Snowplow Analytics Ltd. All rights reserved.
3+
4+
This program is licensed to you under the Apache License Version 2.0,
5+
and you may not use this file except in compliance with the Apache License Version 2.0.
6+
You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
8+
Unless required by applicable law or agreed to in writing,
9+
software distributed under the Apache License Version 2.0 is distributed on an
10+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
14+
#include "cracked_url.hpp"
15+
16+
CrackedUrl::CrackedUrl(const string & url) {
17+
string cleaned_url = url;
18+
if (regex_match(cleaned_url, regex("^https?://.+")) == false) {
19+
cleaned_url = string("http://") + url;
20+
}
21+
22+
regex r_host("(https?)://([^\\s]+\\.[^\\s/]+)(/.*)?");
23+
regex r_hostname_port("([^:]+):(\\d+)");
24+
smatch match;
25+
26+
if (regex_search(cleaned_url, match, r_host)) {
27+
string protocol = match.str(1);
28+
string hostname_port = match.str(2);
29+
this->path = match.str(3);
30+
31+
smatch host_match;
32+
if (regex_search(hostname_port, host_match, r_hostname_port)) {
33+
this->hostname = host_match.str(1);
34+
string port = host_match.str(2);
35+
this->port = stoi(port);
36+
this->use_default_port = false;
37+
}
38+
else {
39+
this->hostname = hostname_port; // it's just a hostname
40+
this->port = 0;
41+
this->use_default_port = true;
42+
}
43+
44+
this->is_https = protocol == "https";
45+
this->error_code = 0;
46+
this->is_valid = true;
47+
}
48+
else {
49+
this->error_code = -1;
50+
this->is_valid = false;
51+
}
52+
}
53+
54+
string CrackedUrl::get_hostname() {
55+
return this->hostname;
56+
}
57+
58+
string CrackedUrl::get_path() {
59+
return this->path;
60+
}
61+
62+
bool CrackedUrl::get_is_https() {
63+
return this->is_https;
64+
}
65+
66+
bool CrackedUrl::get_is_valid() {
67+
return this->is_valid;
68+
}
69+
70+
int CrackedUrl::get_error_code() {
71+
return this->error_code;
72+
}
73+
74+
unsigned int CrackedUrl::get_port() {
75+
return this->port;
76+
}
77+
78+
bool CrackedUrl::get_use_default_port() {
79+
return this->use_default_port;
80+
}
81+
82+
string CrackedUrl::to_string() {
83+
stringstream s;
84+
85+
if (this->get_is_https()) {
86+
s << "https://";
87+
} else {
88+
s << "http://";
89+
}
90+
91+
s << this->get_hostname();
92+
93+
if (!this->get_use_default_port()) {
94+
s << ":" << std::to_string(this->get_port());
95+
}
96+
97+
s << this->get_path();
98+
99+
return s.str();
100+
}

src/cracked_url.hpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
Copyright (c) 2016 Snowplow Analytics Ltd. All rights reserved.
3+
4+
This program is licensed to you under the Apache License Version 2.0,
5+
and you may not use this file except in compliance with the Apache License Version 2.0.
6+
You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
8+
Unless required by applicable law or agreed to in writing,
9+
software distributed under the Apache License Version 2.0 is distributed on an
10+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
14+
#ifndef CRACKED_URL_H
15+
#define CRACKED_URL_H
16+
17+
#include <string>
18+
#include <sstream>
19+
#include <regex>
20+
21+
using namespace std;
22+
23+
class CrackedUrl {
24+
public:
25+
CrackedUrl(const string & url);
26+
string get_hostname();
27+
string get_path();
28+
bool get_is_https();
29+
bool get_is_valid();
30+
int get_error_code();
31+
unsigned int get_port();
32+
bool get_use_default_port();
33+
string to_string();
34+
35+
private:
36+
string hostname;
37+
string path;
38+
bool is_https;
39+
bool is_valid;
40+
int error_code;
41+
unsigned int port;
42+
bool use_default_port;
43+
};
44+
45+
#endif

src/emitter.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,25 @@ See the Apache License Version 2.0 for the specific language governing permissio
1313

1414
#include "emitter.hpp"
1515

16-
const int post_wrapper_bytes = 88; // "schema":"iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-3","data":[]
16+
const int post_wrapper_bytes = 88; // "schema":"iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-4","data":[]
1717
const int post_stm_bytes = 22; // "stm":"1443452851000"
1818

19-
Emitter::Emitter(const string & uri, Strategy strategy, Method method, Protocol protocol, int send_limit, const string & db_name) : m_db(db_name) {
19+
Emitter::Emitter(const string & uri, Strategy strategy, Method method, Protocol protocol, int send_limit,
20+
int byte_limit_post, int byte_limit_get, const string & db_name) : m_db(db_name), m_url(this->get_collector_url(uri, protocol, method)) {
2021

2122
if (uri == "") {
2223
throw invalid_argument("FATAL: Emitter URI cannot be empty.");
2324
}
2425

25-
this->m_uri = uri;
26+
if (!url.get_is_valid()) {
27+
throw invalid_argument("FATAL: Emitter URL is not valid - " + url.to_string());
28+
}
29+
2630
this->m_strategy = strategy;
2731
this->m_method = method;
28-
this->m_protocol = protocol;
2932
this->m_send_limit = send_limit;
30-
31-
this->m_byte_limit_post = 52000;
32-
this->m_byte_limit_get = 52000;
33-
34-
this->m_url = this->get_collector_url();
33+
this->m_byte_limit_post = byte_limit_post;
34+
this->m_byte_limit_get = byte_limit_get;
3535
}
3636

3737
Emitter::~Emitter() {
@@ -129,11 +129,11 @@ void Emitter::do_send(list<Storage::EventRow>* event_rows, list<HttpRequestResul
129129
if (this->m_method == GET) {
130130
for (list<Storage::EventRow>::iterator it = event_rows->begin(); it != event_rows->end(); ++it) {
131131
Payload event_payload = it->event;
132-
event_payload.add("stm", std::to_string(Utils::get_unix_epoch_ms()));
133-
string final_url = this->m_url + "?" + Utils::map_to_query_string(event_payload.get());
132+
event_payload.add(SENT_TIMESTAMP, std::to_string(Utils::get_unix_epoch_ms()));
133+
string query_string = Utils::map_to_query_string(event_payload.get());
134134
list<int> row_id = {it->id};
135135

136-
request_futures.push_back(std::async(HttpClient::http_get, final_url, row_id, (final_url.size() > this->m_byte_limit_get)));
136+
request_futures.push_back(std::async(HttpClient::http_get, this->m_url, query_string, row_id, (query_string.size() > this->m_byte_limit_get)));
137137
}
138138
} else {
139139
list<int> row_ids;
@@ -188,19 +188,19 @@ string Emitter::build_post_data_json(list<Payload> payload_list) {
188188
// Add 'stm' to each payload
189189
string stm = std::to_string(Utils::get_unix_epoch_ms());
190190
for (list<Payload>::iterator it = payload_list.begin(); it != payload_list.end(); ++it) {
191-
it->add("stm", stm);
191+
it->add(SENT_TIMESTAMP, stm);
192192
data_array.push_back(it->get());
193193
}
194194

195195
// Build Post event
196-
SelfDescribingJson post_envelope("iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-4", data_array);
196+
SelfDescribingJson post_envelope(SCHEMA_PAYLOAD_DATA, data_array);
197197
return post_envelope.to_string();
198198
}
199199

200-
string Emitter::get_collector_url() {
200+
string Emitter::get_collector_url(const string & uri, Protocol protocol, Method method) {
201201
stringstream url;
202-
url << (this->m_protocol == HTTP ? "http" : "https") << "://" << this->m_uri;
203-
url << (this->m_method == GET ? "/i" : "/com.snowplowanalytics.snowplow/tp2");
202+
url << (protocol == HTTP ? "http" : "https") << "://" << uri;
203+
url << "/" << (method == GET ? GET_PROTOCOL_PATH : POST_PROTOCOL_VENDOR + "/" + POST_PROTOCOL_VERSION);
204204
return url.str();
205205
}
206206

src/emitter.hpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ See the Apache License Version 2.0 for the specific language governing permissio
1919
#include <condition_variable>
2020
#include <future>
2121
#include <thread>
22+
#include "constants.hpp"
2223
#include "utils.hpp"
2324
#include "storage.hpp"
2425
#include "payload.hpp"
2526
#include "self_describing_json.hpp"
2627
#include "http_client.hpp"
2728
#include "http_request_result.hpp"
29+
#include "cracked_url.hpp"
2830

2931
using namespace std;
3032

@@ -45,19 +47,18 @@ class Emitter {
4547
HTTPS
4648
};
4749

48-
Emitter(const string & uri, Strategy strategy, Method method, Protocol protocol, int send_limit, const string & db_name);
50+
Emitter(const string & uri, Strategy strategy, Method method, Protocol protocol, int send_limit,
51+
int byte_limit_post, int byte_limit_get, const string & db_name);
4952
~Emitter();
5053
void start();
5154
void stop();
5255
void add(Payload payload);
5356
void flush();
5457

5558
private:
56-
string m_uri;
57-
string m_url;
59+
CrackedUrl m_url;
5860
Strategy m_strategy;
5961
Method m_method;
60-
Protocol m_protocol;
6162
int m_send_limit;
6263
int m_byte_limit_get;
6364
int m_byte_limit_post;
@@ -73,7 +74,7 @@ class Emitter {
7374
void run();
7475
void do_send(list<Storage::EventRow>* event_rows, list<HttpRequestResult>* results);
7576
string build_post_data_json(list<Payload> payload_list);
76-
string get_collector_url();
77+
string get_collector_url(const string & uri, Protocol protocol, Method method);
7778
bool is_running();
7879
};
7980

0 commit comments

Comments
 (0)