首页 \ 问答 \ 将验证异常从Camel传递到CXF SOAP服务(Passing validation exceptions from Camel to CXF SOAP service)

将验证异常从Camel传递到CXF SOAP服务(Passing validation exceptions from Camel to CXF SOAP service)

我有一个问题,我已经解决了一段时间了,加上我是apache camel的新手并没有帮助。

我的简单应用程序使用CXF(使用jetty作为http引擎)公开SOAP Web服务,然后使用camel将soap请求传递给akka actor。

我想在前往actor的路上验证SOAP请求,并检查它是否包含某些标头和内容值。 我不想使用CXF拦截器。 问题是,在camel中发生的事情(例外,故障消息返回)不会传播到cxf。 我总是将SUCCESS 202作为响应和有关日志中验证异常的信息。

这是我的简单应用:

class RequestActor extends Actor with WithLogger {
  def receive = {
    case CamelMessage(body: Request, headers) =>
      logger.info(s"Received Request $body [$headers]")
    case msg: CamelMessage =>
      logger.error(s"unknown message ${msg.body}")
  }
}

class CustomRouteBuilder(endpointUrl: String, serviceClassPath: String, system: ActorSystem)
  extends RouteBuilder {
  def configure {
    val requestActor = system.actorOf(Props[RequestActor])

    from(s"cxf:${endpointUrl}?serviceClass=${serviceClassPath}")
      .onException(classOf[PredicateValidationException])
        .handled(true)
        .process(new Processor {
        override def process(exchange: Exchange): Unit = {
          val message = MessageFactory.newInstance().createMessage();
          val envelope = message.getSOAPPart().getEnvelope();
          val body = message.getSOAPBody();
          val fault = body.addFault();
          fault.setFaultCode("Server");
          fault.setFaultString("Unexpected server error.");
          val detail = fault.addDetail();
          val entryName = envelope.createName("message");
          val entry = detail.addDetailEntry(entryName);
          entry.addTextNode("The server is not able to complete the request. Internal error.");

          log.info(s"Returning $message")
          exchange.getOut.setFault(true)
          exchange.getOut.setBody(message)
        }

        })
      .end()
      .validate(header("attribute").isEqualTo("for_sure_not_defined"))
      .to(genericActor)
  }
}

object Init extends App {

  implicit val system = ActorSystem("superman")
  val camel = CamelExtension(system)
  val camelContext = camel.context
  val producerTemplate = camel.template

  val endpointClassPath = classOf[Service].getName
  val endpointUrl = "http://localhost:1234/endpoint"

  camel.context.addRoutes(new CustomRouteBuilder(endpointUrl, endpointClassPath, system))

}

当我运行应用程序时,我看到来自log.info的日志(s“返回$ message”)所以我确定路由调用处理器,因此也没有调用actor因此行:

exchange.getOut.setFault(true)
exchange.getOut.setBody(message)

做好自己的工作。 但我的SOAP服务仍然返回202 SUCCESS而不是故障信息。


I have a problem that i cannot solve for some time already, plus i'm new to apache camel and it does not help.

My simple app exposes SOAP web service using CXF (with jetty as http engine) then soap request are passed to akka actors using camel.

I want to validate SOAP request on the road to actor and check if it contains certain headers and content values. I do not want to use CXF interceptor. Problem is, that what ever happens in camel (exception, fault message return) is not propagate to cxf. I always get SUCCESS 202 as a response and information about validation exception in logs.

This is my simple app:

class RequestActor extends Actor with WithLogger {
  def receive = {
    case CamelMessage(body: Request, headers) =>
      logger.info(s"Received Request $body [$headers]")
    case msg: CamelMessage =>
      logger.error(s"unknown message ${msg.body}")
  }
}

class CustomRouteBuilder(endpointUrl: String, serviceClassPath: String, system: ActorSystem)
  extends RouteBuilder {
  def configure {
    val requestActor = system.actorOf(Props[RequestActor])

    from(s"cxf:${endpointUrl}?serviceClass=${serviceClassPath}")
      .onException(classOf[PredicateValidationException])
        .handled(true)
        .process(new Processor {
        override def process(exchange: Exchange): Unit = {
          val message = MessageFactory.newInstance().createMessage();
          val envelope = message.getSOAPPart().getEnvelope();
          val body = message.getSOAPBody();
          val fault = body.addFault();
          fault.setFaultCode("Server");
          fault.setFaultString("Unexpected server error.");
          val detail = fault.addDetail();
          val entryName = envelope.createName("message");
          val entry = detail.addDetailEntry(entryName);
          entry.addTextNode("The server is not able to complete the request. Internal error.");

          log.info(s"Returning $message")
          exchange.getOut.setFault(true)
          exchange.getOut.setBody(message)
        }

        })
      .end()
      .validate(header("attribute").isEqualTo("for_sure_not_defined"))
      .to(genericActor)
  }
}

object Init extends App {

  implicit val system = ActorSystem("superman")
  val camel = CamelExtension(system)
  val camelContext = camel.context
  val producerTemplate = camel.template

  val endpointClassPath = classOf[Service].getName
  val endpointUrl = "http://localhost:1234/endpoint"

  camel.context.addRoutes(new CustomRouteBuilder(endpointUrl, endpointClassPath, system))

}

When i run app i see log from log.info(s"Returning $message") so i'm sure route invokes processor, also actor is not invoked therefore lines:

exchange.getOut.setFault(true)
exchange.getOut.setBody(message)

do their job. But still my SOAP service returns 202 SUCCESS instead of fault information.


原文:https://stackoverflow.com/questions/42212362
更新时间:2022-08-12 09:08

最满意答案

我已经破解了它。 我的方法是:

  • 对于Voronoi图的每个区域
  • 执行该区域顶点的Delaunay三角剖分
    • 这将返回一组填充该区域的不规则四面体
  • 可以轻松计算四面体的体积(维基百科)
    • 将这些体积相加以得到该区域的体积。

我肯定会有错误和编码不好 - 我会寻找前者,对后者的评论表示欢迎 - 特别是因为我对Python很新。 我还在检查一些东西 - 有时会给出顶点索引-1,根据scipy手册“指示Voronoi图外的顶点”, 此外,生成的顶点的坐标远远超出原始数据(插入numpy.random.seed(42)并查看第7点的区域坐标,它们转到〜(7,-14,6),第49点是相似的。所以我需要弄清楚为什么有时会发生这种情况,有时我得索引-1。

from scipy.spatial import Voronoi,Delaunay
import numpy as np
import matplotlib.pyplot as plt

def tetravol(a,b,c,d):
 '''Calculates the volume of a tetrahedron, given vertices a,b,c and d (triplets)'''
 tetravol=abs(np.dot((a-d),np.cross((b-d),(c-d))))/6
 return tetravol

def vol(vor,p):
 '''Calculate volume of 3d Voronoi cell based on point p. Voronoi diagram is passed in v.'''
 dpoints=[]
 vol=0
 for v in vor.regions[vor.point_region[p]]:
  dpoints.append(list(vor.vertices[v]))
 tri=Delaunay(np.array(dpoints))
 for simplex in tri.simplices:
  vol+=tetravol(np.array(dpoints[simplex[0]]),np.array(dpoints[simplex[1]]),np.array(dpoints[simplex[2]]),np.array(dpoints[simplex[3]]))
 return vol

x= [np.random.random() for i in xrange(50)]
y= [np.random.random() for i in xrange(50)]
z= [np.random.random() for i in xrange(50)]
dpoints=[]
points=zip(x,y,z)
vor=Voronoi(points)
vtot=0


for i,p in enumerate(vor.points):
 out=False
 for v in vor.regions[vor.point_region[i]]:
  if v<=-1: #a point index of -1 is returned if the vertex is outside the Vornoi diagram, in this application these should be ignorable edge-cases
   out=True
  else:
 if not out:
  pvol=vol(vor,i)
  vtot+=pvol
  print "point "+str(i)+" with coordinates "+str(p)+" has volume "+str(pvol)

print "total volume= "+str(vtot)

#oddly, some vertices outside the boundary of the original data are returned, meaning that the total volume can be greater than the volume of the original.

I think I've cracked it. My approach below is:

  • For each region of the Voronoi diagram
  • perform a Delaunay triangulation of the vertices of the region
    • this will return a set of irregular tetrahedra which fill the region
  • The volume of a tetrahedron can be calculated easily (wikipedia)
    • sum these volumes to get the volume of the region.

I'm sure there will be both bugs and poor coding - I'll be looking for the former, comments welcome on the latter - especially as I'm quite new to Python. I'm still checking a couple of things - sometimes a vertex index of -1 is given, which according to the scipy manual "indicates vertex outside the Voronoi diagram", but in addition, vertices are generated with coordinates well outside the original data (insert numpy.random.seed(42) and check out the coordinates of the region for point 7, they go to ~(7,-14,6), point 49 is similar. So I need to figure out why sometimes this happens, and sometimes I get index -1.

from scipy.spatial import Voronoi,Delaunay
import numpy as np
import matplotlib.pyplot as plt

def tetravol(a,b,c,d):
 '''Calculates the volume of a tetrahedron, given vertices a,b,c and d (triplets)'''
 tetravol=abs(np.dot((a-d),np.cross((b-d),(c-d))))/6
 return tetravol

def vol(vor,p):
 '''Calculate volume of 3d Voronoi cell based on point p. Voronoi diagram is passed in v.'''
 dpoints=[]
 vol=0
 for v in vor.regions[vor.point_region[p]]:
  dpoints.append(list(vor.vertices[v]))
 tri=Delaunay(np.array(dpoints))
 for simplex in tri.simplices:
  vol+=tetravol(np.array(dpoints[simplex[0]]),np.array(dpoints[simplex[1]]),np.array(dpoints[simplex[2]]),np.array(dpoints[simplex[3]]))
 return vol

x= [np.random.random() for i in xrange(50)]
y= [np.random.random() for i in xrange(50)]
z= [np.random.random() for i in xrange(50)]
dpoints=[]
points=zip(x,y,z)
vor=Voronoi(points)
vtot=0


for i,p in enumerate(vor.points):
 out=False
 for v in vor.regions[vor.point_region[i]]:
  if v<=-1: #a point index of -1 is returned if the vertex is outside the Vornoi diagram, in this application these should be ignorable edge-cases
   out=True
  else:
 if not out:
  pvol=vol(vor,i)
  vtot+=pvol
  print "point "+str(i)+" with coordinates "+str(p)+" has volume "+str(pvol)

print "total volume= "+str(vtot)

#oddly, some vertices outside the boundary of the original data are returned, meaning that the total volume can be greater than the volume of the original.

相关问答

更多
  • Voronoi数据结构包含构建“无穷远点”位置的所有必要信息。 Qhull还将它们简单地报告为-1指数,所以Scipy不会为你计算它们。 https://gist.github.com/pv/8036995 http://nbviewer.ipython.org/gist/pv/8037100 import numpy as np import matplotlib.pyplot as plt from scipy.spatial import Voronoi def voronoi_finite_pol ...
  • 给定一个矩形边界框,我的第一个想法是定义这个边界框和由scipy.spatial.Voronoi产生的Voronoï图之间的一种交集操作。 一个想法不一定很好,因为这需要编码大量计算几何的基本功能。 然而,下面是我想到的第二个想法(hack?):用于计算平面中一组n点的Voronoï图的算法的时间复杂度为O(n ln(n)) 。 怎么样加入点来约束初始点的Vorono?单元位于边界框? 解决有界Voronoï图 一张照片值得一讲: 我在这里做了什么? 这很简单! 初始点(蓝色)位于[0.0, 1.0] x ...
  • 你有一个你知道的region ,你不知道这vor.point_region[point] == region ,你知道vor.point_region[point] == region 。 对于单个region ,您可以找出相应的point : point = np.argwhere(vor.point_region == region) 您还可以创建region_point索引数组,以从regions数组中计算出多个points ,如下所示: region_point = np.argsort(vor. ...
  • 如果这不是纯粹的几何问题,那么我会去寻找位图。 只需使用整数ID颜色绘制辅助位图(画布)中的所有多边形。 要查找poly的id,只需检查相应位置的像素颜色即可。 一个位置 - 一次取。 它应该是超快但不是几何完美的。 请注意,您可以缩放查找位图以提高准确性。 If this is not purely geometrical problem then I would go for the lookup bitmap. Just paint all the polygons in a secondary bi ...
  • 您必须通过“过滤器”解释您的意思(过滤掉?)。 在任何情况下,您都可以获得voronoi形状的顶点和几种类型的脊: verts = v.vertices ,这将给出一个包含两列(顶点的x和y坐标)的数组。 您可以像使用numpy数组(如verts [:,0]> -0.5)一样屏蔽它们,并将它们用于您想要的任何内容。 我不完全确定这是否能解答你的问题,但你可以在这里找到一个非常好的教程,包括绘图。 You'll have to explain what you mean by "filter" (f ...
  • context.triangles说Delaunay三角形输入点参与其中。 每个三角形与Voronoi顶点相关。 三角形和顶点以triangles和vertices阵列平行存储。 为了找到给定点p Voronoi单元,需要找到使用输入点的所有顶点(三角形)。 然后找到这些顶点如何通过edges数组连接的顺序。 这是一个简单的(未经过测试的)代码: from voronoi import voronoi import random from collections import defaultdict nu ...
  • 色阶: 实际上,您提供的链接提供了将Voronoi图着色所需的代码。 为了给每个单元指定一个表示物理量的颜色,需要使用matplotlib中的将值映射到颜色中显示的方法将此物理量的值映射到规范化的颜色映射。 例如,如果我想为每个单元格分配一个对应于“速度”数量的颜色: import numpy as np import matplotlib as mpl import matplotlib.cm as cm import matplotlib.pyplot as plt from scipy.spatial ...
  • 对于你的第一个问题: 问题在于为N个点定义了N + 1个区域(多边形),我不确定这意味着什么。 这是因为你的vor.regions将始终有一个空数组。 就像是 [[],[0, 0],[0, 1],[1, 1]] 这与你的第二个问题有关: 另一件我不明白的是为什么存储空vor.regions? 根据文档:区域:形成每个Voronoi区域的Voronoi顶点的指数。 -1表示Voronoi图外的顶点。 空白区域是什么意思? 默认情况下,Voronoi()使用带有选项'Qbb Qc Qz Qx'的QHu ...
  • 这个东西很有趣,我已经使用这里的答案为你解决了这个函数的文档在这里 from scipy.spatial import cKDTree points = [[0,0], [1,4], [2,3], [4,1], [1,1], [2,2], [5,3]] voronoi_kdtree = cKDTree(points) extraPoints = [[0.5,0.2], [3, 0], [4,0],[5,0], [4,3]] test_point_dist, test_point_regions = voro ...
  • 我想我已经破解了它。 我的方法是: 对于Voronoi图的每个区域 执行该区域顶点的Delaunay三角剖分 这将返回一组填充该区域的不规则四面体 可以轻松计算四面体的体积(维基百科) 将这些体积相加以得到该区域的体积。 我肯定会有错误和编码不好 - 我会寻找前者,对后者的评论表示欢迎 - 特别是因为我对Python很新。 我还在检查一些东西 - 有时会给出顶点索引-1,根据scipy手册“指示Voronoi图外的顶点”, 但此外,生成的顶点的坐标远远超出原始数据(插入numpy.random.seed(4 ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)