| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.hadoop.tools.rumen.datatypes; |
| |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.tools.rumen.ParsedHost; |
| import org.apache.hadoop.tools.rumen.anonymization.WordList; |
| import org.apache.hadoop.tools.rumen.state.State; |
| import org.apache.hadoop.tools.rumen.state.StatePool; |
| import org.codehaus.jackson.annotate.JsonIgnore; |
| |
| /** |
| * Represents the cluster host. |
| */ |
| public class NodeName implements AnonymizableDataType<String> { |
| private String hostName; |
| private String rackName; |
| private String nodeName; |
| private String anonymizedNodeName; |
| |
| public static final NodeName ROOT = new NodeName("<root>"); |
| |
| /** |
| * A composite state for node-name. |
| */ |
| public static class NodeNameState implements State { |
| private WordList rackNameState = new WordList("rack"); |
| private WordList hostNameState = new WordList("host"); |
| |
| @Override |
| @JsonIgnore |
| public boolean isUpdated() { |
| return rackNameState.isUpdated() || hostNameState.isUpdated(); |
| } |
| |
| public WordList getRackNameState() { |
| return rackNameState; |
| } |
| |
| public WordList getHostNameState() { |
| return hostNameState; |
| } |
| |
| public void setRackNameState(WordList state) { |
| this.rackNameState = state; |
| } |
| |
| public void setHostNameState(WordList state) { |
| this.hostNameState = state; |
| } |
| |
| @Override |
| public String getName() { |
| return "node"; |
| } |
| |
| @Override |
| public void setName(String name) { |
| // for now, simply assert since this class has a hardcoded name |
| if (!getName().equals(name)) { |
| throw new RuntimeException("State name mismatch! Expected '" |
| + getName() + "' but found '" + name + "'."); |
| } |
| } |
| } |
| |
| public NodeName(String nodeName) { |
| this.nodeName = nodeName; |
| ParsedHost pHost = ParsedHost.parse(nodeName); |
| if (pHost == null) { |
| this.rackName = null; |
| this.hostName = nodeName; |
| } else { |
| //TODO check for null and improve .. possibly call NodeName(r,h) |
| this.rackName = pHost.getRackName(); |
| this.hostName = pHost.getNodeName(); |
| } |
| } |
| |
| public NodeName(String rName, String hName) { |
| rName = (rName == null || rName.length() == 0) ? null : rName; |
| hName = (hName == null || hName.length() == 0) ? null : hName; |
| if (hName == null) { |
| nodeName = rName; |
| rackName = rName; |
| } else if (rName == null) { |
| nodeName = hName; |
| ParsedHost pHost = ParsedHost.parse(nodeName); |
| if (pHost == null) { |
| this.rackName = null; |
| this.hostName = hName; |
| } else { |
| this.rackName = pHost.getRackName(); |
| this.hostName = pHost.getNodeName(); |
| } |
| } else { |
| rackName = rName; |
| this.hostName = hName; |
| this.nodeName = "/" + rName + "/" + hName; |
| } |
| } |
| |
| public String getHostName() { |
| return hostName; |
| } |
| |
| public String getRackName() { |
| return rackName; |
| } |
| |
| @Override |
| public String getValue() { |
| return nodeName; |
| } |
| |
| @Override |
| public String getAnonymizedValue(StatePool statePool, Configuration conf) { |
| if (this.getValue().equals(ROOT.getValue())) { |
| return getValue(); |
| } |
| if (anonymizedNodeName == null) { |
| anonymize(statePool); |
| } |
| return anonymizedNodeName; |
| } |
| |
| private void anonymize(StatePool pool) { |
| StringBuffer buf = new StringBuffer(); |
| NodeNameState state = (NodeNameState) pool.getState(getClass()); |
| if (state == null) { |
| state = new NodeNameState(); |
| pool.addState(getClass(), state); |
| } |
| |
| if (rackName != null && hostName != null) { |
| buf.append('/'); |
| buf.append(anonymize(rackName, state.getRackNameState())); |
| buf.append('/'); |
| buf.append(anonymize(hostName, state.getHostNameState())); |
| } else { |
| if (state.getRackNameState().contains(nodeName) || rackName != null) { |
| buf.append(anonymize(nodeName, state.getRackNameState())); |
| } else { |
| buf.append(anonymize(nodeName, state.getHostNameState())); |
| } |
| } |
| |
| anonymizedNodeName = buf.toString(); |
| } |
| |
| //TODO There is no caching for saving memory. |
| private static String anonymize(String data, WordList wordList) { |
| if (data == null) { |
| return null; |
| } |
| |
| if (!wordList.contains(data)) { |
| wordList.add(data); |
| } |
| return wordList.getName() + wordList.indexOf(data); |
| } |
| } |