protected def putEntity[A : A]()

in core/controller/src/main/scala/org/apache/openwhisk/core/controller/ApiUtils.scala [308:367]


  protected def putEntity[A <: DocumentRevisionProvider, Au >: A](factory: DocumentFactory[A],
                                                                  datastore: ArtifactStore[Au],
                                                                  docid: DocId,
                                                                  overwrite: Boolean,
                                                                  update: A => Future[A],
                                                                  create: () => Future[A],
                                                                  treatExistsAsConflict: Boolean = true,
                                                                  postProcess: Option[PostProcessEntity[A]] = None)(
    implicit transid: TransactionId,
    format: RootJsonFormat[A],
    notifier: Option[CacheChangeNotification],
    ma: Manifest[A]) = {
    // marker to return an existing doc with status OK rather than conflict if overwrite is false
    case class IdentityPut(self: A) extends Throwable

    onComplete(factory.get(datastore, docid, ignoreMissingAttachment = overwrite) flatMap { doc =>
      if (overwrite) {
        logging.debug(this, s"[PUT] entity exists, will try to update '$doc'")
        update(doc).map(updatedDoc => (Some(doc), updatedDoc))
      } else if (treatExistsAsConflict) {
        logging.debug(this, s"[PUT] entity exists, but overwrite is not enabled, aborting")
        Future failed RejectRequest(Conflict, "resource already exists")
      } else {
        Future failed IdentityPut(doc)
      }
    } recoverWith {
      case _: NoDocumentException =>
        logging.debug(this, s"[PUT] entity does not exist, will try to create it")
        create().map(newDoc => (None, newDoc))
    } flatMap {
      case (old, a) =>
        logging.debug(this, s"[PUT] entity created/updated, writing back to datastore")
        factory.put(datastore, a, old) map { _ =>
          a
        }
    }) {
      case Success(entity) =>
        logging.debug(this, s"[PUT] entity success")
        if (FeatureFlags.requireResponsePayload) postProcess map { _(entity) } getOrElse complete(OK, entity)
        else postProcess map { _(entity) } getOrElse complete(OK)
      case Failure(IdentityPut(a)) =>
        logging.debug(this, s"[PUT] entity exists, not overwritten")
        complete(OK, a)
      case Failure(t: DocumentConflictException) =>
        logging.debug(this, s"[PUT] entity conflict: ${t.getMessage}")
        terminate(Conflict, conflictMessage)
      case Failure(RejectRequest(code, message)) =>
        logging.debug(this, s"[PUT] entity rejected with code $code: $message")
        terminate(code, message)
      case Failure(t: DocumentTypeMismatchException) =>
        logging.debug(this, s"[PUT] entity conformance check failed: ${t.getMessage}")
        terminate(Conflict, conformanceMessage)
      case Failure(t: ArtifactStoreException) =>
        logging.debug(this, s"[PUT] entity unreadable")
        terminate(InternalServerError, t.getMessage)
      case Failure(t: Throwable) =>
        logging.error(this, s"[PUT] entity failed: ${t.getMessage}")
        terminate(InternalServerError)
    }
  }