@GetMapping("/by-release")
  public PageDTO<InstanceDTO> getByRelease(@RequestParam("releaseId") long releaseId,
                                           Pageable pageable) {
    Release release = releaseService.findOne(releaseId);
    if (release == null) {
      throw NotFoundException.releaseNotFound(releaseId);
    }
    Page<InstanceConfig> instanceConfigsPage = instanceService.findActiveInstanceConfigsByReleaseKey
        (release.getReleaseKey(), pageable);

    List<InstanceDTO> instanceDTOs = Collections.emptyList();

    if (instanceConfigsPage.hasContent()) {
      Multimap<Long, InstanceConfig> instanceConfigMap = HashMultimap.create();
      Set<String> otherReleaseKeys = Sets.newHashSet();

      for (InstanceConfig instanceConfig : instanceConfigsPage.getContent()) {
        instanceConfigMap.put(instanceConfig.getInstanceId(), instanceConfig);
        otherReleaseKeys.add(instanceConfig.getReleaseKey());
      }

      Set<Long> instanceIds = instanceConfigMap.keySet();

      List<Instance> instances = instanceService.findInstancesByIds(instanceIds);

      if (!CollectionUtils.isEmpty(instances)) {
        instanceDTOs = BeanUtils.batchTransform(InstanceDTO.class, instances);
      }

      for (InstanceDTO instanceDTO : instanceDTOs) {
        Collection<InstanceConfig> configs = instanceConfigMap.get(instanceDTO.getId());
        List<InstanceConfigDTO> configDTOs = configs.stream().map(instanceConfig -> {
          InstanceConfigDTO instanceConfigDTO = new InstanceConfigDTO();
          //to save some space
          instanceConfigDTO.setRelease(null);
          instanceConfigDTO.setReleaseDeliveryTime(instanceConfig.getReleaseDeliveryTime());
          instanceConfigDTO.setDataChangeLastModifiedTime(instanceConfig
              .getDataChangeLastModifiedTime());
          return instanceConfigDTO;
        }).collect(Collectors.toList());
        instanceDTO.setConfigs(configDTOs);
      }
    }

    return new PageDTO<>(instanceDTOs, pageable, instanceConfigsPage.getTotalElements());
  }
@Test
  public void getByRelease() throws Exception {
    long someReleaseId = 1;
    long someInstanceId = 1;
    long anotherInstanceId = 2;
    String someReleaseKey = "someKey";
    Release someRelease = new Release();
    someRelease.setReleaseKey(someReleaseKey);
    String someAppId = "someAppId";
    String anotherAppId = "anotherAppId";
    String someCluster = "someCluster";
    String someDataCenter = "someDC";
    String someConfigAppId = "someConfigAppId";
    String someConfigNamespace = "someNamespace";
    String someIp = "someIp";
    Date someReleaseDeliveryTime = new Date();
    Date anotherReleaseDeliveryTime = new Date();

    when(releaseService.findOne(someReleaseId)).thenReturn(someRelease);

    InstanceConfig someInstanceConfig = assembleInstanceConfig(someInstanceId, someConfigAppId,
        someConfigNamespace, someReleaseKey, someReleaseDeliveryTime);
    InstanceConfig anotherInstanceConfig = assembleInstanceConfig(anotherInstanceId,
        someConfigAppId, someConfigNamespace, someReleaseKey, anotherReleaseDeliveryTime);
    List<InstanceConfig> instanceConfigs = Lists.newArrayList(someInstanceConfig,
        anotherInstanceConfig);
    Page<InstanceConfig> instanceConfigPage = new PageImpl<>(instanceConfigs, pageable,
        instanceConfigs.size());

    when(instanceService.findActiveInstanceConfigsByReleaseKey(someReleaseKey, pageable))
        .thenReturn(instanceConfigPage);

    Instance someInstance = assembleInstance(someInstanceId, someAppId,
        someCluster, someDataCenter, someIp);
    Instance anotherInstance = assembleInstance(anotherInstanceId, anotherAppId,
        someCluster, someDataCenter, someIp);
    List<Instance> instances = Lists.newArrayList(someInstance, anotherInstance);

    Set<Long> instanceIds = Sets.newHashSet(someInstanceId, anotherInstanceId);
    when(instanceService.findInstancesByIds(instanceIds))
        .thenReturn(instances);

    PageDTO<InstanceDTO> result = instanceConfigController.getByRelease(someReleaseId, pageable);

    assertEquals(2, result.getContent().size());
    InstanceDTO someInstanceDto = null;
    InstanceDTO anotherInstanceDto = null;

    for (InstanceDTO instanceDTO : result.getContent()) {
      if (instanceDTO.getId() == someInstanceId) {
        someInstanceDto = instanceDTO;
      } else if (instanceDTO.getId() == anotherInstanceId) {
        anotherInstanceDto = instanceDTO;
      }
    }

    verifyInstance(someInstance, someInstanceDto);
    verifyInstance(anotherInstance, anotherInstanceDto);

    assertEquals(1, someInstanceDto.getConfigs().size());
    assertEquals(someReleaseDeliveryTime, someInstanceDto.getConfigs().get(0).getReleaseDeliveryTime());

    assertEquals(1, anotherInstanceDto.getConfigs().size());
    assertEquals(anotherReleaseDeliveryTime, anotherInstanceDto.getConfigs().get(0).getReleaseDeliveryTime());
  }