1 package org.apache.helix.webapp.resources;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 }