Java tutorial
/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.ambari.server.state.stack.upgrade; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Pattern; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.controller.internal.OperatingSystemResourceProvider; import org.apache.ambari.server.controller.internal.RepositoryResourceProvider; import org.apache.ambari.server.controller.internal.RepositoryVersionResourceProvider; import org.apache.ambari.server.orm.entities.OperatingSystemEntity; import org.apache.ambari.server.orm.entities.RepositoryEntity; import org.apache.ambari.server.state.RepositoryInfo; import org.apache.ambari.server.state.stack.UpgradePack; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.inject.Inject; import com.google.inject.Singleton; /** * Provides helper methods to manage repository versions. */ @Singleton public class RepositoryVersionHelper { private static final Logger LOG = LoggerFactory.getLogger(RepositoryVersionHelper.class); @Inject private Gson gson; @Inject(optional = true) private AmbariMetaInfo ambariMetaInfo; /** * Parses operating systems json to a list of entities. Expects json like: * <pre> * [ * { * "repositories":[ * { * "Repositories/base_url":"http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos5/2.x/updates/2.2.0.0", * "Repositories/repo_name":"HDP-UTILS", * "Repositories/repo_id":"HDP-UTILS-1.1.0.20" * }, * { * "Repositories/base_url":"http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos5/2.x/updates/2.2.0.0", * "Repositories/repo_name":"HDP", * "Repositories/repo_id":"HDP-2.2" * } * ], * "OperatingSystems/os_type":"redhat5" * } * ] * </pre> * @param repositoriesJson operating systems json * @return list of operating system entities * @throws Exception if any kind of json parsing error happened */ public List<OperatingSystemEntity> parseOperatingSystems(String repositoriesJson) throws Exception { final List<OperatingSystemEntity> operatingSystems = new ArrayList<OperatingSystemEntity>(); final JsonArray rootJson = new JsonParser().parse(repositoriesJson).getAsJsonArray(); for (JsonElement operatingSystemJson : rootJson) { final OperatingSystemEntity operatingSystemEntity = new OperatingSystemEntity(); operatingSystemEntity.setOsType(operatingSystemJson.getAsJsonObject() .get(OperatingSystemResourceProvider.OPERATING_SYSTEM_OS_TYPE_PROPERTY_ID).getAsString()); for (JsonElement repositoryJson : operatingSystemJson.getAsJsonObject() .get(RepositoryVersionResourceProvider.SUBRESOURCE_REPOSITORIES_PROPERTY_ID).getAsJsonArray()) { final RepositoryEntity repositoryEntity = new RepositoryEntity(); repositoryEntity.setBaseUrl(repositoryJson.getAsJsonObject() .get(RepositoryResourceProvider.REPOSITORY_BASE_URL_PROPERTY_ID).getAsString()); repositoryEntity.setName(repositoryJson.getAsJsonObject() .get(RepositoryResourceProvider.REPOSITORY_REPO_NAME_PROPERTY_ID).getAsString()); repositoryEntity.setRepositoryId(repositoryJson.getAsJsonObject() .get(RepositoryResourceProvider.REPOSITORY_REPO_ID_PROPERTY_ID).getAsString()); operatingSystemEntity.getRepositories().add(repositoryEntity); } operatingSystems.add(operatingSystemEntity); } return operatingSystems; } /** * Serializes repository info to json for storing to DB. * Produces json like: * <pre> * [ * { * "repositories":[ * { * "Repositories/base_url":"http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos5/2.x/updates/2.2.0.0", * "Repositories/repo_name":"HDP-UTILS", * "Repositories/repo_id":"HDP-UTILS-1.1.0.20" * }, * { * "Repositories/base_url":"http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos5/2.x/updates/2.2.0.0", * "Repositories/repo_name":"HDP", * "Repositories/repo_id":"HDP-2.2" * } * ], * "OperatingSystems/os_type":"redhat5" * } * ] * </pre> * * @param repositories list of repository infos * @return serialized list of operating systems */ public String serializeOperatingSystems(List<RepositoryInfo> repositories) { final JsonArray rootJson = new JsonArray(); final Multimap<String, RepositoryInfo> operatingSystems = ArrayListMultimap.create(); for (RepositoryInfo repository : repositories) { operatingSystems.put(repository.getOsType(), repository); } for (Entry<String, Collection<RepositoryInfo>> operatingSystem : operatingSystems.asMap().entrySet()) { final JsonObject operatingSystemJson = new JsonObject(); final JsonArray repositoriesJson = new JsonArray(); for (RepositoryInfo repository : operatingSystem.getValue()) { final JsonObject repositoryJson = new JsonObject(); repositoryJson.addProperty(RepositoryResourceProvider.REPOSITORY_BASE_URL_PROPERTY_ID, repository.getBaseUrl()); repositoryJson.addProperty(RepositoryResourceProvider.REPOSITORY_REPO_NAME_PROPERTY_ID, repository.getRepoName()); repositoryJson.addProperty(RepositoryResourceProvider.REPOSITORY_REPO_ID_PROPERTY_ID, repository.getRepoId()); repositoriesJson.add(repositoryJson); } operatingSystemJson.add(RepositoryVersionResourceProvider.SUBRESOURCE_REPOSITORIES_PROPERTY_ID, repositoriesJson); operatingSystemJson.addProperty(OperatingSystemResourceProvider.OPERATING_SYSTEM_OS_TYPE_PROPERTY_ID, operatingSystem.getKey()); rootJson.add(operatingSystemJson); } return gson.toJson(rootJson); } /** * Scans the given stack for upgrade packages which can be applied to update the cluster to given repository version. * * @param stackName stack name * @param stackVersion stack version * @param repositoryVersion target repository version * @return upgrade pack name * @throws AmbariException if no upgrade packs suit the requirements */ public String getUpgradePackageName(String stackName, String stackVersion, String repositoryVersion) throws AmbariException { final Map<String, UpgradePack> upgradePacks = ambariMetaInfo.getUpgradePacks(stackName, stackVersion); for (Entry<String, UpgradePack> upgradePackEntry : upgradePacks.entrySet()) { final UpgradePack upgradePack = upgradePackEntry.getValue(); final String upgradePackName = upgradePackEntry.getKey(); // check that upgrade pack has <target> node if (StringUtils.isBlank(upgradePack.getTarget())) { LOG.error("Upgrade pack " + upgradePackName + " is corrupted, it should contain <target> node"); continue; } // check that upgrade pack can be applied to selected stack // converting 2.2.*.* -> 2\.2(\.\d+)?(\.\d+)?(-\d+)? String regexPattern = upgradePack.getTarget(); regexPattern = regexPattern.replaceAll("\\.", "\\\\."); // . -> \. regexPattern = regexPattern.replaceAll("\\\\\\.\\*", "(\\\\\\.\\\\d+)?"); // \.* -> (\.\d+)? regexPattern = regexPattern.concat("(-\\d+)?"); if (Pattern.matches(regexPattern, repositoryVersion)) { return upgradePackName; } } throw new AmbariException( "There were no suitable upgrade packs for stack " + stackName + " " + stackVersion); } /** * Scans the given stack for upgrade packages which can be applied to update the cluster to given repository version. * Returns NONE if there were no suitable packages. * * @param stackName stack name * @param stackVersion stack version * @param repositoryVersion target repository version * @return upgrade pack name or NONE */ public String getUpgradePackageNameSafe(String stackName, String stackVersion, String repositoryVersion) { try { return getUpgradePackageName(stackName, stackVersion, repositoryVersion); } catch (AmbariException ex) { return "NONE"; } } }