Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

2. Create a pom.xml in cloudstack/plugins/api/timeofday. Make sure your "parent" relative path points back to plugins/pom.xml, otherwise it won't build. The main entries that matter are the artifactId (cloud-plugin-timeofday), as well as the dependencies.

Code Block
langxml
titleplugins/api/timeofday/pom.xml
borderStylesolid
langxml
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <artifactId>cloud-plugin-api-timeofday</artifactId>
      <name>Apache CloudStack Plugin - TimeOfDay</name>
      <parent>
        <groupId>org.apache.cloudstack</groupId>
        <artifactId>cloudstack-plugins</artifactId>
        <version>4.1.0-SNAPSHOT</version>
        <relativePath>../../pom.xml</relativePath>
      </parent>
      <dependencies>
        <dependency>
          <groupId>org.apache.cloudstack</groupId>
          <artifactId>cloud-api</artifactId>
          <version>${project.version}</version>
        </dependency>
        <dependency>
          <groupId>org.apache.cloudstack</groupId>
          <artifactId>cloud-utils</artifactId>
          <version>${project.version}</version>
        </dependency>
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>${cs.mysql.version}</version>
          <scope>provided</scope>
        </dependency>
      </dependencies>
      <build>
        <defaultGoal>install</defaultGoal>
        <sourceDirectory>src</sourceDirectory>
        <testSourceDirectory>test</testSourceDirectory>
        <plugins>
          <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
              <skipTests>true</skipTests>
            </configuration>
            <executions>
              <execution>
                <phase>integration-test</phase>
                <goals>
                  <goal>test</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </project>

3. Add a module entry in the modules section of cloudstack/plugins/pom.xml for the new plugin, which will let mvn know that the plugin module needs to be built:

Code Block
borderStylesolid
langxmlborderStylesolid

    <module>api/timeofday</module>

...

6. Create an interface that extends from PluggableService

java
Code Block
lang
titleplugins/api/timeofday/src/com/cloud/test/TimeOfDayManager.java
borderStylesolid
langjava

package com.cloud.test;

import com.cloud.utils.component.PluggableService;

public interface TimeOfDayManager extends PluggableService { }

7. Create an implementation of your newly created interface, overriding the getCommands method, and populating it with the classes of each command you want to expose.

java
Code Block
lang
titleplugins/api/timeofday/src/com/cloud/test/TimeOfDayManagerImpl.java
borderStylesolid
langjava

package com.cloud.test;

import com.cloud.utils.component.PluggableService;
import java.util.List;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import com.cloud.test.GetTimeOfDayCmd;
import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;
import javax.ejb.Local;

@Component
@Local(value = { TimeOfDayManager.class })
public class TimeOfDayManagerImpl implements TimeOfDayManager {
    private static final Logger s_logger = Logger.getLogger(TimeOfDayManagerImpl.class);

    public TimeOfDayManagerImpl() {
        super();
    }

    @Override
    public List<Class<?>> getCommands() {
        List<Class<?>> cmdList = new ArrayList<Class<?>>();
        cmdList.add(GetTimeOfDayCmd.class);
        return cmdList;
    }
}

8. Write a command class that implements the correct annotations for a command:

java
Code Block
lang
titleplugins/api/timeofday/src/com/cloud/test/GetTimeOfDayCmd.java
borderStylesolid
langjava

package com.cloud.test;

import javax.inject.Inject;
import org.apache.log4j.Logger;

import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.Parameter;

@APICommand(name = "getTimeOfDay", description="Get Cloudstack's time of day", responseObject = GetTimeOfDayCmdResponse.class, includeInApiDoc=true)
public class GetTimeOfDayCmd extends BaseCmd {
    public static final Logger s_logger = Logger.getLogger(GetTimeOfDayCmd.class.getName());
    private static final String s_name = "gettimeofdayresponse";

    @Parameter(name="example", type=CommandType.STRING, required=false, description="Just an example string that will be uppercased")
    private String example;

    public String getExample() {
        return this.example;
    }

    @Override
    public void execute()
    {
        GetTimeOfDayCmdResponse response = new GetTimeOfDayCmdResponse();
        if ( this.example != null ) {
            response.setExampleEcho(example);
        }

        response.setObjectName("timeofday"); // the inner part of the json structure
        response.setResponseName(getCommandName()); // the outer part of the json structure

        this.setResponseObject(response);
    }

    @Override
    public String getCommandName() {
        return s_name;
    }

    @Override
    public long getEntityOwnerId() {
        return 0;
    }
}

9. Write a Response class for the command:

lang
Code Block
javatitleplugins/api/timeofday/src/com/cloud/test/GetTimeOfDayCmdResponse.java
borderStylesolid
langjava

package com.cloud.test;

import org.apache.cloudstack.api.ApiConstants;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.BaseResponse;

import java.util.Date;
import java.text.SimpleDateFormat;

@SuppressWarnings("unused")
public class GetTimeOfDayCmdResponse extends BaseResponse {
    @SerializedName(ApiConstants.IS_ASYNC) @Param(description="true if api is asynchronous")
    private Boolean isAsync;
    @SerializedName("timeOfDay") @Param(description="The time of day from CloudStack")
    private String  timeOfDay;
    @SerializedName("exampleEcho") @Param(description="An upper cased string")
    private String  exampleEcho;

    public GetTimeOfDayCmdResponse(){
        this.isAsync   = false;

        SimpleDateFormat dateformatYYYYMMDD = new SimpleDateFormat("yyyyMMdd hh:mm:ss");
        this.setTimeOfDay( (new StringBuilder( dateformatYYYYMMDD.format( new Date() ) )).toString() );
    }

    public void setAsync(Boolean isAsync) {
        this.isAsync = isAsync;
    }

    public boolean getAsync() {
        return isAsync;
    }

    public void setTimeOfDay(String timeOfDay) {
        this.timeOfDay = timeOfDay;
    }

    public void setExampleEcho(String exampleEcho) {
        this.exampleEcho = exampleEcho.toUpperCase();
    }
}

10. Update client/tomcatconf/componentContext.xml.in and add your new manager to its configuration:

Code Block
borderStyle
borderStylesolid
langxmlsolid

<bean id="timeOfDayManagerImpl" class="com.cloud.test.TimeOfDayManagerImpl"> </bean>

The above is now obsolete. Instead in your plugin folder you need to add this context, for example in this case:

 

 

 

11. Update client/tomcatconf/commands.properties.in, and add the command name (for the example this would be getTimeOfDay as stated in the @APICommand annotation).

...

13. You can test your new command via the browser, cloudmonkey or even curl. Here is a simple perl script that shows how to test the new getTimeOfDay command.

Code Block
borderStylesolid
langjavascript
borderStylesolid

#!/usr/bin/env perl
use strict;
use Data::Dumper;
use LWP::Simple;
use Mojo::JSON 'j';
my $content = j(get("http://localhost:8096/client/api?command=getTimeOfDay&response=json&example=moo"));
print Dumper($content);

And here is the output

Code Block
borderStylesolid
langjavascriptborderStylesolid

$VAR1 = {
          'gettimeofdayresponse' => {
                                    'timeofday' => {
                                                   'timeOfDay' => '20130404 09:24:00',
                                                   'exampleEcho' => 'MOO',
                                                   'isasync' => bless( do{\(my $o = 0)}, 'Mojo::JSON::_Bool' )
                                                 }
                                  }
        };