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.Date;
14 import java.util.TimeZone;
15 import javax.annotation.Nonnull;
16 import javax.ws.rs.core.Response;
17 import javax.ws.rs.core.UriInfo;
18 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
19 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
20 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
21 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
22 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
23 import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
24 import org.opendaylight.netconf.sal.restconf.impl.PATCHStatusContext;
25 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
26 import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
27 import org.opendaylight.netconf.sal.restconf.impl.WriterParameters;
28 import org.opendaylight.restconf.RestConnectorProvider;
29 import org.opendaylight.restconf.common.references.SchemaContextRef;
30 import org.opendaylight.restconf.handlers.DOMMountPointServiceHandler;
31 import org.opendaylight.restconf.handlers.SchemaContextHandler;
32 import org.opendaylight.restconf.handlers.TransactionChainHandler;
33 import org.opendaylight.restconf.restful.services.api.RestconfDataService;
34 import org.opendaylight.restconf.restful.transaction.TransactionVarsWrapper;
35 import org.opendaylight.restconf.restful.utils.DeleteDataTransactionUtil;
36 import org.opendaylight.restconf.restful.utils.PatchDataTransactionUtil;
37 import org.opendaylight.restconf.restful.utils.PostDataTransactionUtil;
38 import org.opendaylight.restconf.restful.utils.PutDataTransactionUtil;
39 import org.opendaylight.restconf.restful.utils.ReadDataTransactionUtil;
40 import org.opendaylight.restconf.restful.utils.RestconfDataServiceConstant;
41 import org.opendaylight.restconf.utils.parser.ParserIdentifier;
42 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
43 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
48 * Implementation of {@link RestconfDataService}
50 public class RestconfDataServiceImpl implements RestconfDataService {
52 private final static Logger LOG = LoggerFactory.getLogger(RestconfDataServiceImpl.class);
54 private final SchemaContextHandler schemaContextHandler;
55 private final TransactionChainHandler transactionChainHandler;
56 private final DOMMountPointServiceHandler mountPointServiceHandler;
58 public RestconfDataServiceImpl(final SchemaContextHandler schemaContextHandler,
59 final TransactionChainHandler transactionChainHandler,
60 final DOMMountPointServiceHandler mountPointServiceHandler) {
61 this.schemaContextHandler = schemaContextHandler;
62 this.transactionChainHandler = transactionChainHandler;
63 this.mountPointServiceHandler = mountPointServiceHandler;
67 public Response readData(final UriInfo uriInfo) {
68 return readData(null, uriInfo);
72 public Response readData(final String identifier, final UriInfo uriInfo) {
73 final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
74 final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(
75 identifier, schemaContextRef.get(), Optional.of(this.mountPointServiceHandler.get()));
77 final WriterParameters parameters = ReadDataTransactionUtil.parseUriParameters(
78 instanceIdentifier, uriInfo);
80 final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
81 final DOMTransactionChain transactionChain;
82 if (mountPoint == null) {
83 transactionChain = this.transactionChainHandler.get();
85 transactionChain = transactionChainOfMountPoint(mountPoint);
88 final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
89 instanceIdentifier, mountPoint, transactionChain);
90 final NormalizedNode<?, ?> node = ReadDataTransactionUtil.readData(parameters.getContent(), transactionNode);
92 throw new RestconfDocumentedException(
93 "Request could not be completed because the relevant data model content does not exist",
94 RestconfError.ErrorType.PROTOCOL,
95 RestconfError.ErrorTag.DATA_MISSING);
97 final SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
98 dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
99 final String etag = '"' + node.getNodeType().getModule().getFormattedRevision()
100 + node.getNodeType().getLocalName() + '"';
103 if ((parameters.getContent().equals(RestconfDataServiceConstant.ReadData.ALL))
104 || parameters.getContent().equals(RestconfDataServiceConstant.ReadData.CONFIG)) {
105 resp = Response.status(200)
106 .entity(new NormalizedNodeContext(instanceIdentifier, node, parameters))
107 .header("ETag", etag)
108 .header("Last-Modified", dateFormatGmt.format(new Date()))
111 resp = Response.status(200)
112 .entity(new NormalizedNodeContext(instanceIdentifier, node, parameters))
120 public Response putData(final String identifier, final NormalizedNodeContext payload) {
121 Preconditions.checkNotNull(payload);
123 final InstanceIdentifierContext<? extends SchemaNode> iid = payload
124 .getInstanceIdentifierContext();
126 PutDataTransactionUtil.validInputData(iid.getSchemaNode(), payload);
127 PutDataTransactionUtil.validTopLevelNodeName(iid.getInstanceIdentifier(), payload);
128 PutDataTransactionUtil.validateListKeysEqualityInPayloadAndUri(payload);
130 final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
131 final DOMTransactionChain transactionChain;
132 final SchemaContextRef ref;
133 if (mountPoint == null) {
134 transactionChain = this.transactionChainHandler.get();
135 ref = new SchemaContextRef(this.schemaContextHandler.get());
137 transactionChain = transactionChainOfMountPoint(mountPoint);
138 ref = new SchemaContextRef(mountPoint.getSchemaContext());
141 final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
142 payload.getInstanceIdentifierContext(), mountPoint, transactionChain);
143 return PutDataTransactionUtil.putData(payload, ref, transactionNode);
147 public Response postData(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
148 return postData(payload, uriInfo);
152 public Response postData(final NormalizedNodeContext payload, final UriInfo uriInfo) {
153 Preconditions.checkNotNull(payload);
155 final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
156 final DOMTransactionChain transactionChain;
157 final SchemaContextRef ref;
158 if (mountPoint == null) {
159 transactionChain = this.transactionChainHandler.get();
160 ref = new SchemaContextRef(this.schemaContextHandler.get());
162 transactionChain = transactionChainOfMountPoint(mountPoint);
163 ref = new SchemaContextRef(mountPoint.getSchemaContext());
165 final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
166 payload.getInstanceIdentifierContext(), mountPoint, transactionChain);
167 return PostDataTransactionUtil.postData(uriInfo, payload, transactionNode, ref);
171 public Response deleteData(final String identifier) {
172 final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
173 final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(
174 identifier, schemaContextRef.get(), Optional.of(this.mountPointServiceHandler.get()));
176 final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
177 final DOMTransactionChain transactionChain;
178 if (mountPoint == null) {
179 transactionChain = this.transactionChainHandler.get();
181 transactionChain = transactionChainOfMountPoint(mountPoint);
184 final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(instanceIdentifier, mountPoint,
186 return DeleteDataTransactionUtil.deleteData(transactionNode);
190 public PATCHStatusContext patchData(final String identifier, final PATCHContext context, final UriInfo uriInfo) {
191 return patchData(context, uriInfo);
195 public PATCHStatusContext patchData(final PATCHContext context, final UriInfo uriInfo) {
196 Preconditions.checkNotNull(context);
197 final DOMMountPoint mountPoint = context.getInstanceIdentifierContext().getMountPoint();
199 final DOMTransactionChain transactionChain;
200 final SchemaContextRef ref;
201 if (mountPoint == null) {
202 transactionChain = this.transactionChainHandler.get();
203 ref = new SchemaContextRef(this.schemaContextHandler.get());
205 transactionChain = transactionChainOfMountPoint(mountPoint);
206 ref = new SchemaContextRef(mountPoint.getSchemaContext());
209 final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
210 context.getInstanceIdentifierContext(), mountPoint, transactionChain);
212 return PatchDataTransactionUtil.patchData(context, transactionNode, ref);
216 * Prepare transaction chain to access data of mount point
218 * - mount point reference
219 * @return {@link DOMTransactionChain}
221 private static DOMTransactionChain transactionChainOfMountPoint(@Nonnull final DOMMountPoint mountPoint) {
222 final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
223 if (domDataBrokerService.isPresent()) {
224 return domDataBrokerService.get().createTransactionChain(RestConnectorProvider.transactionListener);
226 final String errMsg = "DOM data broker service isn't available for mount point "
227 + mountPoint.getIdentifier();
229 throw new RestconfDocumentedException(errMsg);