@Test
  public void testBadRegistrationOfDataCenterInfo() throws Exception {
    try {
      // test 400 when configured to return client error
      ConfigurationManager.getConfigInstance()
          .setProperty("eureka.experimental.registration.validation.dataCenterInfoId", "true");
      InstanceInfo instanceInfo = spy(InstanceInfoGenerator.takeOne());
      when(instanceInfo.getDataCenterInfo()).thenReturn(new TestDataCenterInfo());
      Response response = applicationResource.addInstance(instanceInfo, false + "");
      assertThat(response.getStatus(), is(400));

      // test backfill of data for AmazonInfo
      ConfigurationManager.getConfigInstance()
          .setProperty("eureka.experimental.registration.validation.dataCenterInfoId", "false");
      instanceInfo = spy(InstanceInfoGenerator.takeOne());
      assertThat(instanceInfo.getDataCenterInfo(), instanceOf(AmazonInfo.class));
      ((AmazonInfo) instanceInfo.getDataCenterInfo())
          .getMetadata()
          .remove(AmazonInfo.MetaDataKey.instanceId.getName()); // clear the Id
      response = applicationResource.addInstance(instanceInfo, false + "");
      assertThat(response.getStatus(), is(204));

    } finally {
      ConfigurationManager.getConfigInstance()
          .clearProperty("eureka.experimental.registration.validation.dataCenterInfoId");
    }
  }
Esempio n. 2
0
  /** Unbind the EIP that this instance is associated with. */
  public void unbindEIP() throws Exception {
    InstanceInfo myInfo = applicationInfoManager.getInfo();
    String myPublicIP = null;
    if (myInfo != null && myInfo.getDataCenterInfo().getName() == Name.Amazon) {
      myPublicIP = ((AmazonInfo) myInfo.getDataCenterInfo()).get(MetaDataKey.publicIpv4);
      if (myPublicIP == null) {
        logger.info("Instance is not associated with an EIP. Will not try to unbind");
        return;
      }

      try {
        AmazonEC2 ec2Service = getEC2Service();
        DescribeAddressesRequest describeAddressRequest =
            new DescribeAddressesRequest().withPublicIps(myPublicIP);
        DescribeAddressesResult result = ec2Service.describeAddresses(describeAddressRequest);
        if ((result.getAddresses() != null) && (!result.getAddresses().isEmpty())) {
          Address eipAddress = result.getAddresses().get(0);
          DisassociateAddressRequest dissociateRequest = new DisassociateAddressRequest();
          String domain = eipAddress.getDomain();
          if ("vpc".equals(domain)) {
            dissociateRequest.setAssociationId(eipAddress.getAssociationId());
          } else {
            dissociateRequest.setPublicIp(eipAddress.getPublicIp());
          }

          ec2Service.disassociateAddress(dissociateRequest);
          logger.info("Dissociated the EIP {} from this instance", myPublicIP);
        }
      } catch (Throwable e) {
        throw new RuntimeException("Cannot dissociate address from this instance", e);
      }
    }
  }
Esempio n. 3
0
  /**
   * Checks if an EIP is already bound to the instance.
   *
   * @return true if an EIP is bound, false otherwise
   */
  public boolean isEIPBound() {
    InstanceInfo myInfo = applicationInfoManager.getInfo();
    String myInstanceId = ((AmazonInfo) myInfo.getDataCenterInfo()).get(MetaDataKey.instanceId);
    String myZone = ((AmazonInfo) myInfo.getDataCenterInfo()).get(MetaDataKey.availabilityZone);
    String myPublicIP = ((AmazonInfo) myInfo.getDataCenterInfo()).get(MetaDataKey.publicIpv4);

    Collection<String> candidateEIPs = getCandidateEIPs(myInstanceId, myZone);
    for (String eipEntry : candidateEIPs) {
      if (eipEntry.equals(myPublicIP)) {
        logger.info(
            "My instance {} seems to be already associated with the public ip {}",
            myInstanceId,
            myPublicIP);
        return true;
      }
    }
    return false;
  }
  @Test
  public void testBadRegistration() throws Exception {
    InstanceInfo instanceInfo = spy(InstanceInfoGenerator.takeOne());
    when(instanceInfo.getId()).thenReturn(null);
    Response response = applicationResource.addInstance(instanceInfo, false + "");
    assertThat(response.getStatus(), is(400));

    instanceInfo = spy(InstanceInfoGenerator.takeOne());
    when(instanceInfo.getHostName()).thenReturn(null);
    response = applicationResource.addInstance(instanceInfo, false + "");
    assertThat(response.getStatus(), is(400));

    instanceInfo = spy(InstanceInfoGenerator.takeOne());
    when(instanceInfo.getAppName()).thenReturn("");
    response = applicationResource.addInstance(instanceInfo, false + "");
    assertThat(response.getStatus(), is(400));

    instanceInfo = spy(InstanceInfoGenerator.takeOne());
    when(instanceInfo.getAppName()).thenReturn(applicationResource.getName() + "extraExtra");
    response = applicationResource.addInstance(instanceInfo, false + "");
    assertThat(response.getStatus(), is(400));

    instanceInfo = spy(InstanceInfoGenerator.takeOne());
    when(instanceInfo.getDataCenterInfo()).thenReturn(null);
    response = applicationResource.addInstance(instanceInfo, false + "");
    assertThat(response.getStatus(), is(400));

    instanceInfo = spy(InstanceInfoGenerator.takeOne());
    when(instanceInfo.getDataCenterInfo())
        .thenReturn(
            new DataCenterInfo() {
              @Override
              public Name getName() {
                return null;
              }
            });
    response = applicationResource.addInstance(instanceInfo, false + "");
    assertThat(response.getStatus(), is(400));
  }
Esempio n. 5
0
  /**
   * Checks if an EIP is bound and optionally binds the EIP.
   *
   * <p>The list of EIPs are arranged with the EIPs allocated in the zone first followed by other
   * EIPs.
   *
   * <p>If an EIP is already bound to this instance this method simply returns. Otherwise, this
   * method tries to find an unused EIP based on information from AWS. If it cannot find any unused
   * EIP this method, it will be retried for a specified interval.
   *
   * <p>One of the following scenarios can happen here :
   *
   * <p>1) If the instance is already bound to an EIP as deemed by AWS, no action is taken. 2) If an
   * EIP is already bound to another instance as deemed by AWS, that EIP is skipped. 3) If an EIP is
   * not already bound to an instance and if this instance is not bound to an EIP, then the EIP is
   * bound to this instance.
   */
  public void bindEIP() {
    InstanceInfo myInfo = applicationInfoManager.getInfo();
    String myInstanceId = ((AmazonInfo) myInfo.getDataCenterInfo()).get(MetaDataKey.instanceId);
    String myZone = ((AmazonInfo) myInfo.getDataCenterInfo()).get(MetaDataKey.availabilityZone);

    Collection<String> candidateEIPs = getCandidateEIPs(myInstanceId, myZone);

    AmazonEC2 ec2Service = getEC2Service();
    boolean isMyinstanceAssociatedWithEIP = false;
    Address selectedEIP = null;

    for (String eipEntry : candidateEIPs) {
      try {
        String associatedInstanceId;

        // Check with AWS, if this EIP is already been used by another instance
        DescribeAddressesRequest describeAddressRequest =
            new DescribeAddressesRequest().withPublicIps(eipEntry);
        DescribeAddressesResult result = ec2Service.describeAddresses(describeAddressRequest);
        if ((result.getAddresses() != null) && (!result.getAddresses().isEmpty())) {
          Address eipAddress = result.getAddresses().get(0);
          associatedInstanceId = eipAddress.getInstanceId();
          // This EIP is not used by any other instance, hence mark it for selection if it is not
          // already marked.
          if (((associatedInstanceId == null) || (associatedInstanceId.isEmpty()))) {
            if (selectedEIP == null) {
              selectedEIP = eipAddress;
            }
          } else if (isMyinstanceAssociatedWithEIP = (associatedInstanceId.equals(myInstanceId))) {
            // This EIP is associated with an instance, check if this is the same as the current
            // instance.
            // If it is the same, stop searching for an EIP as this instance is already associated
            // with an
            // EIP
            selectedEIP = eipAddress;
            break;
          } else {
            // The EIP is used by some other instance, hence skip it
            logger.warn(
                "The selected EIP {} is associated with another instance {} according to AWS,"
                    + " hence skipping this",
                eipEntry,
                associatedInstanceId);
          }
        }
      } catch (Throwable t) {
        logger.error("Failed to bind elastic IP: {} to {}", eipEntry, myInstanceId, t);
      }
    }
    if (null != selectedEIP) {
      String publicIp = selectedEIP.getPublicIp();
      // Only bind if the EIP is not already associated
      if (!isMyinstanceAssociatedWithEIP) {

        AssociateAddressRequest associateAddressRequest =
            new AssociateAddressRequest().withInstanceId(myInstanceId);

        String domain = selectedEIP.getDomain();
        if ("vpc".equals(domain)) {
          associateAddressRequest.setAllocationId(selectedEIP.getAllocationId());
        } else {
          associateAddressRequest.setPublicIp(publicIp);
        }

        ec2Service.associateAddress(associateAddressRequest);
        logger.info(
            "\n\n\nAssociated {} running in zone: {} to elastic IP: {}",
            myInstanceId,
            myZone,
            publicIp);
      }
      logger.info(
          "My instance {} seems to be already associated with the EIP {}", myInstanceId, publicIp);
    } else {
      logger.info(
          "No EIP is free to be associated with this instance. Candidate EIPs are: {}",
          candidateEIPs);
    }
  }
Esempio n. 6
0
    /*
     * (non-Javadoc)
     *
     * @see
     * com.thoughtworks.xstream.converters.Converter#marshal(java.lang.Object
     * , com.thoughtworks.xstream.io.HierarchicalStreamWriter,
     * com.thoughtworks.xstream.converters.MarshallingContext)
     */
    @Override
    public void marshal(
        Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
      InstanceInfo info = (InstanceInfo) source;

      if (info.getInstanceId() != null) {
        writer.startNode(ELEM_INSTANCE_ID);
        writer.setValue(info.getInstanceId());
        writer.endNode();
      }

      writer.startNode(ELEM_HOST);
      writer.setValue(info.getHostName());
      writer.endNode();

      writer.startNode(ELEM_APP);
      writer.setValue(info.getAppName());
      writer.endNode();

      writer.startNode(ELEM_IP);
      writer.setValue(info.getIPAddr());
      writer.endNode();

      if (!("unknown".equals(info.getSID()) || "na".equals(info.getSID()))) {
        writer.startNode(ELEM_SID);
        writer.setValue(info.getSID());
        writer.endNode();
      }

      writer.startNode(ELEM_STATUS);
      writer.setValue(getStatus(info));
      writer.endNode();

      writer.startNode(ELEM_OVERRIDDEN_STATUS);
      writer.setValue(info.getOverriddenStatus().name());
      writer.endNode();

      writer.startNode(ELEM_PORT);
      writer.addAttribute(ATTR_ENABLED, String.valueOf(info.isPortEnabled(PortType.UNSECURE)));
      writer.setValue(String.valueOf(info.getPort()));
      writer.endNode();

      writer.startNode(ELEM_SECURE_PORT);
      writer.addAttribute(ATTR_ENABLED, String.valueOf(info.isPortEnabled(PortType.SECURE)));
      writer.setValue(String.valueOf(info.getSecurePort()));
      writer.endNode();

      writer.startNode(ELEM_COUNTRY_ID);
      writer.setValue(String.valueOf(info.getCountryId()));
      writer.endNode();

      if (info.getDataCenterInfo() != null) {
        writer.startNode(NODE_DATACENTER);
        // This is needed for backward compat. for now.
        if (info.getDataCenterInfo().getName() == Name.Amazon) {
          writer.addAttribute("class", "com.netflix.appinfo.AmazonInfo");
        } else {
          writer.addAttribute("class", "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo");
        }
        context.convertAnother(info.getDataCenterInfo());
        writer.endNode();
      }

      if (info.getLeaseInfo() != null) {
        writer.startNode(NODE_LEASE);
        context.convertAnother(info.getLeaseInfo());
        writer.endNode();
      }

      if (info.getMetadata() != null) {
        writer.startNode(NODE_METADATA);
        // for backward compat. for now
        if (info.getMetadata().size() == 0) {
          writer.addAttribute("class", "java.util.Collections$EmptyMap");
        }
        context.convertAnother(info.getMetadata());
        writer.endNode();
      }
      autoMarshalEligible(source, writer);
    }