Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:OpenBankProject/OBP-API into dev…
Browse files Browse the repository at this point in the history
…elop
  • Loading branch information
simonredfern committed Nov 8, 2023
2 parents 1c6a11c + ec57c5d commit a3ca83f
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 10 deletions.
14 changes: 5 additions & 9 deletions obp-api/src/main/scala/code/api/cache/Redis.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package code.api.cache

import code.api.util.{APIUtil, CustomJsonFormats}
import code.api.util.APIUtil
import code.util.Helper.MdcLoggable
import com.openbankproject.commons.ExecutionContext.Implicits.global
import redis.clients.jedis.Jedis
import scalacache.memoization.{cacheKeyExclude, memoize, memoizeSync}
import scalacache.{Flags, ScalaCache}
import scalacache.redis.RedisCache
import scalacache.serialization.Codec
import net.liftweb.json
import net.liftweb.json.{Extraction, Formats, parse}

import scala.concurrent.Future
import scala.concurrent.duration.Duration
Expand Down Expand Up @@ -38,16 +36,14 @@ object Redis extends MdcLoggable {

implicit val scalaCache = ScalaCache(RedisCache(url, port))
implicit val flags = Flags(readsEnabled = true, writesEnabled = true)
implicit def formats: Formats = CustomJsonFormats.formats

implicit def anyToByte[T](implicit m: Manifest[T]) = new Codec[T, Array[Byte]] {

import com.twitter.chill.KryoInjection

def serialize(value: T): Array[Byte] = {
val jsonString = json.compactRender(Extraction.decompose(value))
logger.debug("KryoInjection started")
logger.trace(s"redis.anyToByte.serialize value is $jsonString")
val bytes: Array[Byte] = KryoInjection(jsonString)
val bytes: Array[Byte] = KryoInjection(value)
logger.debug("KryoInjection finished")
bytes
}
Expand All @@ -56,9 +52,9 @@ object Redis extends MdcLoggable {
import scala.util.{Failure, Success}
val tryDecode: scala.util.Try[Any] = KryoInjection.invert(data)
tryDecode match {
case Success(v) => json.parse(v.toString).extract[T]
case Success(v) => v.asInstanceOf[T]
case Failure(e) =>
logger.error(e)
println(e)
"NONE".asInstanceOf[T]
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright 2006-2011 WorldWide Conferencing, LLC
*
* Licensed 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 com.openbankproject.commons.util

import net.liftweb.common.{Box, Empty, Failure, Full, ParamFailure}
import net.liftweb.json.Extraction.{decompose, extract}
import net.liftweb.json.JsonAST.{JField, JNothing, JNull, JObject, JString, JValue}
import net.liftweb.json.{Formats, MappingException, Serializer, TypeInfo}
import org.apache.commons.codec.binary.Base64

import java.io._
import java.lang.reflect.ParameterizedType

class JsonBoxSerializer extends Serializer[Box[_]] {
private val BoxClass = classOf[Box[_]]

def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), Box[_]] = {
case (TypeInfo(BoxClass, ptype), json) => json match {
case JNull | JNothing => Empty
case JObject(JField("box_failure", JString("Failure")) ::
JField("msg", JString(msg)) ::
JField("exception", exception) ::
JField("chain", chain) :: Nil) =>
Failure(msg, deserializeException(exception),
extract(chain, TypeInfo(BoxClass, Some(typeHoldingFailure))).asInstanceOf[Box[Failure]])
case JObject(JField("box_failure", JString("ParamFailure")) ::
JField("msg", JString(msg)) ::
JField("exception", exception) ::
JField("chain", chain) ::
JField("paramType", JString(paramType)) ::
JField("param", param) :: Nil) =>
val clazz = Thread.currentThread.getContextClassLoader.loadClass(paramType)
ParamFailure(msg, deserializeException(exception),
extract(chain, TypeInfo(BoxClass, Some(typeHoldingFailure))).asInstanceOf[Box[Failure]],
extract(param, TypeInfo(clazz, None)))
case x =>
val t = ptype.getOrElse(throw new MappingException("parameterized type not known for Box"))
Full(extract(x, TypeInfo(t.getActualTypeArguments()(0).asInstanceOf[Class[_]], None)))
}
}

def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
case Full(x) => decompose(x)
case Empty => JNull
case ParamFailure(msg, exception, chain, param) =>
JObject(JField("box_failure", JString("ParamFailure")) ::
JField("msg", JString(msg)) ::
JField("exception", serializeException(exception)) ::
JField("chain", decompose(chain)) ::
JField("paramType", JString(param.asInstanceOf[AnyRef].getClass.getName)) ::
JField("param", decompose(param)) :: Nil)
case Failure(msg, exception, chain) =>
JObject(JField("box_failure", JString("Failure")) ::
JField("msg", JString(msg)) ::
JField("exception", serializeException(exception)) ::
JField("chain", decompose(chain)) :: Nil)
}

private val typeHoldingFailure = new ParameterizedType {
def getActualTypeArguments = Array(classOf[Failure])
def getOwnerType = classOf[Box[Failure]]
def getRawType = classOf[Box[Failure]]
}

private def serializeException(exception: Box[Throwable]) = exception match {
case Full(x) => JString(javaSerialize(x))
case _ => JNull
}

private def deserializeException(json: JValue) = json match {
case JString(s) => Full(javaDeserialize(s).asInstanceOf[Throwable])
case _ => Empty
}

private def javaSerialize(obj: AnyRef): String = {
val bytes = new ByteArrayOutputStream
val out = new ObjectOutputStream(bytes)
out.writeObject(obj)
new String((new Base64).encode(bytes.toByteArray))
}

private def javaDeserialize(s: String): Any = {
val bytes = new ByteArrayInputStream((new Base64).decode(s.getBytes("UTF-8")))
val in = new ObjectInputStream(bytes)
in.readObject
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ object JsonSerializers {
}
}

val BoxSerializer: JsonBoxSerializer = new JsonBoxSerializer

val serializers: List[Serializer[_]] =
AbstractTypeDeserializer :: SimpleEnumDeserializer :: ScalaProductDeserializer ::
BoxSerializer :: AbstractTypeDeserializer :: SimpleEnumDeserializer :: ScalaProductDeserializer ::
BigDecimalSerializer :: StringDeserializer ::
FiledRenameSerializer :: EnumValueSerializer ::
JsonAbleSerializer :: ListResultSerializer.asInstanceOf[Serializer[_]] :: // here must do class cast, or it cause compile error, looks like a bug of scala.
Expand Down

0 comments on commit a3ca83f

Please sign in to comment.