Skip to content

Commit ef01a52

Browse files
Implement action-version view for memoryDB and cosmosDB
1 parent fb447b2 commit ef01a52

File tree

4 files changed

+64
-33
lines changed

4 files changed

+64
-33
lines changed

common/scala/src/main/scala/org/apache/openwhisk/core/database/DocumentHandler.scala

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,28 @@ abstract class SimpleHandler extends DocumentHandler {
115115
* Key is an array which matches the view query key
116116
*/
117117
protected def createKey(ddoc: String, view: String, startKey: List[Any], js: JsObject): JsArray
118+
119+
/**
120+
* Finds and transforms annotation with matching key.
121+
*
122+
* @param js js object having annotations array
123+
* @param key annotation key
124+
* @param vtr transformer function to map annotation value
125+
* @param default default value to use if no matching annotation found
126+
* @return annotation value matching given key
127+
*/
128+
protected[database] def annotationValue[T](js: JsObject, key: String, vtr: JsValue => T, default: T): T = {
129+
js.fields.get("annotations") match {
130+
case Some(JsArray(e)) =>
131+
e.view
132+
.map(_.asJsObject.getFields("key", "value"))
133+
.collectFirst {
134+
case Seq(JsString(`key`), v: JsValue) => vtr(v) //match annotation with given key
135+
}
136+
.getOrElse(default)
137+
case _ => default
138+
}
139+
}
118140
}
119141

120142
object ActivationHandler extends SimpleHandler {
@@ -177,42 +199,23 @@ object ActivationHandler extends SimpleHandler {
177199
}, name)
178200
}
179201

180-
/**
181-
* Finds and transforms annotation with matching key.
182-
*
183-
* @param js js object having annotations array
184-
* @param key annotation key
185-
* @param vtr transformer function to map annotation value
186-
* @param default default value to use if no matching annotation found
187-
* @return annotation value matching given key
188-
*/
189-
protected[database] def annotationValue[T](js: JsObject, key: String, vtr: JsValue => T, default: T): T = {
190-
js.fields.get("annotations") match {
191-
case Some(JsArray(e)) =>
192-
e.view
193-
.map(_.asJsObject.getFields("key", "value"))
194-
.collectFirst {
195-
case Seq(JsString(`key`), v: JsValue) => vtr(v) //match annotation with given key
196-
}
197-
.getOrElse(default)
198-
case _ => default
199-
}
200-
}
201-
202202
private def dropNull(fields: JsField*) = JsObject(fields.filter(_._2 != JsNull): _*)
203203
}
204204

205205
object WhisksHandler extends SimpleHandler {
206206
val ROOT_NS = "rootns"
207+
val FULL_NAME = "fullname"
207208
private val commonFields = Set("namespace", "name", "version", "publish", "annotations", "updated")
208209
private val actionFields = commonFields ++ Set("limits", "exec.binary")
210+
private val actionVersionFields = commonFields ++ Set("_id")
209211
private val packageFields = commonFields ++ Set("binding")
210212
private val packagePublicFields = commonFields
211213
private val ruleFields = commonFields
212214
private val triggerFields = commonFields
213215

214216
protected val supportedTables = Set(
215217
"whisks.v2.1.0/actions",
218+
"whisks.v2.1.0/action-versions",
216219
"whisks.v2.1.0/packages",
217220
"whisks.v2.1.0/packages-public",
218221
"whisks.v2.1.0/rules",
@@ -223,13 +226,20 @@ object WhisksHandler extends SimpleHandler {
223226
case Some(JsString(namespace)) =>
224227
val ns = namespace.split(PATHSEP)
225228
val rootNS = if (ns.length > 1) ns(0) else namespace
226-
JsObject((ROOT_NS, JsString(rootNS)))
229+
js.fields.get("name") match {
230+
case Some(JsString(name)) =>
231+
val fullName = s"$namespace$PATHSEP$name"
232+
JsObject((ROOT_NS, JsString(rootNS)), (FULL_NAME, JsString(fullName)))
233+
case _ =>
234+
JsObject((ROOT_NS, JsString(rootNS)))
235+
}
227236
case _ => JsObject.empty
228237
}
229238
}
230239

231240
override def fieldsRequiredForView(ddoc: String, view: String): Set[String] = view match {
232241
case "actions" => actionFields
242+
case "action-versions" => actionVersionFields
233243
case "packages" => packageFields
234244
case "packages-public" => packagePublicFields
235245
case "rules" => ruleFields
@@ -239,6 +249,7 @@ object WhisksHandler extends SimpleHandler {
239249

240250
def computeView(ddoc: String, view: String, js: JsObject): JsObject = view match {
241251
case "actions" => computeActionView(js)
252+
case "action-versions" => computeActionVersionsView(js)
242253
case "packages" => computePackageView(js)
243254
case "packages-public" => computePublicPackageView(js)
244255
case "rules" => computeRulesView(js)
@@ -256,6 +267,7 @@ object WhisksHandler extends SimpleHandler {
256267

257268
def getEntityTypeForDesignDoc(ddoc: String, view: String): String = view match {
258269
case "actions" => "action"
270+
case "action-versions" => "action"
259271
case "rules" => "rule"
260272
case "triggers" => "trigger"
261273
case "packages" | "packages-public" => "package"
@@ -288,6 +300,15 @@ object WhisksHandler extends SimpleHandler {
288300
val exec_binary = JsHelpers.getFieldPath(js, "exec", "binary")
289301
JsObject(base + ("exec" -> JsObject("binary" -> exec_binary.getOrElse(JsFalse))))
290302
}
303+
304+
private def computeActionVersionsView(js: JsObject): JsObject = {
305+
val publish = annotationValue(js, "publish", { v =>
306+
v.convertTo[Boolean]
307+
}, true)
308+
309+
val base = js.fields.filterKeys(actionVersionFields).toMap
310+
JsObject(base + ("publish" -> publish.toJson))
311+
}
291312
}
292313

293314
object SubjectHandler extends DocumentHandler {

common/scala/src/main/scala/org/apache/openwhisk/core/database/cosmosdb/CosmosDBViewMapper.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import kamon.metric.MeasurementUnit
2626
import org.apache.openwhisk.common.{LogMarkerToken, TransactionId, WhiskInstants}
2727
import org.apache.openwhisk.core.database.ActivationHandler.NS_PATH
2828
import org.apache.openwhisk.core.database.WhisksHandler.ROOT_NS
29+
import org.apache.openwhisk.core.database.WhisksHandler.FULL_NAME
2930
import org.apache.openwhisk.core.database.cosmosdb.CosmosDBConstants.{alias, computed, deleted}
3031
import org.apache.openwhisk.core.database.{
3132
ActivationHandler,
@@ -143,6 +144,7 @@ private[cosmosdb] abstract class SimpleMapper extends CosmosDBViewMapper {
143144
private[cosmosdb] object WhisksViewMapper extends SimpleMapper {
144145
private val NS = "namespace"
145146
private val ROOT_NS_C = s"$computed.$ROOT_NS"
147+
private val FULL_NAME_C = s"$computed.$FULL_NAME"
146148
private val TYPE = "entityType"
147149
private val UPDATED = "updated"
148150
private val PUBLISH = "publish"
@@ -169,7 +171,8 @@ private[cosmosdb] object WhisksViewMapper extends SimpleMapper {
169171
viewConditions(ddoc, view).map(q => (s"${q._1} AND", q._2)).getOrElse((NOTHING, Nil))
170172

171173
val params = ("@entityType", entityType) :: ("@namespace", namespace) :: vcParams
172-
val baseCondition = s"$vc r.$TYPE = @entityType AND (r.$NS = @namespace OR r.$ROOT_NS_C = @namespace)"
174+
val baseCondition =
175+
s"$vc r.$TYPE = @entityType AND (r.$NS = @namespace OR r.$ROOT_NS_C = @namespace OR r.$FULL_NAME_C = @namespace)"
173176

174177
(startKey, endKey) match {
175178
case (_ :: Nil, _ :: `TOP` :: Nil) =>
@@ -194,7 +197,8 @@ private[cosmosdb] object WhisksViewMapper extends SimpleMapper {
194197
}
195198

196199
override protected def orderByField(ddoc: String, view: String): String = view match {
197-
case "actions" | "rules" | "triggers" | "packages" | "packages-public" if ddoc.startsWith("whisks") =>
200+
case "actions" | "action-versions" | "rules" | "triggers" | "packages" | "packages-public"
201+
if ddoc.startsWith("whisks") =>
198202
s"r.$UPDATED"
199203
case _ => throw UnsupportedView(s"$ddoc/$view")
200204
}

common/scala/src/main/scala/org/apache/openwhisk/core/database/memory/MemoryViewMapper.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ private object ActivationViewMapper extends MemoryViewMapper {
123123
private object WhisksViewMapper extends MemoryViewMapper {
124124
private val NS = "namespace"
125125
private val ROOT_NS = WhisksHandler.ROOT_NS
126+
private val FULL_NAME = WhisksHandler.FULL_NAME
126127
private val TYPE = "entityType"
127128
private val UPDATED = "updated"
128129
private val PUBLISH = "publish"
@@ -140,20 +141,23 @@ private object WhisksViewMapper extends MemoryViewMapper {
140141
val matchTypeAndView = equal(d, TYPE, entityType) && matchViewConditions(ddoc, view, d)
141142
val matchNS = equal(d, NS, startKey.head.asInstanceOf[String])
142143
val matchRootNS = equal(c, ROOT_NS, startKey.head.asInstanceOf[String])
144+
val matchFullName = equal(c, FULL_NAME, startKey.head.asInstanceOf[String])
143145

144146
//Here ddocs for actions, rules and triggers use
145147
//namespace and namespace/packageName as first key
146148

147149
val filterResult = (startKey, endKey) match {
148150
case (ns :: Nil, _ :: `TOP` :: Nil) =>
149-
(matchTypeAndView && matchNS) || (matchTypeAndView && matchRootNS)
151+
(matchTypeAndView && matchNS) || (matchTypeAndView && matchRootNS) || (matchTypeAndView && matchFullName)
150152

151153
case (ns :: (since: Number) :: Nil, _ :: `TOP` :: `TOP` :: Nil) =>
152154
(matchTypeAndView && matchNS && gte(d, UPDATED, since)) ||
153-
(matchTypeAndView && matchRootNS && gte(d, UPDATED, since))
155+
(matchTypeAndView && matchRootNS && gte(d, UPDATED, since)) ||
156+
(matchTypeAndView && matchFullName && gte(d, UPDATED, since))
154157
case (ns :: (since: Number) :: Nil, _ :: (upto: Number) :: `TOP` :: Nil) =>
155158
(matchTypeAndView && matchNS && gte(d, UPDATED, since) && lte(d, UPDATED, upto)) ||
156-
(matchTypeAndView && matchRootNS && gte(d, UPDATED, since) && lte(d, UPDATED, upto))
159+
(matchTypeAndView && matchRootNS && gte(d, UPDATED, since) && lte(d, UPDATED, upto)) ||
160+
(matchTypeAndView && matchFullName && gte(d, UPDATED, since) && lte(d, UPDATED, upto))
157161

158162
case _ => throw UnsupportedQueryKeys(s"$ddoc/$view -> ($startKey, $endKey)")
159163
}
@@ -177,7 +181,8 @@ private object WhisksViewMapper extends MemoryViewMapper {
177181

178182
override def sort(ddoc: String, view: String, descending: Boolean, s: Seq[JsObject]): Seq[JsObject] = {
179183
view match {
180-
case "actions" | "rules" | "triggers" | "packages" | "packages-public" if ddoc.startsWith("whisks") =>
184+
case "actions" | "action-versions" | "rules" | "triggers" | "packages" | "packages-public"
185+
if ddoc.startsWith("whisks") =>
181186
numericSort(s, descending, UPDATED)
182187
case _ => throw UnsupportedView(s"$ddoc/$view")
183188
}

common/scala/src/main/scala/org/apache/openwhisk/core/entity/WhiskAction.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ case class ExecutableWhiskActionMetaData(namespace: EntityPath,
361361
case class WhiskActionVersion(id: String, namespace: EntityPath, name: EntityName, version: SemVer, publish: Boolean)
362362

363363
object WhiskActionVersion {
364-
val serdes = jsonFormat5(WhiskActionVersion.apply)
364+
val serdes = jsonFormat(WhiskActionVersion.apply, "_id", "namespace", "name", "version", "publish")
365365
}
366366

367367
case class WhiskActionVersionList(namespace: EntityPath, name: EntityName, versions: Map[SemVer, String]) {
@@ -389,14 +389,15 @@ object WhiskActionVersionList extends MultipleReadersSingleWriterCache[WhiskActi
389389
implicit val logger: Logging = datastore.logging
390390
implicit val ec = datastore.executionContext
391391

392-
val key = List(action.fullPath.asString)
392+
val startKey = List(action.fullPath.asString)
393+
val endKey = List(action.fullPath.asString, WhiskQueries.TOP)
393394
cacheLookup(
394395
cacheKey(action),
395396
datastore
396397
.query(
397398
viewName,
398-
startKey = key,
399-
endKey = key,
399+
startKey = startKey,
400+
endKey = endKey,
400401
skip = 0,
401402
limit = 0,
402403
includeDocs = false,

0 commit comments

Comments
 (0)