Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
7eea001
add new and update existing maven modules using respective pom.xml
Nov 15, 2025
e4ff60f
add module.properties
Nov 15, 2025
b14b726
add list and response class
Nov 15, 2025
72b9ca7
add service and inject it as a bean
Nov 15, 2025
364cd4c
update apidocs
Nov 15, 2025
5dacb24
add CreateCoffeeCmd
Nov 24, 2025
cd7acf5
add UpdateCoffeeCmd
Nov 24, 2025
e06880f
add RemoveCoffeeCmd
Nov 24, 2025
5e72ab6
load feature after backend by making it a child of backend.
Nov 24, 2025
3319d2d
use coffeeManager and it's implementation instead of service
Nov 24, 2025
f7cfda9
add coffee resource
Nov 24, 2025
c1cdfd6
use dependency injection and coffee resource in api commands
Nov 24, 2025
ff437da
remove un-needed comment
Nov 24, 2025
6f8f8c5
use naming convention for static variable logger
Nov 25, 2025
5a2404e
add missing license
Nov 25, 2025
1356b58
add zone scoped coffee.ttl.interval config key
Nov 25, 2025
5bfc52c
add coffee.gc.interval for running a background task
Nov 25, 2025
ebacdbc
add coffee table schema
Nov 26, 2025
e67c234
fix typo
Nov 26, 2025
f9fc8ba
add CoffeeVO entity class
Nov 26, 2025
027a1c4
add size and offering getters again
Nov 26, 2025
1a9a1d2
add dao interface and class
Nov 26, 2025
efd6a02
update VO with missing getters
Nov 26, 2025
155f23a
register dao class for dependency injection
Nov 26, 2025
d517c7e
remove not null - not needed anymore
Nov 26, 2025
ff504ac
add size and offering to schema
Nov 26, 2025
1380c08
remove hardcoded data and use dao
Nov 26, 2025
e0523c1
fix filter and update logic
Nov 26, 2025
e75c4f9
fix type for id
Nov 26, 2025
b951b3a
Replace UUID with LONG for id param
Nov 26, 2025
d7d073f
code cleanup for api commands
Nov 26, 2025
9ec07cf
code cleanup
Nov 26, 2025
73f9dcb
code cleanup
Nov 27, 2025
5fb8b1c
code cleanup
Nov 27, 2025
a77127a
fix spacing
Nov 27, 2025
0e11495
code cleanup
Nov 27, 2025
e6660dc
remove unused code
Nov 27, 2025
0584c02
remove unused imports
Nov 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
<version>4.23.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-hackerbook-feature</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,17 @@
--;
-- Schema upgrade from 4.22.0.0 to 4.23.0.0
--;
CREATE TABLE IF NOT EXISTS `cloud`.`coffee` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(40) UNIQUE,
`name` varchar(255) NOT NULL,
`offering` varchar(40) NOT NULL,
`size` varchar(40) NOT NULL,
`state` varchar(40) NOT NULL,
`account_id` bigint unsigned NOT NULL,
`created` datetime NOT NULL COMMENT 'date of creation',
`removed` datetime COMMENT 'date of removal',
PRIMARY KEY (`id`),
KEY (`uuid`),
KEY `i_coffee` (`name`, `account_id`, `created`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
48 changes: 48 additions & 0 deletions plugins/hackerbook/feature/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!--
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.
-->
<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-hackerbook-feature</artifactId>
<name>Apache CloudStack Plugin - HackerBook Coffee Feature</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.23.0.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>
</dependencies>
<properties>
<maven.compiler.source>11</maven.compiler.source>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you revisit these properties? We are currently using JDK 17

<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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;

/**
* Represents a coffee order in the system.
* @since 4.23.0.0
*/
public interface Coffee extends InternalIdentity, Identity {

/**
* Size options for coffee orders.
*/
enum Size {
SMALL,
MEDIUM,
LARGE
}

/**
* Available coffee offerings/types.
*/
enum Offering {
ESPRESSO,
CAPPUCCINO,
MOCHA,
LATTE
}

/**
* Lifecycle states for a coffee order.
*/
enum State {
CREATED,
BREWING,
BREWED
}

/**
* Returns the name of the coffee order.
* @return the coffee name
*/
String getName();

/**
* Returns the type of coffee ordered.
* @return the coffee offering type
*/
Offering getOffering();

/**
* Returns the size of the coffee order.
* @return the coffee size
*/
Size getSize();

/**
* Returns the current state of the coffee order.
* @return the coffee state
*/
State getState();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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;

import org.apache.cloudstack.api.command.CreateCoffeeCmd;
import org.apache.cloudstack.api.command.ListCoffeeCmd;
import org.apache.cloudstack.api.command.RemoveCoffeeCmd;
import org.apache.cloudstack.api.command.UpdateCoffeeCmd;
import org.apache.cloudstack.api.response.CoffeeResponse;

import java.util.List;

public interface CoffeeManager {
Coffee createCoffee(CreateCoffeeCmd cmd);

List<Coffee> listCoffees(ListCoffeeCmd cmd);

Coffee updateCoffee(UpdateCoffeeCmd cmd);

boolean removeCoffee(RemoveCoffeeCmd cmd);

CoffeeResponse createCoffeeResponse(Coffee coffee);

List<CoffeeResponse> createCoffeeResponses(List<Coffee> coffees);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* 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;

import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.Coffee;
import org.apache.cloudstack.api.CoffeeManager;
import org.apache.cloudstack.api.response.CoffeeResponse;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.context.CallContext;

import javax.inject.Inject;

@APICommand(
name = CreateCoffeeCmd.APINAME,
description = "Creates a new coffee order",
responseObject = CoffeeResponse.class,
since = "4.23.0.0",
requestHasSensitiveInfo = false,
responseHasSensitiveInfo = false,
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User}
)
public class CreateCoffeeCmd extends BaseAsyncCreateCmd {
public static final String APINAME = "createCoffee";

@Inject
private CoffeeManager coffeeManager;

private Coffee coffee;

/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////

@Parameter(name = ApiConstants.NAME,
type = CommandType.STRING,
required = true,
description = "name of the coffee order")
private String name;

@Parameter(name = "offering",
type = CommandType.STRING,
required = true,
description = "type of coffee (ESPRESSO, CAPPUCCINO, MOCHA, LATTE)")
private String offering;

@Parameter(name = "size",
type = CommandType.STRING,
required = true,
description = "size of coffee (SMALL, MEDIUM, LARGE)")
private String size;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////

public String getName() {
return name;
}

public String getOffering() {
return offering;
}

public String getSize() {
return size;
}

/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

@Override
public void create() {
coffee = coffeeManager.createCoffee(this);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think coffee can be defined as a local variable to this method and not outside of it

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The coffee field needs to be an instance variable because it's set in create() and then accessed in execute(). If coffee were a local variable in create(), then execute() wouldn't have access to it.


if (coffee != null) {
setEntityId(coffee.getId());
setEntityUuid(coffee.getUuid());
}
}

@Override
public void execute() {
CoffeeResponse response = coffeeManager.createCoffeeResponse(coffee);
response.setResponseName(getCommandName());
setResponseObject(response);
}

@Override
public String getEventType() {
return "COFFEE.CREATE";
}

@Override
public String getEventDescription() {
return "Creating coffee: " + name;
}

@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccountId();
}
}
Loading
Loading