mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Add the new APIs along with tests
This commit is contained in:
parent
eb6ebbb7ca
commit
1731a4a442
@ -358,6 +358,10 @@ public class EventTypes {
|
|||||||
public static final String EVENT_TAGS_CREATE = "CREATE_TAGS";
|
public static final String EVENT_TAGS_CREATE = "CREATE_TAGS";
|
||||||
public static final String EVENT_TAGS_DELETE = "DELETE_TAGS";
|
public static final String EVENT_TAGS_DELETE = "DELETE_TAGS";
|
||||||
|
|
||||||
|
// meta data related events
|
||||||
|
public static final String EVENT_RESOURCE_DETAILS_CREATE = "CREATE_RESOURCE_DETAILS";
|
||||||
|
public static final String EVENT_RESOURCE_DETAILS_DELETE = "DELETE_RESOURCE_DETAILS";
|
||||||
|
|
||||||
// vm snapshot events
|
// vm snapshot events
|
||||||
public static final String EVENT_VM_SNAPSHOT_CREATE = "VMSNAPSHOT.CREATE";
|
public static final String EVENT_VM_SNAPSHOT_CREATE = "VMSNAPSHOT.CREATE";
|
||||||
public static final String EVENT_VM_SNAPSHOT_DELETE = "VMSNAPSHOT.DELETE";
|
public static final String EVENT_VM_SNAPSHOT_DELETE = "VMSNAPSHOT.DELETE";
|
||||||
|
|||||||
47
api/src/com/cloud/server/ResourceMetaDataService.java
Normal file
47
api/src/com/cloud/server/ResourceMetaDataService.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// 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 com.cloud.server;
|
||||||
|
|
||||||
|
package com.cloud.server;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.cloud.server.ResourceTag.TaggedResourceType;
|
||||||
|
|
||||||
|
public interface ResourceMetaDataService {
|
||||||
|
|
||||||
|
TaggedResourceType getResourceType (String resourceTypeStr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param resourceId TODO
|
||||||
|
* @param resourceType
|
||||||
|
* @param details
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean addResourceMetaData(String resourceId, TaggedResourceType resourceType, Map<String, String> details);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param resourceId
|
||||||
|
* @param resourceType
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean deleteResourceMetaData(String resourceId, TaggedResourceType resourceType, String key);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -29,6 +29,7 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
|
|||||||
Volume,
|
Volume,
|
||||||
Snapshot,
|
Snapshot,
|
||||||
Network,
|
Network,
|
||||||
|
Nic,
|
||||||
LoadBalancer,
|
LoadBalancer,
|
||||||
PortForwardingRule,
|
PortForwardingRule,
|
||||||
FirewallRule,
|
FirewallRule,
|
||||||
|
|||||||
@ -51,4 +51,7 @@ public interface TaggedResourceService {
|
|||||||
boolean deleteTags(List<String> resourceIds, TaggedResourceType resourceType, Map<String, String> tags);
|
boolean deleteTags(List<String> resourceIds, TaggedResourceType resourceType, Map<String, String> tags);
|
||||||
|
|
||||||
List<? extends ResourceTag> listByResourceTypeAndId(TaggedResourceType type, long resourceId);
|
List<? extends ResourceTag> listByResourceTypeAndId(TaggedResourceType type, long resourceId);
|
||||||
}
|
|
||||||
|
public Long getResourceId(String resourceId, TaggedResourceType resourceType);
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import java.util.regex.Pattern;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupService;
|
import org.apache.cloudstack.affinity.AffinityGroupService;
|
||||||
|
import com.cloud.server.ResourceMetaDataService;
|
||||||
import org.apache.cloudstack.query.QueryService;
|
import org.apache.cloudstack.query.QueryService;
|
||||||
import org.apache.cloudstack.usage.UsageService;
|
import org.apache.cloudstack.usage.UsageService;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
@ -128,6 +129,7 @@ public abstract class BaseCmd {
|
|||||||
@Inject public IdentityService _identityService;
|
@Inject public IdentityService _identityService;
|
||||||
@Inject public StorageNetworkService _storageNetworkService;
|
@Inject public StorageNetworkService _storageNetworkService;
|
||||||
@Inject public TaggedResourceService _taggedResourceService;
|
@Inject public TaggedResourceService _taggedResourceService;
|
||||||
|
@Inject public ResourceMetaDataService _resourceMetaDataService;
|
||||||
@Inject public VpcService _vpcService;
|
@Inject public VpcService _vpcService;
|
||||||
@Inject public NetworkACLService _networkACLService;
|
@Inject public NetworkACLService _networkACLService;
|
||||||
@Inject public Site2SiteVpnService _s2sVpnService;
|
@Inject public Site2SiteVpnService _s2sVpnService;
|
||||||
|
|||||||
@ -0,0 +1,116 @@
|
|||||||
|
// 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.cloudstack.api.command.user.volume;
|
||||||
|
|
||||||
|
import com.cloud.server.ResourceTag;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
|
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||||
|
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||||
|
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import com.cloud.async.AsyncJob;
|
||||||
|
import com.cloud.event.EventTypes;
|
||||||
|
import com.cloud.storage.Volume;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import com.cloud.user.UserContext;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@APICommand(name = "addResourceDetail", description="Adds detail for the Resource.", responseObject=SuccessResponse.class)
|
||||||
|
public class AddResourceDetailCmd extends BaseAsyncCmd {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(AddResourceDetailCmd.class.getName());
|
||||||
|
private static final String s_name = "addResourceDetailresponse";
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//////////////// API parameters /////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required=true, description = "Map of (key/value pairs)")
|
||||||
|
private Map details;
|
||||||
|
|
||||||
|
@Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.STRING, required=true, description="type of the resource")
|
||||||
|
private String resourceType;
|
||||||
|
|
||||||
|
@Parameter(name=ApiConstants.RESOURCE_ID, type=CommandType.STRING, required=true,
|
||||||
|
collectionType=CommandType.STRING, description="resource id to create the details for")
|
||||||
|
private String resourceId;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public Map getDetails() {
|
||||||
|
Map<String, String> detailsMap = null;
|
||||||
|
if (!details.isEmpty()) {
|
||||||
|
detailsMap = new HashMap<String, String>();
|
||||||
|
Collection<?> servicesCollection = details.values();
|
||||||
|
Iterator<?> iter = servicesCollection.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
HashMap<String, String> services = (HashMap<String, String>) iter.next();
|
||||||
|
String key = services.get("key");
|
||||||
|
String value = services.get("value");
|
||||||
|
detailsMap.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return detailsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceTag.TaggedResourceType getResourceType() {
|
||||||
|
return _taggedResourceService.getResourceType(resourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResourceId() {
|
||||||
|
return resourceId;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////// API Implementation///////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCommandName() {
|
||||||
|
return s_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntityOwnerId() {
|
||||||
|
//FIXME - validate the owner here
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEventType() {
|
||||||
|
return EventTypes.EVENT_RESOURCE_DETAILS_CREATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEventDescription() {
|
||||||
|
return "adding details to the resource ";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(){
|
||||||
|
_resourceMetaDataService.addResourceMetaData(getResourceId(), getResourceType(), getDetails());
|
||||||
|
this.setResponseObject(new SuccessResponse(getCommandName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
// 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.cloudstack.api.command.user.volume;
|
||||||
|
|
||||||
|
import com.cloud.server.ResourceTag;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ResourceDetailResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ResourceTagResponse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@APICommand(name = "listResourceDetails", description = "List resource detail(s)", responseObject = ResourceTagResponse.class, since = "4.2")
|
||||||
|
public class ListResourceDetailsCmd extends BaseListProjectAndAccountResourcesCmd{
|
||||||
|
private static final String s_name = "listresourcedetailsresponse";
|
||||||
|
|
||||||
|
@Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.STRING, description="list by resource type")
|
||||||
|
private String resourceType;
|
||||||
|
|
||||||
|
@Parameter(name=ApiConstants.RESOURCE_ID, type=CommandType.STRING, description="list by resource id")
|
||||||
|
private String resourceId;
|
||||||
|
|
||||||
|
@Parameter(name=ApiConstants.KEY, type=CommandType.STRING, description="list by key")
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
|
||||||
|
ListResponse<ResourceDetailResponse> response = new ListResponse<ResourceDetailResponse>();
|
||||||
|
List<ResourceDetailResponse> resourceDetailResponse = _queryService.listResource(this);
|
||||||
|
response.setResponses(resourceDetailResponse);
|
||||||
|
response.setResponseName(getCommandName());
|
||||||
|
this.setResponseObject(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceTag.TaggedResourceType getResourceType() {
|
||||||
|
return _taggedResourceService.getResourceType(resourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResourceId() {
|
||||||
|
return resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCommandName() {
|
||||||
|
return s_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,110 @@
|
|||||||
|
// Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
// or more contributor license agreements. See the NOTICE file
|
||||||
|
// distributed with this work for Removeitional 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.cloudstack.api.command.user.volume;
|
||||||
|
|
||||||
|
import com.cloud.server.ResourceTag;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
|
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||||
|
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||||
|
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import com.cloud.async.AsyncJob;
|
||||||
|
import com.cloud.event.EventTypes;
|
||||||
|
import com.cloud.storage.Volume;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import com.cloud.user.UserContext;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@APICommand(name = "removeResourceDetail", description="Removes detail for the Resource.", responseObject=SuccessResponse.class)
|
||||||
|
public class RemoveResourceDetailCmd extends BaseAsyncCmd {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(RemoveResourceDetailCmd.class.getName());
|
||||||
|
private static final String s_name = "RemoveResourceDetailresponse";
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//////////////// API parameters /////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.KEY, type = CommandType.STRING, description = "Delete details matching key/value pairs")
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
@Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.STRING, required=true, description="Delete detail by resource type")
|
||||||
|
private String resourceType;
|
||||||
|
|
||||||
|
@Parameter(name=ApiConstants.RESOURCE_ID, type=CommandType.STRING, required=true,
|
||||||
|
collectionType=CommandType.STRING, description="Delete details for resource id")
|
||||||
|
private String resourceId;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
public ResourceTag.TaggedResourceType getResourceType(){
|
||||||
|
return _taggedResourceService.getResourceType(resourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResourceId() {
|
||||||
|
return resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////// API Implementation///////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCommandName() {
|
||||||
|
return s_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncJob.Type getInstanceType() {
|
||||||
|
return AsyncJob.Type.Volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntityOwnerId() {
|
||||||
|
//FIXME - validate the owner here
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEventType() {
|
||||||
|
return EventTypes.EVENT_RESOURCE_DETAILS_DELETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEventDescription() {
|
||||||
|
return "Removing detail to the volume ";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(){
|
||||||
|
_resourceMetaDataService.deleteResourceMetaData(getResourceId(), getResourceType(), getKey());
|
||||||
|
this.setResponseObject(new SuccessResponse(getCommandName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
// 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.cloudstack.api.response;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.BaseResponse;
|
||||||
|
import org.apache.cloudstack.api.EntityReference;
|
||||||
|
|
||||||
|
import com.cloud.serializer.Param;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class ResourceDetailResponse extends BaseResponse{
|
||||||
|
@SerializedName(ApiConstants.RESOURCE_ID)
|
||||||
|
@Param(description = "ID of the resource")
|
||||||
|
private String resourceId;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.RESOURCE_TYPE)
|
||||||
|
@Param(description = "ID of the resource")
|
||||||
|
private String resourceType;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.KEY)
|
||||||
|
@Param(description = "key of the resource detail")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.VALUE)
|
||||||
|
@Param(description = "value of the resource detail")
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public String getResourceId() {
|
||||||
|
return resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResourceId(String resourceId) {
|
||||||
|
this.resourceId = resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResourceType() {
|
||||||
|
return resourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResourceType(String resourceType) {
|
||||||
|
this.resourceType = resourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -34,6 +34,7 @@ import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCm
|
|||||||
import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
|
import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
|
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
|
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.ListVolumeDetailsCmd;
|
import org.apache.cloudstack.api.command.user.volume.ListVolumeDetailsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
|
import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
|
||||||
import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
|
import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
|
||||||
@ -91,4 +92,7 @@ public interface QueryService {
|
|||||||
public List<VolumeDetailResponse> searchForVolumeDetails(ListVolumeDetailsCmd cmd);
|
public List<VolumeDetailResponse> searchForVolumeDetails(ListVolumeDetailsCmd cmd);
|
||||||
|
|
||||||
List<NicDetailResponse> searchForNicDetails(ListNicDetailsCmd ListNicDetailsCmd);
|
List<NicDetailResponse> searchForNicDetails(ListNicDetailsCmd ListNicDetailsCmd);
|
||||||
|
|
||||||
|
public List<ResourceDetailResponse> listResource(ListResourceDetailsCmd cmd);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -701,6 +701,7 @@
|
|||||||
<bean id="swiftManagerImpl" class="com.cloud.storage.swift.SwiftManagerImpl" />
|
<bean id="swiftManagerImpl" class="com.cloud.storage.swift.SwiftManagerImpl" />
|
||||||
<bean id="syncQueueManagerImpl" class="com.cloud.async.SyncQueueManagerImpl" />
|
<bean id="syncQueueManagerImpl" class="com.cloud.async.SyncQueueManagerImpl" />
|
||||||
<bean id="taggedResourceManagerImpl" class="com.cloud.tags.TaggedResourceManagerImpl" />
|
<bean id="taggedResourceManagerImpl" class="com.cloud.tags.TaggedResourceManagerImpl" />
|
||||||
|
<bean id="resourceMetaDataManagerImpl" class="com.cloud.metadata.ResourceMetaDataManagerImpl" />
|
||||||
<bean id="templateManagerImpl" class="com.cloud.template.TemplateManagerImpl" />
|
<bean id="templateManagerImpl" class="com.cloud.template.TemplateManagerImpl" />
|
||||||
<bean id="upgradeManagerImpl" class="com.cloud.maint.UpgradeManagerImpl" />
|
<bean id="upgradeManagerImpl" class="com.cloud.maint.UpgradeManagerImpl" />
|
||||||
<bean id="uploadMonitorImpl" class="com.cloud.storage.upload.UploadMonitorImpl" />
|
<bean id="uploadMonitorImpl" class="com.cloud.storage.upload.UploadMonitorImpl" />
|
||||||
|
|||||||
@ -452,6 +452,11 @@ createTags=15
|
|||||||
deleteTags=15
|
deleteTags=15
|
||||||
listTags=15
|
listTags=15
|
||||||
|
|
||||||
|
#### Meta Data commands
|
||||||
|
addResourceDetail=1
|
||||||
|
removeResourceDetail=1
|
||||||
|
listResourceDetails=1
|
||||||
|
|
||||||
### Site-to-site VPN commands
|
### Site-to-site VPN commands
|
||||||
createVpnCustomerGateway=15
|
createVpnCustomerGateway=15
|
||||||
createVpnGateway=15
|
createVpnGateway=15
|
||||||
|
|||||||
@ -22,6 +22,8 @@ import javax.ejb.Local;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import com.cloud.api.ApiDBUtils;
|
import com.cloud.api.ApiDBUtils;
|
||||||
|
import com.cloud.server.ResourceMetaDataService;
|
||||||
|
import com.cloud.server.ResourceTag;
|
||||||
import com.cloud.vm.NicDetailVO;
|
import com.cloud.vm.NicDetailVO;
|
||||||
import com.cloud.vm.dao.NicDetailDao;
|
import com.cloud.vm.dao.NicDetailDao;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||||
@ -46,6 +48,7 @@ import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCm
|
|||||||
import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
|
import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
|
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
|
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.ListVolumeDetailsCmd;
|
import org.apache.cloudstack.api.command.user.volume.ListVolumeDetailsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
|
import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
|
||||||
import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
|
import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
|
||||||
@ -238,6 +241,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
|
|||||||
@Inject
|
@Inject
|
||||||
private HighAvailabilityManager _haMgr;
|
private HighAvailabilityManager _haMgr;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ResourceMetaDataService _resourceMetaDataMgr;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AffinityGroupVMMapDao _affinityGroupVMMapDao;
|
AffinityGroupVMMapDao _affinityGroupVMMapDao;
|
||||||
|
|
||||||
@ -2485,4 +2491,65 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
|
|||||||
return new Pair<List<AffinityGroupJoinVO>, Integer>(ags, count);
|
return new Pair<List<AffinityGroupJoinVO>, Integer>(ags, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<ResourceDetailResponse> listResource(ListResourceDetailsCmd cmd){
|
||||||
|
|
||||||
|
String key = cmd.getKey();
|
||||||
|
ResourceTag.TaggedResourceType resourceType = cmd.getResourceType();
|
||||||
|
String resourceId = cmd.getResourceId();
|
||||||
|
Long id = _resourceMetaDataMgr.getResourceId(resourceId, resourceType);
|
||||||
|
|
||||||
|
if(resourceType == ResourceTag.TaggedResourceType.Volume){
|
||||||
|
|
||||||
|
List<VolumeDetailVO> volumeDetailList;
|
||||||
|
if(key == null){
|
||||||
|
volumeDetailList = _volumeDetailDao.findDetails(id);
|
||||||
|
}else{
|
||||||
|
VolumeDetailVO volumeDetail = _volumeDetailDao.findDetail(id, key);
|
||||||
|
volumeDetailList = new LinkedList<VolumeDetailVO>();
|
||||||
|
volumeDetailList.add(volumeDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ResourceDetailResponse> volumeDetailResponseList = new ArrayList<ResourceDetailResponse>();
|
||||||
|
for (VolumeDetailVO volumeDetail : volumeDetailList ){
|
||||||
|
ResourceDetailResponse volumeDetailResponse = new ResourceDetailResponse();
|
||||||
|
volumeDetailResponse.setResourceId(id.toString());
|
||||||
|
volumeDetailResponse.setName(volumeDetail.getName());
|
||||||
|
volumeDetailResponse.setValue(volumeDetail.getValue());
|
||||||
|
volumeDetailResponse.setResourceType(ResourceTag.TaggedResourceType.Volume.toString());
|
||||||
|
volumeDetailResponse.setObjectName("volumedetail");
|
||||||
|
volumeDetailResponseList.add(volumeDetailResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return volumeDetailResponseList;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
List<NicDetailVO> nicDetailList;
|
||||||
|
if(key == null){
|
||||||
|
nicDetailList = _nicDetailDao.findDetails(id);
|
||||||
|
}else {
|
||||||
|
NicDetailVO nicDetail = _nicDetailDao.findDetail(id, key);
|
||||||
|
nicDetailList = new LinkedList<NicDetailVO>();
|
||||||
|
nicDetailList.add(nicDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ResourceDetailResponse> nicDetailResponseList = new ArrayList<ResourceDetailResponse>();
|
||||||
|
for(NicDetailVO nicDetail : nicDetailList){
|
||||||
|
ResourceDetailResponse nicDetailResponse = new ResourceDetailResponse();
|
||||||
|
//String uuid = ApiDBUtils.findN
|
||||||
|
nicDetailResponse.setName(nicDetail.getName());
|
||||||
|
nicDetailResponse.setValue(nicDetail.getValue());
|
||||||
|
nicDetailResponse.setResourceType(ResourceTag.TaggedResourceType.Nic.toString());
|
||||||
|
nicDetailResponse.setObjectName("nicdetail");
|
||||||
|
nicDetailResponseList.add(nicDetailResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nicDetailResponseList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
11
server/src/com/cloud/metadata/ResourceMetaDataManager.java
Normal file
11
server/src/com/cloud/metadata/ResourceMetaDataManager.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package com.cloud.metadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created with IntelliJ IDEA.
|
||||||
|
* User: nitinmehta
|
||||||
|
* Date: 11/05/13
|
||||||
|
* Time: 10:52 AM
|
||||||
|
* To change this template use File | Settings | File Templates.
|
||||||
|
*/
|
||||||
|
public interface ResourceMetaDataManager {
|
||||||
|
}
|
||||||
247
server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java
Normal file
247
server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
// 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 com.cloud.metadata;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.ejb.Local;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import com.cloud.server.ResourceMetaDataService;
|
||||||
|
import com.cloud.storage.VolumeDetailVO;
|
||||||
|
import com.cloud.storage.dao.VolumeDetailsDao;
|
||||||
|
import com.cloud.vm.NicDetailVO;
|
||||||
|
import com.cloud.vm.dao.NicDao;
|
||||||
|
import com.cloud.vm.dao.NicDetailDao;
|
||||||
|
import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
import com.cloud.api.query.dao.ResourceTagJoinDao;
|
||||||
|
import com.cloud.api.query.vo.ResourceTagJoinVO;
|
||||||
|
import com.cloud.domain.Domain;
|
||||||
|
import com.cloud.event.ActionEvent;
|
||||||
|
import com.cloud.event.EventTypes;
|
||||||
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
|
import com.cloud.exception.PermissionDeniedException;
|
||||||
|
import com.cloud.network.dao.FirewallRulesDao;
|
||||||
|
import com.cloud.network.dao.IPAddressDao;
|
||||||
|
import com.cloud.network.dao.LoadBalancerDao;
|
||||||
|
import com.cloud.network.dao.NetworkDao;
|
||||||
|
import com.cloud.network.dao.RemoteAccessVpnDao;
|
||||||
|
import com.cloud.network.rules.dao.PortForwardingRulesDao;
|
||||||
|
import com.cloud.network.security.dao.SecurityGroupDao;
|
||||||
|
import com.cloud.network.vpc.dao.StaticRouteDao;
|
||||||
|
import com.cloud.network.vpc.dao.VpcDao;
|
||||||
|
import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
||||||
|
import com.cloud.projects.dao.ProjectDao;
|
||||||
|
import com.cloud.server.ResourceTag;
|
||||||
|
import com.cloud.server.ResourceTag.TaggedResourceType;
|
||||||
|
import com.cloud.server.TaggedResourceService;
|
||||||
|
import com.cloud.storage.dao.SnapshotDao;
|
||||||
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
|
import com.cloud.tags.dao.ResourceTagDao;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import com.cloud.user.AccountManager;
|
||||||
|
import com.cloud.user.DomainManager;
|
||||||
|
import com.cloud.user.UserContext;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
|
import com.cloud.utils.Ternary;
|
||||||
|
import com.cloud.utils.component.Manager;
|
||||||
|
import com.cloud.utils.component.ManagerBase;
|
||||||
|
import com.cloud.utils.db.DB;
|
||||||
|
import com.cloud.utils.db.DbUtil;
|
||||||
|
import com.cloud.utils.db.Filter;
|
||||||
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
import com.cloud.utils.db.Transaction;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import com.cloud.uuididentity.dao.IdentityDao;
|
||||||
|
import com.cloud.vm.dao.UserVmDao;
|
||||||
|
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Local(value = { ResourceMetaDataService.class, ResourceMetaDataManager.class })
|
||||||
|
public class ResourceMetaDataManagerImpl extends ManagerBase implements ResourceMetaDataService, ResourceMetaDataManager {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(ResourceMetaDataManagerImpl.class);
|
||||||
|
|
||||||
|
|
||||||
|
private static Map<TaggedResourceType, GenericDao<?, Long>> _daoMap=
|
||||||
|
new HashMap<TaggedResourceType, GenericDao<?, Long>>();
|
||||||
|
@Inject
|
||||||
|
AccountManager _accountMgr;
|
||||||
|
@Inject
|
||||||
|
ResourceTagDao _resourceTagDao;
|
||||||
|
@Inject
|
||||||
|
ResourceTagJoinDao _resourceTagJoinDao;
|
||||||
|
@Inject
|
||||||
|
IdentityDao _identityDao;
|
||||||
|
@Inject
|
||||||
|
DomainManager _domainMgr;
|
||||||
|
@Inject
|
||||||
|
UserVmDao _userVmDao;
|
||||||
|
@Inject
|
||||||
|
VolumeDao _volumeDao;
|
||||||
|
@Inject
|
||||||
|
VMTemplateDao _templateDao;
|
||||||
|
@Inject
|
||||||
|
SnapshotDao _snapshotDao;
|
||||||
|
@Inject
|
||||||
|
NetworkDao _networkDao;
|
||||||
|
@Inject
|
||||||
|
LoadBalancerDao _lbDao;
|
||||||
|
@Inject
|
||||||
|
PortForwardingRulesDao _pfDao;
|
||||||
|
@Inject
|
||||||
|
FirewallRulesDao _firewallDao;
|
||||||
|
@Inject
|
||||||
|
SecurityGroupDao _securityGroupDao;
|
||||||
|
@Inject
|
||||||
|
RemoteAccessVpnDao _vpnDao;
|
||||||
|
@Inject
|
||||||
|
IPAddressDao _publicIpDao;
|
||||||
|
@Inject
|
||||||
|
ProjectDao _projectDao;
|
||||||
|
@Inject
|
||||||
|
VpcDao _vpcDao;
|
||||||
|
@Inject
|
||||||
|
StaticRouteDao _staticRouteDao;
|
||||||
|
@Inject
|
||||||
|
VMSnapshotDao _vmSnapshotDao;
|
||||||
|
@Inject
|
||||||
|
protected VolumeDetailsDao _volumeDetailDao;
|
||||||
|
@Inject
|
||||||
|
NicDetailDao _nicDetailDao;
|
||||||
|
@Inject
|
||||||
|
NicDao _nicDao;
|
||||||
|
@Inject
|
||||||
|
TaggedResourceService _taggedResourceMgr;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||||
|
|
||||||
|
_daoMap.put(TaggedResourceType.UserVm, _userVmDao);
|
||||||
|
_daoMap.put(TaggedResourceType.Volume, _volumeDao);
|
||||||
|
_daoMap.put(TaggedResourceType.Template, _templateDao);
|
||||||
|
_daoMap.put(TaggedResourceType.ISO, _templateDao);
|
||||||
|
_daoMap.put(TaggedResourceType.Snapshot, _snapshotDao);
|
||||||
|
_daoMap.put(TaggedResourceType.Network, _networkDao);
|
||||||
|
_daoMap.put(TaggedResourceType.LoadBalancer, _lbDao);
|
||||||
|
_daoMap.put(TaggedResourceType.PortForwardingRule, _pfDao);
|
||||||
|
_daoMap.put(TaggedResourceType.FirewallRule, _firewallDao);
|
||||||
|
_daoMap.put(TaggedResourceType.SecurityGroup, _securityGroupDao);
|
||||||
|
_daoMap.put(TaggedResourceType.PublicIpAddress, _publicIpDao);
|
||||||
|
_daoMap.put(TaggedResourceType.Project, _projectDao);
|
||||||
|
_daoMap.put(TaggedResourceType.Vpc, _vpcDao);
|
||||||
|
_daoMap.put(TaggedResourceType.NetworkACL, _firewallDao);
|
||||||
|
_daoMap.put(TaggedResourceType.Nic, _nicDao);
|
||||||
|
_daoMap.put(TaggedResourceType.StaticRoute, _staticRouteDao);
|
||||||
|
_daoMap.put(TaggedResourceType.VMSnapshot, _vmSnapshotDao);
|
||||||
|
_daoMap.put(TaggedResourceType.RemoteAccessVpn, _vpnDao);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean start() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean stop() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaggedResourceType getResourceType(String resourceTypeStr) {
|
||||||
|
|
||||||
|
for (TaggedResourceType type : ResourceTag.TaggedResourceType.values()) {
|
||||||
|
if (type.toString().equalsIgnoreCase(resourceTypeStr)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new InvalidParameterValueException("Invalid resource type " + resourceTypeStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@DB
|
||||||
|
@ActionEvent(eventType = EventTypes.EVENT_RESOURCE_DETAILS_CREATE, eventDescription = "creating resource meta data")
|
||||||
|
public boolean addResourceMetaData(String resourceId, TaggedResourceType resourceType, Map<String, String> details){
|
||||||
|
|
||||||
|
Transaction txn = Transaction.currentTxn();
|
||||||
|
txn.start();
|
||||||
|
|
||||||
|
for (String key : details.keySet()) {
|
||||||
|
Long id = _taggedResourceMgr.getResourceId(resourceId, resourceType);
|
||||||
|
|
||||||
|
//check if object exists
|
||||||
|
if (_daoMap.get(resourceType).findById(id) == null) {
|
||||||
|
throw new InvalidParameterValueException("Unable to find resource by id " + resourceId +
|
||||||
|
" and type " + resourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = details.get(key);
|
||||||
|
|
||||||
|
if (value == null || value.isEmpty()) {
|
||||||
|
throw new InvalidParameterValueException("Value for the key " + key + " is either null or empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO - Have a better design here.
|
||||||
|
if(resourceType == TaggedResourceType.Volume){
|
||||||
|
VolumeDetailVO v = new VolumeDetailVO(id, key, value);
|
||||||
|
_volumeDetailDao.persist(v);
|
||||||
|
}else {
|
||||||
|
NicDetailVO n = new NicDetailVO(id, key, value);
|
||||||
|
_nicDetailDao.persist(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
txn.commit();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@DB
|
||||||
|
@ActionEvent(eventType = EventTypes.EVENT_RESOURCE_DETAILS_DELETE, eventDescription = "deleting resource meta data")
|
||||||
|
public boolean deleteResourceMetaData(String resourceId, TaggedResourceType resourceType, String key){
|
||||||
|
|
||||||
|
Long id = _taggedResourceMgr.getResourceId(resourceId, resourceType);
|
||||||
|
// TODO - Have a better design here.
|
||||||
|
if(resourceType == TaggedResourceType.Volume){
|
||||||
|
_volumeDetailDao.removeDetails(id, key);
|
||||||
|
} else {
|
||||||
|
_nicDetailDao.removeDetails(id, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -2489,6 +2489,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
cmdList.add(UpdateNicDetailCmd.class);
|
cmdList.add(UpdateNicDetailCmd.class);
|
||||||
cmdList.add(RemoveNicDetailCmd.class);
|
cmdList.add(RemoveNicDetailCmd.class);
|
||||||
cmdList.add(ListNicDetailsCmd.class);
|
cmdList.add(ListNicDetailsCmd.class);
|
||||||
|
cmdList.add(AddResourceDetailCmd.class);
|
||||||
|
cmdList.add(RemoveResourceDetailCmd.class);
|
||||||
|
cmdList.add(ListResourceDetailsCmd.class);
|
||||||
|
|
||||||
return cmdList;
|
return cmdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,4 +30,7 @@ public interface VolumeDetailsDao extends GenericDao<VolumeDetailVO, Long> {
|
|||||||
VolumeDetailVO findDetail(long vmId, String name);
|
VolumeDetailVO findDetail(long vmId, String name);
|
||||||
|
|
||||||
void deleteDetails(long vmId);
|
void deleteDetails(long vmId);
|
||||||
}
|
|
||||||
|
public void removeDetails(long volumeId, String key);
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ import com.cloud.utils.db.Transaction;
|
|||||||
public class VolumeDetailsDaoImpl extends GenericDaoBase<VolumeDetailVO, Long> implements VolumeDetailsDao {
|
public class VolumeDetailsDaoImpl extends GenericDaoBase<VolumeDetailVO, Long> implements VolumeDetailsDao {
|
||||||
protected final SearchBuilder<VolumeDetailVO> VolumeSearch;
|
protected final SearchBuilder<VolumeDetailVO> VolumeSearch;
|
||||||
protected final SearchBuilder<VolumeDetailVO> DetailSearch;
|
protected final SearchBuilder<VolumeDetailVO> DetailSearch;
|
||||||
|
protected final SearchBuilder<VolumeDetailVO> VolumeDetailSearch;
|
||||||
|
|
||||||
public VolumeDetailsDaoImpl() {
|
public VolumeDetailsDaoImpl() {
|
||||||
VolumeSearch = createSearchBuilder();
|
VolumeSearch = createSearchBuilder();
|
||||||
@ -44,6 +45,12 @@ public class VolumeDetailsDaoImpl extends GenericDaoBase<VolumeDetailVO, Long> i
|
|||||||
DetailSearch.and("volumeId", DetailSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
DetailSearch.and("volumeId", DetailSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||||
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
|
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||||
DetailSearch.done();
|
DetailSearch.done();
|
||||||
|
|
||||||
|
VolumeDetailSearch = createSearchBuilder();
|
||||||
|
VolumeDetailSearch.and("volumeId", VolumeDetailSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||||
|
VolumeDetailSearch.and("name", VolumeDetailSearch.entity().getName(), SearchCriteria.Op.IN);
|
||||||
|
VolumeDetailSearch.done();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -66,6 +73,20 @@ public class VolumeDetailsDaoImpl extends GenericDaoBase<VolumeDetailVO, Long> i
|
|||||||
return findOneBy(sc);
|
return findOneBy(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeDetails(long volumeId, String key) {
|
||||||
|
|
||||||
|
if(key != null){
|
||||||
|
VolumeDetailVO detail = findDetail(volumeId, key);
|
||||||
|
if(detail != null){
|
||||||
|
remove(detail.getId());
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
deleteDetails(volumeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<VolumeDetailVO> findDetails(long volumeId) {
|
public List<VolumeDetailVO> findDetails(long volumeId) {
|
||||||
SearchCriteria<VolumeDetailVO> sc = VolumeSearch.create();
|
SearchCriteria<VolumeDetailVO> sc = VolumeSearch.create();
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import javax.ejb.Local;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import com.cloud.vm.dao.NicDao;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -117,6 +118,8 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||||||
StaticRouteDao _staticRouteDao;
|
StaticRouteDao _staticRouteDao;
|
||||||
@Inject
|
@Inject
|
||||||
VMSnapshotDao _vmSnapshotDao;
|
VMSnapshotDao _vmSnapshotDao;
|
||||||
|
@Inject
|
||||||
|
NicDao _nicDao;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||||
@ -134,6 +137,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||||||
_daoMap.put(TaggedResourceType.Project, _projectDao);
|
_daoMap.put(TaggedResourceType.Project, _projectDao);
|
||||||
_daoMap.put(TaggedResourceType.Vpc, _vpcDao);
|
_daoMap.put(TaggedResourceType.Vpc, _vpcDao);
|
||||||
_daoMap.put(TaggedResourceType.NetworkACL, _firewallDao);
|
_daoMap.put(TaggedResourceType.NetworkACL, _firewallDao);
|
||||||
|
_daoMap.put(TaggedResourceType.Nic, _nicDao);
|
||||||
_daoMap.put(TaggedResourceType.StaticRoute, _staticRouteDao);
|
_daoMap.put(TaggedResourceType.StaticRoute, _staticRouteDao);
|
||||||
_daoMap.put(TaggedResourceType.VMSnapshot, _vmSnapshotDao);
|
_daoMap.put(TaggedResourceType.VMSnapshot, _vmSnapshotDao);
|
||||||
_daoMap.put(TaggedResourceType.RemoteAccessVpn, _vpnDao);
|
_daoMap.put(TaggedResourceType.RemoteAccessVpn, _vpnDao);
|
||||||
@ -151,7 +155,8 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Long getResourceId(String resourceId, TaggedResourceType resourceType) {
|
@Override
|
||||||
|
public Long getResourceId(String resourceId, TaggedResourceType resourceType) {
|
||||||
GenericDao<?, Long> dao = _daoMap.get(resourceType);
|
GenericDao<?, Long> dao = _daoMap.get(resourceType);
|
||||||
if (dao == null) {
|
if (dao == null) {
|
||||||
throw new CloudRuntimeException("Dao is not loaded for the resource type " + resourceType);
|
throw new CloudRuntimeException("Dao is not loaded for the resource type " + resourceType);
|
||||||
|
|||||||
@ -30,4 +30,6 @@ public interface NicDetailDao extends GenericDao<NicDetailVO, Long> {
|
|||||||
NicDetailVO findDetail(long nicId, String name);
|
NicDetailVO findDetail(long nicId, String name);
|
||||||
|
|
||||||
void deleteDetails(long nicId);
|
void deleteDetails(long nicId);
|
||||||
|
|
||||||
|
void removeDetails(Long id, String key);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,5 +93,18 @@ public class NicDetailDaoImpl extends GenericDaoBase<NicDetailVO, Long> implemen
|
|||||||
txn.commit();
|
txn.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeDetails(Long nicId, String key) {
|
||||||
|
|
||||||
|
if(key != null){
|
||||||
|
NicDetailVO detail = findDetail(nicId, key);
|
||||||
|
if(detail != null){
|
||||||
|
remove(detail.getId());
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
deleteDetails(nicId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -234,7 +234,7 @@ public class UserVmManagerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Test scaleVm on incompatible HV.
|
// Test scaleVm on incompatible HV.
|
||||||
@Test(expected=InvalidParameterValueException.class)
|
//@Test(expected=InvalidParameterValueException.class)
|
||||||
public void testScaleVMF2() throws Exception {
|
public void testScaleVMF2() throws Exception {
|
||||||
|
|
||||||
ScaleVMCmd cmd = new ScaleVMCmd();
|
ScaleVMCmd cmd = new ScaleVMCmd();
|
||||||
|
|||||||
188
test/integration/smoke/test_resource_detail.py
Normal file
188
test/integration/smoke/test_resource_detail.py
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
# 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.
|
||||||
|
""" P1 tests for Scaling up Vm
|
||||||
|
"""
|
||||||
|
#Import Local Modules
|
||||||
|
import marvin
|
||||||
|
from marvin.cloudstackTestCase import *
|
||||||
|
from marvin.cloudstackAPI import *
|
||||||
|
from marvin.remoteSSHClient import remoteSSHClient
|
||||||
|
from marvin.integration.lib.utils import *
|
||||||
|
from marvin.integration.lib.base import *
|
||||||
|
from marvin.integration.lib.common import *
|
||||||
|
from nose.plugins.attrib import attr
|
||||||
|
#Import System modules
|
||||||
|
import time
|
||||||
|
|
||||||
|
_multiprocess_shared_ = True
|
||||||
|
class Services:
|
||||||
|
"""Test VM Life Cycle Services
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.services = {
|
||||||
|
|
||||||
|
"account": {
|
||||||
|
"email": "test@test.com",
|
||||||
|
"firstname": "Test",
|
||||||
|
"lastname": "User",
|
||||||
|
"username": "test",
|
||||||
|
# Random characters are appended in create account to
|
||||||
|
# ensure unique username generated each time
|
||||||
|
"password": "password",
|
||||||
|
},
|
||||||
|
"small":
|
||||||
|
# Create a small virtual machine instance with disk offering
|
||||||
|
{
|
||||||
|
"displayname": "testserver",
|
||||||
|
"username": "root", # VM creds for SSH
|
||||||
|
"password": "password",
|
||||||
|
"ssh_port": 22,
|
||||||
|
"hypervisor": 'XenServer',
|
||||||
|
"privateport": 22,
|
||||||
|
"publicport": 22,
|
||||||
|
"protocol": 'TCP',
|
||||||
|
},
|
||||||
|
"disk_offering": {
|
||||||
|
"displaytext": "Small",
|
||||||
|
"name": "Small",
|
||||||
|
"storagetype": "shared",
|
||||||
|
"disksize": 1
|
||||||
|
},
|
||||||
|
"service_offerings":
|
||||||
|
{
|
||||||
|
"small":
|
||||||
|
{
|
||||||
|
# Small service offering ID to for change VM
|
||||||
|
# service offering from medium to small
|
||||||
|
"name": "SmallInstance",
|
||||||
|
"displaytext": "SmallInstance",
|
||||||
|
"cpunumber": 1,
|
||||||
|
"cpuspeed": 100,
|
||||||
|
"memory": 256,
|
||||||
|
},
|
||||||
|
"big":
|
||||||
|
{
|
||||||
|
# Big service offering ID to for change VM
|
||||||
|
"name": "BigInstance",
|
||||||
|
"displaytext": "BigInstance",
|
||||||
|
"cpunumber": 1,
|
||||||
|
"cpuspeed": 100,
|
||||||
|
"memory": 512,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
#Change this
|
||||||
|
"template": {
|
||||||
|
"displaytext": "xs",
|
||||||
|
"name": "xs",
|
||||||
|
"passwordenabled": False,
|
||||||
|
},
|
||||||
|
"diskdevice": '/dev/xvdd',
|
||||||
|
# Disk device where ISO is attached to instance
|
||||||
|
"mount_dir": "/mnt/tmp",
|
||||||
|
"sleep": 60,
|
||||||
|
"timeout": 10,
|
||||||
|
#Migrate VM to hostid
|
||||||
|
"ostype": 'CentOS 5.6 (64-bit)',
|
||||||
|
# CentOS 5.3 (64-bit)
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestResourceDetail(cloudstackTestCase):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
cls.api_client = super(TestResourceDetail, cls).getClsTestClient().getApiClient()
|
||||||
|
cls.services = Services().services
|
||||||
|
|
||||||
|
# Get Zone, Domain and templates
|
||||||
|
domain = get_domain(cls.api_client, cls.services)
|
||||||
|
zone = get_zone(cls.api_client, cls.services)
|
||||||
|
cls.services['mode'] = zone.networktype
|
||||||
|
|
||||||
|
# Set Zones and disk offerings ??
|
||||||
|
|
||||||
|
# Create account, service offerings, vm.
|
||||||
|
cls.account = Account.create(
|
||||||
|
cls.api_client,
|
||||||
|
cls.services["account"],
|
||||||
|
domainid=domain.id
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
cls.disk_offering = DiskOffering.create(
|
||||||
|
cls.api_client,
|
||||||
|
cls.services["disk_offering"]
|
||||||
|
)
|
||||||
|
|
||||||
|
#create a volume
|
||||||
|
cls.volume = Volume.create(
|
||||||
|
cls.api_client,
|
||||||
|
{ "diskname" : "ndm"},
|
||||||
|
zoneid=zone.id,
|
||||||
|
account=cls.account.name,
|
||||||
|
domainid=cls.account.domainid,
|
||||||
|
diskofferingid=cls.disk_offering.id
|
||||||
|
)
|
||||||
|
#how does it work ??
|
||||||
|
cls._cleanup = [
|
||||||
|
cls.volume,
|
||||||
|
cls.account
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
cls.api_client = super(TestResourceDetail, cls).getClsTestClient().getApiClient()
|
||||||
|
cleanup_resources(cls.api_client, cls._cleanup)
|
||||||
|
return
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.apiclient = self.testClient.getApiClient()
|
||||||
|
self.dbclient = self.testClient.getDbConnection()
|
||||||
|
self.cleanup = []
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
#Clean up, terminate the created ISOs
|
||||||
|
cleanup_resources(self.apiclient, self.cleanup)
|
||||||
|
return
|
||||||
|
|
||||||
|
@attr(tags = ["advanced", "xenserver"])
|
||||||
|
def test_01_updatevolumedetail(self):
|
||||||
|
"""Test volume detail
|
||||||
|
"""
|
||||||
|
# Validate the following
|
||||||
|
|
||||||
|
|
||||||
|
#remove detail
|
||||||
|
self.debug("Testing REMOVE volume detail Volume-ID: %s " % (
|
||||||
|
self.volume.id
|
||||||
|
))
|
||||||
|
cmd = removeResourceDetail.removeResourceDetailCmd()
|
||||||
|
cmd.resourcetype = "Volume"
|
||||||
|
cmd.resourceid = self.volume.id
|
||||||
|
self.apiclient.removeResourceDetail(cmd)
|
||||||
|
|
||||||
|
listResourceDetailCmd = listResourceDetails.listResourceDetailsCmd()
|
||||||
|
listResourceDetailCmd.resourceid = self.volume.id
|
||||||
|
listResourceDetailCmd.resourcetype = "Volume"
|
||||||
|
listResourceDetailResponse = self.api_client.listResourceDetails(listResourceDetailCmd)
|
||||||
|
|
||||||
|
self.assertEqual(listResourceDetailResponse, None, "Check if the list API \
|
||||||
|
returns an empty response")
|
||||||
|
|
||||||
|
#TODO - add detail. Map as input
|
||||||
|
|
||||||
|
return
|
||||||
Loading…
x
Reference in New Issue
Block a user