Skip to content

Commit

Permalink
Merge pull request cloudfoundry#533 from cloudfoundry/develop
Browse files Browse the repository at this point in the history
Bump developer to master
  • Loading branch information
cdlliuy authored Oct 9, 2019
2 parents 85d8677 + c3af7ca commit a4be98e
Show file tree
Hide file tree
Showing 61 changed files with 3,405 additions and 605 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ You can follow the development progress on [Pivotal Tracker][t].
* Node 6.2 or above
* NPM 3.9.5 or above
* [Cloud Foundry cf command line][f]
* Go 1.7
* Go 1.11 or above

### Database requirement

Expand Down
4 changes: 2 additions & 2 deletions api/lib/oauth/oauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ module.exports = function(settings) {
};
request(options, function(error, response, body) {
if (error) {
logger.error("Failed to check user token via UAA", { "userToken": userToken, "http-options": options, "error": error });
logger.error("Failed to check user token via UAA", { "error": error });
error.statusCode = HttpStatus.INTERNAL_SERVER_ERROR;
callback(error, null);
} else {
Expand All @@ -181,7 +181,7 @@ module.exports = function(settings) {
var errorObj = {
"statusCode": response.statusCode
};
logger.error("Failed to check user token via UAA", { "userToken": userToken, "http-options": options, "error": errorObj, "body": body });
logger.error("Failed to check user token via UAA", { "error": errorObj, "body": body });
callback(errorObj, null);
}
}
Expand Down
6 changes: 0 additions & 6 deletions docs/policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,6 @@

With above definition, schedule #1 and #3 will be applied, while scheudle #2 is ignored.

* If a schedule's start time is earlier than the policy creation/update time, the schedule will not be executed. For example:

- Schedule #1: 09:00 - 13:00 , Everyday

If above schedule is created at 10:00AM someday, it won't take effect when it creates, but will be certainly triggered on the next day.

## Sample Policy

* [Autoscaling policy with dynamic scaling rules][policy-dynamic]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.cloudfoundry.autoscaler.scheduler.dao;

import org.cloudfoundry.autoscaler.scheduler.entity.ActiveScheduleEntity;

import java.util.List;

import org.cloudfoundry.autoscaler.scheduler.entity.ActiveScheduleEntity;

public interface ActiveScheduleDao {

ActiveScheduleEntity find(Long id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import org.cloudfoundry.autoscaler.scheduler.entity.ActiveScheduleEntity;
import org.cloudfoundry.autoscaler.scheduler.util.error.DatabaseValidationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ public class ScheduleEntity {
@JsonProperty(value = "guid")
private String guid;

public void copy(ScheduleEntity orig) {
this.appId = orig.appId;
this.timeZone = orig.timeZone;
this.defaultInstanceMaxCount = orig.defaultInstanceMaxCount;
this.defaultInstanceMinCount = orig.defaultInstanceMinCount;
this.instanceMaxCount = orig.instanceMaxCount;
this.instanceMinCount = orig.instanceMinCount;
this.initialMinInstanceCount = orig.initialMinInstanceCount;
this.guid = orig.guid;
}

public Long getId() {
return id;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package org.cloudfoundry.autoscaler.scheduler.service;

import java.io.IOException;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand All @@ -23,11 +31,13 @@
import org.cloudfoundry.autoscaler.scheduler.rest.model.Schedules;
import org.cloudfoundry.autoscaler.scheduler.rest.model.SynchronizeResult;
import org.cloudfoundry.autoscaler.scheduler.util.ScalingEngineUtil;
import org.cloudfoundry.autoscaler.scheduler.util.ScheduleJobHelper;
import org.cloudfoundry.autoscaler.scheduler.util.ScheduleTypeEnum;
import org.cloudfoundry.autoscaler.scheduler.util.error.DatabaseValidationException;
import org.cloudfoundry.autoscaler.scheduler.util.error.MessageBundleResourceHelper;
import org.cloudfoundry.autoscaler.scheduler.util.error.SchedulerInternalException;
import org.cloudfoundry.autoscaler.scheduler.util.error.ValidationErrorResult;
import org.quartz.CronExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -156,33 +166,45 @@ private void setUpSchedules(String appId, String guid, ApplicationSchedules appl
*/
@Transactional
public void createSchedules(Schedules schedules) {


List<RecurringScheduleEntity> recurringSchedules = schedules.getRecurringSchedule();
List<SpecificDateScheduleEntity> specificDateSchedules = schedules.getSpecificDate();
if (specificDateSchedules != null) {
for (SpecificDateScheduleEntity specificDateScheduleEntity : specificDateSchedules) {

if (recurringSchedules != null) {
for (RecurringScheduleEntity recurringScheduleEntity : recurringSchedules) {
// Persist the schedule in database
SpecificDateScheduleEntity savedScheduleEntity = saveNewSpecificDateSchedule(
specificDateScheduleEntity);
RecurringScheduleEntity savedScheduleEntity = saveNewRecurringSchedule(recurringScheduleEntity);

// Ask ScalingJobManager to create scaling job
if (savedScheduleEntity != null) {
scheduleJobManager.createSimpleJob(savedScheduleEntity);
SpecificDateScheduleEntity compensatorySchedule = createCompensatorySchedule(recurringScheduleEntity);
if (compensatorySchedule != null){
//create a compensatory schedule to bring the first fire back
if (specificDateSchedules == null) {
specificDateSchedules = new ArrayList<SpecificDateScheduleEntity>();
}
specificDateSchedules.add(compensatorySchedule);
logger.debug("add an addition specific date event to compensate the misfire for TODAY: " + compensatorySchedule.toString());
}
scheduleJobManager.createCronJob(savedScheduleEntity);
}
}
}

List<RecurringScheduleEntity> recurringSchedules = schedules.getRecurringSchedule();
if (recurringSchedules != null) {
for (RecurringScheduleEntity recurringScheduleEntity : recurringSchedules) {

if (specificDateSchedules != null) {
for (SpecificDateScheduleEntity specificDateScheduleEntity : specificDateSchedules) {
// Persist the schedule in database
RecurringScheduleEntity savedScheduleEntity = saveNewRecurringSchedule(recurringScheduleEntity);
SpecificDateScheduleEntity savedScheduleEntity = saveNewSpecificDateSchedule(
specificDateScheduleEntity);

// Ask ScalingJobManager to create scaling job
if (savedScheduleEntity != null) {
scheduleJobManager.createCronJob(savedScheduleEntity);
scheduleJobManager.createSimpleJob(savedScheduleEntity);
}
}
}


}

/**
Expand Down Expand Up @@ -218,6 +240,40 @@ private RecurringScheduleEntity saveNewRecurringSchedule(RecurringScheduleEntity
return savedScheduleEntity;
}


private SpecificDateScheduleEntity createCompensatorySchedule(RecurringScheduleEntity recurringScheduleEntity){

SpecificDateScheduleEntity compenstatorySchedule = null;
try {
ZoneId timezone = ZoneId.of(recurringScheduleEntity.getTimeZone());
CronExpression expression = new CronExpression(ScheduleJobHelper.convertRecurringScheduleToCronExpression(
recurringScheduleEntity.getStartTime(), recurringScheduleEntity));
expression.setTimeZone(TimeZone.getTimeZone(timezone));

Date firstValidTime = expression.getNextValidTimeAfter(Date.from(LocalDate.now(timezone).atStartOfDay(timezone).toInstant()));
if (recurringScheduleEntity.getStartTime() == LocalTime.of(0, 0)) {
firstValidTime = expression.getNextValidTimeAfter(Date.from(LocalDate.now(timezone).atStartOfDay(timezone).toInstant().minusSeconds(60)));
}

if (firstValidTime.toInstant().atZone(timezone).toLocalDateTime().isBefore(LocalDateTime.now(timezone))){
if (recurringScheduleEntity.getStartDate() == null ||
!(recurringScheduleEntity.getStartDate().atStartOfDay(timezone).isAfter(ZonedDateTime.now(timezone)))){
compenstatorySchedule = new SpecificDateScheduleEntity();
compenstatorySchedule.copy(recurringScheduleEntity);
LocalDateTime startDateTime = LocalDateTime.now(timezone).plusMinutes(1);
LocalDateTime endDateTime = LocalDateTime.of(LocalDate.now(timezone),recurringScheduleEntity.getEndTime());
compenstatorySchedule.setStartDateTime(startDateTime);
compenstatorySchedule.setEndDateTime(endDateTime);
}
}

} catch (ParseException e) {
logger.error("Invalid parse or clone");
}

return compenstatorySchedule;

}
/**
* Calls private helper methods to delete the schedules from the database and
* calls ScalingJobManager to delete scaling action jobs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;

import org.cloudfoundry.autoscaler.scheduler.dao.ActiveScheduleDao;
Expand Down Expand Up @@ -174,9 +173,10 @@ public void testCreateAndGetSchedules_from_jsonFile() throws Exception {
resultActions = mockMvc.perform(get(TestDataSetupHelper.getSchedulerPath(appId)).accept(MediaType.APPLICATION_JSON));

ApplicationSchedules applicationSchedules = getApplicationSchedulesFromResultActions(resultActions);
assertSchedulesFoundEquals(applicationSchedules, appId, resultActions, 2, 4);
assertSchedulesFoundEquals(applicationSchedules, appId, resultActions, 4, 3);

Mockito.verify(scheduler, Mockito.times(7)).scheduleJob(Mockito.anyObject(), Mockito.anyObject());

Mockito.verify(scheduler, Mockito.times(6)).scheduleJob(Mockito.anyObject(), Mockito.anyObject());
}

@Test
Expand Down
Loading

0 comments on commit a4be98e

Please sign in to comment.