def new_agent(ts, params): db = get_conn() # validate, agent name not empty if len(params["agentName"].strip()) == 0: raise WebException("Agent name is empty") # validate, agent name must be uniq old = db.agents.find({"name": params["agentName"]}) if old.count() > 0: raise WebException("Agent with identical name already exists.") service_need = {str(randint(0, 100)): None for x in range(4)} service_offer = [str(randint(0, 100)) for x in range(4)] agent = { "name": params["agentName"], "owner": params["agentOwner"], "batch": params["agentBatch"], "locality": float(params["agentLocality"]), "ts_added": ts, "x": float(params["agentX"]), "y": float(params["agentY"]), "friends_h": params["agentFriendsH"].split('-'), "friends_m": params["agentFriendsM"].split('-'), "friends_l": params["agentFriendsL"].split('-'), "qoi": randint(0, 10), "qod": randint(0, 10), "qos": randint(0, 10), "availability": randint(0, 10), "friendships": {}, "friendships_h": {}, "service_need": service_need, "service_offer": service_offer } db.agents.insert(agent) return agents(ts, ts)
def test_batch(self): """batch test: two node with same batchId should be friend after 2 step""" agent.deleteAll() simulation.clear_all_messages() simulation.reset_ts() a = agent.random_agent() b = agent.random_agent() a["agentName"] = "a" a["agentX"] = str(150) a["agentY"] = str(100) a["agentOwner"] = str(53) a["agentBatch"] = str(50) a["agentLocality"] = str(50) b["agentName"] = "b" b["agentX"] = str(950) b["agentY"] = str(100) b["agentOwner"] = str(52) b["agentBatch"] = str(50) b["agentLocality"] = str(50) agent.new_agent(0, a) agent.new_agent(0, b) simulation.start(2) db = get_conn() ag = {a["name"]: a for a in db.agents.find()} self.assertTrue("a" in ag["b"]["friendships"]) self.assertTrue("b" in ag["a"]["friendships"])
def start_friendship(current_ts, node1, node2): if not is_friend(node1,node2): db = get_conn() db.agents.find_one_and_update({"_id":node1["_id"]}, {"$set":{ "friendships."+ node2["name"]: {"ts_start":current_ts,"strength":1}}}) db.agents.find_one_and_update({"_id":node1["_id"]}, {"$push":{ "friendships_h."+ node2["name"]: {"ts":current_ts,"strength":1}}})
def find_ts(do_update=True): db = get_conn() lastmsg = db.vars.find({},{"ts"}) if lastmsg.count() == 0: db.vars.insert({"ts":0}) current_ts = 0 else: current_ts = lastmsg.next()["ts"] if do_update: db.vars.find_one_and_update({},{"$inc":{"ts":1}}) return current_ts
def update_friendship_strength(current_ts,node1,node2,strength): if strength > 5: return db = get_conn() if strength == 0: # terminate friendship terminate_friendship(current_ts,node1,node2) send_msg(current_ts,node1,node2,MESSAGE_FRIENDSHIP_TERMINATE,"") else: # update friendship db.agents.find_one_and_update({"name":node1["name"]},{"$push":{"friendships_h."+node2["name"]: {"ts":current_ts,"strength":strength}}}) db.agents.find_one_and_update({"name":node1["name"]},{"$set":{"friendships."+node2["name"]+".strength" : strength,"friendships."+node2["name"]+".ts_start" : current_ts}}) log_msg(current_ts, node1["name"] +"-"+ node2["name"] , "-", LOG_FRIENDSHIP_CHANGE,strength)
def agents(ts_real, ts_requested): if ts_requested is None: ts_requested = ts_real ts_requested = int(ts_requested) db = get_conn() agents = list(db.agents.find({"ts_added": {"$lte": ts_requested}})) data = [] for agent in agents: agent.pop('_id') data.append({ "data": { "id": agent["name"], "locality": agent.get("locality"), "obj": agent }, "position": { "x": agent["x"], "y": agent["y"] } }) for fshipk, fshipv_a in agent["friendships_h"].items(): tmp = [x for x in fshipv_a if x["ts"] <= ts_requested] if len(tmp) == 0: continue fshipv = tmp[-1] # average: skip_me = False for d in data: if d["data"].get("source") == fshipk and d["data"].get( "target") == agent["name"]: skip_me = True break if skip_me: continue for agent2 in agents: if agent2["name"] == fshipk: score2 = agent2["friendships_h"][ agent["name"]][-1]["strength"] # data.append({ "data": { "id": agent["name"] + "-" + fshipk, "source": agent["name"], "target": fshipk, "strength": (int(fshipv["strength"]) + int(score2)) / 2 } }) return {"data": data, "ts_real": ts_real, "ts_requested": ts_requested}
def logs_for_ts(numberOfSteps): db = get_conn() ts = find_ts(do_update=False) data = [] for i in range(int(numberOfSteps)): for msg in list(db.messages.find({"ts":ts-i})): data.append({ "from":msg["from"], "to": msg["to"], "ts":msg["ts"], "type": { 100: "FRIENDSHIP_INIT", 101: "FRIENDSHIP_ACCEPTED", 102: "FRIENDSHIP_TERMINATE" }[msg["msg_type"]], "extra":msg.get("extra") }) return data
def last_messages(number): db = get_conn() data = [] for msg in list(db.messages.find().sort("ts",-1).limit(number)): data.append({ "from":msg["from"], "to": msg["to"], "ts":msg["ts"], "type": { 100: "FRIENDSHIP_INIT", 101: "FRIENDSHIP_ACCEPTED", 102: "FRIENDSHIP_TERMINATE", 200: "CONSUME_SERVICE_FRIEND", 210: "CONSUME_SERVICE_FRIEND_FRIEND", 220: "CONSUME_SERVICE_FRIEND_FRIEND_FRIEND", 1000: "LOG_FRIENDSHIP_CHANGE" }[msg["msg_type"]], "extra":msg.get("extra") }) return data
def makeCSVString(): db = get_conn() # TOD O update agents = db.agents.find() output = io.StringIO() spamwriter = csv.writer(output) spamwriter.writerow([ "agentName", "agentOwner", "agentBatch", "agentFamily", "agentX", "agentY", "agentFriends", "agentNeeds", "agentOffers" ]) for agent in agents: spamwriter.writerow([ agent.get("agentName"), agent.get("agentOwner"), agent.get("agentBatch"), agent.get("agentFamily"), agent.get("agentX"), agent.get("agentY"), agent.get("agentFriends"), agent.get("agentNeeds"), agent.get("agentOffers") ]) return output.getvalue()
def test_frienship_change(self): """Frienship change: if a+b+c+d is more than 20 frienship strength gets increased and if it is less than 20 gets decreased""" agent.deleteAll() simulation.clear_all_messages() simulation.reset_ts() a = agent.random_agent() b = agent.random_agent() a["agentName"] = "a" a["agentX"] = str(150) a["agentY"] = str(100) a["agentOwner"] = str(53) a["agentBatch"] = str(50) a["agentLocality"] = str(50) b["agentName"] = "b" b["agentX"] = str(950) b["agentY"] = str(100) b["agentOwner"] = str(52) b["agentBatch"] = str(50) b["agentLocality"] = str(50) agent.new_agent(0, a) agent.new_agent(0, b) simulation.start(2) db = get_conn() ag = {a["name"]: a for a in db.agents.find()} self.assertTrue("a" in ag["b"]["friendships"]) self.assertTrue("b" in ag["a"]["friendships"]) db.agents.find_one_and_update( {"name": "a"}, {"$set": { "qoi": 5, "qos": 5, "qod": 5, "availability": 5 }}) db.agents.find_one_and_update( {"name": "b"}, {"$set": { "qoi": 5, "qos": 5, "qod": 5, "availability": 5 }}) simulation.start(30) ag = {a["name"]: a for a in db.agents.find()} self.assertTrue(ag["b"]["friendships"]["a"]["strength"] == 2) self.assertTrue(ag["a"]["friendships"]["b"]["strength"] == 2) simulation.start(30) ag = {a["name"]: a for a in db.agents.find()} self.assertTrue(ag["b"]["friendships"]["a"]["strength"] == 3) self.assertTrue(ag["a"]["friendships"]["b"]["strength"] == 3) simulation.start(30) ag = {a["name"]: a for a in db.agents.find()} self.assertTrue(ag["b"]["friendships"]["a"]["strength"] == 4) self.assertTrue(ag["a"]["friendships"]["b"]["strength"] == 4) simulation.start(30) ag = {a["name"]: a for a in db.agents.find()} self.assertTrue(ag["b"]["friendships"]["a"]["strength"] == 5) self.assertTrue(ag["a"]["friendships"]["b"]["strength"] == 5) simulation.start(70) ag = {a["name"]: a for a in db.agents.find()} self.assertTrue(ag["b"]["friendships"]["a"]["strength"] == 5) self.assertTrue(ag["a"]["friendships"]["b"]["strength"] == 5) db.agents.find_one_and_update( {"name": "a"}, {"$set": { "qoi": 5, "qos": 5, "qod": 5, "availability": 2 }}) db.agents.find_one_and_update( {"name": "b"}, {"$set": { "qoi": 5, "qos": 5, "qod": 5, "availability": 2 }}) simulation.start(30) ag = {a["name"]: a for a in db.agents.find()} self.assertTrue(ag["b"]["friendships"]["a"]["strength"] == 4) self.assertTrue(ag["a"]["friendships"]["b"]["strength"] == 4) simulation.start(30) ag = {a["name"]: a for a in db.agents.find()} self.assertTrue(ag["b"]["friendships"]["a"]["strength"] == 3) self.assertTrue(ag["a"]["friendships"]["b"]["strength"] == 3) simulation.start(30) ag = {a["name"]: a for a in db.agents.find()} self.assertTrue(ag["b"]["friendships"]["a"]["strength"] == 2) self.assertTrue(ag["a"]["friendships"]["b"]["strength"] == 2) simulation.start(30) ag = {a["name"]: a for a in db.agents.find()} self.assertTrue(ag["b"]["friendships"]["a"]["strength"] == 1) self.assertTrue(ag["a"]["friendships"]["b"]["strength"] == 1) simulation.start(30) ag = {a["name"]: a for a in db.agents.find()} self.assertTrue("a" not in ag["b"]["friendships"]) self.assertTrue("b" not in ag["a"]["friendships"])
def consume_service(current_ts,node1, node2, service, type): send_msg(current_ts,node1,node2,type,service) db = get_conn() db.agents.find_one_and_update({"name":node1["name"]},{"$set":{"service_need."+service : node2["name"]}})
def clear_all_messages(): db = get_conn() db.messages.delete_many({})
def terminate_friendship(current_ts,node1, node2): db = get_conn() db.agents.find_one_and_update({"name":node1["name"]},{"$push":{"friendships_h."+node2["name"]: {"ts":current_ts,"strength":0 }}}) db.agents.find_one_and_update({"name":node1["name"]},{"$unset":{"friendships."+node2["name"] : ""}})
def simulate_one_step(current_ts): db = get_conn() nodes = list( db.agents.find()) nodes_dic = {node1["name"]:node1 for node1 in nodes} # reply message for node1 in nodes: for node2 in nodes: if node1 == node2: continue # if there is a message j->i at t-1 then respond for msg in db.messages.find({"from":node2["name"],"to":node1["name"],"ts":current_ts-1}): reply_msg(msg, current_ts, node1, node2) # friendship for node1 in find_nodes_friendship(nodes): for node2 in find_nodes_friendship_for_node(nodes,node1): if node1 == node2: continue if is_friend(node1,node2): change_friendship_level(current_ts,node1,node2) else: if is_first_relation(node1,node2): trying_frienship(current_ts,node1,node2) # service for node1 in find_nodes_services(nodes): for service in [srv[0] for srv in node1["service_need"].items() if srv[1] is None]: found = False for fshipk,fshipv in sorted(node1["friendships"].items(), key=lambda x: x[1]["strength"] * -1): node2 = nodes_dic[fshipk] if service in node2["service_offer"]: consume_service(current_ts,node1, node2, service,CONSUME_SERVICE_FRIEND) found = True break if found: break for fshipk2,fshipv2 in sorted(node1["friendships"].items(), key=lambda x: x[1]["strength"] * -1): node2 = nodes_dic[fshipk2] for fshipk3,fshipv3 in sorted(node2["friendships"].items(), key=lambda x: x[1]["strength"] * -1): node3 = nodes_dic[fshipk3] if service in node3["service_offer"]: consume_service(current_ts,node1, node3, service,CONSUME_SERVICE_FRIEND_FRIEND) found = True break if found: break if found: break for fshipk2,fshipv2 in sorted(node1["friendships"].items(), key=lambda x: x[1]["strength"] * -1): node2 = nodes_dic[fshipk2] for fshipk3,fshipv3 in sorted(node2["friendships"].items(), key=lambda x: x[1]["strength"] * -1): node3 = nodes_dic[fshipk3] for fshipk4,fshipv4 in sorted(node3["friendships"].items(), key=lambda x: x[1]["strength"] * -1): node4 = nodes_dic[fshipk4] if service in node4["service_offer"]: consume_service(current_ts,node1, node4, service,CONSUME_SERVICE_FRIEND_FRIEND_FRIEND) found = True break if found: break if found: break
def log_msg(current_ts,node1,node2,msg_type,extra): db = get_conn() db.messages.insert({"from":node1,"to":node2,"ts":current_ts,"msg_type":msg_type,"extra":extra})
def is_first_relation(node1,node2): db = get_conn() return db.messages.count({"from":node1["name"],"to":node2["name"],"msg_type":MESSAGE_FRIENDSHIP_INIT})==0
def reset_ts(): db = get_conn() db.vars.find_one_and_update({},{"$set":{"ts":0}})
def deleteAll(): db = get_conn() db.agents.delete_many({})