You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by mr...@apache.org on 2018/09/28 21:20:36 UTC
[ambari] 05/20: AMBARI-21523: DELETE Api for Mpacks (mradhakrishnan)
This is an automated email from the ASF dual-hosted git repository.
mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git
commit ab5721cc761c2992c8c238d20b3b48b60ae8437e
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Tue Jul 25 10:10:50 2017 -0700
AMBARI-21523: DELETE Api for Mpacks (mradhakrishnan)
---
.../ambari/server/api/services/AmbariMetaInfo.java | 18 +++++++
.../ambari/server/api/services/MpacksService.java | 23 ++++++++
.../controller/AmbariManagementController.java | 10 ++++
.../controller/AmbariManagementControllerImpl.java | 18 ++++++-
.../AbstractControllerResourceProvider.java | 2 +
.../internal/AbstractResourceProvider.java | 2 +-
.../controller/internal/MpackResourceProvider.java | 61 ++++++++++++++++++++--
.../apache/ambari/server/mpack/MpackManager.java | 45 +++++++++++++++-
.../org/apache/ambari/server/orm/dao/MpackDAO.java | 4 ++
.../org/apache/ambari/server/orm/dao/StackDAO.java | 25 +++++++++
.../ambari/server/orm/entities/StackEntity.java | 1 +
.../apache/ambari/server/stack/StackManager.java | 5 ++
12 files changed, 207 insertions(+), 7 deletions(-)
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index ea0c68b..1ea5369 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -61,6 +61,9 @@ import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.dao.MetainfoDAO;
import org.apache.ambari.server.orm.dao.StackDAO;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.stack.StackDirectory;
import org.apache.ambari.server.stack.StackManager;
import org.apache.ambari.server.stack.StackManagerFactory;
import org.apache.ambari.server.stack.upgrade.ConfigUpgradePack;
@@ -1541,4 +1544,19 @@ public class AmbariMetaInfo {
return commonWidgetsDescriptorFile;
}
+ /***
+ * Remove Mpack from the mpackMap and stackMap which is used to power the Mpack and Stack APIs.
+ * Stack should be removed from stackMap only if it points to the mpack that is being removed.
+ * @param mpackEntity
+ * @param stackEntity
+ * @throws IOException
+ */
+ public void removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException {
+
+ boolean stackDelete = mpackManager.removeMpack(mpackEntity, stackEntity);
+
+ if(stackDelete) {
+ stackManager.removeStack(stackEntity);
+ }
+ }
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/MpacksService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/MpacksService.java
index 32dae0f..c69ed01 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/MpacksService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/MpacksService.java
@@ -19,7 +19,10 @@ package org.apache.ambari.server.api.services;
import org.apache.ambari.server.api.resources.ResourceInstance;
+
import org.apache.ambari.server.controller.spi.Resource;
+
+import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@@ -154,6 +157,26 @@ public class MpacksService extends BaseService {
createMpackResource(mpackId));
}
+ @DELETE
+ @Path("{mpack_id}")
+ @Produces(MediaType.TEXT_PLAIN)
+ @ApiOperation(value = "Deletes a selected management pack")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, dataType = DATA_TYPE_STRING,
+ paramType = PARAM_TYPE_QUERY, defaultValue = MpackResourceProvider.ALL_PROPERTIES),
+ })
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_CLUSTER_OR_HOST_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+ })
+ public Response deleteMpack(String body, @Context HttpHeaders headers, @Context UriInfo ui, @PathParam("mpack_id") String mpackId) {
+ return handleRequest(headers, body, ui, Request.Type.DELETE,
+ createMpackResource(mpackId));
+ }
+
/**
* Create an mpack resource instance
* @param mpackId
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index 74a75b5..78f5f94 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -45,6 +45,8 @@ import org.apache.ambari.server.events.TopologyUpdateEvent;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.metadata.RoleCommandOrder;
import org.apache.ambari.server.orm.entities.ExtensionLinkEntity;
+import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
import org.apache.ambari.server.scheduler.ExecutionScheduleManager;
import org.apache.ambari.server.security.authorization.AuthorizationException;
import org.apache.ambari.server.security.encryption.CredentialStoreService;
@@ -974,5 +976,13 @@ public interface AmbariManagementController {
*/
ArrayList<Packlet> getPacklets(Long mpackId);
+ /***
+ * Remove Mpack from the mpackMap and stackMap which is used to power the Mpack and Stack APIs.
+ * @param mpackEntity
+ * @param stackEntity
+ * @throws IOException
+ */
+ void removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException;
+
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 9632d47..6d4d090 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -159,9 +159,11 @@ import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
import org.apache.ambari.server.orm.entities.HostEntity;
import org.apache.ambari.server.orm.entities.RepoDefinitionEntity;
import org.apache.ambari.server.orm.entities.RepoOsEntity;
+import org.apache.ambari.server.orm.entities.MpackEntity;
import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
import org.apache.ambari.server.orm.entities.SettingEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
import org.apache.ambari.server.orm.entities.WidgetEntity;
import org.apache.ambari.server.orm.entities.WidgetLayoutEntity;
import org.apache.ambari.server.orm.entities.WidgetLayoutUserWidgetEntity;
@@ -591,7 +593,12 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
createHostComponents(requests, false);
}
- public MpackResponse registerMpack(MpackRequest request) throws IOException, AuthorizationException, ResourceAlreadyExistsException{
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public MpackResponse registerMpack(MpackRequest request)
+ throws IOException, AuthorizationException, ResourceAlreadyExistsException{
MpackResponse mpackResponse = ambariMetaInfo.registerMpack(request);
updateStacks();
return mpackResponse;
@@ -3806,6 +3813,15 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
}
/**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException{
+
+ ambariMetaInfo.removeMpack(mpackEntity, stackEntity);
+ }
+
+ /**
* Get a request response for the given request ids. Note that this method
* fully populates a request resource including the set of task sub-resources
* in the request response.
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index 06dbc7b..2ec5b77 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -64,6 +64,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractAuthori
this.managementController = managementController;
}
+
+
public static void init(ResourceProviderFactory factory) {
resourceProviderFactory = factory;
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
index 40e1b2d..21a70ca 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
@@ -68,7 +68,7 @@ public abstract class AbstractResourceProvider extends BaseProvider implements R
*/
private final Set<ResourceProviderObserver> observers = new HashSet<>();
- private static final Logger LOG = LoggerFactory.getLogger(AbstractResourceProvider.class);
+ protected static final Logger LOG = LoggerFactory.getLogger(AbstractResourceProvider.class);
protected final static String PROPERTIES_ATTRIBUTES_REGEX = "properties_attributes/[a-zA-Z][a-zA-Z._-]*$";
public static Pattern propertiesAttributesPattern = Pattern.compile(".*/" + PROPERTIES_ATTRIBUTES_REGEX);
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java
index f939da7..7366390 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java
@@ -29,6 +29,7 @@ import java.util.ArrayList;
import java.util.List;
import com.google.inject.Inject;
+import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.StaticallyInject;
import org.apache.ambari.server.api.services.parsers.BodyParseException;
import org.apache.ambari.server.controller.spi.RequestStatus;
@@ -106,7 +107,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
}
MpackResourceProvider(AmbariManagementController controller) {
- super(PROPERTY_IDS, KEY_PROPERTY_IDS, controller);
+ super(Resource.Type.Mpack, PROPERTY_IDS, KEY_PROPERTY_IDS, controller);
}
@Override
@@ -187,8 +188,8 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
resource.setProperty(REGISTRY_ID, entity.getRegistryId());
results.add(resource);
}
- } //Fetch a particular mpack based on id
- else {
+ } else {
+ // Fetch a particular mpack based on id
Map<String, Object> propertyMap = new HashMap<>(PredicateHelper.getProperties(predicate));
if (propertyMap.containsKey(STACK_NAME_PROPERTY_ID) && propertyMap.containsKey(STACK_VERSION_PROPERTY_ID)) {
String stackName = (String) propertyMap.get(STACK_NAME_PROPERTY_ID);
@@ -237,5 +238,59 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
return results;
}
+ @Override
+ protected RequestStatus deleteResourcesAuthorized(final Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+ final Long mpackId;
+ Map<String, Object> propertyMap = new HashMap<>(PredicateHelper.getProperties(predicate));
+ DeleteStatusMetaData deleteStatusMetaData = null;
+
+ //Allow deleting mpack only if there are no cluster services deploying using this mpack. Support deleting mpacks only if no cluster has been deployed
+ // (i.e. you should be able to delete an mpack during install wizard only).
+ //Todo : Relax the rule
+ if (getManagementController().getClusters().getClusters().size() > 0) {
+ throw new SystemException("Delete request cannot be completed since there is a cluster deployed");
+ } else {
+ if (propertyMap.containsKey(MPACK_ID)) {
+ Object objMpackId = propertyMap.get(MPACK_ID);
+ if (objMpackId != null) {
+ mpackId = Long.valueOf((String) objMpackId);
+ LOG.info("Deleting Mpack, id = " + mpackId.toString());
+
+ MpackEntity mpackEntity = mpackDAO.findById(mpackId);
+ StackEntity stackEntity = stackDAO.findByMpack(mpackId);
+ try {
+ getManagementController().removeMpack(mpackEntity, stackEntity);
+ if (mpackEntity != null) {
+ deleteStatusMetaData = modifyResources(new Command<DeleteStatusMetaData>() {
+ @Override
+ public DeleteStatusMetaData invoke() throws AmbariException {
+ if (stackEntity != null) {
+ stackDAO.removeByMpack(mpackId);
+ notifyDelete(Resource.Type.Stack, predicate);
+ }
+ mpackDAO.removeById(mpackId);
+
+ return new DeleteStatusMetaData();
+ }
+ });
+ notifyDelete(Resource.Type.Mpack, predicate);
+ deleteStatusMetaData.addDeletedKey(mpackId.toString());
+ } else {
+ throw new NoSuchResourceException("The requested resource doesn't exist: " + predicate);
+ }
+ } catch (IOException e) {
+ throw new SystemException("There is an issue with the Files");
+ }
+ }
+ } else {
+ throw new UnsupportedPropertyException(Resource.Type.Mpack, null);
+ }
+
+ return getRequestStatus(null, null, deleteStatusMetaData);
+ }
+ }
+
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java b/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java
index f19320e..619823c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java
@@ -32,6 +32,7 @@ import org.apache.ambari.server.state.Packlet;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
+import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -328,8 +329,8 @@ public class MpackManager {
MpackEntity mpackEntity = new MpackEntity();
mpackEntity.setMpackName(mpackName);
mpackEntity.setMpackVersion(mpackVersion);
- mpackEntity.setMpackUri(mpacks.getMpacksUri());
-
+ mpackEntity.setMpackUri(mpack.getMpacksUri());
+ mpackEntity.setRegistryId(mpack.getRegistryId());
Long mpackId = mpackDAO.create(mpackEntity);
return mpackId;
}
@@ -375,4 +376,44 @@ public class MpackManager {
return mpack.getPacklets();
return null;
}
+
+ /***
+ * Remove the mpack and stack directories when a request comes in to delete a particular mpack.
+ * @param mpackEntity
+ * @throws IOException
+ */
+ public boolean removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException {
+
+ boolean stackDelete = false;
+ File mpackDirToDelete = new File(mpackStaging + File.separator + mpackEntity.getMpackName() + File.separator + mpackEntity.getMpackVersion());
+ File mpackDirectory = new File(mpackStaging + "/" + mpackEntity.getMpackName());
+ String mpackName = mpackEntity.getMpackName() + "-" + mpackEntity.getMpackVersion() + ".tar.gz";
+ Path mpackTarFile = Paths.get(mpackStaging + File.separator + MPACK_TAR_LOCATION +File.separator + mpackName);
+
+ mpackMap.remove(mpackEntity.getMpackId());
+ FileUtils.deleteDirectory(mpackDirToDelete);
+
+ if (mpackDirectory.isDirectory()) {
+ if (mpackDirectory.list().length == 0) {
+ Files.delete(mpackDirectory.toPath());
+ }
+ }
+ if (stackEntity != null) {
+ Path stackPath = Paths.get(stackRoot + "/" + stackEntity.getStackName() + "/" + stackEntity.getStackVersion());
+ File stackDirectory = new File(stackRoot + "/" + stackEntity.getStackName());
+ if (!Files.exists(stackPath))
+ Files.delete(stackPath);
+ if (stackDirectory.isDirectory()) {
+ if (stackDirectory.list().length == 0) {
+ Files.delete(stackDirectory.toPath());
+ }
+ }
+ stackDelete = true;
+ }
+
+ if (Files.exists(mpackTarFile)){
+ Files.delete(mpackTarFile);
+ }
+ return stackDelete;
+ }
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/MpackDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/MpackDAO.java
index a19ceaf..fb4e101 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/MpackDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/MpackDAO.java
@@ -95,5 +95,9 @@ public class MpackDAO {
return m_daoUtils.selectList(query);
}
+ @Transactional
+ public void removeById(Long mpackId) {
+ m_entityManagerProvider.get().remove(findById(mpackId));
+ }
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/StackDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/StackDAO.java
index f7c5dbe..57327c6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/StackDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/StackDAO.java
@@ -175,4 +175,29 @@ public class StackDAO {
entityManager.remove(stack);
}
}
+
+ /**
+ * Removes the specified stack based on mpackid.
+ *
+ * @param mpackId
+ *
+ */
+ @Transactional
+ public void removeByMpack(Long mpackId) {
+ entityManagerProvider.get().remove(findByMpack(mpackId));
+ }
+
+ /**
+ * Gets the stack that matches the specified mpackid.
+ *
+ * @return the stack matching the specified mpackid or {@code null}
+ * if none.
+ */
+ public StackEntity findByMpack(Long mpackId) {
+ TypedQuery<StackEntity> query = entityManagerProvider.get().createNamedQuery(
+ "StackEntity.findByMpack", StackEntity.class);
+ query.setParameter("currentMpackId", mpackId);
+
+ return daoUtils.selectOne(query);
+ }
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity.java
index 0cb8628..bee53b6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity.java
@@ -40,6 +40,7 @@ import javax.persistence.UniqueConstraint;
@TableGenerator(name = "stack_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "stack_id_seq", initialValue = 0)
@NamedQueries({
@NamedQuery(name = "StackEntity.findAll", query = "SELECT stack FROM StackEntity stack"),
+ @NamedQuery(name = "StackEntity.findByMpack", query = "SELECT stack FROM StackEntity stack where stack.currentMpackId = :currentMpackId"),
@NamedQuery(name = "StackEntity.findByNameAndVersion", query = "SELECT stack FROM StackEntity stack WHERE stack.stackName = :stackName AND stack.stackVersion = :stackVersion",
hints = {
@QueryHint(name = "eclipselink.query-results-cache", value = "true"),
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
index fbd0d8c..ca3ff30 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
@@ -677,4 +677,9 @@ public class StackManager {
}
return extensionModules;
}
+
+ public void removeStack(StackEntity stackEntity) {
+ String stackKey = stackEntity.getStackName() + StackManager.PATH_DELIMITER + stackEntity.getStackVersion();
+ stackMap.remove(stackKey);
+ }
}