Doesn't seem to work. I get an exception:
org.apache.xmlrpc.XmlRpcException: Not enough items in array
at
org
.apache
.xmlrpc
.XmlRpcClientResponseProcessor
.decodeException(XmlRpcClientResponseProcessor.java:102)
at
org
.apache
.xmlrpc
.XmlRpcClientResponseProcessor
.decodeResponse(XmlRpcClientResponseProcessor.java:69)
at
org.apache.xmlrpc.XmlRpcClientWorker.execute(XmlRpcClientWorker.java:72)
at org.apache.xmlrpc.XmlRpcClient.execute(XmlRpcClient.java:
193)
at org.apache.xmlrpc.XmlRpcClient.execute(XmlRpcClient.java:
184)
at
org
.sipfoundry
.sipxconfig
.xmlrpc.XmlRpcClientInterceptor.invoke(XmlRpcClientInterceptor.java:60)
at
org
.springframework
.aop
.framework
.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
at
org
.springframework
.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:203)
at $Proxy57.reloadxml(Unknown Source)
at
org
.sipfoundry
.sipxconfig
.conference
.ConferenceBridgeProvisioningImpl
.onApplicationEvent(ConferenceBridgeProvisioningImpl.java:57)
It seems to be right though. The XML-RPC request it's generating looks
like this;
<?xml version="1.0">
<methodCall>
<methodName>freeswitch.api</methodName>
<params>
<param><value>reloadxml</value></param>
</params>
</methodCall>
On May 13, 2008, at 6:45 PM, Damian Krzeminski wrote:
> This is probably mostly interesting for Bob and Joe at the moment
> (freeswitch XML/RPC), but if you plan to call any XML/RPC API from
> sipXconfig you should read this.
>
> Can you guys check if this was of calling XML/RPC for freeswitch
> (attached!) works for you (my RPMs are still building).
>
> Some background:
>
> sipXconfig (with a big help from Spring [1]) allows for automatic
> proxing for XML/RPC. What it means is that - as a developer - you
> are mostly responsible for defining Java interface and configuring
> the proxy for that interface.
> Until recently that only worked if XML/RPC method names and
> parameter types can actually be expressed in legal Java.
>
> I added a very simple marshaller that can let you proxy interfaces
> that are less than Java friendly. For example freeswitch API
> provides just a single method called "freeswitch.api" and the first
> parameter of this method is operation ("a.k.a. real method name)
> followed by the remaining parameters.
>
> So now instead of:
>
> XmlRpcClientInterceptor interceptor = new XmlRpcClientInterceptor();
> interceptor.setServiceInterface(FreeSWITCHFunctions.class);
> interceptor.setServiceUrl(serviceUrl);
> interceptor.afterPropertiesSet();
> FreeSWITCHFunctions proxy = (FreeSWITCHFunctions)
> ProxyFactory.getProxy(
> FreeSWITCHFunctions.class, interceptor);
> proxy.freeswitch_api("reloadxml", "");
>
> You can just write:
>
> FreeswitchApi api = m_freeswitchApiProvider.getApi(serviceUrl);
> api.reloadxml();
>
>
> The magic is in FreeswitchApiMarshaller - I'll gladly change/fix it
> if you let me know of other vagaries of that interface.
>
> [1]
> http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html
>
>> From 42edd60842995711509d0fd349be17ff1329c9d4 Mon Sep 17 00:00:00
>> 2001
> From: dkrzemin <[EMAIL PROTECTED]>
> Date: Tue, 13 May 2008 18:21:25 -0400
> Subject: [PATCH] Freeswitch API XML/RPC proxy defined properly.
>
> ---
> .../ConferenceBridgeProvisioningImpl.java | 88 ++++++++
> +-----------
> .../sipxconfig/conference/FreeswitchApi.java | 17 ++++
> .../conference/FreeswitchApiMarshaller.java | 36 ++++++++
> .../sipxconfig/conference/conference.beans.xml | 77 ++++++++
> +--------
> 4 files changed, 134 insertions(+), 84 deletions(-)
> create mode 100644 sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/
> conference/FreeswitchApi.java
> create mode 100644 sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/
> conference/FreeswitchApiMarshaller.java
>
> diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/
> conference/ConferenceBridgeProvisioningImpl.java b/sipXconfig/
> neoconf/src/org/sipfoundry/sipxconfig/conference/
> ConferenceBridgeProvisioningImpl.java
> index 9d13373..f196264 100644
> --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/conference/
> ConferenceBridgeProvisioningImpl.java
> +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/conference/
> ConferenceBridgeProvisioningImpl.java
> @@ -14,7 +14,6 @@ import java.util.List;
>
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
> -
> import
> org.sipfoundry.sipxconfig.admin.commserver.SipxReplicationContext;
> import org.sipfoundry.sipxconfig.admin.commserver.imdb.DataSet;
> import org.sipfoundry.sipxconfig.job.JobContext;
> @@ -23,100 +22,93 @@ import org.sipfoundry.sipxconfig.setting.Setting;
> import org.sipfoundry.sipxconfig.setting.SettingFilter;
> import org.sipfoundry.sipxconfig.setting.SettingValue;
> import org.sipfoundry.sipxconfig.setting.SettingValueImpl;
> -import org.sipfoundry.sipxconfig.xmlrpc.XmlRpcClientInterceptor;
> -
> -import org.springframework.aop.framework.ProxyFactory;
> +import org.sipfoundry.sipxconfig.xmlrpc.ApiProvider;
> +import org.springframework.beans.factory.annotation.Required;
> import org.springframework.context.ApplicationEvent;
> import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
>
> -public class ConferenceBridgeProvisioningImpl extends
> HibernateDaoSupport implements
> - ConferenceBridgeProvisioning {
> +public class ConferenceBridgeProvisioningImpl extends
> HibernateDaoSupport implements ConferenceBridgeProvisioning {
>
> protected static final Log LOG =
> LogFactory.getLog(ConferenceBridgeProvisioningImpl.class);
> private SipxReplicationContext m_sipxReplicationContext;
> private JobContext m_jobContext;
> + private ApiProvider<FreeswitchApi> m_freeswitchApiProvider;
>
> - public interface FreeSWITCHFunctions {
> - void freeswitch_api(String funcion, String params);
> - }
> -
> public void deploy(Serializable bridgeId) {
> Bridge bridge = (Bridge)
> getHibernateTemplate().load(Bridge.class, bridgeId);
> List conferences =
> getHibernateTemplate().loadAll(Conference.class);
> generateAdmissionData(bridge, conferences);
> - generateConfigurationData(bridge, conferences);
> - m_sipxReplicationContext.publishEvent(new
> ConferenceConfigReplicatedEvent(this, bridge.getServiceUri()));
> + generateConfigurationData(bridge, conferences);
> + ApplicationEvent event = new
> ConferenceConfigReplicatedEvent(this, bridge.getServiceUri());
> + m_sipxReplicationContext.publishEvent(event);
> m_sipxReplicationContext.generate(DataSet.ALIAS);
> }
> -
> +
> public void onApplicationEvent(ApplicationEvent event) {
> - if (event instanceof ConferenceConfigReplicatedEvent) {
> - boolean success = false;
> - Serializable jobId = m_jobContext.schedule("FreeSWITCH
> reload configuration");
> - try {
> - m_jobContext.start(jobId);
> - String serviceUrl =
> ((ConferenceConfigReplicatedEvent) event).getServiceUrl();
> - XmlRpcClientInterceptor interceptor = new
> XmlRpcClientInterceptor();
> -
> interceptor.setServiceInterface(FreeSWITCHFunctions.class);
> - interceptor.setServiceUrl(serviceUrl);
> - interceptor.afterPropertiesSet();
> -
> - FreeSWITCHFunctions proxy = (FreeSWITCHFunctions)
> ProxyFactory.getProxy(FreeSWITCHFunctions.class,
> - interceptor);
> -
> - requestConfigUpdate(proxy);
> - success = true;
> - } finally {
> - if (success) {
> - m_jobContext.success(jobId);
> - } else {
> - m_jobContext.failure(jobId, null, null);
> - }
> + if (!(event instanceof ConferenceConfigReplicatedEvent)) {
> + return;
> + }
> + boolean success = false;
> + Serializable jobId = m_jobContext.schedule("FreeSWITCH
> reload configuration");
> + try {
> + ConferenceConfigReplicatedEvent e =
> (ConferenceConfigReplicatedEvent) event;
> + m_jobContext.start(jobId);
> + FreeswitchApi api =
> m_freeswitchApiProvider.getApi(e.getServiceUrl());
> + api.reloadxml();
> + success = true;
> + } finally {
> + if (success) {
> + m_jobContext.success(jobId);
> + } else {
> + m_jobContext.failure(jobId, null, null);
> }
> }
> }
> -
>
> void generateAdmissionData(Bridge bridge, List conferences) {
> ConferenceAdmission admission = new ConferenceAdmission();
> admission.generate(conferences);
> m_sipxReplicationContext.replicate(admission);
> }
> -
> +
> void generateConfigurationData(Bridge bridge, List conferences) {
> ConferenceConfiguration configuration = new
> ConferenceConfiguration(bridge);
> configuration.generate(conferences);
> m_sipxReplicationContext.replicate(configuration);
> }
> -
> - void requestConfigUpdate(FreeSWITCHFunctions proxy) {
> - proxy.freeswitch_api("reloadxml", "");
> - }
>
> + @Required
> public void setSipxReplicationContext(SipxReplicationContext
> sipxReplicationContext) {
> m_sipxReplicationContext = sipxReplicationContext;
> }
> -
> +
> + @Required
> public void setJobContext(JobContext jobContext) {
> m_jobContext = jobContext;
> - }
> + }
> +
> + @Required
> + public void setFreeswitchApiProvider(ApiProvider<FreeswitchApi>
> freeswitchApiProvider) {
> + m_freeswitchApiProvider = freeswitchApiProvider;
> + }
>
> public static class BostonBridgeFilter implements SettingFilter {
> private static final String PREFIX = "fs-conf";
> +
> public boolean acceptSetting(Setting root_, Setting setting) {
> String profileName = setting.getProfileName();
> return profileName.startsWith(PREFIX);
> }
> }
> -
> +
> public static class ConferenceProfileName implements
> ProfileNameHandler {
> private static final char SEPARATOR = '.';
> private final String m_conferenceName;
>
> ConferenceProfileName(String conferenceName) {
> - m_conferenceName = SEPARATOR + conferenceName;
> + m_conferenceName = SEPARATOR + conferenceName;
> }
> -
> +
> public SettingValue getProfileName(Setting setting) {
> String profileName = setting.getProfileName();
> StringBuffer buffer = new StringBuffer(profileName);
> @@ -126,8 +118,8 @@ public class ConferenceBridgeProvisioningImpl
> extends HibernateDaoSupport implem
> } else {
> buffer.append(m_conferenceName);
> }
> -
> - return new SettingValueImpl(buffer.toString());
> +
> + return new SettingValueImpl(buffer.toString());
> }
> }
> }
> diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/
> conference/FreeswitchApi.java b/sipXconfig/neoconf/src/org/
> sipfoundry/sipxconfig/conference/FreeswitchApi.java
> new file mode 100644
> index 0000000..4cfb4f0
> --- /dev/null
> +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/conference/
> FreeswitchApi.java
> @@ -0,0 +1,17 @@
> +/*
> + *
> + *
> + * Copyright (C) 2008 Pingtel Corp., certain elements licensed
> under a Contributor Agreement.
> + * Contributors retain copyright to elements licensed under a
> Contributor Agreement.
> + * Licensed to the User under the LGPL license.
> + *
> + *
> + */
> +package org.sipfoundry.sipxconfig.conference;
> +
> +/**
> + * XML/RPC API provided by Freeswitch
> + */
> +public interface FreeswitchApi {
> + void reloadxml();
> +}
> diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/
> conference/FreeswitchApiMarshaller.java b/sipXconfig/neoconf/src/org/
> sipfoundry/sipxconfig/conference/FreeswitchApiMarshaller.java
> new file mode 100644
> index 0000000..11994dc
> --- /dev/null
> +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/conference/
> FreeswitchApiMarshaller.java
> @@ -0,0 +1,36 @@
> +/*
> + *
> + *
> + * Copyright (C) 2008 Pingtel Corp., certain elements licensed
> under a Contributor Agreement.
> + * Contributors retain copyright to elements licensed under a
> Contributor Agreement.
> + * Licensed to the User under the LGPL license.
> + *
> + *
> + */
> +package org.sipfoundry.sipxconfig.conference;
> +
> +import org.apache.commons.lang.ArrayUtils;
> +import org.sipfoundry.sipxconfig.xmlrpc.XmlRpcMarshaller;
> +
> +/**
> + * Hides details of low level XML/RPC that freeswitch provides.
> + *
> + * See: http://wiki.freeswitch.org/wiki/Freeswitch_XML-RPC
> + *
> + * There is really only one method and the first parameter is the
> name of the command. Other
> + * parameters follow.
> + */
> +public class FreeswitchApiMarshaller implements XmlRpcMarshaller {
> +
> + public String methodName(String name) {
> + return "freeswitch.api";
> + }
> +
> + public Object[] parameters(String name, Object... args) {
> + // for now: CamelCase to lowercase
> + String[] operation = new String[] {
> + name.toLowerCase()
> + };
> + return ArrayUtils.addAll(operation, args);
> + }
> +}
> diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/
> conference/conference.beans.xml b/sipXconfig/neoconf/src/org/
> sipfoundry/sipxconfig/conference/conference.beans.xml
> index 97a7622..6e917dd 100644
> --- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/conference/
> conference.beans.xml
> +++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/conference/
> conference.beans.xml
> @@ -1,60 +1,65 @@
> <?xml version="1.0" encoding="UTF-8"?>
> -<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
> - "http://www.springframework.org/dtd/spring-beans.dtd">
> -<beans>
> -
> - <bean name="conferenceBridge"
> class="org.sipfoundry.sipxconfig.conference.Bridge"
> - singleton="false" parent="beanWithSettings">
> - <property name="systemDefaults" ref="phoneDefaults"/>
> - <property name="audioDirectory" value="${sysdir.doc}/
> stdprompts"/>
> +<beans xmlns="http://www.springframework.org/schema/beans"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> + xsi:schemaLocation="http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
> ">
> +
> + <bean name="conferenceBridge"
> class="org.sipfoundry.sipxconfig.conference.Bridge" scope="prototype"
> + parent="beanWithSettings">
> + <property name="systemDefaults" ref="phoneDefaults" />
> + <property name="audioDirectory" value="${sysdir.doc}/
> stdprompts" />
> <!-- default value - overridden in sipxconfig.properties -->
> - <property name="host" value="localhost"/>
> - <property name="port" value="8080"/>
> + <property name="host" value="localhost" />
> + <property name="port" value="8080" />
> </bean>
>
> - <bean name="conferenceConference"
> class="org.sipfoundry.sipxconfig.conference.Conference"
> - singleton="false" parent="beanWithSettings">
> + <bean name="conferenceConference"
> class="org.sipfoundry.sipxconfig.conference.Conference"
> scope="prototype"
> + parent="beanWithSettings">
> <!-- default value - overridden in sipxconfig.properties -->
> </bean>
> -
> - <bean id="conferenceBridgeContextImpl"
> -
> class
> ="org.sipfoundry.sipxconfig.conference.ConferenceBridgeContextImpl">
> - <property name="sessionFactory" ref="sessionFactory"/>
> - <property name="aliasManager" ref="aliasManager"/>
> - <property name="coreContext" ref="coreContext"/>
> +
> + <bean id="conferenceBridgeContextImpl"
> class
> ="org.sipfoundry.sipxconfig.conference.ConferenceBridgeContextImpl">
> + <property name="sessionFactory" ref="sessionFactory" />
> + <property name="aliasManager" ref="aliasManager" />
> + <property name="coreContext" ref="coreContext" />
> <property name="provisioning">
> - <ref local="conferenceBridgeProvisioning"/>
> + <ref local="conferenceBridgeProvisioning" />
> </property>
> </bean>
> -
> - <bean id="conferenceBridgeContext"
> class="org.springframework.aop.framework.ProxyFactoryBean"
> - parent="abstractDao">
> +
> + <bean id="conferenceBridgeContext"
> class="org.springframework.aop.framework.ProxyFactoryBean"
> parent="abstractDao">
> <property name="proxyInterfaces"
>
> value="org.sipfoundry.sipxconfig.conference.ConferenceBridgeContext,
> - org.sipfoundry.sipxconfig.admin.commserver.AliasProvider"/>
> + org.sipfoundry.sipxconfig.admin.commserver.AliasProvider" />
> <property name="target">
> - <ref local="conferenceBridgeContextImpl"/>
> + <ref local="conferenceBridgeContextImpl" />
> </property>
> </bean>
> -
> - <bean id="eagerConferenceBridgeProvisioning"
> class="org.springframework.aop.framework.ProxyFactoryBean"
> parent="abstractDao">
> - <property name="proxyInterfaces"
> -
> value
> ="org.sipfoundry.sipxconfig.conference.ConferenceBridgeProvisioning"/>
> +
> + <bean id="freeswitchApiProvider"
> class="org.sipfoundry.sipxconfig.xmlrpc.XmlRpcApiProvider">
> + <property name="serviceInterface"
> value="org.sipfoundry.sipxconfig.conference.FreeswitchApi" />
> + <property name="marshaller">
> + <bean
> class
> ="org.sipfoundry.sipxconfig.conference.FreeswitchApiMarshaller" />
> + </property>
> + </bean>
> +
> + <bean id="eagerConferenceBridgeProvisioning"
> class="org.springframework.aop.framework.ProxyFactoryBean"
> + parent="abstractDao">
> + <property name="proxyInterfaces"
> value
> =
> "org.sipfoundry.sipxconfig.conference.ConferenceBridgeProvisioning" />
> <property name="target">
> <bean
> class
> =
> "org
> .sipfoundry.sipxconfig.conference.ConferenceBridgeProvisioningImpl">
> - <property name="sipxReplicationContext"
> ref="sipxReplicationContext"/>
> - <property name="jobContext" ref="jobContext"/>
> - <property name="sessionFactory" ref="sessionFactory"/>
> + <property name="sipxReplicationContext"
> ref="sipxReplicationContext" />
> + <property name="jobContext" ref="jobContext" />
> + <property name="sessionFactory" ref="sessionFactory" />
> + <property name="freeswitchApiProvider"
> ref="freeswitchApiProvider" />
> </bean>
> </property>
> </bean>
> -
> - <bean id="conferenceBridgeProvisioning"
> class
> =
> "org
> .sipfoundry
> .sipxconfig.conference.LazyConferenceBridgeProvisioningImpl"
> - init-method="init">
> +
> + <bean id="conferenceBridgeProvisioning"
> +
> class
> =
> "org
> .sipfoundry
> .sipxconfig.conference.LazyConferenceBridgeProvisioningImpl" init-
> method="init">
> <property name="target">
> <ref local="eagerConferenceBridgeProvisioning"></ref>
> </property>
> - <property name="sleepInterval" value="15000"/>
> + <property name="sleepInterval" value="15000" />
> </bean>
> -
> +
> </beans>
> --
> 1.5.4.1
>
> _______________________________________________
> sipx-dev mailing list
> [email protected]
> List Archive: http://list.sipfoundry.org/archive/sipx-dev
> Unsubscribe: http://list.sipfoundry.org/mailman/listinfo/sipx-dev
--
/**
* Joe Attardi
* Bluesocket, Inc.
* [EMAIL PROTECTED]
* 781-494-1083
*/
_______________________________________________
sipx-dev mailing list
[email protected]
List Archive: http://list.sipfoundry.org/archive/sipx-dev
Unsubscribe: http://list.sipfoundry.org/mailman/listinfo/sipx-dev