private String renderMoveForm(PhysicalPort port, Model model, RedirectAttributes redirectAttrs) {
    List<UnallocatedPortView> unallocatedPorts =
        physicalPortService
            .findUnallocatedPorts()
            .stream()
            .filter(x -> x.isAvailable(port.getSVlan(), port.getAllowedVlan().orElse(Vlan.none())))
            .collect(Collectors.toList());

    if (unallocatedPorts.isEmpty()) {
      messageManager.addInfoFlashMessage(
          redirectAttrs, "info_physicalport_nounallocated", port.isVlanRequired() ? "EVPL" : "EPL");
      return redirectPortListPage(port);
    }

    long numberOfVirtualPorts =
        port instanceof UniPort ? virtualPortService.countForUniPort((UniPort) port) : 0;
    long numberOfReservations = reservationService.countForPhysicalPort(port);
    long numberOfActiveReservations =
        reservationService.countActiveReservationsForPhysicalPort(port);

    model.addAttribute(
        "relatedObjects",
        new RelatedObjects(numberOfVirtualPorts, numberOfReservations, numberOfActiveReservations));
    model.addAttribute("physicalPort", new PhysicalPortMoveView(port));
    model.addAttribute("unallocatedPhysicalPorts", unallocatedPorts);

    if (!model.containsAttribute("movePhysicalPortCommand")) {
      // Only add when not present. Otherwise validatione errors are
      // automagically removed by Spring :(
      model.addAttribute("movePhysicalPortCommand", new MovePhysicalPortCommand(port));
    }

    return PAGE_URL + "/move";
  }
 @RequestMapping(value = "move", method = RequestMethod.GET)
 public String moveForm(@RequestParam Long id, Model model, RedirectAttributes redirectAttrs) {
   return physicalPortService
       .find(id)
       .map(port -> renderMoveForm(port, model, redirectAttrs))
       .orElse("redirect:");
 }
  @RequestMapping(value = "create", params = ID_KEY, method = RequestMethod.GET)
  public String createForm(@RequestParam(ID_KEY) String nmsPortId, Model model) {
    Optional<NbiPort> maybeNbiPort = physicalPortService.findNbiPort(nmsPortId);
    if (!maybeNbiPort.isPresent()) {
      return "redirect:";
    }

    NbiPort nbiPort = maybeNbiPort.get();

    model.addAttribute("interfaceTypes", availableInterfaceTypes(nbiPort));
    model.addAttribute("availableTopologies", physicalPortService.findTopologyNames());
    model.addAttribute("vlanRequired", nbiPort.isVlanRequired());
    model.addAttribute(
        "createPhysicalPortCommand",
        new CreatePhysicalPortCommand(nbiPort, bodEnvironment.getBodTopologyName()));

    return PAGE_URL + CREATE;
  }
  @RequestMapping(value = "move", method = RequestMethod.POST)
  public String move(
      @Valid MovePhysicalPortCommand command,
      BindingResult result,
      RedirectAttributes redirectAttrs,
      Model model) {
    Optional<NbiPort> newPort = physicalPortService.findNbiPort(command.getNewPhysicalPort());

    Optional<PhysicalPort> oldPort = physicalPortService.find(command.getId());

    if (!newPort.isPresent() || !oldPort.isPresent()) {
      return "redirect:";
    }

    if (result.hasErrors()) {
      return renderMoveForm(oldPort.get(), model, redirectAttrs);
    }

    model.addAttribute("lastEventId", endPoints.getLastEventId());

    try {
      Collection<Reservation> reservations = nocService.movePort(oldPort.get(), newPort.get());

      ElementActionView disabledAction = new ElementActionView(false);

      Collection<ReservationView> reservationViews =
          reservations
              .stream()
              .map(
                  reservation ->
                      new ReservationView(
                          reservation, disabledAction, disabledAction, disabledAction))
              .collect(toList());

      messageManager.addInfoMessage(model, "label_physicalport_port_moved");

      model.addAttribute("list", reservationViews);

      return PAGE_URL + "/moveResult";
    } catch (OverlappingSubportAllocationException e) {
      result.reject(e.getMessage());
      return renderMoveForm(oldPort.get(), model, redirectAttrs);
    }
  }
  private List<InterfaceType> availableInterfaceTypes(NbiPort nbiPort) {
    List<PhysicalPort> allocatedPorts =
        physicalPortService.findAllocatedByNmsPortId(nbiPort.getNmsPortId());
    Set<InterfaceType> allocatedInterfaceTypes =
        allocatedPorts.stream().map(PhysicalPort::getInterfaceType).collect(Collectors.toSet());

    if (allocatedInterfaceTypes.contains(InterfaceType.E_NNI)) {
      return Arrays.asList(InterfaceType.E_NNI);
    } else if (allocatedInterfaceTypes.contains(InterfaceType.UNI)) {
      return Arrays.asList(InterfaceType.UNI);
    } else {
      return Arrays.asList(InterfaceType.values());
    }
  }
  @RequestMapping(value = DELETE, params = ID_KEY, method = RequestMethod.DELETE)
  public String delete(
      Long id, @RequestParam(value = PAGE_KEY, required = false) Integer page, Model uiModel) {
    return physicalPortService
        .find(id)
        .map(
            port -> {
              if (port instanceof UniPort) {
                virtualServiceService
                    .findEntriesForUniPort((UniPort) port)
                    .forEach(
                        service ->
                            virtualServiceService.delete(service, Security.getUserDetails()));
              }

              physicalPortService.delete(id);

              uiModel.asMap().clear();
              uiModel.addAttribute(PAGE_KEY, page == null ? "1" : page.toString());

              return redirectPortListPage(port);
            })
        .orElse("redirect:");
  }
  @Test
  public void listAllUnallocatedPortsShouldSetPorts() throws Exception {
    when(physicalPortServiceMock.findUnallocatedPorts())
        .thenReturn(
            FluentIterable.from(
                    Iterables.cycle(
                        new UnallocatedPortView(
                            new NbiPortFactory().setSuggestedNocLabel("NOC label").create(),
                            Collections.emptyList())))
                .limit(100)
                .toList());

    mockMvc
        .perform(get("/noc/physicalports/free"))
        .andExpect(status().isOk())
        .andExpect(
            model().<Collection<?>>attribute(DATA_LIST, hasSize(WebUtils.MAX_ITEMS_PER_PAGE)))
        .andExpect(model().attribute("filterSelect", PhysicalPortFilter.UN_ALLOCATED))
        .andExpect(
            model()
                .attribute(
                    WebUtils.MAX_PAGES_KEY,
                    (int) Math.ceil((float) 100 / WebUtils.MAX_ITEMS_PER_PAGE)));
  }
  @RequestMapping(method = RequestMethod.POST)
  public String create(
      @Valid CreatePhysicalPortCommand command,
      BindingResult result,
      RedirectAttributes redirectAttributes,
      Model model) {
    PhysicalPort physicalPort = physicalPortService.findByBodPortId(command.getBodPortId());
    if (physicalPort != null) {
      result.rejectValue("bodPortId", "validation.not.unique");
    }

    Optional<NbiPort> maybeNbiPort = physicalPortService.findNbiPort(command.getNmsPortId());
    if (!maybeNbiPort.isPresent()) {
      return "redirect:";
    }

    NbiPort nbiPort = maybeNbiPort.get();

    command.validate(nbiPort, bodEnvironment.getBodTopologyName(), result);

    if (result.hasErrors()) {
      model.addAttribute("interfaceTypes", availableInterfaceTypes(nbiPort));
      model.addAttribute("availableTopologies", physicalPortService.findTopologyNames());
      model.addAttribute("vlanRequired", nbiPort.isVlanRequired());
      model.addAttribute("createPhysicalPortCommand", command);

      return PAGE_URL + CREATE;
    }

    PhysicalPort port;
    switch (command.getInterfaceType()) {
      case E_NNI:
        port = createEnniPort(command, nbiPort);

        messageManager.addInfoFlashMessage(
            redirectAttributes, "info_physicalport_enni_created", port.getNocLabel());

        break;
      case UNI:
        UniPort uniPort = createUniPort(command, nbiPort);

        messageManager.addInfoFlashMessage(
            redirectAttributes,
            "info_physicalport_uni_created",
            uniPort.getNocLabel(),
            uniPort.getPhysicalResourceGroup().getName());

        port = uniPort;
        break;
      default:
        throw new IllegalArgumentException("unknown interface type " + command.getInterfaceType());
    }

    try {
      physicalPortService.save(port);
    } catch (OverlappingSubportAllocationException e) {
      result.reject(e.getMessage());
      model.addAttribute("interfaceTypes", availableInterfaceTypes(nbiPort));
      model.addAttribute("availableTopologies", physicalPortService.findTopologyNames());
      model.addAttribute("vlanRequired", nbiPort.isVlanRequired());
      model.addAttribute("createPhysicalPortCommand", command);

      return PAGE_URL + CREATE;
    }

    return redirectPortListPage(port);
  }