Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RJA-1469] [feature] - More links #798

Merged
merged 1 commit into from
Feb 1, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion api/src/main/scala/com/griddynamics/genesis/api/Model.scala
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -332,4 +332,6 @@ case class SystemSettings(links: Array[Link])


case class ApplicationRole(name: String) case class ApplicationRole(name: String)


case class Access(users: Array[User], groups: Array[String]) case class Access(users: Array[User], groups: Array[String])

case class Action(name: String)
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*/ */
package com.griddynamics.genesis.rest package com.griddynamics.genesis.rest


import annotations.{AddSelfLinks, LinkTo, LinksTo}
import annotations.LinkTarget._ import annotations.LinkTarget._
import filters.EnvFilter import filters.EnvFilter
import links._ import links._
Expand All @@ -47,6 +48,7 @@ import java.util.concurrent.TimeUnit
import com.griddynamics.genesis.api._ import com.griddynamics.genesis.api._
import com.griddynamics.genesis.spring.security.LinkSecurityBean import com.griddynamics.genesis.spring.security.LinkSecurityBean
import com.griddynamics.genesis.template.dsl.groovy.Reserved import com.griddynamics.genesis.template.dsl.groovy.Reserved
import com.griddynamics.genesis.model.EnvStatus


@Controller @Controller
@RequestMapping(Array("/rest/projects/{projectId}/envs")) @RequestMapping(Array("/rest/projects/{projectId}/envs"))
Expand Down Expand Up @@ -170,26 +172,27 @@ class EnvironmentsController extends RestApiExceptionsHandler {


@RequestMapping(value = Array("{envId}"), method = Array(RequestMethod.GET)) @RequestMapping(value = Array("{envId}"), method = Array(RequestMethod.GET))
@ResponseBody @ResponseBody
@LinksTo(value = Array(
new LinkTo(path = "history", rel = COLLECTION, methods = Array(GET), modelClass = classOf[WorkflowHistory]),
new LinkTo(path = "workflows", rel = COLLECTION, methods = Array(GET), modelClass = classOf[Workflow]),
new LinkTo(path = "actions", rel = COLLECTION, methods = Array(GET), modelClass = classOf[Action])
))
@AddSelfLinks(methods = Array(GET, PUT, DELETE), modelClass = classOf[EnvironmentDetails])
def describeEnv(@PathVariable("projectId") projectId: Int, def describeEnv(@PathVariable("projectId") projectId: Int,
@PathVariable("envId") envId: Int, request: HttpServletRequest) : ItemWrapper[EnvironmentDetails] = { @PathVariable("envId") envId: Int, request: HttpServletRequest) : ItemWrapper[EnvironmentDetails] = {
val wrapper: ItemWrapper[EnvironmentDetails] = genesisService.describeEnv(envId, projectId). genesisService.describeEnv(envId, projectId).
getOrElse(throw new ResourceNotFoundException("Environment [" + envId + "] was not found")) getOrElse(throw new ResourceNotFoundException("Environment [" + envId + "] was not found"))
implicit val req: HttpServletRequest = request
val top = WebPath(request)
wrapper.withLinksToSelf(GET, PUT, DELETE).withLinks(
LinkBuilder(top / "history", COLLECTION, classOf[WorkflowHistory], GET),
LinkBuilder(top / "actions", COLLECTION, POST) // TODO: GET not present now. User can only post there.
).filtered()
} }




@RequestMapping(value = Array("{envId}/history"), method = Array(RequestMethod.GET), params = Array("page_offset", "page_length")) @RequestMapping(value = Array("{envId}/history"), method = Array(RequestMethod.GET))
@ResponseBody @ResponseBody
@AddSelfLinks(methods = Array(GET), modelClass = classOf[WorkflowHistory])
def workflowsHistory(@PathVariable("projectId") projectId: Int, def workflowsHistory(@PathVariable("projectId") projectId: Int,
@PathVariable("envId") envId: Int, @PathVariable("envId") envId: Int,
@RequestParam("page_offset") pageOffset: Int, @RequestParam(value = "page_offset", defaultValue = "0") pageOffset: Int,
@RequestParam("page_length") pageLength: Int, @RequestParam(value = "page_length", defaultValue = "1000") pageLength: Int,
response : HttpServletResponse): WorkflowHistory = { request: HttpServletRequest): ItemWrapper[WorkflowHistory] = {
genesisService.workflowHistory(envId, projectId, pageOffset, pageLength).getOrElse( genesisService.workflowHistory(envId, projectId, pageOffset, pageLength).getOrElse(
throw new ResourceNotFoundException("Environment [" + envId + "] was not found") throw new ResourceNotFoundException("Environment [" + envId + "] was not found")
) )
Expand Down Expand Up @@ -221,8 +224,9 @@ class EnvironmentsController extends RestApiExceptionsHandler {
SELF, classOf[Environment], POST)).filtered() SELF, classOf[Environment], POST)).filtered()
} }


@RequestMapping(value = Array("{envId}/actions"), method = Array(RequestMethod.POST)) @RequestMapping(value = Array("{envId}/actions"), method = Array(GET, POST))
@ResponseBody @ResponseBody
@deprecated(since = "2.0.0", message="This method is kept only for backward compatibility")
def executeAction(@PathVariable("projectId") projectId: Int, def executeAction(@PathVariable("projectId") projectId: Int,
@PathVariable("envId") envId: Int, @PathVariable("envId") envId: Int,
request: HttpServletRequest) = { request: HttpServletRequest) = {
Expand All @@ -248,7 +252,68 @@ class EnvironmentsController extends RestApiExceptionsHandler {
} }
} }


@RequestMapping(value = Array("{envId}/actions/{workflow}"), method = Array(RequestMethod.GET))

@RequestMapping(value = Array("{envId}/actions/{actionName}"), method = Array(RequestMethod.POST))
@ResponseBody
def executeAction(@PathVariable("projectId") projectId: Int,
@PathVariable("envId") envId: Int,
@PathVariable("actionName") actionName: String,
request: HttpServletRequest) = {
Actions.fromString(actionName) match {
case Some(Actions.Cancel) =>
genesisService.cancelWorkflow(envId, projectId)
Success(envId)
case Some(Actions.Reset) => genesisService.resetEnvStatus(envId, projectId)
case _ => throw new ResourceNotFoundException(s"Cannot find action ${actionName} for specified environment")
}
}

@RequestMapping(value = Array("{envId}/workflows/{workflowName}"), method = Array(RequestMethod.POST))
@ResponseBody
def executeWorkflow(@PathVariable("projectId") projectId: Int,
@PathVariable("envId") envId: Int,
@PathVariable("workflowName") workflowName: String,
request: HttpServletRequest) = {
val requestMap = extractParamsMap(request)
val parameters = extractMapValue("parameters", requestMap)
genesisService.requestWorkflow(envId, projectId, workflowName, extractVariables(parameters), getCurrentUser)
}


@RequestMapping(value = Array("{envId}/workflows"), method = Array(RequestMethod.GET))
@ResponseBody
@AddSelfLinks(methods = Array(GET), modelClass = classOf[Workflow])
def getWorkflows(@PathVariable("projectId") projectId: Int,
@PathVariable("envId") envId: Int, request: HttpServletRequest) : CollectionWrapper[ItemWrapper[Workflow]] = {
val env = genesisService.describeEnv(envId, projectId).
getOrElse(throw new ResourceNotFoundException("Environment [" + envId + "] was not found"))
val filteredList: Seq[Workflow] = env.workflows.filter(workflow => {
workflow.name != env.createWorkflowName && EnvStatus.Destroyed.toString != env.status
})
wrap(filteredList) { workflow =>
workflow.withLinksToSelf(WebPath(request) / workflow.name, POST)
}
}

@RequestMapping(value = Array("{envId}/actions"), method = Array(RequestMethod.GET))
@ResponseBody
@AddSelfLinks(methods = Array(GET), modelClass = classOf[Action])
def getActions(@PathVariable("projectId") projectId: Int,
@PathVariable("envId") envId: Int, request: HttpServletRequest) : CollectionWrapper[ItemWrapper[Action]] = {
val env = genesisService.describeEnv(envId, projectId).
getOrElse(throw new ResourceNotFoundException("Environment [" + envId + "] was not found"))
val availableActions = EnvStatus.fromString(env.status) match {
case Some(EnvStatus.Busy) => Actions.Cancel :: Nil
case Some(EnvStatus.Broken) => Actions.Reset :: Nil
case _ => Nil
}
wrap(availableActions.map(v => Action(v.toString))) { action =>
action.withLinksToSelf(WebPath(request) / action.name, POST)
}
}

@RequestMapping(value = Array("{envId}/workflows/{workflow}"), method = Array(RequestMethod.GET))
@ResponseBody @ResponseBody
def getWorkflow(@PathVariable("projectId") projectId: Int, def getWorkflow(@PathVariable("projectId") projectId: Int,
@PathVariable("envId") envId: Int, @PathVariable("envId") envId: Int,
Expand Down Expand Up @@ -303,3 +368,15 @@ class EnvironmentsController extends RestApiExceptionsHandler {
} }


} }

object Actions extends Enumeration {
type Actions = Value
val Reset = Value(0, "reset")
val Cancel = Value(1, "cancel")

def fromString(input: String): Option[Actions] = try {
Some(Actions.withName(input))
} catch {
case e: NoSuchElementException => None
}
}
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@


package com.griddynamics.genesis.rest package com.griddynamics.genesis.rest


import scala.Array import annotations.AddSelfLinks
import links.{WebPath, ItemWrapper, CollectionWrapper}
import links.CollectionWrapper._
import links.WebPath._
import org.springframework.web.bind.annotation.{PathVariable, ResponseBody, RequestMethod, RequestMapping} import org.springframework.web.bind.annotation.{PathVariable, ResponseBody, RequestMethod, RequestMapping}
import org.springframework.web.bind.annotation.RequestMethod._
import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletRequest
import org.springframework.stereotype.Controller import org.springframework.stereotype.Controller
import GenesisRestController._ import GenesisRestController._
Expand All @@ -35,20 +39,30 @@ import com.griddynamics.genesis.api._
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import com.griddynamics.genesis.validation.Validation._ import com.griddynamics.genesis.validation.Validation._
import com.griddynamics.genesis.api.Failure import com.griddynamics.genesis.api.Failure
import com.griddynamics.genesis.spring.security.LinkSecurityBean


@Controller @Controller
@RequestMapping(Array("/rest")) @RequestMapping(Array("/rest"))
class RolesController extends RestApiExceptionsHandler { class RolesController extends RestApiExceptionsHandler {


@Autowired var authorityService: AuthorityService = _ @Autowired var authorityService: AuthorityService = _
@Autowired var projectAuthorityService: ProjectAuthorityService= _ @Autowired var projectAuthorityService: ProjectAuthorityService= _
@Autowired implicit var linkSecurity: LinkSecurityBean = _


@Autowired var userService: UserService = _ @Autowired var userService: UserService = _
@Autowired var groupService: GroupService = _ @Autowired var groupService: GroupService = _


@RequestMapping(value = Array("roles"), method = Array(RequestMethod.GET)) @RequestMapping(value = Array("roles"), method = Array(RequestMethod.GET))
@ResponseBody @ResponseBody
def listSystemRoles() = authorityService.listAuthorities @AddSelfLinks(methods = Array(GET), modelClass = classOf[ApplicationRole])
def listSystemRoles(request: HttpServletRequest) : CollectionWrapper[ItemWrapper[ApplicationRole]] = {
val builtRoles = authorityService.listAuthorities.map(s => ApplicationRole(s))
wrap(builtRoles) {
role => {
role.withLinksToSelf(WebPath(request) / role.name, GET, PUT)
}
}
}


@RequestMapping(value = Array("projectRoles"), method = Array(RequestMethod.GET)) @RequestMapping(value = Array("projectRoles"), method = Array(RequestMethod.GET))
@ResponseBody @ResponseBody
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@


package com.griddynamics.genesis.rest package com.griddynamics.genesis.rest


import annotations.AddSelfLinks
import annotations.LinkTarget._ import annotations.LinkTarget._
import links.{LinkBuilder, WebPath, HrefBuilder} import links.{CollectionWrapper, LinkBuilder, WebPath, HrefBuilder}
import org.springframework.web.bind.annotation._ import org.springframework.web.bind.annotation._
import org.springframework.web.bind.annotation.RequestMethod._ import org.springframework.web.bind.annotation.RequestMethod._
import org.springframework.stereotype.Controller import org.springframework.stereotype.Controller
Expand Down Expand Up @@ -71,7 +72,7 @@ class SettingsController extends RestApiExceptionsHandler {
var result = List ( var result = List (
LinkBuilder(path / "settings", COLLECTION, classOf[ConfigProperty], GET), LinkBuilder(path / "settings", COLLECTION, classOf[ConfigProperty], GET),
LinkBuilder(path / "databags", COLLECTION, classOf[DataBag], GET), LinkBuilder(path / "databags", COLLECTION, classOf[DataBag], GET),
LinkBuilder(path / "roles", COLLECTION, GET, POST), LinkBuilder(path / "roles", COLLECTION, classOf[ApplicationRole], GET),
LinkBuilder(path / "agents", COLLECTION, classOf[RemoteAgent], GET), LinkBuilder(path / "agents", COLLECTION, classOf[RemoteAgent], GET),
LinkBuilder(path / "plugins", COLLECTION, classOf[Plugin], GET) LinkBuilder(path / "plugins", COLLECTION, classOf[Plugin], GET)
) )
Expand All @@ -86,7 +87,8 @@ class SettingsController extends RestApiExceptionsHandler {


@RequestMapping(value = Array(""), method = Array(RequestMethod.GET)) @RequestMapping(value = Array(""), method = Array(RequestMethod.GET))
@ResponseBody @ResponseBody
def listSettings(@RequestParam(value = "prefix", required = false) prefix: String) = { @AddSelfLinks(methods = Array(GET, PUT), modelClass = classOf[ConfigProperty])
def listSettings(@RequestParam(value = "prefix", required = false) prefix: String, request: HttpServletRequest): CollectionWrapper[ConfigProperty] = {
val configs = configService. val configs = configService.
listSettings(paramToOption(prefix)). listSettings(paramToOption(prefix)).
filter(p => isVisible(p.name)) filter(p => isVisible(p.name))
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@


package com.griddynamics.genesis.rest package com.griddynamics.genesis.rest


import annotations.LinkTarget import annotations.{AddSelfLinks, LinkTarget}
import links.CollectionWrapper._ import links.CollectionWrapper._
import links.{WebPath, LinkBuilder} import links.{ItemWrapper, WebPath, LinkBuilder}
import links.HrefBuilder._ import links.HrefBuilder._
import org.springframework.stereotype.Controller import org.springframework.stereotype.Controller
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
Expand Down Expand Up @@ -90,10 +90,9 @@ class UsersController extends RestApiExceptionsHandler {


@RequestMapping(value = Array("{username:.+}"), method=Array(RequestMethod.GET)) @RequestMapping(value = Array("{username:.+}"), method=Array(RequestMethod.GET))
@ResponseBody @ResponseBody
def get(@PathVariable(value = "username") username: String, request: HttpServletRequest) = { @AddSelfLinks(methods = Array(GET, PUT, DELETE), modelClass = classOf[User])
implicit val req = request def get(@PathVariable(value = "username") username: String, request: HttpServletRequest): ItemWrapper[User] = {
val user = find(username) find(username)
wrap(user).withLinksToSelf(GET, PUT, DELETE).filtered()
} }


private def find(username: String) = userService.findByUsername(username).getOrElse(throw new ResourceNotFoundException("User[username = " + username + "] was not found")) private def find(username: String) = userService.findByUsername(username).getOrElse(throw new ResourceNotFoundException("User[username = " + username + "] was not found"))
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ case class WebPath(start: String, elements: List[String] = List()) {
} }


object WebPath { object WebPath {
def apply(request: HttpServletRequest) = new WebPath(HrefBuilder.duplicate(request))
implicit def webPathToString(path: WebPath) = path.toString implicit def webPathToString(path: WebPath) = path.toString
implicit def fromRequest(request: HttpServletRequest) = WebPath(request.getServletPath) implicit def fromRequest(request: HttpServletRequest) = WebPath(HrefBuilder.duplicate(request))
} }


object LinkBuilder { object LinkBuilder {
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function(genesis, Backbone) {
}, },


templatePath: function() {return "/templates/" + this.get("name") + "/v" + this.get("version") + "/" + this.workflow;}, templatePath: function() {return "/templates/" + this.get("name") + "/v" + this.get("version") + "/" + this.workflow;},
actionPath: function() {return "/envs/" + this.instanceId + "/actions/" + this.workflow;} actionPath: function() {return "/envs/" + this.instanceId + "/workflows/" + this.workflow;}
}); });




Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ define ["genesis", "modules/status", "modules/validation", "backbone", "jquery",
class Settings.Collection extends Backbone.Collection class Settings.Collection extends Backbone.Collection
model: Settings.Model model: Settings.Model
url: URL + "?prefix=genesis.system" url: URL + "?prefix=genesis.system"
parse: (json) ->
json.items


class Settings.Views.Main extends Backbone.View class Settings.Views.Main extends Backbone.View
template: "app/templates/settings/system_configs.html" template: "app/templates/settings/system_configs.html"
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ define ["genesis", "backbone", "cs!modules/settings/users", "modules/status", "m
class Groups.Model extends Backbone.Model class Groups.Model extends Backbone.Model
urlRoot: URL urlRoot: URL
class GroupUsers extends Backbone.Collection class GroupUsers extends Backbone.Collection
initialize: (groupId) -> initialize: (models, groupId) ->
@groupId = groupId @groupId = groupId


url: -> url: ->
Expand Down Expand Up @@ -111,7 +111,7 @@ define ["genesis", "backbone", "cs!modules/settings/users", "modules/status", "m


initialize: (options) -> initialize: (options) ->
@group = options.group @group = options.group
@groupUsers = new GroupUsers(@group.id) @groupUsers = new GroupUsers([], @group.id)
@users = new Users.Collections.People() @users = new Users.Collections.People()
@groupRolesArray = [] @groupRolesArray = []
unless @group.isNew() unless @group.isNew()
Expand Down
2 changes: 1 addition & 1 deletion ui/src/main/resources/genesis/app/services/backend.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ function(genesis, $) {
timeout: DEFAULT_TIMEOUT, timeout: DEFAULT_TIMEOUT,
processData: true processData: true
}).done(function(roles) { }).done(function(roles) {
self._rolesListCache = roles; self._rolesListCache = _(roles.items).pluck("name");
def.resolve(self._rolesListCache); def.resolve(self._rolesListCache);
}).fail(function(jqXHR) { }).fail(function(jqXHR) {
def.reject(jqXHR) def.reject(jqXHR)
Expand Down