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.io.IOException;
23  import java.util.List;
24  
25  import org.apache.helix.HelixDataAccessor;
26  import org.apache.helix.HelixException;
27  import org.apache.helix.ZNRecord;
28  import org.apache.helix.PropertyKey.Builder;
29  import org.apache.helix.manager.zk.ZkClient;
30  import org.apache.helix.model.LiveInstance;
31  import org.apache.helix.tools.ClusterSetup;
32  import org.apache.helix.webapp.RestAdminApplication;
33  import org.codehaus.jackson.JsonGenerationException;
34  import org.codehaus.jackson.map.JsonMappingException;
35  import org.restlet.Context;
36  import org.restlet.data.MediaType;
37  import org.restlet.data.Request;
38  import org.restlet.data.Response;
39  import org.restlet.data.Status;
40  import org.restlet.resource.Representation;
41  import org.restlet.resource.Resource;
42  import org.restlet.resource.StringRepresentation;
43  import org.restlet.resource.Variant;
44  
45  
46  public class ClusterResource extends Resource
47  {
48    public ClusterResource(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    @Override
80    public Representation represent(Variant variant)
81    {
82      StringRepresentation presentation = null;
83      try
84      {
85        String clusterName = (String) getRequest().getAttributes().get("clusterName");
86        presentation = getClusterRepresentation(clusterName);
87      }
88  
89      catch (Exception e)
90      {
91        String error = ClusterRepresentationUtil.getErrorAsJsonStringFromException(e);
92        presentation = new StringRepresentation(error, MediaType.APPLICATION_JSON);
93  
94        e.printStackTrace();
95      }
96      return presentation;
97    }
98  
99    StringRepresentation getClusterRepresentation(String clusterName) throws JsonGenerationException,
100       JsonMappingException,
101       IOException
102   {
103     ZkClient zkClient =
104         (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
105     ClusterSetup setupTool = new ClusterSetup(zkClient);
106     List<String> instances =
107         setupTool.getClusterManagementTool().getInstancesInCluster(clusterName);
108 
109     ZNRecord clusterSummayRecord = new ZNRecord("Cluster Summary");
110     clusterSummayRecord.setListField("participants", instances);
111 
112     List<String> resources =
113         setupTool.getClusterManagementTool().getResourcesInCluster(clusterName);
114     clusterSummayRecord.setListField("resources", resources);
115 
116     List<String> models =
117         setupTool.getClusterManagementTool().getStateModelDefs(clusterName);
118     clusterSummayRecord.setListField("stateModelDefs", models);
119 
120     HelixDataAccessor accessor =
121         ClusterRepresentationUtil.getClusterDataAccessor(zkClient, clusterName);
122     Builder keyBuilder = accessor.keyBuilder();
123 
124     LiveInstance leader = accessor.getProperty(keyBuilder.controllerLeader());
125     if (leader != null)
126     {
127       clusterSummayRecord.setSimpleField("LEADER", leader.getInstanceName());
128     }
129     else
130     {
131       clusterSummayRecord.setSimpleField("LEADER", "");
132     }
133     StringRepresentation representation =
134         new StringRepresentation(ClusterRepresentationUtil.ZNRecordToJson(clusterSummayRecord),
135                                  MediaType.APPLICATION_JSON);
136 
137     return representation;
138   }
139 
140   @Override
141   public void acceptRepresentation(Representation entity)
142   {
143     try
144     {
145       String clusterName = (String) getRequest().getAttributes().get("clusterName");
146       ZkClient zkClient =
147           (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
148       ClusterSetup setupTool = new ClusterSetup(zkClient);
149 
150       JsonParameters jsonParameters = new JsonParameters(entity);
151       String command = jsonParameters.getCommand();
152 
153       if (command == null)
154       {
155         throw new HelixException("Could NOT find 'command' in parameterMap: " + jsonParameters._parameterMap);
156       }
157       else if (command.equalsIgnoreCase(ClusterSetup.activateCluster)
158           || JsonParameters.CLUSTERSETUP_COMMAND_ALIASES.get(ClusterSetup.activateCluster)
159                                                         .contains(command))
160       {
161         jsonParameters.verifyCommand(ClusterSetup.activateCluster);
162 
163         boolean enabled = true;
164         if (jsonParameters.getParameter(JsonParameters.ENABLED) != null)
165         {
166           enabled =
167               Boolean.parseBoolean(jsonParameters.getParameter(JsonParameters.ENABLED));
168         }
169 
170         String grandCluster = jsonParameters.getParameter(JsonParameters.GRAND_CLUSTER);
171 
172         setupTool.activateCluster(clusterName, grandCluster, enabled);
173       }
174       else if (command.equalsIgnoreCase(ClusterSetup.expandCluster))
175       {
176         setupTool.expandCluster(clusterName);
177       }
178       else
179       {
180         throw new HelixException("Unsupported command: " + command
181             + ". Should be one of [" + ClusterSetup.activateCluster + ", "
182             + ClusterSetup.expandCluster + "]");
183       }
184       getResponse().setEntity(getClusterRepresentation(clusterName));
185       getResponse().setStatus(Status.SUCCESS_OK);
186     }
187     catch (Exception e)
188     {
189       getResponse().setEntity(ClusterRepresentationUtil.getErrorAsJsonStringFromException(e),
190                               MediaType.APPLICATION_JSON);
191       getResponse().setStatus(Status.SUCCESS_OK);
192     }
193   }
194 
195   @Override
196   public void removeRepresentations()
197   {
198     try
199     {
200       String clusterName = (String) getRequest().getAttributes().get("clusterName");
201       ZkClient zkClient =
202           (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
203       ClusterSetup setupTool = new ClusterSetup(zkClient);
204       setupTool.deleteCluster(clusterName);
205       getResponse().setStatus(Status.SUCCESS_OK);
206     }
207     catch (Exception e)
208     {
209       getResponse().setEntity(ClusterRepresentationUtil.getErrorAsJsonStringFromException(e),
210                               MediaType.APPLICATION_JSON);
211       getResponse().setStatus(Status.SUCCESS_OK);
212     }
213   }
214 }