2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.restconf.restful.services.impl;
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import java.text.SimpleDateFormat;
13 import java.util.TimeZone;
14 import javax.ws.rs.core.Response;
15 import javax.ws.rs.core.UriInfo;
16 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
17 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
18 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
19 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
20 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
21 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
22 import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
23 import org.opendaylight.netconf.sal.restconf.impl.PATCHStatusContext;
24 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
25 import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
26 import org.opendaylight.restconf.RestConnectorProvider;
27 import org.opendaylight.restconf.common.references.SchemaContextRef;
28 import org.opendaylight.restconf.handlers.SchemaContextHandler;
29 import org.opendaylight.restconf.handlers.TransactionChainHandler;
30 import org.opendaylight.restconf.restful.services.api.RestconfDataService;
31 import org.opendaylight.restconf.restful.transaction.TransactionVarsWrapper;
32 import org.opendaylight.restconf.restful.utils.DeleteDataTransactionUtil;
33 import org.opendaylight.restconf.restful.utils.PatchDataTransactionUtil;
34 import org.opendaylight.restconf.restful.utils.PostDataTransactionUtil;
35 import org.opendaylight.restconf.restful.utils.PutDataTransactionUtil;
36 import org.opendaylight.restconf.restful.utils.ReadDataTransactionUtil;
37 import org.opendaylight.restconf.restful.utils.RestconfDataServiceConstant;
38 import org.opendaylight.restconf.utils.parser.ParserIdentifier;
39 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
40 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
45 * Implementation of {@link RestconfDataService}
47 public class RestconfDataServiceImpl implements RestconfDataService {
49 private final static Logger LOG = LoggerFactory.getLogger(RestconfDataServiceImpl.class);
51 private final SchemaContextHandler schemaContextHandler;
52 private final TransactionChainHandler transactionChainHandler;
54 public RestconfDataServiceImpl(final SchemaContextHandler schemaContextHandler,
55 final TransactionChainHandler transactionChainHandler) {
56 this.schemaContextHandler = schemaContextHandler;
57 this.transactionChainHandler = transactionChainHandler;
61 public Response readData(final String identifier, final UriInfo uriInfo) {
62 Preconditions.checkNotNull(identifier);
63 final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
65 final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(identifier,
66 schemaContextRef.get());
67 final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
68 final String value = uriInfo.getQueryParameters().getFirst(RestconfDataServiceConstant.CONTENT);
70 DOMTransactionChain transaction = null;
71 if (mountPoint == null) {
72 transaction = this.transactionChainHandler.get();
74 transaction = transactionOfMountPoint(mountPoint);
76 final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(instanceIdentifier, mountPoint,
78 final NormalizedNode<?, ?> node = ReadDataTransactionUtil.readData(value, transactionNode);
80 throw new RestconfDocumentedException(
81 "Request could not be completed because the relevant data model content does not exist",
82 RestconfError.ErrorType.PROTOCOL,
83 RestconfError.ErrorTag.DATA_MISSING);
85 final SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
86 dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
87 final String etag = '"' + node.getNodeType().getModule().getFormattedRevision()
88 + node.getNodeType().getLocalName() + '"';
91 if ((value == null) || value.contains(RestconfDataServiceConstant.ReadData.CONFIG)) {
92 resp = Response.status(200).entity(new NormalizedNodeContext(instanceIdentifier, node)).header("ETag", etag)
93 .header("Last-Modified", dateFormatGmt.toString()).build();
95 resp = Response.status(200).entity(new NormalizedNodeContext(instanceIdentifier, node)).build();
101 public Response putData(final String identifier, final NormalizedNodeContext payload) {
102 Preconditions.checkNotNull(identifier);
103 Preconditions.checkNotNull(payload);
105 final InstanceIdentifierContext<? extends SchemaNode> iid = payload
106 .getInstanceIdentifierContext();
108 PutDataTransactionUtil.validInputData(iid.getSchemaNode(), payload);
109 PutDataTransactionUtil.validTopLevelNodeName(iid.getInstanceIdentifier(), payload);
110 PutDataTransactionUtil.validateListKeysEqualityInPayloadAndUri(payload);
112 final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
113 DOMTransactionChain transaction = null;
114 SchemaContextRef ref = null;
115 if (mountPoint == null) {
116 transaction = this.transactionChainHandler.get();
117 ref = new SchemaContextRef(this.schemaContextHandler.get());
119 transaction = transactionOfMountPoint(mountPoint);
120 ref = new SchemaContextRef(mountPoint.getSchemaContext());
123 final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
124 payload.getInstanceIdentifierContext(), mountPoint, transaction);
125 return PutDataTransactionUtil.putData(payload, ref, transactionNode);
129 public Response postData(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
130 return postData(payload, uriInfo);
134 public Response postData(final NormalizedNodeContext payload, final UriInfo uriInfo) {
135 Preconditions.checkNotNull(payload);
137 final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
138 DOMTransactionChain transaction = null;
139 SchemaContextRef ref = null;
140 if (mountPoint == null) {
141 transaction = this.transactionChainHandler.get();
142 ref = new SchemaContextRef(this.schemaContextHandler.get());
144 transaction = transactionOfMountPoint(mountPoint);
145 ref = new SchemaContextRef(mountPoint.getSchemaContext());
147 final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
148 payload.getInstanceIdentifierContext(), mountPoint, transaction);
149 return PostDataTransactionUtil.postData(uriInfo, payload, transactionNode, ref);
153 public Response deleteData(final String identifier) {
154 final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
155 final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(identifier,
156 schemaContextRef.get());
158 final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
159 final DOMTransactionChain transaction;
160 if (mountPoint == null) {
161 transaction = this.transactionChainHandler.get();
163 transaction = transactionOfMountPoint(mountPoint);
166 final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(instanceIdentifier, mountPoint,
168 return DeleteDataTransactionUtil.deleteData(transactionNode);
172 public PATCHStatusContext patchData(final String identifier, final PATCHContext context, final UriInfo uriInfo) {
173 Preconditions.checkNotNull(identifier);
174 return patchData(context, uriInfo);
178 public PATCHStatusContext patchData(final PATCHContext context, final UriInfo uriInfo) {
179 Preconditions.checkNotNull(context);
180 final DOMMountPoint mountPoint = context.getInstanceIdentifierContext().getMountPoint();
182 final DOMTransactionChain transaction;
183 final SchemaContextRef ref;
184 if (mountPoint == null) {
185 transaction = this.transactionChainHandler.get();
186 ref = new SchemaContextRef(this.schemaContextHandler.get());
188 transaction = transactionOfMountPoint(mountPoint);
189 ref = new SchemaContextRef(mountPoint.getSchemaContext());
192 final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
193 context.getInstanceIdentifierContext(), mountPoint, transaction);
195 return PatchDataTransactionUtil.patchData(context, transactionNode, ref);
199 * Prepare transaction to read data of mount point, if these data are
202 * @return {@link DOMDataReadWriteTransaction}
204 private static DOMTransactionChain transactionOfMountPoint(final DOMMountPoint mountPoint) {
205 final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
206 if (domDataBrokerService.isPresent()) {
207 return domDataBrokerService.get().createTransactionChain(RestConnectorProvider.transactionListener);
209 final String errMsg = "DOM data broker service isn't available for mount point "
210 + mountPoint.getIdentifier();
212 throw new RestconfDocumentedException(errMsg);