View Javadoc

1   package org.apache.helix.webapp.resources;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Date;
23  import java.util.List;
24  
25  import org.apache.helix.HelixException;
26  import org.apache.helix.ZNRecord;
27  import org.apache.helix.manager.zk.ZkBaseDataAccessor;
28  import org.apache.helix.manager.zk.ZkClient;
29  import org.apache.helix.tools.ClusterSetup;
30  import org.apache.helix.webapp.RestAdminApplication;
31  import org.apache.log4j.Logger;
32  import org.apache.zookeeper.data.Stat;
33  import org.restlet.Context;
34  import org.restlet.data.MediaType;
35  import org.restlet.data.Request;
36  import org.restlet.data.Response;
37  import org.restlet.data.Status;
38  import org.restlet.resource.Representation;
39  import org.restlet.resource.Resource;
40  import org.restlet.resource.StringRepresentation;
41  import org.restlet.resource.Variant;
42  
43  
44  public class ZkPathResource extends Resource
45  {
46    private final static Logger LOG = Logger.getLogger(ZkPathResource.class);
47  
48    public ZkPathResource(Context context, Request request, Response response)
49    {
50      super(context, request, response);
51      getVariants().add(new Variant(MediaType.TEXT_PLAIN));
52      getVariants().add(new Variant(MediaType.APPLICATION_JSON));
53    }
54  
55    @Override
56    public boolean allowGet()
57    {
58      return true;
59    }
60  
61    @Override
62    public boolean allowPost()
63    {
64      return true;
65    }
66  
67    @Override
68    public boolean allowPut()
69    {
70      return false;
71    }
72  
73    @Override
74    public boolean allowDelete()
75    {
76      return true;
77    }
78  
79    private String getZKPath()
80    {
81      String relativeRef = getRequest().getResourceRef().getRelativeRef().toString();
82      if (relativeRef.equals("."))
83      {
84        relativeRef = "";
85      }
86  
87      // strip off trailing "/"
88      while (relativeRef.endsWith("/"))
89      {
90        relativeRef = relativeRef.substring(0, relativeRef.length() - 1);
91      }
92  
93      return "/" + relativeRef;
94    }
95  
96    @Override
97    public void acceptRepresentation(Representation entity)
98    {
99      String zkPath = getZKPath();
100 
101     try
102     {
103       JsonParameters jsonParameters = new JsonParameters(entity);
104       String command = jsonParameters.getCommand();
105 
106       ZkClient zkClient =
107           (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
108       
109       if (command.equalsIgnoreCase(JsonParameters.ZK_DELETE_CHILDREN))
110       {
111         List<String> childNames = zkClient.getChildren(zkPath);
112         if (childNames != null)
113         {
114           for (String childName : childNames)
115           {
116             String childPath = zkPath.equals("/")? "/" + childName : zkPath + "/" + childName;
117             zkClient.deleteRecursive(childPath);
118           }
119         }
120       }
121       else
122       {
123         throw new HelixException("Unsupported command: " + command
124             + ". Should be one of [" + JsonParameters.ZK_DELETE_CHILDREN + "]");
125       }
126 
127       getResponse().setStatus(Status.SUCCESS_OK);
128     }
129     catch (Exception e)
130     {
131       getResponse().setEntity(ClusterRepresentationUtil.getErrorAsJsonStringFromException(e),
132                               MediaType.APPLICATION_JSON);
133       getResponse().setStatus(Status.SUCCESS_OK);
134       LOG.error("Error in post zkPath: " + zkPath, e);
135     }
136   }
137 
138   @Override
139   public Representation represent(Variant variant)
140   {
141     StringRepresentation presentation = null;
142     String zkPath = getZKPath();
143 
144     try
145     {
146       ZkClient zkClient =
147           (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
148       ZNRecord result = readZkDataStatAndChild(zkPath, zkClient);
149 
150       presentation =
151           new StringRepresentation(ClusterRepresentationUtil.ZNRecordToJson(result),
152                                    MediaType.APPLICATION_JSON);
153     }
154     catch (Exception e)
155     {
156       String error = ClusterRepresentationUtil.getErrorAsJsonStringFromException(e);
157       presentation = new StringRepresentation(error, MediaType.APPLICATION_JSON);
158 
159       LOG.error("Error in read zkPath: " + zkPath, e);
160     }
161 
162     return presentation;
163   }
164 
165   private ZNRecord readZkDataStatAndChild(String zkPath, ZkClient zkClient)
166   {
167     ZNRecord result = null;
168 
169     // read data and stat
170     Stat stat = new Stat();
171     ZNRecord data = zkClient.readDataAndStat(zkPath, stat, true);
172     if (data != null)
173     {
174       result = data;
175     }
176     else
177     {
178       result = new ZNRecord("");
179     }
180     result.setSimpleField("zkPath", zkPath);
181     result.setSimpleField("stat", stat.toString());
182     result.setSimpleField("numChildren", "" + stat.getNumChildren());
183     result.setSimpleField("ctime", "" + new Date(stat.getCtime()));
184     result.setSimpleField("mtime", "" + new Date(stat.getMtime()));
185     result.setSimpleField("dataLength", "" + stat.getDataLength());
186 
187     // read childrenList
188     List<String> children = zkClient.getChildren(zkPath);
189     if (children != null && children.size() > 0)
190     {
191       result.setListField("childrenList", children);
192     }
193     return result;
194   }
195 
196   @Override
197   public void removeRepresentations()
198   {
199     String zkPath = getZKPath();
200     try
201     {
202       ZkClient zkClient =
203           (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
204       zkClient.deleteRecursive(zkPath);
205       
206       getResponse().setStatus(Status.SUCCESS_OK);
207     }
208     catch (Exception e)
209     {
210       getResponse().setEntity(ClusterRepresentationUtil.getErrorAsJsonStringFromException(e),
211                               MediaType.APPLICATION_JSON);
212       getResponse().setStatus(Status.SUCCESS_OK);
213       LOG.error("Error in delete zkPath: " + zkPath, e);
214     }
215   }
216 
217 }