/* * 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.server.dao; import com.ibatis.sqlmap.client.SqlMapClient; import com.thoughtworks.go.database.Database; import com.thoughtworks.go.domain.Properties; import com.thoughtworks.go.domain.Property; import com.thoughtworks.go.server.cache.GoCache; import com.thoughtworks.go.server.transaction.SqlMapClientDaoSupport; import com.thoughtworks.go.util.IBatisUtil; import com.thoughtworks.go.util.SystemEnvironment; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Component; import java.util.*; import static com.thoughtworks.go.util.ExceptionUtils.bombUnless; import static com.thoughtworks.go.util.IBatisUtil.arguments; @Component public class PropertySqlMapDao extends SqlMapClientDaoSupport implements PropertyDao { private static final Logger LOGGER = Logger.getLogger(PropertySqlMapDao.class); @Autowired public PropertySqlMapDao(GoCache goCache, SqlMapClient sqlMapClient, SystemEnvironment systemEnvironment, Database database) { super(goCache, sqlMapClient, systemEnvironment, database); } public boolean save(long instanceId, Property property) { ensureExists(instanceId); String propertyName = property.getKey(); try { getSqlMapClientTemplate().insert("saveProperty", arguments("instanceId", instanceId) .and("propertyName", propertyName) .and("value", property.getValue()).asMap() ); return true; } catch (DataAccessException e) { String message = "Error saving property '" + propertyName + "' = '" + property.getValue() + "' on instanceId '" + instanceId + "'"; LOGGER.error(message, e); LOGGER.debug(message, e); return false; } } private void ensureExists(Long instanceId) { Boolean exists = (Boolean) getSqlMapClientTemplate().queryForObject("buildInstanceExists", instanceId); bombUnless(exists, "No instance '" + instanceId + "' found to set property"); } public String value(long instanceId, String propertyName) { Map<String, Object> toGet = new HashMap<>(); toGet.put("instanceId", instanceId); toGet.put("propertyName", propertyName); return (String) getSqlMapClientTemplate().queryForObject("getProperty", toGet); } @SuppressWarnings("unchecked") public Properties list(long buildId) { List<Property> list = getSqlMapClientTemplate() .queryForList("getAllPropertiesByBuildInstanceId", buildId); return new Properties(list); } public List<Properties> loadHistory(String pipelineName, String stageName, String jobName, Long maxPipelineId, Integer limitCount) { IBatisUtil.IBatisArgument arguments = arguments("pipeline", pipelineName) .and("stage", stageName) .and("build", jobName) .and("limitCount", limitCount); if (maxPipelineId != null) { arguments.and("pipelineId", maxPipelineId); } return groupByPipelineId(flatHistory(arguments)); } @SuppressWarnings("unchecked") private List<Map<String, Object>> flatHistory(IBatisUtil.IBatisArgument arguments) { List<Long> pipelineIds = getSqlMapClientTemplate().queryForList("limitedPipelineIds", arguments.asMap()); arguments.and("limitedPipelineIds", pipelineIds); long maxId = Collections.max(pipelineIds); long minId = Collections.min(pipelineIds); arguments = arguments.and("maxId", maxId).and("minId", minId); return (List<Map<String, Object>>) getSqlMapClientTemplate() .queryForList("getAllPropertiesHistory", arguments.asMap()); } static List<Properties> groupByPipelineId(List<Map<String, Object>> flatHistory) { LinkedHashMap<String, Properties> propHistory = new LinkedHashMap<>(); for (Map<String, Object> flatMap : flatHistory) { addToHistory(propHistory, sanitize(flatMap)); } return new ArrayList<>(propHistory.values()); } private static Map<String, Object> sanitize(Map<String, Object> flatMap) { HashMap<String, Object> santizedMap = new HashMap<>(); for (Map.Entry<String, Object> entry : flatMap.entrySet()) { santizedMap.put(entry.getKey().toLowerCase(), entry.getValue()); } return santizedMap; } private static void addToHistory(LinkedHashMap<String, Properties> propHistory, Map<String, Object> flatMap) { String id = String.valueOf(flatMap.get("pipelineid")); String key = (String) flatMap.get("key"); String value = (String) flatMap.get("value"); if (!propHistory.containsKey(id)) { propHistory.put(id, new Properties()); } propHistory.get(id).add(new Property(key, value)); } }