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.text.DateFormat;
24  import java.text.SimpleDateFormat;
25  import java.util.Date;
26  import java.util.Map;
27  import java.util.TreeMap;
28  
29  import org.apache.helix.HelixException;
30  import org.apache.helix.PropertyKey;
31  import org.apache.helix.PropertyKey.Builder;
32  import org.apache.helix.PropertyType;
33  import org.apache.helix.ZNRecord;
34  import org.apache.helix.manager.zk.ZKHelixDataAccessor;
35  import org.apache.helix.manager.zk.ZkBaseDataAccessor;
36  import org.apache.helix.manager.zk.ZkClient;
37  import org.apache.helix.model.LiveInstance;
38  import org.apache.helix.tools.ClusterSetup;
39  import org.apache.helix.util.StatusUpdateUtil.Level;
40  import org.apache.helix.webapp.RestAdminApplication;
41  import org.codehaus.jackson.JsonGenerationException;
42  import org.codehaus.jackson.map.JsonMappingException;
43  import org.restlet.Context;
44  import org.restlet.data.MediaType;
45  import org.restlet.data.Request;
46  import org.restlet.data.Response;
47  import org.restlet.data.Status;
48  import org.restlet.resource.Representation;
49  import org.restlet.resource.Resource;
50  import org.restlet.resource.StringRepresentation;
51  import org.restlet.resource.Variant;
52  
53  public class ControllerResource extends Resource
54  {
55  
56    public ControllerResource(Context context, Request request, Response response)
57  
58    {
59      super(context, request, response);
60      getVariants().add(new Variant(MediaType.TEXT_PLAIN));
61      getVariants().add(new Variant(MediaType.APPLICATION_JSON));
62    }
63  
64    @Override
65    public boolean allowGet()
66    {
67      return true;
68    }
69  
70    @Override
71    public boolean allowPost()
72    {
73      return true;
74    }
75  
76    @Override
77    public boolean allowPut()
78    {
79      return false;
80    }
81  
82    @Override
83    public boolean allowDelete()
84    {
85      return false;
86    }
87  
88    StringRepresentation getControllerRepresentation(String clusterName) throws JsonGenerationException,
89        JsonMappingException,
90        IOException
91    {
92      Builder keyBuilder = new PropertyKey.Builder(clusterName);
93      ZkClient zkClient =
94          (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
95  
96      ZKHelixDataAccessor accessor =
97          new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<ZNRecord>(zkClient));
98  
99      ZNRecord record = null;
100     LiveInstance leader = accessor.getProperty(keyBuilder.controllerLeader());
101     if (leader != null)
102     {
103       record = leader.getRecord();
104     }
105     else
106     {
107       record = new ZNRecord("");
108       DateFormat formatter = new SimpleDateFormat("yyyyMMdd-HHmmss.SSSSSS");
109       String time = formatter.format(new Date());
110       Map<String, String> contentMap = new TreeMap<String, String>();
111       contentMap.put("AdditionalInfo", "No leader exists");
112       record.setMapField(Level.HELIX_INFO + "-" + time, contentMap);
113     }
114 
115     boolean paused = (accessor.getProperty(keyBuilder.pause()) == null ? false : true);
116     record.setSimpleField(PropertyType.PAUSE.toString(), "" + paused);
117 
118     String retVal = ClusterRepresentationUtil.ZNRecordToJson(record);
119     StringRepresentation representation =
120         new StringRepresentation(retVal, MediaType.APPLICATION_JSON);
121 
122     return representation;
123   }
124 
125   @Override
126   public Representation represent(Variant variant)
127   {
128     StringRepresentation presentation = null;
129     try
130     {
131       String clusterName = (String) getRequest().getAttributes().get("clusterName");
132       presentation = getControllerRepresentation(clusterName);
133     }
134     catch (Exception e)
135     {
136       String error = ClusterRepresentationUtil.getErrorAsJsonStringFromException(e);
137       presentation = new StringRepresentation(error, MediaType.APPLICATION_JSON);
138       e.printStackTrace();
139     }
140     return presentation;
141   }
142 
143   @Override
144   public void acceptRepresentation(Representation entity)
145   {
146     try
147     {
148       String clusterName = (String) getRequest().getAttributes().get("clusterName");
149       ZkClient zkClient =
150           (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
151       ClusterSetup setupTool = new ClusterSetup(zkClient);
152 
153       JsonParameters jsonParameters = new JsonParameters(entity);
154       String command = jsonParameters.getCommand();
155 
156       if (command == null)
157       {
158         throw new HelixException("Could NOT find 'command' in parameterMap: "
159             + jsonParameters._parameterMap);
160       }
161       else if (command.equalsIgnoreCase(ClusterSetup.enableCluster))
162       {
163         boolean enabled =
164             Boolean.parseBoolean(jsonParameters.getParameter(JsonParameters.ENABLED));
165 
166         setupTool.getClusterManagementTool().enableCluster(clusterName, enabled);
167       }
168       else
169       {
170         throw new HelixException("Unsupported command: " + command
171             + ". Should be one of [" + ClusterSetup.enableCluster + "]");
172       }
173 
174       getResponse().setEntity(getControllerRepresentation(clusterName));
175       getResponse().setStatus(Status.SUCCESS_OK);
176 
177     }
178     catch (Exception e)
179     {
180       getResponse().setEntity(ClusterRepresentationUtil.getErrorAsJsonStringFromException(e),
181                               MediaType.APPLICATION_JSON);
182       getResponse().setStatus(Status.SUCCESS_OK);
183     }
184   }
185 }