SlideShare a Scribd company logo
1 of 26
Developing API Plug-ins for CloudStack*
* Specifically Using Version 4.5
Mike Tutkowski (@mtutkowski on Twitter)
● CloudStack Software Engineer
● Member of CloudStack Project Management Committee (PMC)
● Focused on CloudStack’s storage component
SolidFire (http://www.solidfire.com/)
● Based out of Boulder, CO, USA
● Develop a scale-out storage technology (using industry-standard hardware)
● Built from the ground up to support guaranteed Quality of Service (QoS) on a per-
volume (logical unit) basis (min, max, and burst IOPS per volume)
● All-Flash Array
● Leverage compression, de-duplication, and thin provisioning (all inline) on a 4-KB block
boundary across the entire cluster to drive down cost/GB to be on par with traditional
disk-based systems
● Rest-like API to enable automation of all aspects of the SAN
Why might I want to develop an API
Plug-in for CloudStack?
●
There is a feature in a third-party product that you would like to give
your CloudStack end users and/or admins access to without the need to
change core CloudStack logic (ex. A SAN that supports virtual
networks).
●
Wrapping this functionality in a CloudStack plug-in decouples your
development process from that of the CloudStack community (you can
release your plug-in against particular versions of CloudStack on your
own schedule).
What's our approach here?
We'll construct a basic API plug-in step by step using an existing
API plug-in as a template. This plug-in will enable us to extend
CloudStack's standard API with new commands.
●
These are invoked in the same manner as any standard CloudStack
API command.
●
The client does not know if the API command is standard or an
extension.
●
The client can discover these extended API commands just like
standard API commands (using the listApis API command).
●
Multiple API plug-ins can all run at the same time providing many
extended API commands.
Creating an API plug-in for CloudStack
●
Relative to CloudStack's root folder, let's leverage an existing Maven
project in plugins/api as a template for yours.
●
We will use a SolidFire project as a template for a new project called “abc123”.
Creating an API plug-in for CloudStack
●
Relative to the root abc123 folder (created on the previous slide
by copying and pasting the “solidfire” folder and naming the new
folder “abc123”), update the pom.xml file with applicable information.
Creating an API plug-in for CloudStack
●
Relative to the root abc123 folder, find all folders and files
that have the text “solidfire” in them and change them to
reference the text “abc123” (ex. spring-solidfire-context.xml →
spring-abc123-context.xml).
●
Relative to the root abc123 folder, locate the resources/META-INF/
cloudstack/abc123/module.properties file.
●
In this file, update the text “solidfire” to the text “abc123”.
name=solidfire
parent=api
Creating an API plug-in for CloudStack
●
Relative to the root abc123 folder, locate the
resources/META-INF/cloudstack/abc123/spring-abc123-context.xml file.
●
In this file, only keep three of the <bean/> lines.
●
Update the <bean/> lines such as below (the id attribute is not
currently used, but each class attribute must reference a class we
are to make later).
<bean id="abc123Util" class="org.apache.cloudstack.util.abc123.Abc123Util" />
<bean id="abc123ManagerImpl" class="org.apache.cloudstack.abc123.Abc123ManagerImpl" />
<bean id="apiAbc123ServiceImpl" class="org.apache.cloudstack.api.abc123.ApiAbc123ServiceImpl" />
Creating an API plug-in for CloudStack
●
Relative to CloudStack's root folder, locate the plugins/pom.xml file.
●
Add the following line into the <modules> section.
<module>api/abc123</module>
Creating an API plug-in for CloudStack
●
Relative to CloudStack's root folder, update the <dependencies>
section of the client/pom.xml file to reference your new project.
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-api-abc123</artifactId>
<version>${project.version}</version>
</dependency>
Creating an API plug-in for CloudStack
Client
http://192.168.1.2:8080/client/api?method=deleteAbc123VirtualNetwork&id=45
API Layer (ex. DeleteAbc123VirtualNetworkCmd)
Service Layer (ex. Abc123Manager)
Data Access Layer (ex. VOs and DAOs)
Note: A layer only knows about the layer right below it. It does not know about any layers above it.
Creating an API plug-in for CloudStack
ApiAbc123Service
ApiAbc123ServiceImpl
APIChecker ConfigurablePluggableService
Abc123ManagerImpl
Abc123Manager
API
Layer
Service Layer
AdapterBase
Note: Black box = Interface; Red box = Class; Dotted box = Optional Interface
Creating an API plug-in for CloudStack
package org.apache.cloudstack.abc123;
import org.apache.cloudstack.framework.config.Configurable;
public interface Abc123Manager extends Configurable {
public interface Configurable {
String getConfigComponentName();
ConfigKey<?>[] getConfigKeys();
}
// example way to implement this
return Abc123ManagerImpl.class.getSimpleName();
Service Layer
Creating an API plug-in for CloudStack
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] { s_TotalAccountCapacity };
}
private static final ConfigKey<Long> s_TotalAccountCapacity =
new ConfigKey<>(
"Advanced",
Long.class,
"abc123.total.capacity",
"0",
"Total capacity the account can draw from any and all clusters (in GBs)",
true, ConfigKey.Scope.Account);
public class Abc123ManagerImpl implements Abc123Manager {
Service Layer
Creating an API plug-in for CloudStack
public interface Abc123Manager extends Configurable {
public List<Abc123VirtualNetwork> listAbc123VirtualNetworks(Long id);
public Abc123VirtualNetwork deleteAbc123VirtualNetwork(long id);
}
If number and
required, I use a
primitive.
If number and NOT
required, I use a
number wrapper and
check for null to see
if it was not
provided.
Service Layer
Creating an API plug-in for CloudStack
public class Abc123ManagerImpl implements Abc123Manager {
Return interface type (ex. Not
Abc123VirtualNetworkVO) so caller is more
abstracted away from where this data lives (in
case its location is changed in the future and
the underlying type needs to change, too).
@Override
public Abc123VirtualNetwork deleteAbc123VirtualNetwork(long id) {
verifyRootAdmin();
Abc123VirtualNetworkVO virtualNetwork = getAbc123VirtualNetworkVO(id);
List<Abc123VolumeVO> volumes = _abc123VolumeDao.findByAbc123VirtualNetworkId(virtualNetwork.getId());
if (volumes != null && volumes.size() > 0) {
throw new CloudRuntimeException("Unable to delete a virtual network that has one or more volumes");
}
if (!_abc123VirtualNetworkDao.remove(id)) {
throw new CloudRuntimeException("Unable to remove the following virtual network: " + id);
}
Abc123ClusterVO cluster = getAbc123ClusterVO(virtualNetwork.getAbc123ClusterId());
Abc123Connection conn = new Abc123Connection(cluster.getIp(), cluster.getUsername(), cluster.getPassword());
conn.deleteVirtualNetwork(virtualNetwork.getAbc123Id());
return virtualNetwork;
}
Service Layer
Creating an API plug-in for CloudStack
package org.apache.cloudstack.abc123;
import com.cloud.utils.component.PluggableService;
import org.apache.cloudstack.acl.APIChecker;
public interface ApiAbc123Service extends PluggableService, APIChecker {
public interface PluggableService {
List<Class<?>> getCommands();
}
// optional: only required if we have special needs with regards to checking API permissions
public interface APIChecker extends Adapter {
boolean checkAccess(User user, String apiCommandName) throws PermissionDeniedException;
}
API Layer
Creating an API plug-in for CloudStack
public class ApiAbc123ServiceImpl extends AdapterBase implements ApiAbc123Service {
@Override
public List<Class<?>> getCommands() {
List<Class<?>> cmdList = new ArrayList<Class<?>>();
cmdList.add(ListAbc123VirtualNetworksCmd.class);
cmdList.add(DeleteAbc123VirtualNetworkCmd.class);
return cmdList;
}
API Layer
Creating an API plug-in for CloudStack
●
Relative to CloudStack's root folder, locate the
client/tomcatconf/commands.properties.in file.
●
Add the following lines into the file (the meaning of the numbers is
provided at the top of the file):
#### API Abc123 Service Commands
deleteAbc123VirtualNetwork=1
listAbc123VirtualNetworks=15
●
If an API command is not listed in this file, the
StaticRoleBasedAPIAccessChecker (which implements the
APIChecker interface) will cause CloudStack to not “see” the command.
API Layer
Creating an API plug-in for CloudStack
@Override
public boolean checkAccess(User user, String apiCommandName) throws PermissionDeniedException {
if (_accountMgr.isRootAdmin(user.getAccountId())) {
return true;
}
if ("listAbc123VirtualNetworks".equals(apiCommandName)) {
return true;
}
throw new PermissionDeniedException("User " + user.getFirstname() + " " +
user.getLastname() + " cannot access the following command: " + apiCommandName);
}
API Layer
public class ApiAbc123ServiceImpl extends AdapterBase implements ApiAbc123Service {
Creating an API plug-in for CloudStack
@APICommand(name = "deleteAbc123VirtualNetwork",
responseObject = ApiAbc123VirtualNetworkResponse.class,
description = "Delete Abc123 Virtual Network",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class DeleteAbc123VirtualNetworkCmd extends BaseCmd {
private static final Logger s_logger =
Logger.getLogger(DeleteAbc123VirtualNetworkCmd.class.getName());
private static final String s_name = "deleteabc123virtualnetworkresponse";
@Parameter(name = ApiConstants.ID, type = CommandType.UUID,
entityType = ApiAbc123VirtualNetworkResponse.class,
description = ApiHelper.VIRTUAL_NETWORK_ID_DESC, required = true)
private long _id;
@Inject private Abc123Util _abc123Util;
@Inject private Abc123Manager _abc123Manager;
API Layer
Creating an API plug-in for CloudStack
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return _accountId;
}
API Layer
Creating an API plug-in for CloudStack
@Override
public void execute() {
try {
s_logger.info(DeleteAbc123VirtualNetworkCmd.class.getName() + ".execute invoked");
Abc123VirtualNetwork virtualNetwork = _apiAbc123Manager.deleteAbc123VirtualNetwork(_id);
ApiAbc123VirtualNetworkResponse response =
_abc123Util.getApiAbc123VirtualNetworkResponse(virtualNetwork, ResponseView.Full);
response.setResponseName(getCommandName());
response.setObjectName("apideleteabc123virtualnetwork");
setResponseObject(response);
}
catch (Throwable t) {
s_logger.error(t.getMessage());
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, t.getMessage());
}
}
API Layer
Creating an API plug-in for CloudStack
@EntityReference(value = Abc123VirtualNetwork.class)
public class ApiAbc123VirtualNetworkResponse extends BaseResponse {
@SerializedName("id")
@Param(description = "CloudStack ID")
private long _id;
@SerializedName("uuid")
@Param(description = "CloudStack UUID")
private String _uuid;
@SerializedName("name")
@Param(description = ApiHelper.VIRTUAL_NETWORK_NAME_DESC)
private String _name;
@SerializedName("size")
@Param(description = ApiHelper.SIZE_DESC)
private int _size;
API Layer
Creating an API plug-in for CloudStack
public ApiAbc123VirtualNetworkResponse getApiAbc123VirtualNetworkResponse(Abc123VirtualNetwork abc123VirtualNetwork, ResponseView responseView) {
ApiAbc123VirtualNetworkResponse abc123Response = new ApiAbc123VirtualNetworkResponse();
abc123Response.setId(abc123VirtualNetwork.getId());
abc123Response.setUuid(abc123VirtualNetwork.getUuid());
abc123Response.setAccountId(abc123VirtualNetwork.getAccountId());
Account account = _accountDao.findById(abc123VirtualNetwork.getAccountId());
abc123Response.setAccountUuid(account.getUuid());
abc123Response.setAccountName(account.getAccountName());
Abc123Cluster abc123Cluster = _abc123ClusterDao.findById(abc123VirtualNetwork.getAbc123ClusterId());
abc123Response.setZoneId(abc123Cluster.getZoneId());
DataCenterVO dataCenterVO = _zoneDao.findById(abc123Cluster.getZoneId());
abc123Response.setZoneUuid(dataCenterVO.getUuid());
abc123Response.setZoneName(dataCenterVO.getName());
if (ResponseView.Full.equals(responseView)) {
abc123Response.setClusterName(abc123Cluster.getName());
}
abc123Response.setObjectName("abc123virtualnetwork");
return abc123Response;
}
Translate Service-Layer Object to API-Layer Object
Creating an API plug-in for CloudStack
Shut down the CloudStack Management Server.
Place cloud-plugin-api-abc123-4.5.3-SNAPSHOT.jar in
/usr/share/cloudstack-management/webapps/client/WEB-
INF/classes.
Updated commands.properties should be placed here:
/usr/share/cloudstack-
management/webapps/client/WEB- INF/classes
Restart the CloudStack Management Server.
Deploying your API Plug-in

More Related Content

What's hot

Aspecio - aspect-oriented programming meets the OSGi service model - Simon Ch...
Aspecio - aspect-oriented programming meets the OSGi service model - Simon Ch...Aspecio - aspect-oriented programming meets the OSGi service model - Simon Ch...
Aspecio - aspect-oriented programming meets the OSGi service model - Simon Ch...
mfrancis
 

What's hot (20)

Heat optimization
Heat optimizationHeat optimization
Heat optimization
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
 
ApacheCon NA - Apache Camel K: a cloud-native integration platform
ApacheCon NA - Apache Camel K: a cloud-native integration platformApacheCon NA - Apache Camel K: a cloud-native integration platform
ApacheCon NA - Apache Camel K: a cloud-native integration platform
 
[AWS Dev Day] 앱 현대화 | AWS Fargate를 사용한 서버리스 컨테이너 활용 하기 - 삼성전자 개발자 포털 사례 - 정영준...
[AWS Dev Day] 앱 현대화 | AWS Fargate를 사용한 서버리스 컨테이너 활용 하기 - 삼성전자 개발자 포털 사례 - 정영준...[AWS Dev Day] 앱 현대화 | AWS Fargate를 사용한 서버리스 컨테이너 활용 하기 - 삼성전자 개발자 포털 사례 - 정영준...
[AWS Dev Day] 앱 현대화 | AWS Fargate를 사용한 서버리스 컨테이너 활용 하기 - 삼성전자 개발자 포털 사례 - 정영준...
 
A Series of Fortunate Events: Building an Operator in Java
A Series of Fortunate Events: Building an Operator in JavaA Series of Fortunate Events: Building an Operator in Java
A Series of Fortunate Events: Building an Operator in Java
 
Heat up your stack
Heat up your stackHeat up your stack
Heat up your stack
 
W-JAX 2011: OSGi with Apache Karaf
W-JAX 2011: OSGi with Apache KarafW-JAX 2011: OSGi with Apache Karaf
W-JAX 2011: OSGi with Apache Karaf
 
Workshop Interstella GTC - Tiffany Jernigan.pdf
Workshop Interstella GTC - Tiffany Jernigan.pdfWorkshop Interstella GTC - Tiffany Jernigan.pdf
Workshop Interstella GTC - Tiffany Jernigan.pdf
 
Helm – The package manager for Kubernetes
Helm – The package manager for KubernetesHelm – The package manager for Kubernetes
Helm – The package manager for Kubernetes
 
MuleSoft Manchester Meetup #3 slides 31st March 2020
MuleSoft Manchester Meetup #3 slides 31st March 2020MuleSoft Manchester Meetup #3 slides 31st March 2020
MuleSoft Manchester Meetup #3 slides 31st March 2020
 
Java Microservices with Netflix OSS & Spring
Java Microservices with Netflix OSS & Spring Java Microservices with Netflix OSS & Spring
Java Microservices with Netflix OSS & Spring
 
Aspecio - aspect-oriented programming meets the OSGi service model - Simon Ch...
Aspecio - aspect-oriented programming meets the OSGi service model - Simon Ch...Aspecio - aspect-oriented programming meets the OSGi service model - Simon Ch...
Aspecio - aspect-oriented programming meets the OSGi service model - Simon Ch...
 
Deploying Flink on Kubernetes - David Anderson
 Deploying Flink on Kubernetes - David Anderson Deploying Flink on Kubernetes - David Anderson
Deploying Flink on Kubernetes - David Anderson
 
Game of Streams: How to Tame and Get the Most from Your Messaging Platforms
Game of Streams: How to Tame and Get the Most from Your Messaging PlatformsGame of Streams: How to Tame and Get the Most from Your Messaging Platforms
Game of Streams: How to Tame and Get the Most from Your Messaging Platforms
 
Oracle API Gateway Installation
Oracle API Gateway InstallationOracle API Gateway Installation
Oracle API Gateway Installation
 
Staying Ahead of the Curve with Spring and Cassandra 4 (SpringOne 2020)
Staying Ahead of the Curve with Spring and Cassandra 4 (SpringOne 2020)Staying Ahead of the Curve with Spring and Cassandra 4 (SpringOne 2020)
Staying Ahead of the Curve with Spring and Cassandra 4 (SpringOne 2020)
 
Salvatore Incandela, Fabio Marinelli - Using Spinnaker to Create a Developmen...
Salvatore Incandela, Fabio Marinelli - Using Spinnaker to Create a Developmen...Salvatore Incandela, Fabio Marinelli - Using Spinnaker to Create a Developmen...
Salvatore Incandela, Fabio Marinelli - Using Spinnaker to Create a Developmen...
 
Introduction to Helm
Introduction to HelmIntroduction to Helm
Introduction to Helm
 
Aura Framework Overview
Aura Framework OverviewAura Framework Overview
Aura Framework Overview
 
Level-up your gaming telemetry using Kafka Streams | DevNation Tech Talk
Level-up your gaming telemetry using Kafka Streams | DevNation Tech TalkLevel-up your gaming telemetry using Kafka Streams | DevNation Tech Talk
Level-up your gaming telemetry using Kafka Streams | DevNation Tech Talk
 

Similar to Developingapiplug insforcs-151112204727-lva1-app6891

Event Streaming with Kafka Streams and Spring Cloud Stream | Soby Chacko, VMware
Event Streaming with Kafka Streams and Spring Cloud Stream | Soby Chacko, VMwareEvent Streaming with Kafka Streams and Spring Cloud Stream | Soby Chacko, VMware
Event Streaming with Kafka Streams and Spring Cloud Stream | Soby Chacko, VMware
HostedbyConfluent
 

Similar to Developingapiplug insforcs-151112204727-lva1-app6891 (20)

Serverless archtiectures
Serverless archtiecturesServerless archtiectures
Serverless archtiectures
 
AWS Serverless Workshop
AWS Serverless WorkshopAWS Serverless Workshop
AWS Serverless Workshop
 
Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
Mythical Mysfits: Monolith to Microservice with Docker and AWS Fargate (CON21...
Mythical Mysfits: Monolith to Microservice with Docker and AWS Fargate (CON21...Mythical Mysfits: Monolith to Microservice with Docker and AWS Fargate (CON21...
Mythical Mysfits: Monolith to Microservice with Docker and AWS Fargate (CON21...
 
Spring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in HeavenSpring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in Heaven
 
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten ZiegelerNew and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
 
Jetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO ExtendedJetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO Extended
 
Mythical Mysfits: Monolith to Microservices with Docker and Fargate - MAD305 ...
Mythical Mysfits: Monolith to Microservices with Docker and Fargate - MAD305 ...Mythical Mysfits: Monolith to Microservices with Docker and Fargate - MAD305 ...
Mythical Mysfits: Monolith to Microservices with Docker and Fargate - MAD305 ...
 
Microsoft Windows Server AppFabric
Microsoft Windows Server AppFabricMicrosoft Windows Server AppFabric
Microsoft Windows Server AppFabric
 
CI/CD on AWS
CI/CD on AWSCI/CD on AWS
CI/CD on AWS
 
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...
 
Let's play with adf 3.0
Let's play with adf 3.0Let's play with adf 3.0
Let's play with adf 3.0
 
JCConf 2016 - Dataflow Workshop Labs
JCConf 2016 - Dataflow Workshop LabsJCConf 2016 - Dataflow Workshop Labs
JCConf 2016 - Dataflow Workshop Labs
 
Activemq installation and master slave setup using shared broker data
Activemq installation and master slave setup using shared broker dataActivemq installation and master slave setup using shared broker data
Activemq installation and master slave setup using shared broker data
 
Event Streaming with Kafka Streams and Spring Cloud Stream | Soby Chacko, VMware
Event Streaming with Kafka Streams and Spring Cloud Stream | Soby Chacko, VMwareEvent Streaming with Kafka Streams and Spring Cloud Stream | Soby Chacko, VMware
Event Streaming with Kafka Streams and Spring Cloud Stream | Soby Chacko, VMware
 
M|18 Ingesting Data with the New Bulk Data Adapters
M|18 Ingesting Data with the New Bulk Data AdaptersM|18 Ingesting Data with the New Bulk Data Adapters
M|18 Ingesting Data with the New Bulk Data Adapters
 
Infrastructure Continuous Delivery Using AWS CloudFormation
Infrastructure Continuous Delivery Using AWS CloudFormationInfrastructure Continuous Delivery Using AWS CloudFormation
Infrastructure Continuous Delivery Using AWS CloudFormation
 
Docker Java App with MariaDB – Deployment in Less than a Minute
Docker Java App with MariaDB – Deployment in Less than a MinuteDocker Java App with MariaDB – Deployment in Less than a Minute
Docker Java App with MariaDB – Deployment in Less than a Minute
 
"Automating AWS Infrastructure with PowerShell", Martin Beeby, AWS Dev Day Ky...
"Automating AWS Infrastructure with PowerShell", Martin Beeby, AWS Dev Day Ky..."Automating AWS Infrastructure with PowerShell", Martin Beeby, AWS Dev Day Ky...
"Automating AWS Infrastructure with PowerShell", Martin Beeby, AWS Dev Day Ky...
 
GraphQL across the stack: How everything fits together
GraphQL across the stack: How everything fits togetherGraphQL across the stack: How everything fits together
GraphQL across the stack: How everything fits together
 

More from NetApp

More from NetApp (20)

DevOps the NetApp Way: 10 Rules for Forming a DevOps Team
DevOps the NetApp Way: 10 Rules for Forming a DevOps TeamDevOps the NetApp Way: 10 Rules for Forming a DevOps Team
DevOps the NetApp Way: 10 Rules for Forming a DevOps Team
 
10 Reasons to Choose NetApp for EUC/VDI
10 Reasons to Choose NetApp for EUC/VDI10 Reasons to Choose NetApp for EUC/VDI
10 Reasons to Choose NetApp for EUC/VDI
 
Spot Lets NetApp Get the Most Out of the Cloud
Spot Lets NetApp Get the Most Out of the CloudSpot Lets NetApp Get the Most Out of the Cloud
Spot Lets NetApp Get the Most Out of the Cloud
 
NetApp #WFH: COVID-19 Impact Report
NetApp #WFH: COVID-19 Impact ReportNetApp #WFH: COVID-19 Impact Report
NetApp #WFH: COVID-19 Impact Report
 
4 Ways FlexPod Forms the Foundation for Cisco and NetApp Success
4 Ways FlexPod Forms the Foundation for Cisco and NetApp Success4 Ways FlexPod Forms the Foundation for Cisco and NetApp Success
4 Ways FlexPod Forms the Foundation for Cisco and NetApp Success
 
NetApp 2020 Predictions
NetApp 2020 Predictions NetApp 2020 Predictions
NetApp 2020 Predictions
 
NetApp 2020 Predictions
NetApp 2020 Predictions NetApp 2020 Predictions
NetApp 2020 Predictions
 
NetApp 2020 Predictions in Tech
NetApp 2020 Predictions in TechNetApp 2020 Predictions in Tech
NetApp 2020 Predictions in Tech
 
Corporate IT at NetApp
Corporate IT at NetAppCorporate IT at NetApp
Corporate IT at NetApp
 
Modernize small and mid-sized enterprise data management with the AFF C190
Modernize small and mid-sized enterprise data management with the AFF C190Modernize small and mid-sized enterprise data management with the AFF C190
Modernize small and mid-sized enterprise data management with the AFF C190
 
Achieving Target State Architecture in NetApp IT
Achieving Target State Architecture in NetApp ITAchieving Target State Architecture in NetApp IT
Achieving Target State Architecture in NetApp IT
 
10 Reasons Why Your SAP Applications Belong on NetApp
10 Reasons Why Your SAP Applications Belong on NetApp10 Reasons Why Your SAP Applications Belong on NetApp
10 Reasons Why Your SAP Applications Belong on NetApp
 
Turbocharge Your Data with Intel Optane Technology and MAX Data
Turbocharge Your Data with Intel Optane Technology and MAX DataTurbocharge Your Data with Intel Optane Technology and MAX Data
Turbocharge Your Data with Intel Optane Technology and MAX Data
 
Redefining HCI: How to Go from Hyper Converged to Hybrid Cloud Infrastructure
Redefining HCI: How to Go from Hyper Converged to Hybrid Cloud InfrastructureRedefining HCI: How to Go from Hyper Converged to Hybrid Cloud Infrastructure
Redefining HCI: How to Go from Hyper Converged to Hybrid Cloud Infrastructure
 
Webinar: NetApp SaaS Backup
Webinar: NetApp SaaS BackupWebinar: NetApp SaaS Backup
Webinar: NetApp SaaS Backup
 
NetApp 2019 Perspectives
NetApp 2019 PerspectivesNetApp 2019 Perspectives
NetApp 2019 Perspectives
 
Künstliche Intelligenz ist in deutschen Unter- nehmen Chefsache
Künstliche Intelligenz ist in deutschen Unter- nehmen ChefsacheKünstliche Intelligenz ist in deutschen Unter- nehmen Chefsache
Künstliche Intelligenz ist in deutschen Unter- nehmen Chefsache
 
Iperconvergenza come migliora gli economics del tuo IT
Iperconvergenza come migliora gli economics del tuo ITIperconvergenza come migliora gli economics del tuo IT
Iperconvergenza come migliora gli economics del tuo IT
 
10 Good Reasons: NetApp for Artificial Intelligence / Deep Learning
10 Good Reasons: NetApp for Artificial Intelligence / Deep Learning10 Good Reasons: NetApp for Artificial Intelligence / Deep Learning
10 Good Reasons: NetApp for Artificial Intelligence / Deep Learning
 
NetApp IT’s Tiered Archive Approach for Active IQ
NetApp IT’s Tiered Archive Approach for Active IQNetApp IT’s Tiered Archive Approach for Active IQ
NetApp IT’s Tiered Archive Approach for Active IQ
 

Recently uploaded

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Recently uploaded (20)

Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software Engineering
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Navigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern EnterpriseNavigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern Enterprise
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptx
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 

Developingapiplug insforcs-151112204727-lva1-app6891

  • 1. Developing API Plug-ins for CloudStack* * Specifically Using Version 4.5
  • 2. Mike Tutkowski (@mtutkowski on Twitter) ● CloudStack Software Engineer ● Member of CloudStack Project Management Committee (PMC) ● Focused on CloudStack’s storage component SolidFire (http://www.solidfire.com/) ● Based out of Boulder, CO, USA ● Develop a scale-out storage technology (using industry-standard hardware) ● Built from the ground up to support guaranteed Quality of Service (QoS) on a per- volume (logical unit) basis (min, max, and burst IOPS per volume) ● All-Flash Array ● Leverage compression, de-duplication, and thin provisioning (all inline) on a 4-KB block boundary across the entire cluster to drive down cost/GB to be on par with traditional disk-based systems ● Rest-like API to enable automation of all aspects of the SAN
  • 3. Why might I want to develop an API Plug-in for CloudStack? ● There is a feature in a third-party product that you would like to give your CloudStack end users and/or admins access to without the need to change core CloudStack logic (ex. A SAN that supports virtual networks). ● Wrapping this functionality in a CloudStack plug-in decouples your development process from that of the CloudStack community (you can release your plug-in against particular versions of CloudStack on your own schedule).
  • 4. What's our approach here? We'll construct a basic API plug-in step by step using an existing API plug-in as a template. This plug-in will enable us to extend CloudStack's standard API with new commands. ● These are invoked in the same manner as any standard CloudStack API command. ● The client does not know if the API command is standard or an extension. ● The client can discover these extended API commands just like standard API commands (using the listApis API command). ● Multiple API plug-ins can all run at the same time providing many extended API commands.
  • 5. Creating an API plug-in for CloudStack ● Relative to CloudStack's root folder, let's leverage an existing Maven project in plugins/api as a template for yours. ● We will use a SolidFire project as a template for a new project called “abc123”.
  • 6. Creating an API plug-in for CloudStack ● Relative to the root abc123 folder (created on the previous slide by copying and pasting the “solidfire” folder and naming the new folder “abc123”), update the pom.xml file with applicable information.
  • 7. Creating an API plug-in for CloudStack ● Relative to the root abc123 folder, find all folders and files that have the text “solidfire” in them and change them to reference the text “abc123” (ex. spring-solidfire-context.xml → spring-abc123-context.xml). ● Relative to the root abc123 folder, locate the resources/META-INF/ cloudstack/abc123/module.properties file. ● In this file, update the text “solidfire” to the text “abc123”. name=solidfire parent=api
  • 8. Creating an API plug-in for CloudStack ● Relative to the root abc123 folder, locate the resources/META-INF/cloudstack/abc123/spring-abc123-context.xml file. ● In this file, only keep three of the <bean/> lines. ● Update the <bean/> lines such as below (the id attribute is not currently used, but each class attribute must reference a class we are to make later). <bean id="abc123Util" class="org.apache.cloudstack.util.abc123.Abc123Util" /> <bean id="abc123ManagerImpl" class="org.apache.cloudstack.abc123.Abc123ManagerImpl" /> <bean id="apiAbc123ServiceImpl" class="org.apache.cloudstack.api.abc123.ApiAbc123ServiceImpl" />
  • 9. Creating an API plug-in for CloudStack ● Relative to CloudStack's root folder, locate the plugins/pom.xml file. ● Add the following line into the <modules> section. <module>api/abc123</module>
  • 10. Creating an API plug-in for CloudStack ● Relative to CloudStack's root folder, update the <dependencies> section of the client/pom.xml file to reference your new project. <dependency> <groupId>org.apache.cloudstack</groupId> <artifactId>cloud-plugin-api-abc123</artifactId> <version>${project.version}</version> </dependency>
  • 11. Creating an API plug-in for CloudStack Client http://192.168.1.2:8080/client/api?method=deleteAbc123VirtualNetwork&id=45 API Layer (ex. DeleteAbc123VirtualNetworkCmd) Service Layer (ex. Abc123Manager) Data Access Layer (ex. VOs and DAOs) Note: A layer only knows about the layer right below it. It does not know about any layers above it.
  • 12. Creating an API plug-in for CloudStack ApiAbc123Service ApiAbc123ServiceImpl APIChecker ConfigurablePluggableService Abc123ManagerImpl Abc123Manager API Layer Service Layer AdapterBase Note: Black box = Interface; Red box = Class; Dotted box = Optional Interface
  • 13. Creating an API plug-in for CloudStack package org.apache.cloudstack.abc123; import org.apache.cloudstack.framework.config.Configurable; public interface Abc123Manager extends Configurable { public interface Configurable { String getConfigComponentName(); ConfigKey<?>[] getConfigKeys(); } // example way to implement this return Abc123ManagerImpl.class.getSimpleName(); Service Layer
  • 14. Creating an API plug-in for CloudStack @Override public ConfigKey<?>[] getConfigKeys() { return new ConfigKey<?>[] { s_TotalAccountCapacity }; } private static final ConfigKey<Long> s_TotalAccountCapacity = new ConfigKey<>( "Advanced", Long.class, "abc123.total.capacity", "0", "Total capacity the account can draw from any and all clusters (in GBs)", true, ConfigKey.Scope.Account); public class Abc123ManagerImpl implements Abc123Manager { Service Layer
  • 15. Creating an API plug-in for CloudStack public interface Abc123Manager extends Configurable { public List<Abc123VirtualNetwork> listAbc123VirtualNetworks(Long id); public Abc123VirtualNetwork deleteAbc123VirtualNetwork(long id); } If number and required, I use a primitive. If number and NOT required, I use a number wrapper and check for null to see if it was not provided. Service Layer
  • 16. Creating an API plug-in for CloudStack public class Abc123ManagerImpl implements Abc123Manager { Return interface type (ex. Not Abc123VirtualNetworkVO) so caller is more abstracted away from where this data lives (in case its location is changed in the future and the underlying type needs to change, too). @Override public Abc123VirtualNetwork deleteAbc123VirtualNetwork(long id) { verifyRootAdmin(); Abc123VirtualNetworkVO virtualNetwork = getAbc123VirtualNetworkVO(id); List<Abc123VolumeVO> volumes = _abc123VolumeDao.findByAbc123VirtualNetworkId(virtualNetwork.getId()); if (volumes != null && volumes.size() > 0) { throw new CloudRuntimeException("Unable to delete a virtual network that has one or more volumes"); } if (!_abc123VirtualNetworkDao.remove(id)) { throw new CloudRuntimeException("Unable to remove the following virtual network: " + id); } Abc123ClusterVO cluster = getAbc123ClusterVO(virtualNetwork.getAbc123ClusterId()); Abc123Connection conn = new Abc123Connection(cluster.getIp(), cluster.getUsername(), cluster.getPassword()); conn.deleteVirtualNetwork(virtualNetwork.getAbc123Id()); return virtualNetwork; } Service Layer
  • 17. Creating an API plug-in for CloudStack package org.apache.cloudstack.abc123; import com.cloud.utils.component.PluggableService; import org.apache.cloudstack.acl.APIChecker; public interface ApiAbc123Service extends PluggableService, APIChecker { public interface PluggableService { List<Class<?>> getCommands(); } // optional: only required if we have special needs with regards to checking API permissions public interface APIChecker extends Adapter { boolean checkAccess(User user, String apiCommandName) throws PermissionDeniedException; } API Layer
  • 18. Creating an API plug-in for CloudStack public class ApiAbc123ServiceImpl extends AdapterBase implements ApiAbc123Service { @Override public List<Class<?>> getCommands() { List<Class<?>> cmdList = new ArrayList<Class<?>>(); cmdList.add(ListAbc123VirtualNetworksCmd.class); cmdList.add(DeleteAbc123VirtualNetworkCmd.class); return cmdList; } API Layer
  • 19. Creating an API plug-in for CloudStack ● Relative to CloudStack's root folder, locate the client/tomcatconf/commands.properties.in file. ● Add the following lines into the file (the meaning of the numbers is provided at the top of the file): #### API Abc123 Service Commands deleteAbc123VirtualNetwork=1 listAbc123VirtualNetworks=15 ● If an API command is not listed in this file, the StaticRoleBasedAPIAccessChecker (which implements the APIChecker interface) will cause CloudStack to not “see” the command. API Layer
  • 20. Creating an API plug-in for CloudStack @Override public boolean checkAccess(User user, String apiCommandName) throws PermissionDeniedException { if (_accountMgr.isRootAdmin(user.getAccountId())) { return true; } if ("listAbc123VirtualNetworks".equals(apiCommandName)) { return true; } throw new PermissionDeniedException("User " + user.getFirstname() + " " + user.getLastname() + " cannot access the following command: " + apiCommandName); } API Layer public class ApiAbc123ServiceImpl extends AdapterBase implements ApiAbc123Service {
  • 21. Creating an API plug-in for CloudStack @APICommand(name = "deleteAbc123VirtualNetwork", responseObject = ApiAbc123VirtualNetworkResponse.class, description = "Delete Abc123 Virtual Network", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteAbc123VirtualNetworkCmd extends BaseCmd { private static final Logger s_logger = Logger.getLogger(DeleteAbc123VirtualNetworkCmd.class.getName()); private static final String s_name = "deleteabc123virtualnetworkresponse"; @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ApiAbc123VirtualNetworkResponse.class, description = ApiHelper.VIRTUAL_NETWORK_ID_DESC, required = true) private long _id; @Inject private Abc123Util _abc123Util; @Inject private Abc123Manager _abc123Manager; API Layer
  • 22. Creating an API plug-in for CloudStack @Override public String getCommandName() { return s_name; } @Override public long getEntityOwnerId() { return _accountId; } API Layer
  • 23. Creating an API plug-in for CloudStack @Override public void execute() { try { s_logger.info(DeleteAbc123VirtualNetworkCmd.class.getName() + ".execute invoked"); Abc123VirtualNetwork virtualNetwork = _apiAbc123Manager.deleteAbc123VirtualNetwork(_id); ApiAbc123VirtualNetworkResponse response = _abc123Util.getApiAbc123VirtualNetworkResponse(virtualNetwork, ResponseView.Full); response.setResponseName(getCommandName()); response.setObjectName("apideleteabc123virtualnetwork"); setResponseObject(response); } catch (Throwable t) { s_logger.error(t.getMessage()); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, t.getMessage()); } } API Layer
  • 24. Creating an API plug-in for CloudStack @EntityReference(value = Abc123VirtualNetwork.class) public class ApiAbc123VirtualNetworkResponse extends BaseResponse { @SerializedName("id") @Param(description = "CloudStack ID") private long _id; @SerializedName("uuid") @Param(description = "CloudStack UUID") private String _uuid; @SerializedName("name") @Param(description = ApiHelper.VIRTUAL_NETWORK_NAME_DESC) private String _name; @SerializedName("size") @Param(description = ApiHelper.SIZE_DESC) private int _size; API Layer
  • 25. Creating an API plug-in for CloudStack public ApiAbc123VirtualNetworkResponse getApiAbc123VirtualNetworkResponse(Abc123VirtualNetwork abc123VirtualNetwork, ResponseView responseView) { ApiAbc123VirtualNetworkResponse abc123Response = new ApiAbc123VirtualNetworkResponse(); abc123Response.setId(abc123VirtualNetwork.getId()); abc123Response.setUuid(abc123VirtualNetwork.getUuid()); abc123Response.setAccountId(abc123VirtualNetwork.getAccountId()); Account account = _accountDao.findById(abc123VirtualNetwork.getAccountId()); abc123Response.setAccountUuid(account.getUuid()); abc123Response.setAccountName(account.getAccountName()); Abc123Cluster abc123Cluster = _abc123ClusterDao.findById(abc123VirtualNetwork.getAbc123ClusterId()); abc123Response.setZoneId(abc123Cluster.getZoneId()); DataCenterVO dataCenterVO = _zoneDao.findById(abc123Cluster.getZoneId()); abc123Response.setZoneUuid(dataCenterVO.getUuid()); abc123Response.setZoneName(dataCenterVO.getName()); if (ResponseView.Full.equals(responseView)) { abc123Response.setClusterName(abc123Cluster.getName()); } abc123Response.setObjectName("abc123virtualnetwork"); return abc123Response; } Translate Service-Layer Object to API-Layer Object
  • 26. Creating an API plug-in for CloudStack Shut down the CloudStack Management Server. Place cloud-plugin-api-abc123-4.5.3-SNAPSHOT.jar in /usr/share/cloudstack-management/webapps/client/WEB- INF/classes. Updated commands.properties should be placed here: /usr/share/cloudstack- management/webapps/client/WEB- INF/classes Restart the CloudStack Management Server. Deploying your API Plug-in