Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Peer Review #13

Open
wants to merge 79 commits into
base: review
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
2a976f6
fixed README
Jan 15, 2019
705b342
Merge pull request #1 from jillianKhoo/readme
jillianKhoo Jan 15, 2019
f26ed86
added backend key value store stubs and got it to compile
Jan 17, 2019
29c24a2
added a map to backendStore
Jan 17, 2019
caccaed
removed generated files
Jan 18, 2019
ed2a14f
added a gitignore
Jan 18, 2019
9c126ee
fixed a line of the gitignore, made structural changes for the KeyVal…
Jan 18, 2019
ab509da
naming fixes
Jan 19, 2019
df67474
comment fixes
Jan 20, 2019
ad67fdf
Merge pull request #2 from jillianKhoo/initial-stubs
jillianKhoo Jan 21, 2019
b0d3d3a
added proto file for service layer
Jan 22, 2019
b8f3f98
added empty file structure
Jan 22, 2019
4696641
stubs for service layer
Jan 23, 2019
71d0205
assorted PR fixes
Jan 23, 2019
bd9d1a3
service header file fixes
Jan 23, 2019
31ea4b8
Merge pull request #3 from jillianKhoo/service-stubs
jillianKhoo Jan 23, 2019
ba9a677
put code and a test
Jan 24, 2019
ef7a259
mini PR fixes
Jan 24, 2019
c609200
fixed gitignore
Jan 24, 2019
55b931b
sample commit
Jan 24, 2019
ee0c29f
added locks to put implementation
Jan 24, 2019
f31815c
pr fix
Jan 24, 2019
56a6469
one last catch:
Jan 24, 2019
fff2ddf
refactored to have data structure behind the service
Jan 24, 2019
cba612c
added ServiceLayer class
Jan 24, 2019
23c8815
pr fixes
Jan 24, 2019
ddd105f
PR fixes
Jan 24, 2019
0d82308
missed something
Jan 24, 2019
43755ec
Merge pull request #5 from jillianKhoo/service-layer-data-structure
jillianKhoo Jan 24, 2019
a181e77
Merge branch 'master' into backend-store-put
jillianKhoo Jan 24, 2019
2961008
added TODO to test
Jan 24, 2019
280b9dd
Merge branch 'backend-store-put' of https://github.com/jillianKhoo/49…
Jan 24, 2019
6f62ded
Merge pull request #4 from jillianKhoo/backend-store-put
jillianKhoo Jan 24, 2019
1ebd1bd
get functionality and tests
Jan 25, 2019
5aab1cc
things noticed in reading diff
Jan 25, 2019
959fa13
added delete functionality and tests
Jan 25, 2019
18e180b
PR fixes but not totally fixed
Jan 28, 2019
b994c5e
fixed everything
Jan 29, 2019
6fa29e7
PR fixes
Jan 29, 2019
b5b522b
Merge pull request #6 from jillianKhoo/backend-store-get
jillianKhoo Jan 29, 2019
ce2b7a2
implementation of register user
Jan 30, 2019
b9e09ce
caught a couple things
Jan 30, 2019
01b020c
I forgot to actually call the function
Jan 31, 2019
98cd8af
refactoring service layer and key value interaction
Jan 31, 2019
cddd70e
added follow functionality
Jan 31, 2019
94d74cb
PR fixes
Feb 2, 2019
97f8d63
fixed get method in key value client
Feb 2, 2019
c69e322
PR fixes
Feb 3, 2019
3df87b5
removing old message
Feb 3, 2019
ddf6f3a
Merge pull request #7 from jillianKhoo/service-register
jillianKhoo Feb 3, 2019
16a7aaf
tests and functionality for chirp and follow
Feb 4, 2019
8112c34
header guard change
Feb 4, 2019
e7035e7
PR fixes
Feb 4, 2019
3566600
PR fix
Feb 4, 2019
98e46b4
caught one more
Feb 4, 2019
8f7c488
Merge pull request #8 from jillianKhoo/service-layer-chirp-read
jillianKhoo Feb 4, 2019
67baaef
nothing works anymore
Feb 5, 2019
ccd4e48
everything works again, fixed headers too
Feb 5, 2019
43b68ac
scripts for compiling until I get a real makefile and header fixes
Feb 5, 2019
7a2d9c1
realized I was including a generated file
Feb 5, 2019
2e7d31c
updated gitignore
Feb 5, 2019
9fb2526
pr fix
Feb 6, 2019
9889cc1
Merge pull request #9 from jillianKhoo/service-monitor
jillianKhoo Feb 6, 2019
d492a16
contact working from client to service layer, all tests still pass
Feb 6, 2019
471aa62
everything works
Feb 7, 2019
f915d24
everything works sort of
Feb 10, 2019
5478a6c
everything works
Feb 10, 2019
c1d1585
added fixes for edge cases and tests
Feb 10, 2019
8b9e92f
code complete
Feb 10, 2019
af88185
added to README
Feb 11, 2019
f2d294a
finished cleanup
Feb 11, 2019
47cfe01
PR fixes
Feb 11, 2019
193343f
PR fixed mutex
Feb 11, 2019
ef3bfd5
Merge pull request #10 from jillianKhoo/client-to-server
jillianKhoo Feb 11, 2019
feaa0b1
fixed readme, changed read to sort by timestamp, changed curr_id_ to …
Feb 12, 2019
64c048d
I forgot what I fixed
Feb 12, 2019
dad6567
Merge pull request #11 from jillianKhoo/small-details
jillianKhoo Feb 12, 2019
74798fa
spacing fix
Feb 12, 2019
40fc0c1
bug where if you follow someone twice they get double chirps
Feb 14, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Don't track these files
*.pb.h
*.pb.cc
*.pb.o
*.o
backendStore
backend_store
service_layer
client_layer
key_value_store_service_impl_tests
service_layer_service_impl_tests
.DS_Store
57 changes: 56 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,56 @@
# 499-jkhoo
# Jillian Khoo - [email protected]

## Installation
### Initial Setup:
#### Download vagrant here:
https://www.vagrantup.com/downloads.html
#### Follow these instructions for Project Setup for your vagrant vm:
https://www.vagrantup.com/intro/getting-started/project_setup.html
#### Install the box:
Use this box: https://app.vagrantup.com/generic/boxes/ubuntu1804
vagrant box add generic/ubuntu1804
Open the Vagrantfile and change its contents to this:
`Vagrant.configure("2") do |config|`
      `config.vm.box = "hashicorp/precise64"`
      `config.vm.synced_folder ".", "/vagrant"`
      `config.vm.provision :shell, path: "bootstrap.sh" `
`end`
#### Create the Shell Script bootstrap.sh
Create the following shell script and save it as bootstrap.sh in the same directory as your Vagrantfile
`apt-get update`
`apt-get install -y apache2`
`if ! [ -L /var/www ]; then`
      `rm -rf /var/www`
      `ln -fs /vagrant /var/www`
`fi`
#### Run `vagrant up` then `vagrant ssh`
#### Install grpc and protobuf
Use these instructions to install grpc and protobuf: https://github.com/grpc/grpc/blob/master/BUILDING.md
Go to grpc/third_party/protobuf in the grpc repository and run `./autogen.sh`, `./configure`, `make && sudo make install`
Go to the root directory of the grpc repository and run `sudo make install`
#### Install gtest
`sudo apt-get install libgtest-dev`
`sudo apt-get install cmake
cd /usr/src/gtest
sudo cmake CMakeLists.txt
sudo make
sudo cp *.a /usr/lib`

## Compiling and running the code:
Go to 499-jkhoo/cpp and run `./compile_clean` to compile everything except tests
Start the Key Value store with `./backend_store`
Start the Service Layer with `./service_layer`
Run the client layer with `./client_layer` and any appropriate flags
#### Example runs for the client layer:
`./client_layer --register <username>`registers the given user
`./client_layer --user <username>` logs in the given user and the --user flag must be before any command other than register
`./client_layer --user <username> --chirp <text>` creates a new chirp by the user with the given text
`./client_layer --user <username> --chirp <text> --reply <parent_id>` creates a new chirp by the user with the given text as a reply to the chirp with the given parent_id
`./client_layer --user <username> --follow <to_follow>` username starts following to_follow
`./client_layer --user <username> --read <chirp_id>` reads the chirp thread starting at the given id
`./client_layer --user <username> --monitor` streams new chirps from those currently followed

## Compiling and running the tests:
Go to 499-jkhoo/tests and run `./test_compile_clean`
Run the key value store tests with `./key_value_store_service_impl_tests`
Run the service layer tests with `./service_layer_service_impl_tests`
20 changes: 20 additions & 0 deletions cpp/backend_store.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "key_value_store_service_impl.h"

// Listens on port 50000 and assembles the key value server
void RunServer() {
std::string server_address("0.0.0.0:50000");
KeyValueStoreServiceImpl service;

grpc::ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);

std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
}

int main(int argc, char** argv) {
RunServer();
return 0;
}
91 changes: 91 additions & 0 deletions cpp/client.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include "client.h"

bool Client::registeruser(std::string username, std::unique_ptr<chirp::ServiceLayer::Stub>& stub_) {
if (username.length() == 0) {
std::cout << "Must enter non empty username" << std::endl;
return false;
}
grpc::ClientContext context;
chirp::RegisterRequest request;
request.set_username(username);
chirp::RegisterReply reply;
grpc::Status status = stub_->registeruser(&context, request, &reply);
if (status.error_code() != 0) {
std::cout << "Something went wrong :(" << std::endl;
return false;
}
std::cout << "User " << username << " registered!" << std::endl;
return true;
}

void Client::sendchirp(std::string username, std::string text, std::string reply_id, std::unique_ptr<chirp::ServiceLayer::Stub>& stub_) {
grpc::ClientContext context;
chirp::ChirpRequest request;
chirp::ChirpReply reply;
request.set_username(username);
request.set_text(text);
request.set_parent_id(reply_id);

grpc::Status status = stub_->chirp(&context, request, &reply);
if (status.error_code() != 0) {
std::cout << "Something went wrong :(" << std::endl;
if (reply_id.length() > 0) {
std::cout << "Make sure the parent id actually exists" << std::endl;
}
}
else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the google style guide, they normally put elses on the same line as the closing bracket for the if

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should fix this throughout the codebase.

std::cout << "Chirp with chirp id " << reply.chirp().id() << " created" << std::endl;
}
}

void Client::follow(std::string username, std::string to_follow, std::unique_ptr<chirp::ServiceLayer::Stub>& stub_) {
if (to_follow.length() == 0) {
std::cout << "Must enter non empty user to follow" << std::endl;
}
else {
grpc::ClientContext context;
chirp::FollowRequest request;
chirp::FollowReply reply;
request.set_username(username);
request.set_to_follow(to_follow);
grpc::Status status = stub_->follow(&context, request, &reply);
if (status.error_code() != 0) {
std::cout << "Something went wrong :(" << std::endl;
}
else {
std::cout << "User " << username << " now following " << to_follow << std::endl;
}
}
}

void Client::read(std::string id, std::unique_ptr<chirp::ServiceLayer::Stub>& stub_) {
grpc::ClientContext context;
chirp::ReadRequest request;
chirp::ReadReply reply;
request.set_chirp_id(id);
grpc::Status status = stub_->read(&context, request, &reply);
if (status.error_code() != 0) {
std::cout << "Something went wrong :(" << std::endl;
}
else {
int num_chirps = reply.chirps_size();
for(int i = 0; i < num_chirps - 1; i++) {
chirp::Chirp this_chirp = reply.chirps(i);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could declare this_chirp outside of the loop

std::cout << this_chirp.username() << ": " << this_chirp.text() << std::endl;
}
}
}

void Client::monitor(std::string username, std::unique_ptr<chirp::ServiceLayer::Stub>& stub_) {
grpc::ClientContext context;
chirp::MonitorRequest request;
request.set_username(username);
chirp::MonitorReply reply;
std::unique_ptr<grpc::ClientReader<chirp::MonitorReply> > stream_handle (stub_->monitor(&context, request));
while (true) {
while (stream_handle->Read(&reply)) {
chirp::Chirp this_chirp = reply.chirp();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also here, chirp could be declared outside of loop

std::cout<<this_chirp.username() << ": " << this_chirp.text() << std::endl;
}
}
}
22 changes: 22 additions & 0 deletions cpp/client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef CPP_CLIENT_H_
#define CPP_CLIENT_H_
#include "service.grpc.pb.h"
#include "service.pb.h"
#include <iostream>

// class behind the client layer
class Client {
public:
// registers user, returns true if successful
bool registeruser(std::string username, std::unique_ptr<chirp::ServiceLayer::Stub>& stub_);
// sends a chirp with the given information
void sendchirp(std::string username, std::string text, std::string reply_id, std::unique_ptr<chirp::ServiceLayer::Stub>& stub_);
// adds to_follow to username's list of users following
void follow(std::string username, std::string to_follow, std::unique_ptr<chirp::ServiceLayer::Stub>& stub_);
// reads the chirp string starting at id
void read(std::string id, std::unique_ptr<chirp::ServiceLayer::Stub>& stub_);
// streams chirps from users username is following
void monitor(std::string username, std::unique_ptr<chirp::ServiceLayer::Stub>& stub_);
private:
};
#endif
43 changes: 43 additions & 0 deletions cpp/client_layer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <grpcpp/grpcpp.h>
#include "service.grpc.pb.h"
#include "service.pb.h"
#include <iostream>
#include <gflags/gflags.h>
#include "client.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im p sure that there should be a blank line between iostream and the rest, and iostream should go first


DEFINE_string(register, "", "Register a username");
DEFINE_string(user, "", "Login a user");
DEFINE_string(chirp, "", "Send a chirp");
DEFINE_string(reply, "", "Make a chirp a reply to another chirp");
DEFINE_string(follow, "", "Follow a user");
DEFINE_string(read, "", "Read a chirp");
DEFINE_bool(monitor, false, "Stream chirps from followed users");

// parses command line flags and triggers appropriate action
int main(int argc, char** argv) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
std::shared_ptr<grpc::Channel> service_connection_ = grpc::CreateChannel("localhost:50002", grpc::InsecureChannelCredentials());
std::unique_ptr<chirp::ServiceLayer::Stub> stub_ = chirp::ServiceLayer::NewStub(service_connection_);
std::string my_username="";
Client client;
if (FLAGS_register != "") {
client.registeruser(FLAGS_register, stub_);
}
if (FLAGS_user != "") {
my_username = FLAGS_user;
}
if (FLAGS_chirp != "" && my_username != "") {
client.sendchirp(my_username, FLAGS_chirp, FLAGS_reply, stub_);
}
if (FLAGS_follow != "" && my_username != "") {
client.follow(my_username, FLAGS_follow, stub_);
}
if (FLAGS_read != "") {
client.read(FLAGS_read, stub_);
}
if (FLAGS_monitor && my_username != "") {
client.monitor(my_username, stub_);
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove blank line maybe?

return 0;
}
49 changes: 49 additions & 0 deletions cpp/compile_clean
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash
# Script that will make clean until I have a makefile

rm *.o
rm -rf service_layer
rm -rf backend_store
protoc -I ../protos --cpp_out=. ../protos/backendStore.proto

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o backendStore.pb.o backendStore.pb.cc

protoc -I ../protos --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../protos/backendStore.proto

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o backendStore.grpc.pb.o backendStore.grpc.pb.cc

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o key_value_store_service_impl.o key_value_store_service_impl.cc

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o key_value_client_interface.o key_value_client_interface.cc

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o key_value_client.o key_value_client.cc

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o key_value_store.o key_value_store.cc

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o backend_store.o backend_store.cc

g++ backendStore.pb.o backendStore.grpc.pb.o backend_store.o key_value_store_service_impl.o key_value_store.o key_value_client_interface.o key_value_client.o -g -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc` -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed -ldl -o backend_store

protoc -I ../protos --cpp_out=. ../protos/service.proto

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -c -o service.pb.o service.pb.cc

protoc -I ../protos --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../protos/service.proto

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o key_value_client.o key_value_client.cc

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o key_value_client_interface.o key_value_client_interface.cc

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o service.grpc.pb.o service.grpc.pb.cc

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o service.o service.cc

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o service_layer_service_impl.o service_layer_service_impl.cc

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o service_layer.o service_layer.cc

g++ backendStore.pb.o backendStore.grpc.pb.o service.pb.o service.grpc.pb.o service_layer.o key_value_client.o service_layer_service_impl.o service.o key_value_client_interface.o -g -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc` -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed -ldl -o service_layer

g++ -std=c++11 `pkg-config --cflags protobuf grpc` -g -c -o client.o client.cc

g++ backendStore.pb.o backendStore.grpc.pb.o service.pb.o service.grpc.pb.o client_layer.cc key_value_client.o service_layer_service_impl.o service.o key_value_client_interface.o client.o -g -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc` -lgflags -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed -ldl -o client_layer
36 changes: 36 additions & 0 deletions cpp/key_value_client.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "key_value_client.h"


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove blank line?

void KeyValueClient::put(const std::string& key, const std::string& value) {
chirp::PutRequest request;
request.set_key(key);
request.set_value(value);
chirp::PutReply reply;
grpc::ClientContext context;
grpc::Status status = stub_->put(&context, request, &reply);
}

std::deque<std::string> KeyValueClient::get(const std::string& key) {
chirp::GetRequest request;
request.set_key(key);
chirp::GetReply reply;
grpc::ClientContext context;

std::unique_ptr<grpc::ClientReaderWriter<chirp::GetRequest, chirp::GetReply> > stream_handle (stub_->get(&context));
stream_handle->Write(request);

std::deque<std::string> returnValues;
while (stream_handle->Read(&reply)) {
returnValues.push_back(reply.value());
}

return returnValues;
}

void KeyValueClient::deletekey(const std::string& key) {
chirp::DeleteRequest request;
request.set_key(key);
chirp::DeleteReply reply;
grpc::ClientContext context;
grpc::Status status = stub_->deletekey(&context, request, &reply);
}
27 changes: 27 additions & 0 deletions cpp/key_value_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef CPP_KEY_VALUE_CLIENT_H_
#define CPP_KEY_VALUE_CLIENT_H_
#include <deque>
#include <string>

#include <grpcpp/grpcpp.h>
#include "backendStore.grpc.pb.h"
#include "key_value_client_interface.h"

// data structure behind the KeyValueStoreServiceImpl
class KeyValueClient : public KeyValueClientInterface {
public:
virtual ~KeyValueClient(){};
// puts key value pair in store_, appending value if there is already a value associated with key
void put(const std::string& key, const std::string& value);
// gets values associated with the key
std::deque<std::string> get(const std::string& key);
// deletes values associated with the key
void deletekey(const std::string& key);

private:
// models connection to an endpoint
std::shared_ptr<grpc::Channel> channel_ = grpc::CreateChannel("localhost:50000", grpc::InsecureChannelCredentials());
// stub to communicate with KeyValueStore
std::unique_ptr<chirp::KeyValueStore::Stub> stub_ = chirp::KeyValueStore::NewStub(channel_);
};
#endif
2 changes: 2 additions & 0 deletions cpp/key_value_client_interface.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include "key_value_client_interface.h"
KeyValueClientInterface::~KeyValueClientInterface(){};
17 changes: 17 additions & 0 deletions cpp/key_value_client_interface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef CPP_KEY_VALUE_CLIENT_INTERFACE_H_
#define CPP_KEY_VALUE_CLIENT_INTERFACE_H_
#include <deque>
#include <string>

// Interface for KeyValueStore interactions from the Service Layer
class KeyValueClientInterface {
public:
virtual ~KeyValueClientInterface() = 0;
// puts key value pair in store_, appending value if there is already a value associated with key
virtual void put(const std::string& key, const std::string& value) = 0;
// gets values associated with the key, return deque is not guaranteed to be unmodified
virtual std::deque<std::string> get(const std::string& key) = 0;
// deletes values associated with the key
virtual void deletekey(const std::string& key) = 0;
};
#endif
Loading