Allow counters to be created with same name, provider and source as a deleted one (#10223)

This commit is contained in:
Pearl Dsilva 2025-10-15 07:06:36 -04:00 committed by GitHub
parent f4b6a74a94
commit 0e8b0b8e40
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 66 additions and 4 deletions

View File

@ -70,6 +70,8 @@ public interface AutoScaleService {
Counter createCounter(CreateCounterCmd cmd);
Counter getCounter(long counterId);
boolean deleteCounter(long counterId) throws ResourceInUseException;
List<? extends Counter> listCounters(ListCountersCmd cmd);

View File

@ -17,6 +17,7 @@
package org.apache.cloudstack.api.command.admin.autoscale;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
@ -89,9 +90,6 @@ public class CreateCounterCmd extends BaseAsyncCreateCmd {
if (ctr != null) {
this.setEntityId(ctr.getId());
this.setEntityUuid(ctr.getUuid());
CounterResponse response = _responseGenerator.createCounterResponse(ctr);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create Counter with name " + getName());
}
@ -99,6 +97,11 @@ public class CreateCounterCmd extends BaseAsyncCreateCmd {
@Override
public void execute() {
CallContext.current().setEventDetails("Counter ID: " + getEntityId());
Counter ctr = _autoScaleService.getCounter(getEntityId());
CounterResponse response = _responseGenerator.createCounterResponse(ctr);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
@Override

View File

@ -24,6 +24,7 @@ import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDao;
public interface CounterDao extends GenericDao<CounterVO, Long> {
CounterVO findByNameProviderValue(String name, String value, String provider);
public List<CounterVO> listCounters(Long id, String name, String source, String provider, String keyword, Filter filter);
}

View File

@ -32,6 +32,7 @@ import com.cloud.utils.db.SearchCriteria.Op;
@Component
public class CounterDaoImpl extends GenericDaoBase<CounterVO, Long> implements CounterDao {
final SearchBuilder<CounterVO> AllFieldsSearch;
final SearchBuilder<CounterVO> CounterValueSearch;
protected CounterDaoImpl() {
AllFieldsSearch = createSearchBuilder();
@ -40,6 +41,21 @@ public class CounterDaoImpl extends GenericDaoBase<CounterVO, Long> implements C
AllFieldsSearch.and("source", AllFieldsSearch.entity().getSource(), Op.EQ);
AllFieldsSearch.and("provider", AllFieldsSearch.entity().getProvider(), Op.EQ);
AllFieldsSearch.done();
CounterValueSearch = createSearchBuilder();
CounterValueSearch.and("name", CounterValueSearch.entity().getName(), Op.EQ);
CounterValueSearch.and("value", CounterValueSearch.entity().getValue(), Op.EQ);
CounterValueSearch.and("provider", CounterValueSearch.entity().getProvider(), Op.EQ);
CounterValueSearch.done();
}
@Override
public CounterVO findByNameProviderValue(String name, String value, String provider) {
SearchCriteria<CounterVO> sc = CounterValueSearch.create();
sc.setParameters("name", name);
sc.setParameters("value", value);
sc.setParameters("provider", provider);
return findOneBy(sc);
}
@Override

View File

@ -0,0 +1,26 @@
-- 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.
-- in cloud
DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_DROP_UNIQUE_KEY`;
CREATE PROCEDURE `cloud`.`IDEMPOTENT_DROP_UNIQUE_KEY` (
IN in_table_name VARCHAR(200),
IN in_index_name VARCHAR(200)
)
BEGIN
DECLARE CONTINUE HANDLER FOR 1091, 1025 BEGIN END; SET @ddl = CONCAT('ALTER TABLE ', in_table_name, ' DROP KEY ', in_index_name); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;

View File

@ -83,3 +83,6 @@ CREATE TABLE IF NOT EXISTS `cloud`.`import_vm_task`(
CALL `cloud`.`INSERT_EXTENSION_IF_NOT_EXISTS`('MaaS', 'Baremetal Extension for Canonical MaaS written in Python', 'MaaS/maas.py');
CALL `cloud`.`INSERT_EXTENSION_DETAIL_IF_NOT_EXISTS`('MaaS', 'orchestratorrequirespreparevm', 'true', 0);
CALL `cloud`.`IDEMPOTENT_DROP_UNIQUE_KEY`('counter', 'uc_counter__provider__source__value');
CALL `cloud`.`IDEMPOTENT_ADD_UNIQUE_KEY`('cloud.counter', 'uc_counter__provider__source__value__removed', '(provider, source, value, removed)');

View File

@ -1457,6 +1457,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
public Counter createCounter(CreateCounterCmd cmd) {
String source = cmd.getSource().toUpperCase();
String name = cmd.getName();
String value = cmd.getValue();
Counter.Source src;
// Validate Source
try {
@ -1473,13 +1474,23 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
CounterVO counter = null;
CounterVO existingCounter = counterDao.findByNameProviderValue(name, value, provider.getName());
if (existingCounter != null) {
throw new InvalidParameterValueException(String.format("Counter with name %s and value %s already exists. ", name,value));
}
logger.debug("Adding Counter " + name);
counter = counterDao.persist(new CounterVO(src, name, cmd.getValue(), provider));
counter = counterDao.persist(new CounterVO(src, name, value, provider));
CallContext.current().setEventDetails(" Id: " + counter.getId() + " Name: " + name);
return counter;
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_COUNTER_CREATE, eventDescription = "Creating a counter", async = true)
public Counter getCounter(long counterId) {
return counterDao.findById(counterId);
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_CONDITION_CREATE, eventDescription = "Condition", create = true)
public Condition createCondition(CreateConditionCmd cmd) {