Bug 1378: Make sure config extender does not block bundle loading.
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / restconf / rpc / impl / AbstractRpcExecutor.java
1 /*
2  * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.sal.restconf.rpc.impl;
9
10 import java.util.concurrent.CancellationException;
11 import java.util.concurrent.ExecutionException;
12 import java.util.concurrent.Future;
13 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
14 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
15 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
16 import org.opendaylight.yangtools.yang.common.RpcResult;
17 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
18 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
19
20 public abstract class AbstractRpcExecutor implements RpcExecutor {
21     private final RpcDefinition rpcDef;
22
23     public AbstractRpcExecutor(RpcDefinition rpcDef) {
24         this.rpcDef = rpcDef;
25     }
26
27     @Override
28     public RpcDefinition getRpcDefinition() {
29         return rpcDef;
30     }
31
32     @Override
33     public RpcResult<CompositeNode> invokeRpc(CompositeNode rpcRequest) throws RestconfDocumentedException {
34         try {
35             return getRpcResult(invokeRpcUnchecked(rpcRequest));
36         } catch (IllegalArgumentException e) {
37             throw new RestconfDocumentedException(e.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
38         } catch (UnsupportedOperationException e) {
39             throw new RestconfDocumentedException(e.getMessage(), ErrorType.RPC, ErrorTag.OPERATION_NOT_SUPPORTED);
40         } catch (Exception e) {
41             throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.", e);
42         }
43     }
44
45     protected abstract Future<RpcResult<CompositeNode>> invokeRpcUnchecked(CompositeNode rpcRequest);
46
47     protected RpcResult<CompositeNode> getRpcResult(Future<RpcResult<CompositeNode>> fromFuture) {
48         try {
49             return fromFuture.get();
50         } catch (InterruptedException e) {
51             throw new RestconfDocumentedException(
52                     "The operation was interrupted while executing and did not complete.", ErrorType.RPC,
53                     ErrorTag.PARTIAL_OPERATION);
54         } catch (ExecutionException e) {
55             Throwable cause = e.getCause();
56             if (cause instanceof CancellationException) {
57                 throw new RestconfDocumentedException("The operation was cancelled while executing.", ErrorType.RPC,
58                         ErrorTag.PARTIAL_OPERATION);
59             } else if (cause != null) {
60                 while (cause.getCause() != null) {
61                     cause = cause.getCause();
62                 }
63
64                 if (cause instanceof IllegalArgumentException) {
65                     throw new RestconfDocumentedException(cause.getMessage(), ErrorType.PROTOCOL,
66                             ErrorTag.INVALID_VALUE);
67                 }
68
69                 throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.",
70                         cause);
71             } else {
72                 throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.",
73                         e);
74             }
75         }
76     }
77 }