a6187f5fa39f022513afaddf85a232315791db74
[netconf.git] / restconf / sal-rest-connector / src / main / java / org / opendaylight / restconf / restful / services / impl / RestconfDataServiceImpl.java
1 /*
2  * Copyright (c) 2016 Cisco 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.restconf.restful.services.impl;
9
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import javax.ws.rs.core.Response;
13 import javax.ws.rs.core.UriInfo;
14 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
15 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
16 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
17 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
18 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
19 import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
20 import org.opendaylight.netconf.sal.restconf.impl.PATCHStatusContext;
21 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
22 import org.opendaylight.restconf.common.references.SchemaContextRef;
23 import org.opendaylight.restconf.handlers.SchemaContextHandler;
24 import org.opendaylight.restconf.handlers.TransactionChainHandler;
25 import org.opendaylight.restconf.restful.services.api.RestconfDataService;
26 import org.opendaylight.restconf.restful.transaction.TransactionVarsWrapper;
27 import org.opendaylight.restconf.restful.utils.DeleteDataTransactionUtil;
28 import org.opendaylight.restconf.restful.utils.PatchDataTransactionUtil;
29 import org.opendaylight.restconf.restful.utils.PostDataTransactionUtil;
30 import org.opendaylight.restconf.restful.utils.PutDataTransactionUtil;
31 import org.opendaylight.restconf.restful.utils.ReadDataTransactionUtil;
32 import org.opendaylight.restconf.restful.utils.RestconfDataServiceConstant;
33 import org.opendaylight.restconf.utils.parser.ParserIdentifier;
34 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
35 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * Implementation of {@link RestconfDataService}
41  */
42 public class RestconfDataServiceImpl implements RestconfDataService {
43
44     private final static Logger LOG = LoggerFactory.getLogger(RestconfDataServiceImpl.class);
45
46     private final SchemaContextHandler schemaContextHandler;
47     private final TransactionChainHandler transactionChainHandler;
48
49     public RestconfDataServiceImpl(final SchemaContextHandler schemaContextHandler,
50             final TransactionChainHandler transactionChainHandler) {
51         this.schemaContextHandler = schemaContextHandler;
52         this.transactionChainHandler = transactionChainHandler;
53     }
54
55     @Override
56     public NormalizedNodeContext readData(final String identifier, final UriInfo uriInfo) {
57         Preconditions.checkNotNull(identifier);
58         final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
59
60         final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(identifier, schemaContextRef.get());
61         final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
62         final String value = uriInfo.getQueryParameters().getFirst(RestconfDataServiceConstant.CONTENT);
63
64         DOMDataReadWriteTransaction transaction = null;
65         if (mountPoint == null) {
66             transaction = this.transactionChainHandler.get().newReadWriteTransaction();
67         } else {
68             transaction = transactionOfMountPoint(mountPoint);
69         }
70         final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(instanceIdentifier, mountPoint,
71                 transaction);
72         final NormalizedNode<?, ?> node = ReadDataTransactionUtil.readData(value, transactionNode);
73
74         return new NormalizedNodeContext(instanceIdentifier, node);
75     }
76
77     @Override
78     public Response putData(final String identifier, final NormalizedNodeContext payload) {
79         Preconditions.checkNotNull(identifier);
80         Preconditions.checkNotNull(payload);
81
82         final InstanceIdentifierContext<? extends SchemaNode> iid = payload
83                 .getInstanceIdentifierContext();
84
85         PutDataTransactionUtil.validInputData(iid.getSchemaNode(), payload);
86         PutDataTransactionUtil.validTopLevelNodeName(iid.getInstanceIdentifier(), payload);
87         PutDataTransactionUtil.validateListKeysEqualityInPayloadAndUri(payload);
88
89         final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
90         DOMDataReadWriteTransaction transaction = null;
91         SchemaContextRef ref = null;
92         if (mountPoint == null) {
93             transaction = this.transactionChainHandler.get().newReadWriteTransaction();
94             ref = new SchemaContextRef(this.schemaContextHandler.get());
95         } else {
96             transaction = transactionOfMountPoint(mountPoint);
97             ref = new SchemaContextRef(mountPoint.getSchemaContext());
98         }
99
100         final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
101                 payload.getInstanceIdentifierContext(), mountPoint, transaction);
102         return PutDataTransactionUtil.putData(payload, ref, transactionNode);
103     }
104
105     @Override
106     public Response postData(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
107         return postData(payload, uriInfo);
108     }
109
110     @Override
111     public Response postData(final NormalizedNodeContext payload, final UriInfo uriInfo) {
112         Preconditions.checkNotNull(payload);
113
114         final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
115         DOMDataReadWriteTransaction transaction = null;
116         SchemaContextRef ref = null;
117         if (mountPoint == null) {
118             transaction = this.transactionChainHandler.get().newReadWriteTransaction();
119             ref = new SchemaContextRef(this.schemaContextHandler.get());
120         } else {
121             transaction = transactionOfMountPoint(mountPoint);
122             ref = new SchemaContextRef(mountPoint.getSchemaContext());
123         }
124         final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
125                 payload.getInstanceIdentifierContext(), mountPoint, transaction);
126         return PostDataTransactionUtil.postData(uriInfo, payload, transactionNode, ref);
127     }
128
129     @Override
130     public Response deleteData(final String identifier) {
131         final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
132         final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(identifier,
133                 schemaContextRef.get());
134
135         final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
136         final DOMDataReadWriteTransaction transaction;
137         if (mountPoint == null) {
138             transaction = this.transactionChainHandler.get().newReadWriteTransaction();
139         } else {
140             transaction = transactionOfMountPoint(mountPoint);
141         }
142
143         final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(instanceIdentifier, mountPoint,
144                 transaction);
145         return DeleteDataTransactionUtil.deleteData(transactionNode);
146     }
147
148     @Override
149     public PATCHStatusContext patchData(final String identifier, final PATCHContext context, final UriInfo uriInfo) {
150         Preconditions.checkNotNull(identifier);
151         return patchData(context, uriInfo);
152     }
153
154     @Override
155     public PATCHStatusContext patchData(final PATCHContext context, final UriInfo uriInfo) {
156         Preconditions.checkNotNull(context);
157         final DOMMountPoint mountPoint = context.getInstanceIdentifierContext().getMountPoint();
158
159         final DOMDataReadWriteTransaction transaction;
160         final SchemaContextRef ref;
161         if (mountPoint == null) {
162             transaction = this.transactionChainHandler.get().newReadWriteTransaction();
163             ref = new SchemaContextRef(this.schemaContextHandler.get());
164         } else {
165             transaction = transactionOfMountPoint(mountPoint);
166             ref = new SchemaContextRef(mountPoint.getSchemaContext());
167         }
168
169         final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
170                 context.getInstanceIdentifierContext(), mountPoint, transaction);
171
172         return PatchDataTransactionUtil.patchData(context, transactionNode, ref);
173     }
174
175     /**
176      * Prepare transaction to read data of mount point, if these data are
177      * present.
178      * @param mountPoint
179      * @return {@link DOMDataReadWriteTransaction}
180      */
181     private static DOMDataReadWriteTransaction transactionOfMountPoint(final DOMMountPoint mountPoint) {
182         final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
183         if (domDataBrokerService.isPresent()) {
184             return domDataBrokerService.get().newReadWriteTransaction();
185         } else {
186             final String errMsg = "DOM data broker service isn't available for mount point "
187                     + mountPoint.getIdentifier();
188             LOG.warn(errMsg);
189             throw new RestconfDocumentedException(errMsg);
190         }
191     }
192 }