Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Current config save handles multiple scenarios so there are repetitive preprocess, validation, cloning..., which is one of reason for slow config updates on servers with large config. * This commit introduces an optimized config save which handles only full config saves through UI, API, config upgrade(during server restart) and config loads(timer every 5 secs) * Entity updates through UI which do not have an API still follow the old flow. * Config save can be toggled between new and old flow using the System Environment 'optimize.full.config.save', this is 'true' by default.
- Loading branch information
Showing
27 changed files
with
1,739 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 152 additions & 0 deletions
152
server/src/com/thoughtworks/go/config/FullConfigSaveFlow.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
/* | ||
* Copyright 2016 ThoughtWorks, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.thoughtworks.go.config; | ||
|
||
import com.rits.cloning.Cloner; | ||
import com.thoughtworks.go.config.registry.ConfigElementImplementationRegistry; | ||
import com.thoughtworks.go.config.remote.FileConfigOrigin; | ||
import com.thoughtworks.go.config.remote.PartialConfig; | ||
import com.thoughtworks.go.config.update.FullConfigUpdateCommand; | ||
import com.thoughtworks.go.domain.GoConfigRevision; | ||
import com.thoughtworks.go.server.util.ServerVersion; | ||
import com.thoughtworks.go.service.ConfigRepository; | ||
import com.thoughtworks.go.util.CachedDigestUtils; | ||
import com.thoughtworks.go.util.SystemEnvironment; | ||
import com.thoughtworks.go.util.TimeProvider; | ||
import org.jdom.Document; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
|
||
public abstract class FullConfigSaveFlow { | ||
protected final MagicalGoConfigXmlLoader loader; | ||
protected final MagicalGoConfigXmlWriter writer; | ||
protected final ServerVersion serverVersion; | ||
protected final TimeProvider timeProvider; | ||
protected final ConfigRepository configRepository; | ||
protected final CachedGoPartials cachedGoPartials; | ||
protected final GoConfigFileWriter fileWriter; | ||
protected final ConfigElementImplementationRegistry configElementImplementationRegistry; | ||
protected final Cloner cloner = new Cloner(); | ||
protected final Logger LOGGER = LoggerFactory.getLogger(getClass().getName()); | ||
|
||
public FullConfigSaveFlow(MagicalGoConfigXmlLoader loader, MagicalGoConfigXmlWriter writer, | ||
ConfigElementImplementationRegistry configElementImplementationRegistry, | ||
ServerVersion serverVersion, TimeProvider timeProvider, | ||
ConfigRepository configRepository, CachedGoPartials cachedGoPartials, | ||
GoConfigFileWriter fileWriter) { | ||
this.loader = loader; | ||
this.writer = writer; | ||
this.configElementImplementationRegistry = configElementImplementationRegistry; | ||
this.serverVersion = serverVersion; | ||
this.timeProvider = timeProvider; | ||
this.configRepository = configRepository; | ||
this.cachedGoPartials = cachedGoPartials; | ||
this.fileWriter = fileWriter; | ||
} | ||
|
||
public FullConfigSaveFlow(MagicalGoConfigXmlLoader loader, MagicalGoConfigXmlWriter writer, | ||
ConfigElementImplementationRegistry configElementImplementationRegistry, | ||
SystemEnvironment systemEnvironment, ServerVersion serverVersion, | ||
TimeProvider timeProvider, ConfigRepository configRepository, CachedGoPartials cachedGoPartials) { | ||
this(loader, writer, configElementImplementationRegistry, serverVersion, timeProvider, configRepository, cachedGoPartials, | ||
new GoConfigFileWriter(systemEnvironment)); | ||
} | ||
|
||
public abstract GoConfigHolder execute(FullConfigUpdateCommand updatingCommand, List<PartialConfig> partials, String currentUser) throws Exception; | ||
|
||
protected void postValidationUpdates(CruiseConfig preProcessedConfig, CruiseConfig configForEdit, String xmlString, List<PartialConfig> partials) throws NoSuchFieldException, IllegalAccessException { | ||
String md5 = CachedDigestUtils.md5Hex(xmlString); | ||
|
||
configForEdit.setOrigins(new FileConfigOrigin()); | ||
preProcessedConfig.setOrigins(new FileConfigOrigin()); | ||
|
||
MagicalGoConfigXmlLoader.setMd5(preProcessedConfig, md5); | ||
MagicalGoConfigXmlLoader.setMd5(configForEdit, md5); | ||
|
||
cachedGoPartials.markAsValid(partials); | ||
} | ||
|
||
protected String toXmlString(CruiseConfig configForEdit) throws Exception { | ||
Document document = documentFrom(configForEdit); | ||
|
||
validateDocument(document); | ||
|
||
return toXmlString(document); | ||
} | ||
|
||
protected void checkinToConfigRepo(String currentUser, CruiseConfig updatedConfig, String xmlString) throws Exception { | ||
LOGGER.debug("[Config Save] Checkin updated config to git: Starting."); | ||
configRepository.checkin(new GoConfigRevision(xmlString, updatedConfig.getMd5(), currentUser, serverVersion.version(), timeProvider)); | ||
LOGGER.debug("[Config Save] Checkin updated config to git: Done."); | ||
} | ||
|
||
protected void writeToConfigXml(String xmlString) { | ||
LOGGER.debug("[Config Save] Writing config xml to file: Starting."); | ||
this.fileWriter.writeToConfigXmlFile(xmlString); | ||
LOGGER.debug("[Config Save] Writing config xml to file: Done."); | ||
} | ||
|
||
protected CruiseConfig configForEditWithPartials(FullConfigUpdateCommand updatingCommand, List<PartialConfig> partials) throws Exception { | ||
CruiseConfig config = updatingCommand.configForEdit(); | ||
config.setPartials(partials); | ||
|
||
return config; | ||
} | ||
|
||
protected CruiseConfig preprocessAndValidate(CruiseConfig configForEdit) throws Exception { | ||
return loader.preprocessAndValidate(configForEdit); | ||
} | ||
|
||
protected org.jdom.Document documentFrom(CruiseConfig configForEdit) { | ||
LOGGER.debug("[Config Save] Building Document from CruiseConfig object: Starting."); | ||
Document document = writer.documentFrom(configForEdit); | ||
LOGGER.debug("[Config Save] Building Document from CruiseConfig object: Done."); | ||
|
||
return document; | ||
} | ||
|
||
protected void validateDocument(Document document) throws Exception { | ||
LOGGER.debug("[Config Save] In XSD validation: Starting."); | ||
writer.verifyXsdValid(document); | ||
LOGGER.debug("[Config Save] In XSD validation: Done."); | ||
|
||
LOGGER.debug("[Config Save] In DOM validation: Starting."); | ||
MagicalGoConfigXmlLoader.validateDom(document.getRootElement(), configElementImplementationRegistry); | ||
LOGGER.debug("[Config Save] In DOM validation: Done."); | ||
} | ||
|
||
protected String toXmlString(Document document) throws IOException { | ||
LOGGER.debug("[Config Save] Serializing Document to xml: Starting."); | ||
String xmlString = writer.toString(document); | ||
LOGGER.debug("[Config Save] Serializing Document to xml: Done."); | ||
|
||
return xmlString; | ||
} | ||
|
||
protected void setMergedConfigForEditOn(GoConfigHolder validatedConfigHolder, List<PartialConfig> partials) { | ||
if (partials.isEmpty()) return; | ||
|
||
LOGGER.debug("[Config Save] Updating GoConfigHolder with mergedCruiseConfigForEdit: Starting."); | ||
CruiseConfig mergedCruiseConfigForEdit = cloner.deepClone(validatedConfigHolder.configForEdit); | ||
mergedCruiseConfigForEdit.merge(partials, true); | ||
validatedConfigHolder.mergedConfigForEdit = mergedCruiseConfigForEdit; | ||
LOGGER.debug("[Config Save] Updating GoConfigHolder with mergedCruiseConfigForEdit: Done."); | ||
} | ||
} |
Oops, something went wrong.