osgi combat project (osmp) step by step to play with osgi's cxf publishing service (3)

I have been busy with the project, and the update is a bit late. Today, I will take the time to talk about publishing services through cxf under osgi. For details, please refer to the osgi-http component.

http://git.oschina.net/wyuxiao729/osmp/tree/master/osmp-http?dir=1&filepath=osmp-http&oid=c57f2e1633345a9298a42656cf707505f88edf1e&sha=e09ee23dba8ee3ef0239747604f6f1179eae0168

 

In fact, it is very simple to use the cxf publishing service in the osgi environment. cxf has encapsulated the release of native ws services such as jaxws and jaxrs, and it is relatively simple to implement. It is OK to define the interface and publish the implementation. In this example of osgi-http, two methods are published through cxf: restful and ws services.

 

Defining the interface is very simple, the code is as follows:

Interface definition:

 

 

/*   
 * Project: OSMP
 * FileName: IRestPlatformTransport.java
 * version: V1.0
 */
package com.osmp.http.transport;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Response;

/**
 * Description: Unified service interface REST
 * @author: wangkaiping
 *@date: Aug 9, 2016 9:14:42AM 10:51:30AM
 */
public interface IRestPlatformTransport {
    
    /**
     * retrieve data
     * @param source source json format {from:xx}
     * @param interfaceName interface name, corresponding service
     * @param parameter interface parameter, corresponding to service parameter
     * @return
     */
    public Response data(String source,String interfaceName,String parameter,HttpServletRequest request);
    /**
     * retrieve data
     * @param source source json format {from:xx}
     * @param interfaceName interface name, corresponding service
     * @param parameter interface parameter, corresponding to service parameter
     * @return
     */
    public Response dataPost(String source,String interfaceName,String parameter,HttpServletRequest request);    
    /**
     * Submit task
     * @param source source json format {from:xx}
     * @param interfaceName interface name, corresponding service
     * @param parameter interface parameter, corresponding to service parameter
     * @return
     */
    public Response task(String source,String interfaceName,String parameter);
}

 

 

Interface implementation:

 

 

/*   
 * Project: OSMP
 * FileName: RestPlatformTransport.java
 * version: V1.0
 */
package com.osmp.http.transport;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

import com.osmp.http.define.ResponseBody;
import com.osmp.http.define.RtCodeConst;
import com.osmp.http.service.DataServiceProxy;
import com.osmp.http.service.ServiceFactoryManager;
import com.osmp.http.tool.ExceptionHandleProvider;
import com.osmp.intf.define.config.FrameConst;
import com.osmp.intf.define.model.InvocationDefine;
import com.osmp.intf.define.model.ServiceContext;
import com.osmp.utils.base.JSONUtils;
import com.osmp.utils.net.RequestInfoHelper;

/**
 *
 * Description: Unified service interface REST
 * @author: wangkaiping
 *@date: Aug 9, 2016 9:16:20AM 10:51:30AM
 */
public class RestPlatformTransport implements IRestPlatformTransport, InitializingBean {
	private Logger logger = LoggerFactory.getLogger (RestPlatformTransport.class);
	
	@POST
	@Path(value = "/{svcName}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response dataPost(@FormParam(FrameConst.SOURCE_NAME) String source,
			@PathParam("svcName") String interfaceName, @FormParam(FrameConst.PARAMETER_NAME) String parameter,
			@Context HttpServletRequest request) {
		return data(source, interfaceName, parameter, request);
	}

	@GET
	@Path(value = "/{svcName}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response data(@QueryParam(FrameConst.SOURCE_NAME) String source,
			@PathParam("svcName") String interfaceName, @QueryParam(FrameConst.PARAMETER_NAME) String parameter,
			@Context HttpServletRequest request) {

		
		return Response.ok().entity("ok")
				.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON + ";charset=UTF-8").build();
	}

	@GET
	@Path(value = "/task")
	@Produces(MediaType.APPLICATION_JSON)
	public Response task(String source, String interfaceName, String parameter) {
		return null;
	}

}

Here we use the jsr annotation to define the interface request type, the interface request url and the mediaType type in the interface

Annotation in the code

@POST defines the type of request

@Path(value="/{svcName}") restful style request path

@Produces(MediaType.APPLICATION_JSON) defines the submission method of request data as JSON, and supports multiple submission methods if necessary. This place can directly default * without writing, and the default is to support all submission methods.

 

 Of course, annotations can also be written on the interface!

 

Because here is only to explain the release of the restful interface. I have removed the specific implementation of the method. If you are interested, you can take a look at the code in osmp-http.

 

 

 

Next webservice interface:

/*   
 * Project: OSMP
 * FileName: ISoapPlatformTransport.java
 * version: V1.0
 */
package com.osmp.http.transport;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

import com.osmp.http.define.ResponseBody;
import com.osmp.intf.define.config.FrameConst;

/**
 * Description: Unified service interface soap
 * @author: wangkaiping
 *@date: Aug 9, 2016 9:15:42AM 10:51:30AM
 */
@WebService(targetNamespace = "osmp.soap")
public interface ISoapPlatformTransport {
    @WebMethod(action = "data", operationName = "data")
    public ResponseBody data(@WebParam(name=FrameConst.SOURCE_NAME) String source,
            @WebParam(name=FrameConst.SERVICE_NAME) String interfaceName,
            @WebParam(name=FrameConst.PARAMETER_NAME) String parameter);
}

 

The interface uses the jdk native jws annotation to define the namespace and method action and operationName and parameters of the interface. For details, please refer to the related information of jws and soap protocols.

 

webservice interface implementation:

 

/*   
 * Project: OSMP
 * FileName: SoapPlatformTransport.java
 * version: V1.0
 */
package com.osmp.http.transport;

import java.util.Map;

import javax.jws.WebService;
import javax.servlet.http.HttpServletRequest;

import org.apache.cxf.message.Message;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

import com.osmp.http.define.ResponseBody;
import com.osmp.http.define.RtCodeConst;
import com.osmp.http.service.DataServiceProxy;
import com.osmp.http.service.ServiceFactoryManager;
import com.osmp.intf.define.config.FrameConst;
import com.osmp.intf.define.model.InvocationDefine;
import com.osmp.intf.define.model.ServiceContext;
import com.osmp.utils.base.JSONUtils;
import com.osmp.utils.net.RequestInfoHelper;

/**
 *
 * Description: Unified service interface SOAP
 * @author: wangkaiping
 * @date: Aug 9, 2016 9:17:10AM 10:51:30AM
 */
@WebService(portName="port",serviceName="data",endpointInterface = "com.osmp.http.transport.ISoapPlatformTransport")
public class SoapPlatformTransport implements ISoapPlatformTransport,InitializingBean{
    
    private Logger logger = LoggerFactory.getLogger (RestPlatformTransport.class);
    private ServiceFactoryManager serviceFactoryManager;

    public void afterPropertiesSet() throws Exception {
        Assert.notNull(serviceFactoryManager,"PlatformServiceTransport property dataServiceManager not set..");
    }
    
    public void setServiceFactoryManager(ServiceFactoryManager serviceFactoryManager) {
        this.serviceFactoryManager = serviceFactoryManager;
    }
    
    public ResponseBody data(String source, String interfaceName, String parameter) {
        Message message = PhaseInterceptorChain.getCurrentMessage();  
        HttpServletRequest request = (HttpServletRequest)message.get(AbstractHTTPDestination.HTTP_REQUEST);
        String ip = RequestInfoHelper.getRemoteIp(request);
        System.out.println("requstId:"+request.getAttribute(FrameConst.CLIENT_REQ_ID));
        System.out.println("ip:"+ip);
        ResponseBody res = new ResponseBody();
        // Get the corresponding service
        InvocationDefine define = serviceFactoryManager.getInvocationDefine(interfaceName);
        if (define == null) {
            res.setCode(RtCodeConst.ERR_CODE);
            res.setMessage("Service not found");
            logger.warn("Service not found...");
            return res;
        }
        // interface parameter validation
        Map<String, String> sourceMap = JSONUtils.jsonString2Map(source);
        if (sourceMap == null || sourceMap.get(FrameConst.CLIENT_FROM) == null) {
            res.setCode(RtCodeConst.ERR_CODE);
            res.setMessage("The interface parameter is illegal");
            logger.warn("The interface parameter is illegal...");
            return res;
        }
        sourceMap.put(FrameConst.CLIENT_IP, ip);
        // call the service
        ServiceContext serviceContext = new ServiceContext(sourceMap, interfaceName, parameter);
        DataServiceProxy serviceProxy = new DataServiceProxy(define, serviceContext);
        Object result = serviceProxy.execute();

        res.setCode(RtCodeConst.SUCC_CODE);
        res.setData(result);
        return res;
    }
    
}

 

 

After completing the interface definition and implementation. We can expose this interface as a service for external calls through cxf.

 

You can use the spring method or the buleprint method. Here I use spring way for compatibility. The configuration file is as follows:

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:cxf="http://cxf.apache.org/core"
    xmlns:jaxws="http://cxf.apache.org/jaxws" 
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
        http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
    
    <cxf:bus>
        <cxf:inInterceptors>
            <ref bean="requestParser"/>
            <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
        </cxf:inInterceptors>
        <cxf:outInterceptors>
            <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
        </cxf:outInterceptors>
    </cxf:bus>
    
    <bean id="webserver" class="com.osmp.http.transport.RestPlatformTransport">
    </bean>
    
    <bean id="soapServer" class="com.osmp.http.transport.SoapPlatformTransport">
    </bean>
    
    <bean id="objectMapper" class="com.osmp.http.tool.DefaultObjectMapper"></bean>
    <jaxrs:server id="restServiceContainer" address="/service">    
        <jaxrs:serviceBeans>        
            <ref bean="webserver" />    
        </jaxrs:serviceBeans>    
        
        <jaxrs:providers>  
            <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider">
                <constructor-arg index="0" ref="objectMapper"></constructor-arg>
            </bean>  
        </jaxrs:providers>  
        
        <jaxrs:extensionMappings>        
            <entry key="json" value="application/json" />        
        </jaxrs:extensionMappings>
        
        <jaxrs:languageMappings>  
            <entry key="en" value="en-gb" />  
        </jaxrs:languageMappings>
    </jaxrs:server>
    
    <jaxws:server id="soapServiceContainer" address="/soap">
        <jaxws:serviceBean>
            <ref bean="soapServer" />
        </jaxws:serviceBean>
    </jaxws:server>

</beans>

 

 

   So far, the code part is complete. If it is a traditional j2ee project. It can be accessed directly through http://ip:port/cxf.

 

   So how do we publish in the osgi environment? It's actually very simple here. I use servicemix as the container. It has already integrated cxf, we can directly deploy it as a bundle. If it is karaf or native felix, it will be more troublesome. You need to install the dependency support of cxf-bundle first. I will not explain it here. Research!

 

   Here the jar package that pom needs to depend on is

 

       <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-bundle</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.osgi</groupId>
            <artifactId>spring-osgi-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
        </dependency>

 

 

Building bundles with the maven plugin requires the use of the maven-bundle-plgin plugin, where we can define settings such as importing, exporting packages, and bundle-embedded jar packages. For detailed settings, see:

http://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html

 

complete pom.xml

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.osmp.baseweb</groupId>
		<artifactId>osmp-parent</artifactId>
		<version>1.0.0</version>
	</parent>

	<artifactId>osmp-http</artifactId>
	<packaging>bundle</packaging>
	<name>osmp-http</name>

	<properties>
		<maven.test.skip>true</maven.test.skip>
	</properties>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<extensions>true</extensions>
				<configuration>
					<instructions>
						<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
						<DynamicImport-Package>*;resolution:=optional</DynamicImport-Package>
						<Import-Package>com.osmp.intf.define.config,
							com.osmp.intf.define.interceptor,
							com.osmp.intf.define.model,
							com.osmp.intf.define.factory,
							com.osmp.intf.define.service,
							com.osmp.utils.net,
							com.osmp.utils.base</Import-Package>
						<Embed-Dependency>jackson-jaxrs,jackson-xc</Embed-Dependency>
					</instructions>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>
		<dependency>
			<groupId>com.osmp.baseweb</groupId>
			<artifactId>osmp-intf-define</artifactId>
			<version>${project.version}</version>
		</dependency>
		<dependency>
			<groupId>com.osmp.baseweb</groupId>
			<artifactId>osmp-resource</artifactId>
			<version>${project.version}</version>
		</dependency>
		<dependency>
			<groupId>com.osmp.baseweb</groupId>
			<artifactId>osmp-tools</artifactId>
			<version>${project.version}</version>
		</dependency>
		<dependency>
			<groupId>com.osmp.baseweb</groupId>
			<artifactId>osmp-utils</artifactId>
			<version>${project.version}</version>
		</dependency>
		<dependency>
			<groupId>com.osmp.baseweb</groupId>
			<artifactId>osmp-log</artifactId>
			<version>${project.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.osgi</groupId>
			<artifactId>spring-osgi-core</artifactId>
		</dependency>
		<dependency>
			<groupId>org.osgi</groupId>
			<artifactId>org.osgi.core</artifactId>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-jaxrs</artifactId>
			<version>1.9.13</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-xc</artifactId>
			<version>1.9.13</version>
		</dependency>
	</dependencies>
</project>

 

 

The typed jar package is of bundle type. Can run in osgi environment.

Visit in the servicemix environment: http://ip:8181/cxf You can see the restful interface and soap interface we have defined

 

 



 

  The default access root path of cxf is cxf, which can be modified through servicemix configuration

 

 

 

 



 

 

I'm about to get off work, so let's write it here first. In fact, it is very simple to publish a cxf restful and soap. There are a lot of online examples. If it is deployed in an osgi environment. It is recommended to use karaf or servicemix.

 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326702007&siteId=291194637