<artifactId>binding-generator-impl</artifactId>
<version>${project.version}</version>
</dependency>
-
</dependencies>
</dependencyManagement>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-proxy-client</artifactId>
</dependency>
-<!--
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-jaxrs</artifactId>
- </dependency>
--->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>binding-generator-impl</artifactId>
</dependency>
-<!-- <dependency> -->
-<!-- <groupId>org.opendaylight.controller.model</groupId> -->
-<!-- <artifactId>model-flow-service</artifactId> -->
-<!-- <version>1.1-SNAPSHOT</version> -->
-<!-- <scope>test</scope> -->
-<!-- </dependency> -->
</dependencies>
<build>
<plugins>
*/
package org.opendaylight.yangtools.restconf.client;
-import com.sun.jersey.api.client.Client;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.api.client.config.ClientConfig;
-import com.sun.jersey.api.client.config.DefaultClientConfig;
-import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
-import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
-import java.net.URI;
import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
-import org.opendaylight.yangtools.restconf.common.ResourceMediaTypes;
+import org.opendaylight.yangtools.restconf.client.to.RestRpcError;
+import org.opendaylight.yangtools.restconf.client.to.RestRpcResult;
import org.opendaylight.yangtools.restconf.common.ResourceUri;
import org.opendaylight.yangtools.restconf.utils.XmlTools;
import org.opendaylight.yangtools.yang.binding.BindingMapping;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSSerializer;
public class BindingToRestRpc implements InvocationHandler {
- private final Client client;
- private final URI defaultUri;
+ private final RestconfClientImpl client;
private static final Logger logger = LoggerFactory.getLogger(BindingToRestRpc.class);
-
- public BindingToRestRpc(URI uri) {
- ClientConfig config = new DefaultClientConfig();
- this.client = Client.create(config);
- this.client.addFilter(new HTTPBasicAuthFilter("admin", "admin"));
- this.defaultUri = uri;
+ private final BindingIndependentMappingService mappingService;
+ private final SchemaContext schcemaContext;
+ private final Module module;
+
+ public BindingToRestRpc(Class proxiedInterface,BindingIndependentMappingService mappingService,RestconfClientImpl client,SchemaContext schemaContext) throws Exception {
+ this.mappingService = mappingService;
+ this.client = client;
+ this.schcemaContext = schemaContext;
+ YangModuleInfo moduleInfo = BindingReflections.getModuleInfo(proxiedInterface);
+ this.module = schemaContext.findModuleByName(moduleInfo.getName(),org.opendaylight.yangtools.yang.common.QName.parseRevision(moduleInfo.getRevision()));
}
@Override
- public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
-
- YangModelParser parser = new YangParserImpl();
-
- Method getInstanceMethod = Class.forName(method.getDeclaringClass().getPackage().getName()+".$YangModuleInfoImpl").getMethod("getInstance",new Class[0]);
-
- YangModuleInfo yangModuleInfo = (YangModuleInfo) getInstanceMethod.invoke(null,new Object[0]);
-
- List<InputStream> moduleStreams = new ArrayList<InputStream>();
- moduleStreams.add(yangModuleInfo.getModuleSourceStream());
-
- Set<Module> modules = parser.parseYangModelsFromStreams(moduleStreams);
-
- for (Module m:modules){
- for (RpcDefinition rpcDef:m.getRpcs()){
- if (method.getName().equals(BindingMapping.getMethodName(rpcDef.getQName()))){
-
- String moduleName = BindingReflections.getModuleInfo(method.getDeclaringClass()).getName();
- String rpcMethodName = rpcDef.getQName().getLocalName();
-
- WebResource resource = client.resource(defaultUri.toString() + ResourceUri.OPERATIONS.getPath() + "/"+ moduleName+":"+rpcMethodName);
-
- final ClientResponse response = resource.accept(ResourceMediaTypes.XML.getMediaType())
- .post(ClientResponse.class);
-
-
- if (response.getStatus() != 200) {
- throw new IllegalStateException("Can't get data from restconf. "+response.getClientResponseStatus());
- }
- return XmlTools.unmarshallXml(method.getReturnType(), response.getEntityInputStream());
+ public Object invoke(Object o,final Method method, Object[] objects) throws Throwable {
+ for (RpcDefinition rpcDef:module.getRpcs()){
+ if (method.getName().equals(BindingMapping.getMethodName(rpcDef.getQName()))){
+
+ String moduleName = BindingReflections.getModuleInfo(method.getDeclaringClass()).getName();
+ String rpcMethodName = rpcDef.getQName().getLocalName();
+ Document rpcInputDoc = null;
+ for (Object component:objects){
+ CompositeNode rpcInput = mappingService.toDataDom((DataObject) component);
+ rpcInputDoc = XmlDocumentUtils.toDocument(rpcInput,rpcDef.getInput(),XmlDocumentUtils.defaultValueCodecProvider());
}
+ DOMImplementationLS lsImpl = (DOMImplementationLS)rpcInputDoc.getImplementation().getFeature("LS", "3.0");
+ LSSerializer serializer = lsImpl.createLSSerializer();
+ serializer.getDomConfig().setParameter("xml-declaration", false);
+
+ String payloadString = serializer.writeToString(rpcInputDoc);
+ final Class<? extends DataContainer> desiredOutputClass = (Class<? extends DataContainer>)BindingReflections.resolveRpcOutputClass(method).get();
+ final DataSchemaNode rpcOutputSchema = rpcDef.getOutput();
+ return client.post(ResourceUri.OPERATIONS.getPath() + "/" + moduleName + ":" + rpcMethodName,payloadString,new Function<ClientResponse, Object>() {
+ @Override
+ public Object apply(ClientResponse clientResponse) {
+ if (clientResponse.getStatus() != 200) {
+ throw new IllegalStateException("Can't get data from restconf. "+clientResponse.getClientResponseStatus());
+ }
+ List<RpcError> errors = new ArrayList<>();
+ try {
+ Document rpcOutputDocument = XmlTools.fromXml(clientResponse.getEntityInputStream());
+ CompositeNode cn = (CompositeNode) XmlDocumentUtils.toDomNode(rpcOutputDocument.getDocumentElement(),
+ Optional.of(rpcOutputSchema),
+ Optional.of(XmlDocumentUtils.defaultValueCodecProvider()));
+ DataContainer rpcOutputDataObject = mappingService.dataObjectFromDataDom(desiredOutputClass, cn);
+ return new RestRpcResult(true,rpcOutputDataObject);
+ } catch (Exception e) {
+ logger.trace("Error while extracting rpc output in proxy method {}",e);
+ RestRpcError error = new RestRpcError(RpcError.ErrorSeverity.ERROR, RpcError.ErrorType.APPLICATION,"Error while extracting rpc output in proxy method.",e);
+ }
+ return new RestRpcResult(false,errors);
+ }
+ });
}
}
- return null;
+ throw new IllegalStateException("Unexpected state of proxy method.");
}
- public static<T> T getProxy(Class<T> intf,
- URI uri) {
- Object obj = (T) Proxy.newProxyInstance
+ public static<T> T getProxy(Class<T> proxiedInterface,
+ BindingIndependentMappingService mappingService,
+ RestconfClientImpl restconfClient,
+ SchemaContext schemaContext) {
+ T proxiedType = null;
+ try {
+ proxiedType = (T) Proxy.newProxyInstance
(BindingToRestRpc.class.getClassLoader(),
- new Class[]{intf}, new BindingToRestRpc(uri));
+ new Class[]{proxiedInterface}, new BindingToRestRpc(proxiedInterface, mappingService, restconfClient, schemaContext));
+ } catch (Exception e) {
+ throw new IllegalStateException(e.getMessage());
+ }
- return (T) obj;
+ return proxiedType;
}
*/
package org.opendaylight.yangtools.restconf.client;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.sun.jersey.api.client.ClientResponse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
-
+import javax.ws.rs.core.MediaType;
import org.opendaylight.yangtools.restconf.client.api.data.ConfigurationDatastore;
import org.opendaylight.yangtools.restconf.client.to.RestRpcError;
import org.opendaylight.yangtools.restconf.client.to.RestRpcResult;
-import org.opendaylight.yangtools.restconf.common.ResourceMediaTypes;
import org.opendaylight.yangtools.restconf.common.ResourceUri;
import org.opendaylight.yangtools.restconf.utils.RestconfUtils;
import org.opendaylight.yangtools.yang.binding.DataObject;
final BindingIndependentMappingService mappingService = getClient().getMappingService();
final Map.Entry<String, DataSchemaNode> pathWithSchema = RestconfUtils.toRestconfIdentifier(path, mappingService, schemaContext);
final String restconfPath = getStorePrefix() + pathWithSchema.getKey();
-
- ListenableFuture<RpcResult<Boolean>> future = pool.submit(new Callable<RpcResult<Boolean>>() {
+ return getClient().delete(restconfPath,MediaType.APPLICATION_XML,new Function<ClientResponse, RpcResult<Boolean>>() {
@Override
- public RpcResult<Boolean> call() throws Exception {
+ public RpcResult<Boolean> apply(ClientResponse clientResponse) {
Entry<String, DataSchemaNode> restconfEntry = RestconfUtils.toRestconfIdentifier(mappingService.toDataDom(path), schemaContext);
- WebResource resource = getClient().getRestClient().resource(getClient().constructPath(restconfPath));
- final ClientResponse response = resource.accept(ResourceMediaTypes.XML.getMediaType())
- .delete(ClientResponse.class);
-
- if (response.getStatus() != 200) {
- RpcError rpcError = new RestRpcError(RpcError.ErrorSeverity.ERROR,RpcError.ErrorType.RPC,null,null,"HTTP status "+response.getStatus(),null,null);
+ if (clientResponse.getStatus() != 200) {
+ RpcError rpcError = new RestRpcError(RpcError.ErrorSeverity.ERROR,RpcError.ErrorType.RPC,null,null,"HTTP status "+clientResponse.getStatus(),null,null);
Collection<RpcError> errors = new ArrayList<RpcError>();
errors.add(rpcError);
RestRpcResult rpcResult = new RestRpcResult(false,null,errors);
return (RpcResult<Boolean>) Optional.of(rpcResult);
}
- DataObject dataObject = RestconfUtils.dataObjectFromInputStream(path, response.getEntityInputStream(), schemaContext, mappingService,restconfEntry.getValue());
+ DataObject dataObject = RestconfUtils.dataObjectFromInputStream(path, clientResponse.getEntityInputStream(), schemaContext, mappingService,restconfEntry.getValue());
RestRpcResult rpcResult = new RestRpcResult(true,dataObject,null);
return (RpcResult<Boolean>) Optional.of(rpcResult);
}
});
- return future;
}
@Override
final Map.Entry<String, DataSchemaNode> pathWithSchema = RestconfUtils.toRestconfIdentifier(path, mappingService, schemaContext);
final String restconfPath = getStorePrefix() + pathWithSchema.getKey();
- ListenableFuture<RpcResult<Boolean>> future = pool.submit(new Callable<RpcResult<Boolean>>() {
+ return getClient().put(restconfPath,MediaType.APPLICATION_XML,new Function<ClientResponse, RpcResult<Boolean>>() {
@Override
- public RpcResult<Boolean> call() throws Exception {
+ public RpcResult<Boolean> apply(ClientResponse clientResponse) {
Map.Entry<String, DataSchemaNode> restconfEntry = RestconfUtils.toRestconfIdentifier(mappingService.toDataDom(path), schemaContext);
- WebResource resource = getClient().getRestClient().resource(getClient().constructPath(restconfPath));
- final ClientResponse response = resource.accept(ResourceMediaTypes.XML.getMediaType())
- .put(ClientResponse.class);
-
- if (response.getStatus() != 200) {
- RpcError rpcError = new RestRpcError(RpcError.ErrorSeverity.ERROR,RpcError.ErrorType.RPC,null,null,"HTTP status "+response.getStatus(),null,null);
+ if (clientResponse.getStatus() != 200) {
+ RpcError rpcError = new RestRpcError(RpcError.ErrorSeverity.ERROR,RpcError.ErrorType.RPC,null,null,"HTTP status "+clientResponse.getStatus(),null,null);
Collection<RpcError> errors = new ArrayList<RpcError>();
errors.add(rpcError);
RestRpcResult rpcResult = new RestRpcResult(false,null,errors);
return (RpcResult<Boolean>) Optional.of(rpcResult);
}
- DataObject dataObject = RestconfUtils.dataObjectFromInputStream(path, response.getEntityInputStream(),schemaContext,mappingService,restconfEntry.getValue());
+ DataObject dataObject = RestconfUtils.dataObjectFromInputStream(path, clientResponse.getEntityInputStream(),schemaContext,mappingService,restconfEntry.getValue());
RestRpcResult rpcResult = new RestRpcResult(true,dataObject);
return (RpcResult<Boolean>) Optional.of(rpcResult);
}
});
- return future;
}
}
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.yangtools.restconf.client.to;
+package org.opendaylight.yangtools.restconf.client;
import com.google.common.base.Charsets;
+import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
-import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.api.client.config.ClientConfig;
-import com.sun.jersey.api.client.config.DefaultClientConfig;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import javax.ws.rs.core.MediaType;
-import javax.xml.bind.annotation.XmlRootElement;
import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.restconf.client.api.event.EventStreamInfo;
import org.opendaylight.yangtools.restconf.client.api.event.EventStreamReplay;
import org.opendaylight.yangtools.restconf.client.api.event.ListenableEventStreamContext;
+import org.opendaylight.yangtools.restconf.client.to.RestRpcResult;
import org.opendaylight.yangtools.restconf.common.ResourceUri;
import org.opendaylight.yangtools.websocket.client.WebSocketIClient;
import org.opendaylight.yangtools.websocket.client.callback.ClientMessageCallback;
-@XmlRootElement
-public class RestListenableEventStreamContext<L extends NotificationListener> implements ListenableEventStreamContext,ClientMessageCallback {
- private final URI defaultUri;
- private final Client client;
+public class RestListenableEventStreamContext<L extends NotificationListener> implements ListenableEventStreamContext,ClientMessageCallback {
private static final Logger logger = LoggerFactory.getLogger(RestListenableEventStreamContext.class.toString());
private final ListeningExecutorService pool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
-
- private URI websocketServerUri;
private WebSocketIClient wsClient;
- private String streamName;
-
private Method listenerCallbackMethod;
+ private final RestconfClientImpl restconfClient;
+ private final EventStreamInfo streamInfo;
- public RestListenableEventStreamContext(URI uri){
- this.defaultUri = uri;
- ClientConfig config = new DefaultClientConfig();
- client = Client.create(config);
+ public RestListenableEventStreamContext(EventStreamInfo streamInfo,RestconfClientImpl restconfClient){
+ this.restconfClient = restconfClient;
+ this.streamInfo = streamInfo;
}
@Override
public <L extends NotificationListener> ListenerRegistration<L> registerNotificationListener(L listener) {
public ListenableFuture<RpcResult<Void>> startListening() {
- ClientResponse response = extractWebSocketUriFromRpc(this.streamName);
+ ClientResponse response = null;
+ try {
+ response = extractWebSocketUriFromRpc(this.streamInfo.getIdentifier());
+ } catch (ExecutionException e) {
+ logger.trace("Execution exception while extracting stream name {}",e);
+ throw new IllegalStateException(e);
+ } catch (InterruptedException e) {
+ logger.trace("InterruptedException while extracting stream name {}",e);
+ throw new IllegalStateException(e);
+ } catch (UnsupportedEncodingException e) {
+ logger.trace("UnsupportedEncodingException while extracting stream name {}",e);
+ throw new IllegalStateException(e);
+ }
boolean success = true;
if (response.getStatus() != 200) {
success = false;
@Override
public void stopListening() {
- this.wsClient.writeAndFlush(new CloseWebSocketFrame(42,this.streamName));
+ this.wsClient.writeAndFlush(new CloseWebSocketFrame(42,this.streamInfo.getIdentifier()));
}
@Override
this.stopListening();
}
- private ClientResponse extractWebSocketUriFromRpc(String streamName){
- String uri = null;
- try {
- uri = this.createUri(defaultUri+"/streams/stream/", streamName);
- } catch (UnsupportedEncodingException e) {
- logger.trace("Unsupported encoding.");
- }
-
- WebResource resource = client.resource(defaultUri.toString() + ResourceUri.STREAMS.getPath());
- final ClientResponse response = resource.accept(MediaType.APPLICATION_XML)
- .get(ClientResponse.class);
+ private ClientResponse extractWebSocketUriFromRpc(String methodName) throws ExecutionException, InterruptedException, UnsupportedEncodingException {
+ ListenableFuture<ClientResponse> clientFuture = restconfClient.get(ResourceUri.STREAM.getPath()+"/"+encodeUri(this.streamInfo.getIdentifier()),MediaType.APPLICATION_XML,new Function<ClientResponse, ClientResponse>(){
- this.websocketServerUri = response.getLocation();
- return response;
+ @Override
+ public ClientResponse apply(ClientResponse clientResponse) {
+ return clientResponse;
+ }
+ });
+ while (!clientFuture.isDone()){
+ //noop
+ }
+ return clientFuture.get();
}
private void createWebsocketClient(URI websocketServerUri){
this.wsClient = new WebSocketIClient(websocketServerUri,this);
}
-
- private String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
- return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
+ private String encodeUri(String encodedPart) throws UnsupportedEncodingException {
+ return URI.create(URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
}
@Override
throw new IllegalStateException(e.getMessage());
}
}
+
}
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
+import javax.ws.rs.core.MediaType;
import org.opendaylight.yangtools.restconf.client.api.RestconfClientContext;
import org.opendaylight.yangtools.restconf.client.api.auth.AuthenticationHolder;
import org.opendaylight.yangtools.restconf.client.api.data.ConfigurationDatastore;
import org.opendaylight.yangtools.restconf.client.api.event.EventStreamInfo;
import org.opendaylight.yangtools.restconf.client.api.event.ListenableEventStreamContext;
import org.opendaylight.yangtools.restconf.client.api.rpc.RpcServiceContext;
-import org.opendaylight.yangtools.restconf.client.to.RestListenableEventStreamContext;
import org.opendaylight.yangtools.restconf.client.to.RestRpcServiceContext;
import org.opendaylight.yangtools.restconf.common.ResourceMediaTypes;
import org.opendaylight.yangtools.restconf.common.ResourceUri;
Preconditions.checkArgument(mappingService != null, "Mapping service must not be null.");
Preconditions.checkNotNull(schemaContextHolder, "Schema Context Holder must not be null.");
ClientConfig config = new DefaultClientConfig();
- restClient = Client.create(config);
+ this.restClient = Client.create(config);
URI uri = null;
try {
uri = url.toURI();
@Override
public ListenableFuture<Set<Class<? extends RpcService>>> getRpcServices() {
- ListenableFuture<Set<Class<? extends RpcService>>> future = pool.submit(new Callable<Set<Class<? extends RpcService>>>() {
+ return get(ResourceUri.MODULES.getPath(), ResourceMediaTypes.XML.getMediaType(),new Function<ClientResponse, Set<Class<? extends RpcService>>>() {
@Override
- public Set<Class<? extends RpcService>> call() throws Exception {
- WebResource resource = restClient.resource(defaultUri.toString() + ResourceUri.MODULES.getPath());
- final ClientResponse response = resource.accept(ResourceMediaTypes.XML.getMediaType())
- .get(ClientResponse.class);
- if (response.getStatus() != 200) {
+ public Set<Class<? extends RpcService>> apply(ClientResponse clientResponse) {
+ if (clientResponse.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
- + response.getStatus());
+ + clientResponse.getStatus());
}
-
- return RestconfUtils.rpcServicesFromInputStream(response.getEntityInputStream(),mappingService,schemaContextHolder.getSchemaContext());
+ return RestconfUtils.rpcServicesFromInputStream(clientResponse.getEntityInputStream(),mappingService,schemaContextHolder.getSchemaContext());
}
});
- return future;
}
@Override
public <T extends RpcService> RpcServiceContext<T> getRpcServiceContext(Class<T> rpcService) {
- RestRpcServiceContext restRpcServiceContext = new RestRpcServiceContext(rpcService,this.defaultUri);
+ RestRpcServiceContext restRpcServiceContext = new RestRpcServiceContext(rpcService,this.mappingService,this,schemaContextHolder.getSchemaContext());
return restRpcServiceContext;
}
@Override
public ListenableFuture<Set<EventStreamInfo>> getAvailableEventStreams() {
- ListenableFuture<Set<org.opendaylight.yangtools.restconf.client.api.event.EventStreamInfo>> future = pool.submit(new Callable<Set<org.opendaylight.yangtools.restconf.client.api.event.EventStreamInfo>>() {
+ return get(ResourceUri.MODULES.getPath(), ResourceMediaTypes.XML.getMediaType(),new Function<ClientResponse, Set<EventStreamInfo>>() {
@Override
- public Set<org.opendaylight.yangtools.restconf.client.api.event.EventStreamInfo> call() throws Exception {
- // when restconf will support discovery by /restconf/streams change ResourceUri.MODULES to ResourceUri.STREAMS
- WebResource resource = restClient.resource(defaultUri.toString() + ResourceUri.MODULES.getPath());
- final ClientResponse response = resource.accept(ResourceMediaTypes.XML.getMediaType())
- .get(ClientResponse.class);
-
- if (response.getStatus() != 200) {
+ public Set<EventStreamInfo> apply(ClientResponse clientResponse) {
+ if (clientResponse.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
- + response.getStatus());
+ + clientResponse.getStatus());
+ }
+ List<RestModule> modules = null;
+ try {
+ modules = XmlTools.getModulesFromInputStream(clientResponse.getEntityInputStream());
+ } catch (Exception e) {
+ logger.trace("");
}
- List<RestModule> modules = XmlTools.getModulesFromInputStream(response.getEntityInputStream());
// when restconf will support discovery by /restconf/streams use this instead of next iteration
//return XmlTools.evenStreamsFromInputStream(response.getEntityInputStream());
Set<EventStreamInfo> evtStreamInfos = new HashSet<EventStreamInfo>();
for (RestModule module:modules){
RestEventStreamInfo esi = new RestEventStreamInfo();
- esi.setIdentifier(module.getName());
- esi.setDescription(module.getNamespace()+" "+module.getRevision());
+ esi.setIdentifier(module.getName()+":"+module.getName());
+ esi.setDescription(module.getNamespace());
evtStreamInfos.add(esi);
}
return evtStreamInfos;
}
});
- return future;
}
@Override
public ListenableEventStreamContext getEventStreamContext(EventStreamInfo info) {
- RestListenableEventStreamContext listenableEventStream = new RestListenableEventStreamContext(defaultUri);
+ RestListenableEventStreamContext listenableEventStream = new RestListenableEventStreamContext(info,this);
return listenableEventStream;
}
}
- protected Client getRestClient() {
- return restClient;
- }
-
public SchemaContext getSchemaContext() {
return this.schemaContextHolder.getSchemaContext();
}
protected <T> ListenableFuture<T> get(final String path, final Function<ClientResponse, T> processingFunction) {
- return pool.submit(new GetAndTransformTask<T>(constructPath(path),processingFunction));
+ return pool.submit(new ExecuteOperationAndTransformTask<T>(constructPath(path), RestOperation.GET, processingFunction));
}
protected <T> ListenableFuture<T> get(final String path,final String mediaType, final Function<ClientResponse, T> processingFunction) {
- return pool.submit(new GetAndTransformTask<T>(constructPath(path),mediaType,processingFunction));
+ return pool.submit(new ExecuteOperationAndTransformTask<T>(constructPath(path),mediaType,RestOperation.GET,processingFunction));
+ }
+
+ protected <T> ListenableFuture<T> post(final String path, String payload, final Function<ClientResponse, T> processingFunction) {
+ return pool.submit(new ExecuteOperationAndTransformTask<T>(constructPath(path),payload,RestOperation.POST,processingFunction));
+ }
+
+ protected <T> ListenableFuture<T> post(final String path,String payload,final String mediaType, final Function<ClientResponse, T> processingFunction) {
+ return pool.submit(new ExecuteOperationAndTransformTask<T>(constructPath(path),payload,RestOperation.POST,mediaType,processingFunction));
+ }
+
+ protected <T> ListenableFuture<T> put(final String path, String payload, final Function<ClientResponse, T> processingFunction) {
+ return pool.submit(new ExecuteOperationAndTransformTask<T>(constructPath(path),RestOperation.PUT,payload,processingFunction));
+ }
+
+ protected <T> ListenableFuture<T> put(final String path,String payload,final String mediaType, final Function<ClientResponse, T> processingFunction) {
+ return pool.submit(new ExecuteOperationAndTransformTask<T>(constructPath(path),payload,RestOperation.PUT,mediaType,processingFunction));
+ }
+ protected <T> ListenableFuture<T> delete(final String path, final Function<ClientResponse, T> processingFunction) {
+ return pool.submit(new ExecuteOperationAndTransformTask<T>(constructPath(path),RestOperation.DELETE,processingFunction));
+ }
+
+ protected <T> ListenableFuture<T> delete(final String path,final String mediaType, final Function<ClientResponse, T> processingFunction) {
+ return pool.submit(new ExecuteOperationAndTransformTask<T>(constructPath(path),RestOperation.DELETE,mediaType,processingFunction));
}
protected String constructPath(String path) {
return getDefaultUri().toString() + path;
}
- //, RestRestconfService {
-
- private class GetAndTransformTask<T> implements Callable<T> {
+ private enum RestOperation{
+ PUT,POST,GET,DELETE;
+ }
+ private class ExecuteOperationAndTransformTask<T> implements Callable<T> {
private final Function<ClientResponse, T> transformation;
private final String path;
private final String acceptType;
+ private final String payload;
+ private final RestOperation restOperation;
- public GetAndTransformTask(String path, Function<ClientResponse, T> processingFunction) {
+ public ExecuteOperationAndTransformTask(String path, String payload, RestOperation operation, Function<ClientResponse, T> processingFunction) {
this.path = path;
this.transformation = processingFunction;
- this.acceptType = ResourceMediaTypes.XML.getMediaType();
+ this.acceptType = MediaType.APPLICATION_XML; //ResourceMediaTypes.XML.getMediaType();
+ this.payload = payload;
+ this.restOperation = operation;
}
- public GetAndTransformTask(String path, String mediaType, Function<ClientResponse, T> processingFunction) {
+ public ExecuteOperationAndTransformTask(String path,String payload, RestOperation operation,String mediaType, Function<ClientResponse, T> processingFunction) {
+ this.path = path;
+ this.transformation = processingFunction;
+ this.acceptType = mediaType;
+ this.payload = payload;
+ this.restOperation = operation;
+ }
+ public ExecuteOperationAndTransformTask(String path, RestOperation operation,String mediaType, Function<ClientResponse, T> processingFunction) {
this.path = path;
this.transformation = processingFunction;
this.acceptType = mediaType;
+ this.payload = null;
+ this.restOperation = operation;
+ }
+ public ExecuteOperationAndTransformTask(String path, RestOperation operation, Function<ClientResponse, T> processingFunction) {
+ this.path = path;
+ this.transformation = processingFunction;
+ this.acceptType = MediaType.APPLICATION_XML;
+ this.payload = null;
+ this.restOperation = operation;
}
@Override
public T call() {
+ ClientResponse response = null;
+ try {
+ WebResource resource = restClient.resource(path);
+ switch (restOperation){
+ case PUT: response = resource.type(MediaType.APPLICATION_XML).accept(acceptType).put(ClientResponse.class, payload);
+ break;
+ case POST : response = resource.type(MediaType.APPLICATION_XML).accept(acceptType).post(ClientResponse.class, payload);
+ break;
+ case GET: response = resource.type(MediaType.APPLICATION_XML).accept(acceptType).get(ClientResponse.class);
+ break;
+ case DELETE: response = resource.type(MediaType.APPLICATION_XML).accept(acceptType).delete(ClientResponse.class);
+ break;
+ }
+
+ } catch (Exception e){
+ logger.trace("Exception occured while posting data to client {}",e);
+ }
- WebResource resource = restClient.resource(path);
- ClientResponse response = resource.accept(acceptType).get(ClientResponse.class);
- // Applies the specific transformation for supplied resource.
return transformation.apply(response);
}
-
}
}
*/
package org.opendaylight.yangtools.restconf.client.to;
-import java.net.URI;
import org.opendaylight.yangtools.restconf.client.BindingToRestRpc;
+import org.opendaylight.yangtools.restconf.client.RestconfClientImpl;
import org.opendaylight.yangtools.restconf.client.api.rpc.RpcServiceContext;
import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(RestRpcServiceContext.class);
private T rpcServiceProxy;
- public RestRpcServiceContext(Class<T> rpcService,URI uri){
- this.rpcServiceProxy = BindingToRestRpc.getProxy(rpcService,uri);
+ public RestRpcServiceContext(Class<T> rpcService,BindingIndependentMappingService mappingService, RestconfClientImpl
+ restconfClient,SchemaContext schemaContext){
+ this.rpcServiceProxy = BindingToRestRpc.getProxy(rpcService,mappingService,restconfClient,schemaContext);
}
@Override
public enum ResourceMediaTypes {
XML("application/yang.api+xml"),
- JSON("application/yang.api+json");
+ JSON("application/yang.api+json"),
+ TEXT_EVT("text/event-stream");
private final String mediaType;
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-topology-isis</artifactId>
- <version>2013.10.21.2-SNAPSHOT</version>
- <scope>test</scope>
- </dependency>
+ <dependency>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ <version>2.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>ietf-topology-isis</artifactId>
+ <version>2013.10.21.2-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
import java.util.List;
import java.util.Set;
import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.stream.StreamSource;
import org.opendaylight.yangtools.restconf.client.api.dto.RestEventStreamInfo;
+import org.opendaylight.yangtools.restconf.client.api.dto.RestModule;
import org.opendaylight.yangtools.restconf.client.api.dto.RestRpcService;
import org.opendaylight.yangtools.restconf.client.api.event.EventStreamInfo;
-import org.opendaylight.yangtools.restconf.client.api.dto.RestModule;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class XmlTools {
private static final Logger logger = LoggerFactory.getLogger(XmlTools.class.toString());
+ static final String JAXP_SCHEMA_LOCATION =
+ "http://java.sun.com/xml/jaxp/properties/schemaSource";
-
- public static Object unmarshallXml(Class<?> clazz,InputStream xmlStream) throws Exception{
+ public static Object unmarshallXml(Class<?> clazz,InputStream xmlStream,String namespace) throws Exception{
if (null == xmlStream){
throw new Exception("XML input stream can't be null");
}
- JAXBContext jc = null;
- jc = JAXBContext.newInstance(clazz);
+ JAXBContext jc = JAXBContext.newInstance(clazz);
- Unmarshaller unmarshaller = null;
- Object o = null;
- unmarshaller = jc.createUnmarshaller();
- return unmarshaller.unmarshal(xmlStream);
+ Unmarshaller unmarshaller = jc.createUnmarshaller();
+ StreamSource xmlInputSource = new StreamSource(xmlStream);
+ JAXBElement<?> obj = unmarshaller.unmarshal(xmlInputSource, clazz);
+ return obj;
}
public static Document fromXml(InputStream is) throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+ dbFactory.setNamespaceAware(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+
Document doc = dBuilder.parse(is);
doc.getDocumentElement().normalize();
return doc;
private void initialize(){
String protocol = uri.getScheme();
- if (!"ws".equals(protocol)) {
+ if (!"ws".equals(protocol) && !"http".equals(protocol)) {
throw new IllegalArgumentException("Unsupported protocol: " + protocol);
}