@Override public EurekaHttpResponse<Void> statusUpdate(String appName, String id, InstanceStatus newStatus, InstanceInfo info) { String urlPath = "apps/" + appName + '/' + id + "/status"; Response response = null; try { Builder requestBuilder = jerseyClient.target(serviceUrl) .path(urlPath) .queryParam("value", newStatus.name()) .queryParam("lastDirtyTimestamp", info.getLastDirtyTimestamp().toString()) .request(); addExtraProperties(requestBuilder); addExtraHeaders(requestBuilder); response = requestBuilder.put(Entity.entity("{}", MediaType.APPLICATION_JSON_TYPE)); // Jersey2 refuses to handle PUT with no body return anEurekaHttpResponse(response.getStatus()).headers(headersOf(response)).build(); } finally { if (logger.isDebugEnabled()) { logger.debug("Jersey2 HTTP PUT {}/{}; statusCode={}", serviceUrl, urlPath, response == null ? "N/A" : response.getStatus()); } if (response != null) { response.close(); } } }
/** * Populates the provided instance count map. The instance count map is used * as part of the general app list synchronization mechanism. * * @param instanceCountMap * the map to populate */ public void populateInstanceCountMap(Map<String, AtomicInteger> instanceCountMap) { for (Application app : this.getRegisteredApplications()) { for (InstanceInfo info : app.getInstancesAsIsFromEureka()) { AtomicInteger instanceCount = instanceCountMap.computeIfAbsent(info.getStatus().name(), k -> new AtomicInteger(0)); instanceCount.incrementAndGet(); } } }
.queryParam("lastDirtyTimestamp", info.getLastDirtyTimestamp().toString()); if (overriddenStatus != null) { webResource = webResource.queryParam("overriddenstatus", overriddenStatus.name());
@Override public EurekaHttpResponse<InstanceInfo> sendHeartBeat(String appName, String id, InstanceInfo info, InstanceStatus overriddenStatus) { String urlPath = "apps/" + appName + '/' + id; ClientResponse response = null; try { WebResource webResource = jerseyClient.resource(serviceUrl) .path(urlPath) .queryParam("status", info.getStatus().toString()) .queryParam("lastDirtyTimestamp", info.getLastDirtyTimestamp().toString()); if (overriddenStatus != null) { webResource = webResource.queryParam("overriddenstatus", overriddenStatus.name()); } Builder requestBuilder = webResource.getRequestBuilder(); addExtraHeaders(requestBuilder); response = requestBuilder.put(ClientResponse.class); EurekaHttpResponseBuilder<InstanceInfo> eurekaResponseBuilder = anEurekaHttpResponse(response.getStatus(), InstanceInfo.class).headers(headersOf(response)); if (response.hasEntity()) { eurekaResponseBuilder.entity(response.getEntity(InstanceInfo.class)); } return eurekaResponseBuilder.build(); } finally { if (logger.isDebugEnabled()) { logger.debug("Jersey HTTP PUT {}/{}; statusCode={}", serviceUrl, urlPath, response == null ? "N/A" : response.getStatus()); } if (response != null) { response.close(); } } }
.queryParam("lastDirtyTimestamp", info.getLastDirtyTimestamp().toString()); if (overriddenStatus != null) { webResource = webResource.queryParam("overriddenstatus", overriddenStatus.name());
@Test public void testPopulateInstanceCount() { DataCenterInfo myDCI = new DataCenterInfo() { public DataCenterInfo.Name getName() { return DataCenterInfo.Name.MyOwn; } }; InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder() .setAppName("test") .setVIPAddress("test.testname:1") .setSecureVIPAddress("securetest.testname:7102") .setDataCenterInfo(myDCI) .setHostName("test.hostname") .setStatus(InstanceStatus.UP) .build(); Application application = new Application("TestApp"); application.addInstance(instanceInfo); Applications applications = new Applications(); applications.addApplication(application); TreeMap<String, AtomicInteger> instanceCountMap = new TreeMap<>(); applications.populateInstanceCountMap(instanceCountMap); assertEquals(1, instanceCountMap.size()); assertNotNull(instanceCountMap.get(InstanceStatus.UP.name())); assertEquals(1, instanceCountMap.get(InstanceStatus.UP.name()).get()); }
@Override public StatusOverrideResult apply(InstanceInfo instanceInfo, Lease<InstanceInfo> existingLease, boolean isReplication) { // This is for backward compatibility until all applications have ASG // names, otherwise while starting up // the client status may override status replicated from other servers if (!isReplication) { InstanceInfo.InstanceStatus existingStatus = null; if (existingLease != null) { existingStatus = existingLease.getHolder().getStatus(); } // Allow server to have its way when the status is UP or OUT_OF_SERVICE if ((existingStatus != null) && (InstanceInfo.InstanceStatus.OUT_OF_SERVICE.equals(existingStatus) || InstanceInfo.InstanceStatus.UP.equals(existingStatus))) { logger.debug("There is already an existing lease with status {} for instance {}", existingLease.getHolder().getStatus().name(), existingLease.getHolder().getId()); return StatusOverrideResult.matchingStatus(existingLease.getHolder().getStatus()); } } return StatusOverrideResult.NO_MATCH; }
@Test public void testBatchRequestEncoding() throws Exception { InstanceInfo instance = InstanceInfoGenerator.takeOne(); List<ReplicationInstance> replicationInstances = new ArrayList<>(); replicationInstances.add(new ReplicationInstance( instance.getAppName(), instance.getId(), System.currentTimeMillis(), null, instance.getStatus().name(), instance, Action.Register )); final ReplicationList replicationList = new ReplicationList(replicationInstances); Action2 codingAction = new Action2() { @Override public void call(EncoderWrapper encodingCodec, DecoderWrapper decodingCodec) throws IOException { String encodedString = encodingCodec.encode(replicationList); ReplicationList decodedValue = decodingCodec.decode(encodedString, ReplicationList.class); assertThat(decodedValue.getReplicationList().size(), is(equalTo(1))); } }; // In replication channel we use JSON only List<CodecWrapper> jsonCodes = Arrays.asList( new CodecWrappers.JacksonJson(), new CodecWrappers.LegacyJacksonJson() ); verifyAllPairs(codingAction, ReplicationList.class, jsonCodes); }
/** * Stores overridden status if it is not already there. This happens during * a reconciliation process during renewal requests. * * @param appName the application name of the instance. * @param id the unique identifier of the instance. * @param overriddenStatus overridden status if any. */ @Override public void storeOverriddenStatusIfRequired(String appName, String id, InstanceStatus overriddenStatus) { InstanceStatus instanceStatus = overriddenInstanceStatusMap.get(id); if ((instanceStatus == null) || (!overriddenStatus.equals(instanceStatus))) { // We might not have the overridden status if the server got // restarted -this will help us maintain the overridden state // from the replica logger.info("Adding overridden status for instance id {} and the value is {}", id, overriddenStatus.name()); overriddenInstanceStatusMap.put(id, overriddenStatus); InstanceInfo instanceInfo = this.getInstanceByAppAndId(appName, id, false); instanceInfo.setOverriddenStatus(overriddenStatus); logger.info("Set the overridden status for instance (appname:{}, id:{}} and the value is {} ", appName, id, overriddenStatus.name()); } }
@Override public EurekaHttpResponse<Void> statusUpdate(String appName, String id, InstanceStatus newStatus, InstanceInfo info) { String urlPath = "apps/" + appName + '/' + id + "/status"; ClientResponse response = null; try { Builder requestBuilder = jerseyClient.resource(serviceUrl) .path(urlPath) .queryParam("value", newStatus.name()) .queryParam("lastDirtyTimestamp", info.getLastDirtyTimestamp().toString()) .getRequestBuilder(); addExtraHeaders(requestBuilder); response = requestBuilder.put(ClientResponse.class); return anEurekaHttpResponse(response.getStatus()).headers(headersOf(response)).build(); } finally { if (logger.isDebugEnabled()) { logger.debug("Jersey HTTP PUT {}/{}; statusCode={}", serviceUrl, urlPath, response == null ? "N/A" : response.getStatus()); } if (response != null) { response.close(); } } }
@Override public String getStatus(InstanceInfo info) { Version version = CurrentRequestVersion.get(); if (version == null || version == Version.V1) { InstanceStatus status = info.getStatus(); switch (status) { case DOWN: case STARTING: case UP: break; default: // otherwise return DOWN status = InstanceStatus.DOWN; break; } return status.name(); } else { return super.getStatus(info); } } }
private static ReplicationInstance createReplicationInstanceOf(InstanceReplicationTask task) { ReplicationInstanceBuilder instanceBuilder = aReplicationInstance(); instanceBuilder.withAppName(task.getAppName()); instanceBuilder.withId(task.getId()); InstanceInfo instanceInfo = task.getInstanceInfo(); if (instanceInfo != null) { String overriddenStatus = task.getOverriddenStatus() == null ? null : task.getOverriddenStatus().name(); instanceBuilder.withOverriddenStatus(overriddenStatus); instanceBuilder.withLastDirtyTimestamp(instanceInfo.getLastDirtyTimestamp()); if (task.shouldReplicateInstanceInfo()) { instanceBuilder.withInstanceInfo(instanceInfo); } String instanceStatus = instanceInfo.getStatus() == null ? null : instanceInfo.getStatus().name(); instanceBuilder.withStatus(instanceStatus); } instanceBuilder.withAction(task.getAction()); return instanceBuilder.build(); } }
@Test public void testBatch() throws Exception { InstanceInfo instanceInfo = instanceInfoIt.next(); ReplicationInstance replicationInstance = ReplicationInstance.replicationInstance() .withAction(Action.Register) .withAppName(instanceInfo.getAppName()) .withId(instanceInfo.getId()) .withInstanceInfo(instanceInfo) .withLastDirtyTimestamp(System.currentTimeMillis()) .withStatus(instanceInfo.getStatus().name()) .build(); EurekaHttpResponse<ReplicationListResponse> httpResponse = jerseyReplicationClient.submitBatchUpdates(new ReplicationList(replicationInstance)); assertThat(httpResponse.getStatusCode(), is(equalTo(200))); List<ReplicationInstanceResponse> replicationListResponse = httpResponse.getEntity().getResponseList(); assertThat(replicationListResponse.size(), is(equalTo(1))); assertThat(replicationListResponse.get(0).getStatusCode(), is(equalTo(200))); }
public String getStatus(InstanceInfo info) { return info.getStatus().name(); }
private void expectStatus(InstanceInfo.InstanceStatus expected, long timeout, TimeUnit timeUnit) throws InterruptedException { String status = mockLocalEurekaServer.registrationStatusesQueue.poll(timeout, timeUnit); Assert.assertEquals(expected.name(), status); }
@Test public void testHeartbeat() throws Exception { when(instanceResource.renewLease(anyString(), anyString(), anyString(), anyString())).thenReturn(Response.ok().build()); ReplicationInstance replicationInstance = newReplicationInstanceOf(Action.Heartbeat, instanceInfo); Response response = peerReplicationResource.batchReplication(new ReplicationList(replicationInstance)); assertStatusOkReply(response); verify(instanceResource, times(1)).renewLease( "true", replicationInstance.getOverriddenStatus(), instanceInfo.getStatus().name(), Long.toString(replicationInstance.getLastDirtyTimestamp()) ); }
@Test public void testStatusOverrideDeleteReturnsNotFoundErrorCodeIfInstanceNotRegistered() throws Exception { Response response = instanceResource.deleteStatusUpdate(InstanceStatus.OUT_OF_SERVICE.name(), "false", "0"); assertThat(response.getStatus(), is(equalTo(Status.NOT_FOUND.getStatusCode()))); }
@Override public StatusOverrideResult apply(InstanceInfo instanceInfo, Lease<InstanceInfo> existingLease, boolean isReplication) { InstanceInfo.InstanceStatus overridden = statusOverrides.get(instanceInfo.getId()); // If there are instance specific overrides, then they win - otherwise the ASG status if (overridden != null) { logger.debug("The instance specific override for instance {} and the value is {}", instanceInfo.getId(), overridden.name()); return StatusOverrideResult.matchingStatus(overridden); } return StatusOverrideResult.NO_MATCH; }
@Test public void testStatusOverrideReturnsNotFoundErrorCodeIfInstanceNotRegistered() throws Exception { Response response = instanceResource.statusUpdate(InstanceStatus.OUT_OF_SERVICE.name(), "false", "0"); assertThat(response.getStatus(), is(equalTo(Status.NOT_FOUND.getStatusCode()))); }