Exemplo n.º 1
0
 def __init__(self, number):
     self.shard_size = int(number)
     self.past_shard_size = int(number)
     self.views = get_array_views()
     self.num_nodes = len(self.views)
     self.shard_directory = {}
     self.build_directory()
Exemplo n.º 2
0
def read_repair(all_node_info, key):
    for each in all_node_info:
        print(all_node_info[each])
        print("")
    max = None
    all_clocks = []
    for k in all_node_info:
        print(k)
        print("")
        value = all_node_info[k]
        vc_ts_k = (value['payload']['vc'], value['payload']['tstamp'], k)
        if max == None:
            max = vc_ts_k
        else:
            max = find_larger_vector_or_timestamp(vc_ts_k, max)

    correct_vc = max[0]
    correct_ts = max[1]
    correct_ip = max[2]
    correct_payload = all_node_info[correct_ip]
    print(correct_payload)

    ip_list_to_repair = get_array_views()
    ip_list_to_repair.remove(correct_ip)

    payload = {
        "latest_timestamp": correct_ts,
        "vc": correct_vc,
        "pos": get_array_views().index(correct_ip),
        "causal_context": correct_payload['payload']['causal_context'],
        "tstamp": correct_ts
    }

    if 'val' in correct_payload:
        val = correct_payload['val']

        data = "val=" + val + "&&payload=" + json.dumps(payload)
        for i in range(0, len(ip_list_to_repair)):
            url = "http://" + ip_list_to_repair[i] + "/keyValue-store/" + key
            requests.put(url, data=data)
    else:
        val = None

    return val
Exemplo n.º 3
0
def put(shards, num_shards, store, should_broadcast):
    response = shards.update(num_shards, store)
    if should_broadcast == True:
        payload_to_send = {"num": num_shards, "broadcaster": False}
        ips = get_array_views()
        my_ip = environ.get("IP_PORT")
        for ip in ips:
            if ip == my_ip:
                continue
            url = "http://" + ip + "/shard/changeShardNumber"
            requests.put(url, data=payload_to_send)
    status = None
    if response["is_successful"]:
        status = 200
        return JsonResponse(response, status=status)
    else:
        status = 400
        return JsonResponse(response, status=status)
Exemplo n.º 4
0
def delete_handling(request, details):
    clock = details["clock"]
    shards = details["shards"]
    store = details["store"]

    body_unicode = request.body.decode("utf-8")
    body = urllib.parse.parse_qs(body_unicode)
    ip_port_to_delete = body["ip_port"][0]
    checkpoint = None
    if "checkpoint" in body:
        checkpoint = body["checkpoint"][0]

    result_msg = ""
    msg = ""
    statuscode = 200
    number_of_shards = environ.get("S")
    ips = get_array_views()
    response_content = {
        "result": "Success",
        "msg": "Successfully removed %s from view" % ip_port_to_delete,
    }

    if ip_port_to_delete in ips:
        index_to_delete = get_index_of_target_in_views(ip_port_to_delete)

        delete_ip(clock, ip_port_to_delete, ips, shards)

        reconstruct_shard(shards, index_to_delete, ip_port_to_delete, store)

        if checkpoint is None:
            broadcast(ip_port_to_delete, ips)

    else:
        response_content = {
            "result": "Error",
            "msg": ip_port_to_delete + " is not in current view",
        }
        statuscode = 404

    return JsonResponse(response_content, status=statuscode)
Exemplo n.º 5
0
def broadcast(data, method, path, filter=None):
    # loop = asyncio.get_event_loop()
    # loop.run_until_complete(broadcast_async(data, method, path, filter))
    # return True
    ip_addresses = get_array_views(filter)
    # ip_addresses.remove(filter)

    if method == "PUT":
        ip_addresses.remove(filter)
        for i in range(0, len(ip_addresses)):
            url = "http://" + ip_addresses[i] + path
            requests.put(url, data=data)
    elif (method == "DELETE"):
        ip_addresses.remove(filter)
        for i in range(0, len(ip_addresses)):
            url = "http://" + ip_addresses[i] + path
            requests.delete(url, data=data)
    elif (method == "GET"):
        result = {}
        for i in range(0, len(ip_addresses)):
            url = "http://" + ip_addresses[i] + path
            response = requests.get(url, data=data)
            result[ip_addresses[i]] = response.json()
        return result
Exemplo n.º 6
0
def put_handling(request, details, key):
    store = details["store"]
    latest_timestamp = details["latest_timestamp"]
    curr_node_vc = details["clock"]
    shards = details["shards"]
    response_content = {}

    # OPTION: VALUE MISSING
    if len(request.body) <= 0:
        response_content["msg"] = "Error"
        response_content["result"] = "Error"
        response_content["error"] = "Value is missing"
        return JsonResponse(response_content, status=422)

    # OPTION: KEY LENGTH INVALID
    if 0 < len(key) > 200:
        response_content["msg"] = "Error"
        response_content["result"] = "Error"
        response_content["error"] = "Key not valid"
        return JsonResponse(response_content, status=422)

    body_unicode = request.body.decode("utf-8")
    body = parse_qs(body_unicode)

    payload_json = None
    if "rebalance" not in body:
        payload_json = val_and_payload(request.body)["payload_json"]
    else:
        print("HIII")

    val = val_and_payload(request.body)["val"]

    # OPTION: VALUE SIZE TOO BIG
    if getsizeof(val) > 1024:
        response_content["result"] = "Error"
        response_content["msg"] = "Object too large. Size limit is 1MB"
        response_content["error"] = "Key not valid"
        return JsonResponse(response_content, status=422)

    shard_location = None
    print("Before: ", payload_json)

    # OPTION: NON-EMPTY PAYLOAD (NODES COMMUNICATING)
    if payload_json:
        req_vc = payload_json["vc"]
        req_timestamp = payload_json["tstamp"]
        if (
            "latest_timestamp" in payload_json
            and latest_timestamp.get_timestamp() == None
        ):
            latest_timestamp.set_timestamp(payload_json["latest_timestamp"])
        else:
            lt = latest_timestamp.max_timestamp(req_timestamp)
            latest_timestamp.set_timestamp(lt)
        req_position = int(payload_json["pos"])

    # OPTION: EMPTY PAYLOAD (USER REQUEST)
    else:
        views = get_array_views()
        req_vc = curr_node_vc.get_vc()
        req_position = views.index(environ.get("IP_PORT"))
        req_timestamp = time.time()
        if latest_timestamp.get_timestamp() == None:
            latest_timestamp.set_timestamp(req_timestamp)
            payload_json["latest_timestamp"] = latest_timestamp.get_timestamp()
        payload_json = {
            "pos": req_position,
            "tstamp": req_timestamp,
            "causal_context": details["causal_context"],
            "vc": req_vc,
        }
        details["causal_context"] = None
        binary_key = sha1(key.encode())
        shard_location = int(binary_key.hexdigest(), 16) % shards.get_shard_size()

    # OPTION: KEY NEVER EXISTED
    if not store.has_key(key):
        response_content["replaced"] = False
        response_content["msg"] = "Added successfully"
        response_content["payload"] = payload_json
        status = 201

    # OPTION: KEY ALREADY EXISTS AND IS BEING REPLACED
    elif store.has_key(key):
        response_content["replaced"] = True
        response_content["msg"] = "Updated successfully"
        response_content["payload"] = payload_json
        status = 200

    members = shards.get_members_in_ID(shard_location)
    # if in right shard
    if shard_location != None:
        if members != None:
            rand_address = random.choice(members)
            if "rebalance" in body:
                store.add(key, val, {})
            data = "val=" + val + "&&payload=" + json.dumps(payload_json)
            response = requests.put(
                "http://" + rand_address + "/keyValue-store/" + key, data=data
            )
            return JsonResponse(response.json(), status=response.status_code)
        else:
            response_content = {
                "result": "Error",
                "msg": "No nodes in shard " + str(shard_location),
                "payload": payload_json,
            }
            status = 400
            return JsonResponse(response_content, status=status)
    else:
        if "rebalance" not in body:
            curr_node_vc.increment_self()
            payload_json["vc"] = curr_node_vc.get_vc()
        store.add(key, val, payload_json["causal_context"])
        print("I AM ADDING KEY")
        response_content["owner"] = shards.get_my_shard()
        return JsonResponse(response_content, status=status)

    return JsonResponse(response_content, status=status)
Exemplo n.º 7
0
def delete_handling(request, details, key):
    store = details["store"]
    latest_timestamp = details["latest_timestamp"]
    curr_node_vc = details["clock"]
    shards = details["shards"]
    response_content = {}

    # OPTION: NO KEY PROVIDED
    if key is None:
        response_content['result'] = 'Error'
        response_content['msg'] = 'Not provided'
        return JsonResponse(response_content, status=422)

    payload_json = val_and_payload(request.body)["payload_json"]
    shard_location = None
    # OPTION: NON-EMPTY PAYLOAD (NODES COMMUNICATING)
    if payload_json:
        req_vc = payload_json['vc']
        req_timestamp = payload_json['tstamp']
        if 'latest_timestamp' in payload_json and latest_timestamp.get_timestamp() == None:
            latest_timestamp.set_timestamp(payload_json['latest_timestamp'])
        else:
            lt = latest_timestamp.max_timestamp(req_timestamp)
            latest_timestamp.set_timestamp(lt)
        req_position = int(payload_json['pos'])

    # OPTION: EMPTY PAYLOAD (USER REQUEST)
    else:
        IP_PORT = environ.get("IP_PORT")
        views = get_array_views()
        req_vc = curr_node_vc.get_vc()
        req_position = views.index(IP_PORT)
        req_timestamp = time.time()
        if latest_timestamp.get_timestamp() == None:
            latest_timestamp.set_timestamp(req_timestamp)
            payload_json['latest_timestamp'] = latest_timestamp.get_timestamp()
        payload_json['vc'] = req_vc
        payload_json['pos'] = req_position
        payload_json['tstamp'] = req_timestamp
        payload_json['causal_context'] = details["causal_context"]
        details["causal_context"] = None
        binary_key = sha1(key.encode())
        shard_location = int(binary_key.hexdigest(),
                             16) % shards.get_shard_size()
    status = 200

    # OPTION: KEY DELETED
    if not store.has_key(key) or store.get()[key]['tombstone'] == True:
        response_content['result'] = "Error"
        response_content['msg'] = "Key does not exist"
        response_content['payload'] = payload_json
        status = 404

    # OPTION: KEY EXISTS, SUCCESSFULLY DELETED
    else:
        response_content['result'] = "Success"
        response_content['msg'] = "Key deleted"
        response_content['payload'] = payload_json

    # if in right shard
    if (shard_location != None and not (environ.get("IP_PORT") in shards.get_members_in_ID(shard_location))):
        members = shards.get_members_in_ID(shard_location)
        if members != None:
            rand_address = random.choice(members)
            data = "payload="+json.dumps(payload_json)
            response = requests.delete(
                "http://"+rand_address+"/keyValue-store/"+key, data=data)
            return JsonResponse(response.json(), status=response.status_code)
        else:
            response_content = {
                "result": "Error",
                "msg": "No nodes in shard " + shard_location,
                "payload": payload_json
            }
            status = 400
            return JsonResponse(response_content, status=status)
    # if in wrong shard
    else:
        # reconsider to move this
        curr_node_vc.increment_index(req_position)
        payload_json['vc'] = curr_node_vc.get_vc()
        store.delete_key(key)
        print("I AM DELETING KEY KEY")
        response_content["owner"] = shards.get_my_shard()
        return JsonResponse(response_content, status=status)
    # #reconsider to move this
    # curr_node_vc.increment_index(req_position)

    return JsonResponse(response_content, status=status)
Exemplo n.º 8
0
 def update_view(self):
     self.views = get_array_views()
     self.num_nodes = len(self.views)
Exemplo n.º 9
0
def get_handling(request, details, key):
    store = details["store"]
    latest_timestamp = details["latest_timestamp"]
    curr_node_vc = details["clock"]
    shards = details["shards"]
    response_content = {}

    payload_json = val_and_payload(request.body)["payload_json"]

    # OPTION: NO KEY PROVIDED
    if key == None:
        response_content = {
            "result": "Error",
            "msg": "Not provided",
            "error": "Key does not exist",
        }
        return JsonResponse(response_content, status=422)

    if store.is_exists(key):
        value = store.get_item(key)["val"]
        if value == "this-is-invalid":
            response_content = {
                "result": "Error",
                "msg": "Unable to access key: " + key,
                "payload": payload_json,
            }
            return JsonResponse(response_content, status=400)

    # OPTION: SEARCH-GET
    if "/keyValue-store/search" in request.path:
        response_content["result"] = "Success"
        response_content["payload"] = payload_json
        if store.is_exists(key):
            response_content["isExists"] = True
        else:
            response_content["isExists"] = False
        return JsonResponse(response_content, status=200)

    # OPTION: EMPTY PAYLOAD (USER REQUEST), HASH KEY AND CHECK SHARD DIRECTORY
    if not payload_json:
        payload_json = {
            "vc": curr_node_vc.get_vc(),
            "pos": get_array_views().index(environ.get("IP_PORT")),
            "tstamp": latest_timestamp.get_timestamp(),
            "causal_context": details["causal_context"],
        }
        details["causal_context"] = None
        data = "payload=" + json.dumps(payload_json)

        if store.is_exists(key):
            response_content = {
                "result": "Success",
                "val": store.get_item(key)["val"],
                "payload": payload_json,
                "owner": shards.get_my_shard()
            }
            status = 200
        else:
            response_content = {
                "result": "Error",
                "msg": "Key does not exist",
                "payload": payload_json,
            }
            status = 404

        shard_location = None
        binary_key = sha1(key.encode())
        shard_location = int(binary_key.hexdigest(),
                             16) % shards.get_shard_size()

        # OPTION: WE'RE IN THE WRONG SHARD, REDIRECT REQUEST TO NODE WITH CORRECT SHARD
        current_node_not_in_shard = shards.get_members_in_ID(
            shard_location) is not None and not (environ.get(
                "IP_PORT") in shards.get_members_in_ID(shard_location))
        if current_node_not_in_shard:
            members = shards.get_members_in_ID(shard_location)
            if members != None and len(members) > 0:
                rand_address = random.choice(members)
                data = "payload=" + json.dumps(payload_json)
                response = requests.get("http://" + rand_address +
                                        "/keyValue-store/" + key,
                                        data=data)
                response_content = response.json()
                if response.status_code == 404:
                    response_content = {
                        "result": "Error",
                        "msg": "Key does not exist",
                        "payload": payload_json,
                    }
                else:
                    del response_content["owner"]
                return JsonResponse(response_content,
                                    status=response.status_code)
            else:
                response_content = {
                    "result": "Error",
                    "msg": "No nodes in shard " + shard_location,
                    "payload": payload_json,
                }
                status = 400
                return JsonResponse(response_content, status=status)
        else:
            return JsonResponse(response_content, status=status)

    # OPTION: NON-EMPTY PAYLOAD (NODES COMMUNICATING). WE'RE IN THE
    # RIGHT CONTAINER, JUST DO NORMAL GET
    else:
        views = get_array_views()

        # CONDITION: If store already has the key
        if store.is_exists(key):
            details["causal_context"] = {
                "key": key,
                "vc": curr_node_vc.get_vc()
            }
            response_content["result"] = "Success"
            response_content["val"] = store.get_item(key)["val"]

            # payload_json['value'] = store.get_item(key)['val']
            # CONDITION: If causal context exists and requestor's vc > this vc
            # if cc_key != None and curr_node_vc.greater_than_or_equal(payload_json["vc"]) is False:
            #     store.add(cc_key, "too_old", None)
            #     UP_TO_DATE_PAYLOAD = payload_json

            # CONDITION: if reading an old value, return Payload out of date,
            # remove val from response_content, and set status to 400
            if store.get_item(key)["val"] == "too_old":
                del response_content["val"]
                response_content = {
                    "msg": "Payload out of date",
                    "status": 400,
                    "payload": UP_TO_DATE_PAYLOAD,
                }
                status = 400
            status = 200
            payload_json = {
                "vc": curr_node_vc.get_vc(),
                "pos": views.index(environ.get("IP_PORT")),
                "tstamp": latest_timestamp.get_timestamp(),
                "causal_context": details["causal_context"],
            }
        else:
            payload_json = {
                "value": None,
                "vc": curr_node_vc.get_vc(),
                "pos": views.index(environ.get("IP_PORT")),
                "tstamp": latest_timestamp.get_timestamp(),
                "causal_context": details["causal_context"],
            }
            response_content["payload"] = payload_json
            status = 404
        response_content["owner"] = shards.get_my_shard()
        response_content["payload"] = payload_json
    return JsonResponse(response_content, status=status)