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.LinkedList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.TreeMap;
27
28 import org.apache.helix.HelixDataAccessor;
29 import org.apache.helix.HelixException;
30 import org.apache.helix.manager.zk.ZkClient;
31 import org.apache.helix.model.InstanceConfig;
32 import org.apache.helix.model.LiveInstance;
33 import org.apache.helix.tools.ClusterSetup;
34 import org.apache.helix.webapp.RestAdminApplication;
35 import org.apache.log4j.Logger;
36 import org.codehaus.jackson.JsonGenerationException;
37 import org.codehaus.jackson.map.JsonMappingException;
38 import org.restlet.Context;
39 import org.restlet.data.MediaType;
40 import org.restlet.data.Request;
41 import org.restlet.data.Response;
42 import org.restlet.data.Status;
43 import org.restlet.resource.Representation;
44 import org.restlet.resource.Resource;
45 import org.restlet.resource.StringRepresentation;
46 import org.restlet.resource.Variant;
47
48
49 public class InstancesResource extends Resource
50 {
51 private final static Logger LOG = Logger.getLogger(InstancesResource.class);
52
53 public InstancesResource(Context context, Request request, Response response)
54 {
55 super(context, request, response);
56 getVariants().add(new Variant(MediaType.TEXT_PLAIN));
57 getVariants().add(new Variant(MediaType.APPLICATION_JSON));
58 }
59
60 @Override
61 public boolean allowGet()
62 {
63 return true;
64 }
65
66 @Override
67 public boolean allowPost()
68 {
69 return true;
70 }
71
72 @Override
73 public boolean allowPut()
74 {
75 return false;
76 }
77
78 @Override
79 public boolean allowDelete()
80 {
81 return false;
82 }
83
84 @Override
85 public Representation represent(Variant variant)
86 {
87 StringRepresentation presentation = null;
88 try
89 {
90 String clusterName = (String) getRequest().getAttributes().get("clusterName");
91 presentation = getInstancesRepresentation(clusterName);
92 }
93
94 catch (Exception e)
95 {
96 String error = ClusterRepresentationUtil.getErrorAsJsonStringFromException(e);
97 presentation = new StringRepresentation(error, MediaType.APPLICATION_JSON);
98
99 LOG.error("", e);
100 }
101 return presentation;
102 }
103
104 StringRepresentation getInstancesRepresentation(String clusterName) throws JsonGenerationException,
105 JsonMappingException,
106 IOException
107 {
108 ZkClient zkClient =
109 (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
110
111 HelixDataAccessor accessor =
112 ClusterRepresentationUtil.getClusterDataAccessor(zkClient, clusterName);
113 Map<String, LiveInstance> liveInstancesMap =
114 accessor.getChildValuesMap(accessor.keyBuilder().liveInstances());
115 Map<String, InstanceConfig> instanceConfigsMap =
116 accessor.getChildValuesMap(accessor.keyBuilder().instanceConfigs());
117
118 Map<String, List<String>> tagInstanceLists = new TreeMap<String, List<String>>();
119
120 for (String instanceName : instanceConfigsMap.keySet())
121 {
122 boolean isAlive = liveInstancesMap.containsKey(instanceName);
123 instanceConfigsMap.get(instanceName)
124 .getRecord()
125 .setSimpleField("Alive", isAlive + "");
126 InstanceConfig config = instanceConfigsMap.get(instanceName);
127 for(String tag : config.getTags())
128 {
129 if(!tagInstanceLists.containsKey(tag))
130 {
131 tagInstanceLists.put(tag, new LinkedList<String>());
132 }
133 if(!tagInstanceLists.get(tag).contains(instanceName))
134 {
135 tagInstanceLists.get(tag).add(instanceName);
136 }
137 }
138 }
139
140 StringRepresentation representation =
141 new StringRepresentation(ClusterRepresentationUtil.ObjectToJson(instanceConfigsMap.values()) + ClusterRepresentationUtil.ObjectToJson(tagInstanceLists),
142 MediaType.APPLICATION_JSON);
143
144 return representation;
145 }
146
147 @Override
148 public void acceptRepresentation(Representation entity)
149 {
150 try
151 {
152 String clusterName = (String) getRequest().getAttributes().get("clusterName");
153 JsonParameters jsonParameters = new JsonParameters(entity);
154 String command = jsonParameters.getCommand();
155
156 ZkClient zkClient =
157 (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
158 ClusterSetup setupTool = new ClusterSetup(zkClient);
159
160 if (command.equalsIgnoreCase(ClusterSetup.addInstance)
161 || JsonParameters.CLUSTERSETUP_COMMAND_ALIASES.get(ClusterSetup.addInstance)
162 .contains(command))
163 {
164 if (jsonParameters.getParameter(JsonParameters.INSTANCE_NAME) != null)
165 {
166 setupTool.addInstanceToCluster(clusterName,
167 jsonParameters.getParameter(JsonParameters.INSTANCE_NAME));
168 }
169 else if (jsonParameters.getParameter(JsonParameters.INSTANCE_NAMES) != null)
170 {
171 setupTool.addInstancesToCluster(clusterName,
172 jsonParameters.getParameter(JsonParameters.INSTANCE_NAMES)
173 .split(";"));
174 }
175 else
176 {
177 throw new HelixException("Missing Json paramaters: '"
178 + JsonParameters.INSTANCE_NAME + "' or '" + JsonParameters.INSTANCE_NAMES
179 + "' ");
180 }
181 }
182 else if (command.equalsIgnoreCase(ClusterSetup.swapInstance))
183 {
184 if (jsonParameters.getParameter(JsonParameters.NEW_INSTANCE) == null
185 || jsonParameters.getParameter(JsonParameters.OLD_INSTANCE) == null)
186 {
187 throw new HelixException("Missing Json paramaters: '"
188 + JsonParameters.NEW_INSTANCE + "' or '" + JsonParameters.OLD_INSTANCE
189 + "' ");
190 }
191 setupTool.swapInstance(clusterName,
192 jsonParameters.getParameter(JsonParameters.OLD_INSTANCE),
193 jsonParameters.getParameter(JsonParameters.NEW_INSTANCE));
194 }
195 else
196 {
197 throw new HelixException("Unsupported command: " + command
198 + ". Should be one of [" + ClusterSetup.addInstance + ", "
199 + ClusterSetup.swapInstance + "]");
200 }
201
202 getResponse().setEntity(getInstancesRepresentation(clusterName));
203 getResponse().setStatus(Status.SUCCESS_OK);
204 }
205 catch (Exception e)
206 {
207 getResponse().setEntity(ClusterRepresentationUtil.getErrorAsJsonStringFromException(e),
208 MediaType.APPLICATION_JSON);
209 getResponse().setStatus(Status.SUCCESS_OK);
210 LOG.error("", e);
211 }
212 }
213 }