@RequestMapping(value = VIDEO_REMOVE_PATH, method = RequestMethod.DELETE)
  public @ResponseBody int deleteVideo(
      @RequestParam(value = "username") String uName,
      @RequestParam(value = "video") String videoHash,
      HttpServletResponse response) {
    try {

      if (!user_vidNameMap.containsKey(uName)) {
        response.setStatus(402); // client not connected
        return 0;
      }
      videoHash = videoHash.trim();
      int ans = masterService.psDeleteVideo(hostAdder, uName, videoHash);
      while (ans == PS_NOT_CONNECTED) {
        reconnectToMS();
        ans = masterService.psDeleteVideo(hostAdder, uName, videoHash);
      }
      if (ans == FAILED) return FAILED;
      user_vidNameMap.get(uName).remove(videoHash);
      removeFromvidName_UserMap(uName, videoHash);

      return ACK;
    } catch (Exception e) {
      System.err.println(e.getMessage());
      return FAILED;
    }
  }
  @RequestMapping(value = CLIENT_CONNECT_PATH, method = RequestMethod.POST)
  public @ResponseBody int connectClient(@RequestBody String allVid) {
    try {
      int reply = FAILED;
      String[] videos = allVid.split(",");
      String uName = videos[0].trim();
      videos = java.util.Arrays.copyOfRange(videos, 1, videos.length);
      // System.out.println("Client connect"+hostAdder+" "+uName+" "+ Arrays.asList(videos));
      int ans = masterService.psConnectClient(hostAdder, uName, videos);
      // System.out.println("ans =" +ans +" "+FAILED);
      while (ans == PS_NOT_CONNECTED) {
        reconnectToMS();
        ans = masterService.psConnectClient(hostAdder, uName, videos);
      }
      if (ans == FAILED) return FAILED;
      // System.out.println("Clinet "+ uName + " connected");

      if (user_vidNameMap.containsKey(uName)) {
        reply = CLIENT_ALREADY_CONNECTED;
      } else {
        reply = CLIENT_CONNECTED;
        user_vidNameMap.put(uName, new HashSet<String>());
      }
      // System.out.println("Clinet "+ uName + " connected");

      Set<String> vidSet = user_vidNameMap.get(uName);
      for (int i = 0; i < videos.length; i++) {
        String temp = videos[i].trim();
        // System.out.println("add video");

        if (!temp.equals("")) {
          vidSet.add(temp);
          addTovidName_UserMap(uName, temp);
        }
      }
      // System.out.println("Clinet "+ uName + " connected");

      userAliveMap.put(uName, new Long(System.currentTimeMillis() + TTL));
      // System.out.println("Clinet "+ uName + " connected");

      activeUsers.add(uName);
      System.out.println("Clinet " + uName + " connected");
      return reply;
    } catch (Exception e) {
      System.out.println("Error: " + e.getMessage());
      return FAILED;
    }
  }
 @Scheduled(fixedDelay = SEND_HEART_BEAT_DELAY)
 public void sendHeartBeat() {
   try {
     masterService.psHeartBeat(hostAdder);
   } catch (Exception e) {
     System.out.println("Error Sending HeardBeat");
   }
 }
  private void removeUser(String user) {
    int count = 0;

    if (user_vidNameMap.containsKey(user)) {
      Set<String> vids = user_vidNameMap.get(user);
      Iterator<String> it = vids.iterator();
      while (it.hasNext()) {
        removeFromvidName_UserMap(user, it.next());
      }
      vids.clear();
      user_vidNameMap.remove(user);
    }
    activeUsers.remove(user);
    int ans = masterService.psDisConnectClient(hostAdder, user);
    while (ans != ACK) {
      if (count > 10) throw new RuntimeException("Time out in removing user from MS");
      reconnectToMS();
      ans = masterService.psDisConnectClient(hostAdder, user);
      count++;
    }
    System.out.println("User " + user + " removed.");
  }
  @RequestMapping(value = VIDEO_SEARCH_PATH, method = RequestMethod.GET)
  public @ResponseBody String[] searchVideo(
      @RequestParam(value = "username") String uName,
      @RequestParam(value = "video") String videoHash,
      HttpServletResponse response) {
    System.out.println("Search from:" + uName);
    if (!user_vidNameMap.containsKey(uName)) {
      response.setStatus(402); // client not connected
      return null;
    }

    Set<String> users = vidName_UserMap.get(videoHash);

    if (users == null) {
      System.out.println("Srearching main server\n");
      try {
        users = masterService.psSearch(hostAdder, videoHash);
      } catch (Exception e) {
        System.err.println(e.getMessage());
        return null;
      }
      if (users == null) return null;
      if (vidName_UserMap.containsKey(videoHash)) {
        vidName_UserMap.get(videoHash).addAll(users);
      } else {
        Set<String> s = new HashSet<String>();
        s.addAll(users);
        vidName_UserMap.put(videoHash, s);
      }
    } else {
      Iterator<String> it = users.iterator();
      while (it.hasNext()) {
        String temp = it.next();
        if (!activeUsers.contains(temp)) {
          it.remove();
        }
      }
    }
    System.out.println("Search result : " + Arrays.asList(users.toArray(new String[0])));
    // String [] a = new String[]
    return users.toArray(new String[0]);
  }
 @PostConstruct
 public void getHostAdderesAndConnectToMS() {
   try {
     Enumeration e = NetworkInterface.getNetworkInterfaces();
     while (e.hasMoreElements()) {
       NetworkInterface n = (NetworkInterface) e.nextElement();
       Enumeration ee = n.getInetAddresses();
       while (ee.hasMoreElements()) {
         InetAddress i = (InetAddress) ee.nextElement();
         if (i.getHostAddress().contains("10.") || i.getHostAddress().contains("192.")) {
           hostAdder = i.getHostAddress().trim();
           System.out.println("Run at start. IP:" + hostAdder);
           if (masterService.connectPS(hostAdder) == FAILED) {
             System.out.println("Could not connect to MS. Shutting down");
             System.exit(0);
           }
           return;
         }
       }
     }
   } catch (Exception e) {
   }
 }
 private void reconnectToMS() {
   if (masterService.connectPS(hostAdder) == FAILED) {
     System.out.println("Could not connect to MS. Shutting down");
     System.exit(0);
   }
 }