hadoop-mapreduce-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From acmur...@apache.org
Subject svn commit: r1082677 [20/38] - in /hadoop/mapreduce/branches/MR-279: ./ assembly/ ivy/ mr-client/ mr-client/hadoop-mapreduce-client-app/ mr-client/hadoop-mapreduce-client-app/src/ mr-client/hadoop-mapreduce-client-app/src/main/ mr-client/hadoop-mapredu...
Date Thu, 17 Mar 2011 20:21:54 GMT
Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/ContainerTokenIdentifier.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/ContainerTokenIdentifier.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/ContainerTokenIdentifier.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/ContainerTokenIdentifier.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,96 @@
+/**
+* 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.yarn.security;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.token.TokenIdentifier;
+import org.apache.hadoop.yarn.ApplicationID;
+import org.apache.hadoop.yarn.ContainerID;
+import org.apache.hadoop.yarn.Resource;
+
+public class ContainerTokenIdentifier extends TokenIdentifier {
+
+  private static Log LOG = LogFactory
+      .getLog(ContainerTokenIdentifier.class);
+
+  public static final Text KIND = new Text("ContainerToken");
+
+  private ContainerID containerID;
+  private String nmHostName;
+  private Resource resource;
+
+  public ContainerTokenIdentifier(ContainerID containerID, String hostName, Resource r) {
+    this.containerID = containerID;
+    this.nmHostName = hostName;
+    this.resource = r;
+  }
+
+  public ContainerTokenIdentifier() {
+  }
+
+  public ContainerID getContainerID() {
+    return containerID;
+  }
+
+  public String getNmHostName() {
+    return nmHostName;
+  }
+
+  public Resource getResource() {
+    return resource;
+  }
+
+  @Override
+  public void write(DataOutput out) throws IOException {
+    LOG.info("Writing ContainerTokenIdentifier to RPC layer");
+    out.writeInt(this.containerID.appID.id);
+    out.writeInt(this.containerID.id);
+    out.writeUTF(this.nmHostName);
+    out.writeInt(this.resource.memory); // TODO: more resources.
+  }
+
+  @Override
+  public void readFields(DataInput in) throws IOException {
+    this.containerID = new ContainerID();
+    this.containerID.appID = new ApplicationID();
+    this.containerID.appID.id = in.readInt();
+    this.containerID.id = in.readInt();
+    this.nmHostName = in.readUTF();
+    this.resource = new Resource();
+    this.resource.memory = in.readInt(); // TODO: more resources.
+  }
+
+  @Override
+  public Text getKind() {
+    return this.KIND;
+  }
+
+  @Override
+  public UserGroupInformation getUser() {
+    return UserGroupInformation.createRemoteUser(this.containerID.toString());
+  }
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/ContainerTokenSelector.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/ContainerTokenSelector.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/ContainerTokenSelector.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/ContainerTokenSelector.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,46 @@
+/**
+* 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.yarn.security;
+
+import java.util.Collection;
+
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.security.token.Token;
+import org.apache.hadoop.security.token.TokenIdentifier;
+import org.apache.hadoop.security.token.TokenSelector;
+
+public class ContainerTokenSelector implements
+    TokenSelector<ContainerTokenIdentifier> {
+
+  @Override
+  public Token<ContainerTokenIdentifier> selectToken(Text service,
+      Collection<Token<? extends TokenIdentifier>> tokens) {
+    if (service == null) {
+      return null;
+    }
+    for (Token<? extends TokenIdentifier> token : tokens) {
+      if (ContainerTokenIdentifier.KIND.equals(token.getKind()) && 
+          service.equals(token.getService())) {
+        return (Token<ContainerTokenIdentifier>) token;
+      }
+    }
+    return null;
+  }
+
+}
\ No newline at end of file

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/SchedulerSecurityInfo.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/SchedulerSecurityInfo.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/SchedulerSecurityInfo.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/SchedulerSecurityInfo.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,53 @@
+/**
+* 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.yarn.security;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.hadoop.security.KerberosInfo;
+import org.apache.hadoop.security.SecurityInfo;
+import org.apache.hadoop.security.token.TokenIdentifier;
+import org.apache.hadoop.security.token.TokenInfo;
+import org.apache.hadoop.security.token.TokenSelector;
+
+public class SchedulerSecurityInfo implements SecurityInfo {
+
+  @Override
+  public KerberosInfo getKerborosInfo(Class<?> protocol) {
+    return null;
+  }
+
+  @Override
+  public TokenInfo getTokenInfo(Class<?> protocol) {
+    return new TokenInfo() {
+
+      @Override
+      public Class<? extends Annotation> annotationType() {
+        return null;
+      }
+
+      @Override
+      public Class<? extends TokenSelector<? extends TokenIdentifier>>
+          value() {
+        return ApplicationTokenSelector.class;
+      }
+    };
+  }
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/client/ClientRMSecurityInfo.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/client/ClientRMSecurityInfo.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/client/ClientRMSecurityInfo.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/client/ClientRMSecurityInfo.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,56 @@
+/**
+* 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.yarn.security.client;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.hadoop.security.KerberosInfo;
+import org.apache.hadoop.security.SecurityInfo;
+import org.apache.hadoop.security.token.TokenInfo;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+
+public class ClientRMSecurityInfo implements SecurityInfo {
+
+  @Override
+  public KerberosInfo getKerborosInfo(Class<?> protocol) {
+    return new KerberosInfo() {
+
+      @Override
+      public Class<? extends Annotation> annotationType() {
+        return null;
+      }
+
+      @Override
+      public String serverPrincipal() {
+        return YarnConfiguration.RM_SERVER_PRINCIPAL_KEY;
+      }
+
+      @Override
+      public String clientPrincipal() {
+        return null;
+      }
+    };
+  }
+
+  @Override
+  public TokenInfo getTokenInfo(Class<?> protocol) {
+    return null;
+  }
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/client/ClientToAMSecretManager.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/client/ClientToAMSecretManager.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/client/ClientToAMSecretManager.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/security/client/ClientToAMSecretManager.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,104 @@
+/**
+* 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.yarn.security.client;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.SecretKey;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.security.token.SecretManager;
+import org.apache.hadoop.yarn.security.ApplicationTokenIdentifier;
+
+public class ClientToAMSecretManager extends
+    SecretManager<ApplicationTokenIdentifier> {
+
+  private static Log LOG = LogFactory.getLog(ClientToAMSecretManager.class);
+
+  // Per application masterkeys for managing client-tokens
+  private Map<Text, SecretKey> masterKeys = new HashMap<Text, SecretKey>();
+
+  public void setMasterKey(ApplicationTokenIdentifier identifier, byte[] key) {
+    SecretKey sk = SecretManager.createSecretKey(key);
+    Text applicationID = identifier.getApplicationID();
+    this.masterKeys.put(applicationID, sk);
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Setting master key for "
+          + applicationID
+          + " as "
+          + new String(Base64.encodeBase64(this.masterKeys.get(applicationID)
+              .getEncoded())));
+    }
+  }
+
+  private void addMasterKey(ApplicationTokenIdentifier identifier) {
+    Text applicationID = identifier.getApplicationID();
+    this.masterKeys.put(applicationID, generateSecret());
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Creating master key for "
+          + applicationID
+          + " as "
+          + new String(Base64.encodeBase64(this.masterKeys.get(applicationID)
+              .getEncoded())));}
+  }
+
+  // TODO: Handle the masterKey invalidation.
+  public synchronized SecretKey getMasterKey(
+      ApplicationTokenIdentifier identifier) {
+    Text applicationID = identifier.getApplicationID();
+    if (!this.masterKeys.containsKey(applicationID)) {
+      addMasterKey(identifier);
+    }
+    return this.masterKeys.get(applicationID);
+  }
+
+  @Override
+  public synchronized byte[] createPassword(
+      ApplicationTokenIdentifier identifier) {
+    byte[] password =
+        createPassword(identifier.getBytes(), getMasterKey(identifier));
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Password created is "
+          + new String(Base64.encodeBase64(password)));
+    }
+    return password;
+  }
+
+  @Override
+  public byte[] retrievePassword(ApplicationTokenIdentifier identifier)
+      throws SecretManager.InvalidToken {
+    byte[] password =
+        createPassword(identifier.getBytes(), getMasterKey(identifier));
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Password retrieved is "
+          + new String(Base64.encodeBase64(password)));
+    }
+    return password;
+  }
+
+  @Override
+  public ApplicationTokenIdentifier createIdentifier() {
+    return new ApplicationTokenIdentifier();
+  }
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/AbstractService.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/AbstractService.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/AbstractService.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/AbstractService.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,106 @@
+/**
+* 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.yarn.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+
+public abstract class AbstractService implements Service {
+
+  private static final Log LOG = LogFactory.getLog(AbstractService.class);
+  
+  private STATE state = STATE.NOTINITED;
+  private final String name;
+  private Configuration config;
+  private List<ServiceStateChangeListener> listeners =
+    new ArrayList<ServiceStateChangeListener>();
+
+  public AbstractService(String name) {
+    this.name = name;
+  }
+
+  @Override
+  public synchronized STATE getServiceState() {
+    return state;
+  }
+
+  @Override
+  public synchronized void init(Configuration conf) {
+    ensureCurrentState(STATE.NOTINITED);
+    this.config = conf;
+    changeState(STATE.INITED);
+    LOG.info("Service:" + getName() + " is inited.");
+  }
+
+  @Override
+  public synchronized void start() {
+    ensureCurrentState(STATE.INITED);
+    changeState(STATE.STARTED);
+    LOG.info("Service:" + getName() + " is started.");
+  }
+
+  @Override
+  public synchronized void stop() {
+    if (state == STATE.STOPPED) {
+      return;//already stopped
+    }
+    ensureCurrentState(STATE.STARTED);
+    changeState(STATE.STOPPED);
+    LOG.info("Service:" + getName() + " is stopped.");
+  }
+
+  @Override
+  public synchronized void register(ServiceStateChangeListener l) {
+    listeners.add(l);
+  }
+
+  @Override
+  public synchronized void unregister(ServiceStateChangeListener l) {
+    listeners.remove(l);
+  }
+
+  @Override
+  public String getName() {
+    return name;
+  }
+
+  @Override
+  public synchronized Configuration getConfig() {
+    return config;
+  }
+
+  private void ensureCurrentState(STATE currentState) {
+    if (state != currentState) {
+      throw new IllegalStateException("For this operation, current State must " +
+        "be " + currentState + " instead of " + state);
+    }
+  }
+
+  private void changeState(STATE newState) {
+    state = newState;
+    //notify listeners
+    for (ServiceStateChangeListener l : listeners) {
+      l.stateChanged(this);
+    }
+  }
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/CompositeService.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/CompositeService.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/CompositeService.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/CompositeService.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,74 @@
+/**
+* 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.yarn.service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hadoop.conf.Configuration;
+
+/**
+ * Composition of services.
+ */
+public class CompositeService extends AbstractService {
+
+  private List<Service> serviceList = new ArrayList<Service>();
+
+  public CompositeService(String name) {
+    super(name);
+  }
+
+  public Collection<Service> getServices() {
+    return Collections.unmodifiableList(serviceList);
+  }
+
+  protected synchronized void addService(Service service) {
+    serviceList.add(service);
+  }
+
+  protected synchronized boolean removeService(Service service) {
+    return serviceList.remove(service);
+  }
+
+  public synchronized void init(Configuration conf) {
+    for (Service service : serviceList) {
+      service.init(conf);
+    }
+    super.init(conf);
+  }
+
+  public synchronized void start() {
+    for (Service service : serviceList) {
+      service.start();
+    }
+    super.start();
+  }
+
+  public synchronized void stop() {
+    //stop in reserve order of start
+    for (int i = serviceList.size() - 1; i >= 0; i--) {
+      Service service = serviceList.get(i);
+      service.stop();
+    }
+    super.stop();
+  }
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/FilterService.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/FilterService.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/FilterService.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/FilterService.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,71 @@
+/**
+* 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.yarn.service;
+
+import org.apache.hadoop.conf.Configuration;
+
+public class FilterService implements Service {
+
+  private final Service service;
+
+  public FilterService(Service service) {
+    this.service = service;
+  }
+
+  @Override
+  public void init(Configuration config) {
+    service.init(config);
+  }
+
+  @Override
+  public void start() {
+    service.start();
+  }
+
+  @Override
+  public void stop() {
+    service.stop();
+  }
+
+  @Override
+  public void register(ServiceStateChangeListener listener) {
+    service.register(listener);
+  }
+
+  @Override
+  public void unregister(ServiceStateChangeListener listener) {
+    service.unregister(listener);
+  }
+
+  @Override
+  public String getName() {
+    return service.getName();
+  }
+
+  @Override
+  public Configuration getConfig() {
+    return service.getConfig();
+  }
+
+  @Override
+  public STATE getServiceState() {
+    return service.getServiceState();
+  }
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/Service.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/Service.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/Service.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/Service.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,45 @@
+/**
+* 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.yarn.service;
+
+import org.apache.hadoop.conf.Configuration;
+
+/**
+ * Service LifeCycle.
+ */
+public interface Service {
+
+  public enum STATE {
+    NOTINITED,
+    INITED,
+    STARTED,
+    STOPPED;
+  }
+
+  void init(Configuration config);
+  void start();
+  void stop();
+  void register(ServiceStateChangeListener listener);
+  void unregister(ServiceStateChangeListener listener);
+
+  String getName();
+  Configuration getConfig();
+  STATE getServiceState();
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/ServiceStateChangeListener.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/ServiceStateChangeListener.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/ServiceStateChangeListener.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/service/ServiceStateChangeListener.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,28 @@
+/**
+* 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.yarn.service;
+
+/**
+ * Interface to notify state changes of a service.
+ */
+public interface ServiceStateChangeListener {
+
+  void stateChanged(Service service);
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/InvalidStateTransitonException.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/InvalidStateTransitonException.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/InvalidStateTransitonException.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/InvalidStateTransitonException.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,42 @@
+/**
+* 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.yarn.state;
+
+import org.apache.hadoop.yarn.YarnException;
+
+public class InvalidStateTransitonException extends YarnException {
+
+ private Enum<?> currentState;
+  private Enum<?> event;
+
+  public InvalidStateTransitonException(Enum<?> currentState, Enum<?> event) {
+    super("Invalid event: " + event + " at " + currentState);
+    this.currentState = currentState;
+    this.event = event;
+  }
+
+  public Enum<?> getCurrentState() {
+    return currentState;
+  }
+  
+  public Enum<?> getEvent() {
+    return event;
+  }
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/MultipleArcTransition.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/MultipleArcTransition.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/MultipleArcTransition.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/MultipleArcTransition.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,41 @@
+/**
+* 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.yarn.state;
+
+
+
+/**
+ * Hook for Transition. 
+ * Post state is decided by Transition hook. Post state must be one of the 
+ * valid post states registered in StateMachine.
+ */
+public interface MultipleArcTransition
+        <OPERAND, EVENT, STATE extends Enum<STATE>> {
+
+  /**
+   * Transition hook.
+   * @return the postState. Post state must be one of the 
+   *                      valid post states registered in StateMachine.
+   * @param operand the entity attached to the FSM, whose internal 
+   *                state may change.
+   * @param event causal event
+   */
+  public STATE transition(OPERAND operand, EVENT event);
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/SingleArcTransition.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/SingleArcTransition.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/SingleArcTransition.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/SingleArcTransition.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,36 @@
+/**
+* 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.yarn.state;
+
+
+/**
+ * Hook for Transition. This lead to state machine to move to 
+ * the post state as registered in the state machine.
+ */
+public interface SingleArcTransition<OPERAND, EVENT> {
+  /**
+   * Transition hook.
+   * 
+   * @param operand the entity attached to the FSM, whose internal 
+   *                state may change.
+   * @param event causal event
+   */
+  public void transition(OPERAND operand, EVENT event);
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/StateMachine.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/StateMachine.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/StateMachine.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/StateMachine.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,27 @@
+/**
+* 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.yarn.state;
+
+public interface StateMachine
+                 <STATE extends Enum<STATE>,
+                  EVENTTYPE extends Enum<EVENTTYPE>, EVENT> {
+  public STATE getCurrentState();
+  public STATE doTransition(EVENTTYPE eventType, EVENT event)
+        throws InvalidStateTransitonException;
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/StateMachineFactory.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/StateMachineFactory.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/StateMachineFactory.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/state/StateMachineFactory.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,481 @@
+/**
+* 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.yarn.state;
+
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+/**
+ * State machine topology.
+ * This object is semantically immutable.  If you have a
+ * StateMachineFactory there's no operation in the API that changes
+ * its semantic properties.
+ *
+ * @param <OPERAND> The object type on which this state machine operates.
+ * @param <STATE> The state of the entity.
+ * @param <EVENTTYPE> The external eventType to be handled.
+ * @param <EVENT> The event object.
+ *
+ */
+final public class StateMachineFactory
+             <OPERAND, STATE extends Enum<STATE>,
+              EVENTTYPE extends Enum<EVENTTYPE>, EVENT> {
+
+  private final TransitionsListNode transitionsListNode;
+
+  private Map<STATE, Map<EVENTTYPE,
+    Transition<OPERAND, STATE, EVENTTYPE, EVENT>>> stateMachineTable;
+
+  private STATE defaultInitialState;
+
+  private final boolean optimized;
+
+  /**
+   * Constructor
+   *
+   * This is the only constructor in the API.
+   *
+   */
+  public StateMachineFactory(STATE defaultInitialState) {
+    this.transitionsListNode = null;
+    this.defaultInitialState = defaultInitialState;
+    this.optimized = false;
+    this.stateMachineTable = null;
+  }
+  
+  private StateMachineFactory
+      (StateMachineFactory<OPERAND, STATE, EVENTTYPE, EVENT> that,
+       ApplicableTransition t) {
+    this.defaultInitialState = that.defaultInitialState;
+    this.transitionsListNode 
+        = new TransitionsListNode(t, that.transitionsListNode);
+    this.optimized = false;
+    this.stateMachineTable = null;
+  }
+
+  private StateMachineFactory
+      (StateMachineFactory<OPERAND, STATE, EVENTTYPE, EVENT> that,
+       boolean optimized) {
+    this.defaultInitialState = that.defaultInitialState;
+    this.transitionsListNode = that.transitionsListNode;
+    this.optimized = optimized;
+    if (optimized) {
+      makeStateMachineTable();
+    } else {
+      stateMachineTable = null;
+    }
+  }
+
+  private interface ApplicableTransition
+             <OPERAND, STATE extends Enum<STATE>,
+              EVENTTYPE extends Enum<EVENTTYPE>, EVENT> {
+    void apply(StateMachineFactory<OPERAND, STATE, EVENTTYPE, EVENT> subject);
+  }
+
+  private class TransitionsListNode {
+    final ApplicableTransition transition;
+    final TransitionsListNode next;
+
+    TransitionsListNode
+        (ApplicableTransition transition, TransitionsListNode next) {
+      this.transition = transition;
+      this.next = next;
+    }
+  }
+
+  static private class ApplicableSingleTransition
+             <OPERAND, STATE extends Enum<STATE>,
+              EVENTTYPE extends Enum<EVENTTYPE>, EVENT>
+          implements ApplicableTransition<OPERAND, STATE, EVENTTYPE, EVENT> {
+    final STATE preState;
+    final EVENTTYPE eventType;
+    final Transition<OPERAND, STATE, EVENTTYPE, EVENT> transition;
+
+    ApplicableSingleTransition
+        (STATE preState, EVENTTYPE eventType,
+         Transition<OPERAND, STATE, EVENTTYPE, EVENT> transition) {
+      this.preState = preState;
+      this.eventType = eventType;
+      this.transition = transition;
+    }
+
+    @Override
+    public void apply
+             (StateMachineFactory<OPERAND, STATE, EVENTTYPE, EVENT> subject) {
+      Map<EVENTTYPE, Transition<OPERAND, STATE, EVENTTYPE, EVENT>> transitionMap
+        = subject.stateMachineTable.get(preState);
+      if (transitionMap == null) {
+        // I use HashMap here because I would expect most EVENTTYPE's to not
+        //  apply out of a particular state, so FSM sizes would be 
+        //  quadratic if I use EnumMap's here as I do at the top level.
+        transitionMap = new HashMap<EVENTTYPE,
+          Transition<OPERAND, STATE, EVENTTYPE, EVENT>>();
+        subject.stateMachineTable.put(preState, transitionMap);
+      }
+      transitionMap.put(eventType, transition);
+    }
+  }
+
+  static private class ApplicableMultipleTransition
+             <OPERAND, STATE extends Enum<STATE>,
+              EVENTTYPE extends Enum<EVENTTYPE>, EVENT>
+          implements ApplicableTransition<OPERAND, STATE, EVENTTYPE, EVENT> {
+    final STATE preState;
+    final Set<STATE> postStates;
+    final EVENTTYPE eventType;
+    final Transition<OPERAND, STATE, EVENTTYPE, EVENT> transition;
+
+    ApplicableMultipleTransition
+        (STATE preState, Set<STATE> postStates, EVENTTYPE eventType,
+         Transition<OPERAND, STATE, EVENTTYPE, EVENT> transition) {
+      this.preState = preState;
+      this.postStates = postStates;
+      this.eventType = eventType;
+      this.transition = transition;
+    }
+
+    @Override
+    public void apply
+             (StateMachineFactory<OPERAND, STATE, EVENTTYPE, EVENT> subject) {
+
+      Map<EVENTTYPE, Transition<OPERAND, STATE, EVENTTYPE, EVENT>> transitionMap
+        = subject.stateMachineTable.get(preState);
+      if (transitionMap == null) {
+        // I use HashMap here because I would expect most EVENTTYPE's to not
+        //  apply out of a particular state, so FSM sizes would be 
+        //  quadratic if I use EnumMap's here as I do at the top level.
+        transitionMap = new HashMap<EVENTTYPE,
+          Transition<OPERAND, STATE, EVENTTYPE, EVENT>>();
+        subject.stateMachineTable.put(preState, transitionMap);
+      }
+      transitionMap.put(eventType, transition);
+    }
+  }
+
+  /**
+   * @return a NEW StateMachineFactory just like {@code this} with the current
+   *          transition added as a new legal transition.  This overload
+   *          has no hook object.
+   *
+   *         Note that the returned StateMachineFactory is a distinct
+   *         object.
+   *
+   *         This method is part of the API.
+   *
+   * @param preState pre-transition state
+   * @param postState post-transition state
+   * @param eventType stimulus for the transition
+   */
+  public StateMachineFactory
+             <OPERAND, STATE, EVENTTYPE, EVENT>
+          addTransition(STATE preState, STATE postState, EVENTTYPE eventType) {
+    return addTransition(preState, postState, eventType, null);
+  }
+
+  /**
+   * @return a NEW StateMachineFactory just like {@code this} with the current
+   *          transition added as a new legal transition.  This overload
+   *          has no hook object.
+   *
+   *
+   *         Note that the returned StateMachineFactory is a distinct
+   *         object.
+   *
+   *         This method is part of the API.
+   *
+   * @param preState pre-transition state
+   * @param postState post-transition state
+   * @param eventTypes List of stimuli for the transitions
+   */
+  public StateMachineFactory<OPERAND, STATE, EVENTTYPE, EVENT> addTransition(
+      STATE preState, STATE postState, Set<EVENTTYPE> eventTypes) {
+    return addTransition(preState, postState, eventTypes, null);
+  }
+
+  /**
+   * @return a NEW StateMachineFactory just like {@code this} with the current
+   *          transition added as a new legal transition
+   *
+   *         Note that the returned StateMachineFactory is a distinct
+   *         object.
+   *
+   *         This method is part of the API.
+   *
+   * @param preState pre-transition state
+   * @param postState post-transition state
+   * @param eventTypes List of stimuli for the transitions
+   * @param hook transition hook
+   */
+  public StateMachineFactory<OPERAND, STATE, EVENTTYPE, EVENT> addTransition(
+      STATE preState, STATE postState, Set<EVENTTYPE> eventTypes,
+      SingleArcTransition<OPERAND, EVENT> hook) {
+    StateMachineFactory<OPERAND, STATE, EVENTTYPE, EVENT> factory = null;
+    for (EVENTTYPE event : eventTypes) {
+      if (factory == null) {
+        factory = addTransition(preState, postState, event, hook);
+      } else {
+        factory = factory.addTransition(preState, postState, event, hook);
+      }
+    }
+    return factory;
+  }
+
+  /**
+   * @return a NEW StateMachineFactory just like {@code this} with the current
+   *          transition added as a new legal transition
+   *
+   *         Note that the returned StateMachineFactory is a distinct object.
+   *
+   *         This method is part of the API.
+   *
+   * @param preState pre-transition state
+   * @param postState post-transition state
+   * @param eventType stimulus for the transition
+   * @param hook transition hook
+   */
+  public StateMachineFactory
+             <OPERAND, STATE, EVENTTYPE, EVENT>
+          addTransition(STATE preState, STATE postState,
+                        EVENTTYPE eventType,
+                        SingleArcTransition<OPERAND, EVENT> hook){
+    return new StateMachineFactory
+        (this, new ApplicableSingleTransition
+           (preState, eventType, new SingleInternalArc(postState, hook)));
+  }
+
+  /**
+   * @return a NEW StateMachineFactory just like {@code this} with the current
+   *          transition added as a new legal transition
+   *
+   *         Note that the returned StateMachineFactory is a distinct object.
+   *
+   *         This method is part of the API.
+   *
+   * @param preState pre-transition state
+   * @param postStates valid post-transition states
+   * @param eventType stimulus for the transition
+   * @param hook transition hook
+   */
+  public StateMachineFactory
+             <OPERAND, STATE, EVENTTYPE, EVENT>
+          addTransition(STATE preState, Set<STATE> postStates,
+                        EVENTTYPE eventType,
+                        MultipleArcTransition<OPERAND, EVENT, STATE> hook){
+    return new StateMachineFactory
+        (this,
+         new ApplicableMultipleTransition
+           (preState, postStates,
+            eventType, new MultipleInternalArc(postStates, hook)));
+  }
+
+  /**
+   * @return a StateMachineFactory just like {@code this}, except that if
+   *         you won't need any synchronization to build a state machine
+   *
+   *         Note that the returned StateMachineFactory is a distinct object.
+   *
+   *         This method is part of the API.
+   *
+   *         The only way you could distinguish the returned
+   *         StateMachineFactory from {@code this} would be by
+   *         measuring the performance of the derived 
+   *         {@code StateMachine} you can get from it.
+   *
+   * Calling this is optional.  It doesn't change the semantics of the factory,
+   *   if you call it then when you use the factory there is no synchronization.
+   */
+  public StateMachineFactory
+             <OPERAND, STATE, EVENTTYPE, EVENT>
+          installTopology() {
+    return new StateMachineFactory(this, true);
+  }
+
+  /**
+   * Effect a transition due to the effecting stimulus.
+   * @param state current state
+   * @param eventType trigger to initiate the transition
+   * @param cause causal eventType context
+   * @return transitioned state
+   */
+  private STATE doTransition
+           (OPERAND operand, STATE oldState, EVENTTYPE eventType, EVENT event)
+      throws InvalidStateTransitonException {
+    // We can assume that stateMachineTable is non-null because we call
+    //  maybeMakeStateMachineTable() when we build an InnerStateMachine ,
+    //  and this code only gets called from inside a working InnerStateMachine .
+    Map<EVENTTYPE, Transition<OPERAND, STATE, EVENTTYPE, EVENT>> transitionMap
+      = stateMachineTable.get(oldState);
+    if (transitionMap != null) {
+      Transition<OPERAND, STATE, EVENTTYPE, EVENT> transition
+          = transitionMap.get(eventType);
+      if (transition != null) {
+        return transition.doTransition(operand, oldState, event, eventType);
+      }
+    }
+    throw new InvalidStateTransitonException(oldState, eventType);
+  }
+
+  private synchronized void maybeMakeStateMachineTable() {
+    if (stateMachineTable == null) {
+      makeStateMachineTable();
+    }
+  }
+
+  private void makeStateMachineTable() {
+    Stack<ApplicableTransition> stack = new Stack<ApplicableTransition>();
+
+    Map<STATE, Map<EVENTTYPE, Transition<OPERAND, STATE, EVENTTYPE, EVENT>>>
+      prototype = new HashMap<STATE, Map<EVENTTYPE, Transition<OPERAND, STATE, EVENTTYPE, EVENT>>>();
+
+    prototype.put(defaultInitialState, null);
+
+    // I use EnumMap here because it'll be faster and denser.  I would
+    //  expect most of the states to have at least one transition.
+    stateMachineTable
+       = new EnumMap<STATE, Map<EVENTTYPE,
+                           Transition<OPERAND, STATE, EVENTTYPE, EVENT>>>(prototype);
+
+    for (TransitionsListNode cursor = transitionsListNode;
+         cursor != null;
+         cursor = cursor.next) {
+      stack.push(cursor.transition);
+    }
+
+    while (!stack.isEmpty()) {
+      stack.pop().apply(this);
+    }
+  }
+
+  private interface Transition<OPERAND, STATE extends Enum<STATE>,
+          EVENTTYPE extends Enum<EVENTTYPE>, EVENT> {
+    STATE doTransition(OPERAND operand, STATE oldState,
+                       EVENT event, EVENTTYPE eventType);
+  }
+
+  private class SingleInternalArc
+                    implements Transition<OPERAND, STATE, EVENTTYPE, EVENT> {
+
+    private STATE postState;
+    private SingleArcTransition<OPERAND, EVENT> hook; // transition hook
+
+    SingleInternalArc(STATE postState,
+        SingleArcTransition<OPERAND, EVENT> hook) {
+      this.postState = postState;
+      this.hook = hook;
+    }
+
+    @Override
+    public STATE doTransition(OPERAND operand, STATE oldState,
+                              EVENT event, EVENTTYPE eventType) {
+      if (hook != null) {
+        hook.transition(operand, event);
+      }
+      return postState;
+    }
+  }
+
+  private class MultipleInternalArc
+              implements Transition<OPERAND, STATE, EVENTTYPE, EVENT>{
+
+    // Fields
+    private Set<STATE> validPostStates;
+    private MultipleArcTransition<OPERAND, EVENT, STATE> hook;  // transition hook
+
+    MultipleInternalArc(Set<STATE> postStates,
+                   MultipleArcTransition<OPERAND, EVENT, STATE> hook) {
+      this.validPostStates = postStates;
+      this.hook = hook;
+    }
+
+    @Override
+    public STATE doTransition(OPERAND operand, STATE oldState,
+                              EVENT event, EVENTTYPE eventType)
+        throws InvalidStateTransitonException {
+      STATE postState = hook.transition(operand, event);
+
+      if (!validPostStates.contains(postState)) {
+        throw new InvalidStateTransitonException(oldState, eventType);
+      }
+      return postState;
+    }
+  }
+
+  /* 
+   * @return a {@link StateMachine} that starts in 
+   *         {@code initialState} and whose {@link Transition} s are
+   *         applied to {@code operand} .
+   *
+   *         This is part of the API.
+   *
+   * @param operand the object upon which the returned 
+   *                {@link StateMachine} will operate.
+   * @param initialState the state in which the returned 
+   *                {@link StateMachine} will start.
+   *                
+   */
+  public StateMachine<STATE, EVENTTYPE, EVENT>
+        make(OPERAND operand, STATE initialState) {
+    return new InternalStateMachine(operand, initialState);
+  }
+
+  /* 
+   * @return a {@link StateMachine} that starts in the default initial
+   *          state and whose {@link Transition} s are applied to
+   *          {@code operand} . 
+   *
+   *         This is part of the API.
+   *
+   * @param operand the object upon which the returned 
+   *                {@link StateMachine} will operate.
+   *                
+   */
+  public StateMachine<STATE, EVENTTYPE, EVENT> make(OPERAND operand) {
+    return new InternalStateMachine(operand, defaultInitialState);
+  }
+
+  private class InternalStateMachine
+        implements StateMachine<STATE, EVENTTYPE, EVENT> {
+    private final OPERAND operand;
+    private STATE currentState;
+
+    InternalStateMachine(OPERAND operand, STATE initialState) {
+      this.operand = operand;
+      this.currentState = initialState;
+      if (!optimized) {
+        maybeMakeStateMachineTable();
+      }
+    }
+
+    @Override
+    public synchronized STATE getCurrentState() {
+      return currentState;
+    }
+
+    @Override
+    public synchronized STATE doTransition(EVENTTYPE eventType, EVENT event)
+         throws InvalidStateTransitonException  {
+      currentState = StateMachineFactory.this.doTransition
+          (operand, currentState, eventType, event);
+      return currentState;
+    }
+  }
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,65 @@
+/**
+* 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.yarn.util;
+
+import java.util.Iterator;
+
+import org.apache.hadoop.yarn.YarnException;
+import org.apache.hadoop.yarn.ApplicationID;
+
+import static org.apache.hadoop.yarn.util.StringHelper.*;
+
+/**
+ * Yarn application related utilities
+ */
+public class Apps {
+  public static final String APP = "app";
+  public static final String ID = "ID";
+
+  public static String toString(ApplicationID id) {
+    return _join("app", id.clusterTimeStamp, id.id);
+  }
+
+  public static ApplicationID toAppID(String aid) {
+    Iterator<String> it = _split(aid).iterator();
+    return toAppID(APP, aid, it);
+  }
+
+  public static ApplicationID toAppID(String prefix, String s, Iterator<String> it) {
+    if (!it.hasNext() || !it.next().equals(prefix)) {
+      throwParseException(sjoin(prefix, ID), s);
+    }
+    shouldHaveNext(prefix, s, it);
+    ApplicationID appID = new ApplicationID();
+    appID.clusterTimeStamp = Long.parseLong(it.next());
+    shouldHaveNext(prefix, s, it);
+    appID.id = Integer.parseInt(it.next());
+    return appID;
+  }
+
+  public static void shouldHaveNext(String prefix, String s, Iterator<String> it) {
+    if (!it.hasNext()) {
+      throwParseException(sjoin(prefix, ID), s);
+    }
+  }
+
+  public static void throwParseException(String name, String s) {
+    throw new YarnException(join("Error parsing ", name, ": ", s));
+  }
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/AvroUtil.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/AvroUtil.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/AvroUtil.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/AvroUtil.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,126 @@
+/**
+* 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.yarn.util;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.NumberFormat;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.yarn.ApplicationID;
+import org.apache.hadoop.yarn.ContainerID;
+import org.apache.hadoop.yarn.URL;
+
+/**
+ * This class contains a set of utilities which help converting data structures
+ * from/to avro to/from hadoop/nativejava data structures.
+ *
+ */
+public class AvroUtil {
+
+  /**
+   * return a hadoop path from a given avro url
+   * 
+   * @param url
+   *          avro url to convert
+   * @return
+   * @throws URISyntaxException
+   */
+  public static Path getPathFromYarnURL(URL url) throws URISyntaxException {
+    String scheme = url.scheme == null ? "" : url.scheme.toString();
+    String authority = url.host != null ? url.host.toString() + ":" + url.port
+        : "";
+    return new Path(
+        (new URI(scheme, authority, url.file.toString(), null, null))
+            .normalize());
+  }
+  
+  /**
+   * change from CharSequence to string for map key and value
+   * @param env
+   * @return
+   */
+  public static Map<String, String> convertToString(
+      Map<CharSequence, CharSequence> env) {
+    
+    Map<String, String> stringMap = new HashMap<String, String>();
+    for (Entry<CharSequence, CharSequence> entry: env.entrySet()) {
+      stringMap.put(entry.getKey().toString(), entry.getValue().toString());
+    }
+    return stringMap;
+   }
+
+  public static URL getYarnUrlFromPath(Path path) {
+    return getYarnUrlFromURI(path.toUri());
+  }
+  
+  public static URL getYarnUrlFromURI(URI uri) {
+    URL url = new URL();
+    if (uri.getHost() != null) {
+      url.host = uri.getHost();
+    }
+    url.port = uri.getPort();
+    url.scheme = uri.getScheme();
+    url.file = uri.getPath();
+    return url;
+  }
+
+  // TODO: Why thread local?
+  private static final ThreadLocal<NumberFormat> appIdFormat =
+    new ThreadLocal<NumberFormat>() {
+      @Override
+      public NumberFormat initialValue() {
+        NumberFormat fmt = NumberFormat.getInstance();
+        fmt.setGroupingUsed(false);
+        fmt.setMinimumIntegerDigits(4);
+        return fmt;
+      }
+    };
+
+  // TODO: Why thread local?
+  private static final ThreadLocal<NumberFormat> containerIdFormat =
+      new ThreadLocal<NumberFormat>() {
+        @Override
+        public NumberFormat initialValue() {
+          NumberFormat fmt = NumberFormat.getInstance();
+          fmt.setGroupingUsed(false);
+          fmt.setMinimumIntegerDigits(6);
+          return fmt;
+        }
+      };
+
+  public static String toString(ApplicationID appId) {
+    StringBuilder sb = new StringBuilder();
+    sb.append("application_").append(appId.clusterTimeStamp).append("_");
+    sb.append(appIdFormat.get().format(appId.id));
+    return sb.toString();
+  }
+
+  public static String toString(ContainerID cId) {
+    StringBuilder sb = new StringBuilder();
+    ApplicationID appId = cId.appID;
+    sb.append("container_").append(appId.clusterTimeStamp).append("_");
+    sb.append(appIdFormat.get().format(appId.id)).append("_");
+    sb.append(containerIdFormat.get().format(cId.id));
+    return sb.toString();
+  }
+}
\ No newline at end of file

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/BuilderUtils.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/BuilderUtils.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/BuilderUtils.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/BuilderUtils.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,45 @@
+/**
+* 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.yarn.util;
+
+import java.net.URI;
+
+import org.apache.hadoop.yarn.LocalResource;
+import org.apache.hadoop.yarn.LocalResourceType;
+import org.apache.hadoop.yarn.LocalResourceVisibility;
+
+/**
+ * Builder utilities to construct various objects.
+ *
+ */
+public class BuilderUtils {
+
+  public static LocalResource newLocalResource(URI uri, 
+      LocalResourceType type, LocalResourceVisibility visibility, 
+      long size, long timestamp) {
+    LocalResource resource = new LocalResource();
+    resource.resource = AvroUtil.getYarnUrlFromURI(uri);
+    resource.type = type;
+    resource.state = visibility;
+    resource.size = size;
+    resource.timestamp = timestamp;
+    return resource;
+  }
+
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/ContainerBuilderHelper.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/ContainerBuilderHelper.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/ContainerBuilderHelper.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/ContainerBuilderHelper.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,49 @@
+/**
+* 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.yarn.util;
+
+import java.util.regex.Pattern;
+
+import org.apache.hadoop.yarn.YarnContainerTags;
+
+// TODO: Remove this and related stuff?
+public class ContainerBuilderHelper {
+
+  private static final String DOT = ".";
+  private static final String YARN_TAG_BEGIN = "<";
+  private static final String YARN_TAG_END = ">";
+
+  private static String workDir = YARN_TAG_BEGIN
+      + YarnContainerTags.YARN_WORK_DIR + YARN_TAG_END;
+  private static Pattern envPattern = Pattern.compile(getEnvVar("([^"
+      + YARN_TAG_END + "]*)")); // <YARN_ENV_TAG.([^>])*>
+
+  public static String getWorkDir() {
+    return "$PWD";
+  }
+
+  public static String getEnvVar(String varName) {
+    return YARN_TAG_BEGIN + YarnContainerTags.YARN_ENV_TAG + DOT + varName
+        + YARN_TAG_END;
+  }
+
+  public static Pattern getEnvPattern() {
+    return envPattern;
+  }
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/MasterKeyGenerator.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/MasterKeyGenerator.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/MasterKeyGenerator.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/MasterKeyGenerator.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,62 @@
+/**
+* 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.yarn.util;
+
+import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.Credentials;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.security.ApplicationTokenSecretManager;
+
+public class MasterKeyGenerator {
+
+  public static void main(String[] args) throws IOException,
+      InterruptedException {
+    final Configuration myConf = new Configuration();
+    UserGroupInformation.setConfiguration(myConf);
+    if (UserGroupInformation.isSecurityEnabled()) {
+      UserGroupInformation clientUgi = UserGroupInformation.getLoginUser();
+      clientUgi.doAs(new PrivilegedExceptionAction<Object>() {
+        @Override
+        public Object run() throws Exception {
+          generateMasterKey(myConf);
+          return null;
+        }
+      });
+    }
+  }
+
+  // For now RM and NM share the secret key through a file. This should be
+  // changed to RPC based sharing. TODO:
+  public static void generateMasterKey(Configuration conf) throws IOException {
+    ApplicationTokenSecretManager appSecretManager =
+        new ApplicationTokenSecretManager();
+    Credentials masterSecretKey = new Credentials();
+    masterSecretKey.addSecretKey(YarnConfiguration.RMNMMasterKeyAliasName,
+        appSecretManager.getMasterKey().getEncoded());
+    Path masterKeyFile =
+        new Path(YarnConfiguration.MASTER_KEYS_DIR,
+            YarnConfiguration.MASTER_KEY_FILE_NAME);
+    masterSecretKey.writeTokenStorageFile(masterKeyFile, conf);
+  }
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/SecurityUtil.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/SecurityUtil.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/SecurityUtil.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/SecurityUtil.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,122 @@
+/**
+* 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.yarn.util;
+
+import java.io.IOException;
+
+import javax.crypto.SecretKey;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.io.DataInputBuffer;
+import org.apache.hadoop.io.DataOutputBuffer;
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.security.Credentials;
+import org.apache.hadoop.security.KerberosName;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.token.Token;
+import org.apache.hadoop.security.token.TokenIdentifier;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.security.ApplicationTokenIdentifier;
+import org.apache.hadoop.yarn.security.ApplicationTokenSecretManager;
+import org.apache.hadoop.yarn.ApplicationID;
+
+public class SecurityUtil {
+
+  private static final Log LOG = LogFactory.getLog(SecurityUtil.class);
+
+  // imitation of operations done by client to upload FileSystem
+  // DelegationTokens
+  public static void uploadFileSystemDelegationTokens(Configuration conf,
+      ApplicationID appId, Path[] resourcePaths, Credentials credentials)
+      throws IOException {
+
+    getFileSystemTokens(conf, resourcePaths, credentials);
+
+    FileSystem defaultFS = FileSystem.get(conf);
+    // TODO: fix
+    credentials.writeTokenStorageFile(
+        new Path("yarn", Integer.toString(appId.id),
+            YarnConfiguration.FS_TOKENS_FILE_NAME).makeQualified(
+            FileSystem.getDefaultUri(conf), defaultFS.getWorkingDirectory()),
+        conf);
+  }
+
+  public static void getFileSystemTokens(Configuration conf,
+      Path[] resourcePaths, Credentials credentials) throws IOException {
+    // get JobManager principal id (for the renewer)
+    KerberosName jmKrbName =
+        new KerberosName(
+            conf.get(YarnConfiguration.APPLICATION_MANAGER_PRINCIPAL, ""));
+    String delegTokenRenewer = jmKrbName.getShortName();
+
+    for (Path path : resourcePaths) {
+      FileSystem fs = FileSystem.get(path.toUri(), conf);
+      Token<?> token = fs.getDelegationToken(delegTokenRenewer);
+      String fsName = fs.getCanonicalServiceName();
+      if (token != null) {
+        Text fsNameText = new Text(fsName);
+        token.setService(fsNameText);
+        credentials.addToken(fsNameText, token);
+        LOG.info("Got delegationToken for " + fs.getUri() + ";uri=" + fsName
+            + ";t.service=" + token.getService());
+      }
+    }
+  }
+
+  // TODO: ApplicationMaster needs one token for each NodeManager. This should
+  // be created by ResourceManager and sent to ApplicationMaster via RPC.
+  public static void loadContainerManagerTokens(ApplicationID appId,
+      Configuration conf, String nmServiceAddress) throws IOException {
+
+    Path masterKeyFile =
+        new Path(YarnConfiguration.MASTER_KEYS_DIR,
+            YarnConfiguration.MASTER_KEY_FILE_NAME);
+    Credentials allMasterSecretKeys =
+        Credentials.readTokenStorageFile(masterKeyFile, conf);
+    byte[] masterKeyBytes =
+        allMasterSecretKeys
+            .getSecretKey(YarnConfiguration.RMNMMasterKeyAliasName);
+    SecretKey masterKey =
+        ApplicationTokenSecretManager.createSecretKey(masterKeyBytes);
+
+    ApplicationTokenSecretManager appSecretManager =
+        new ApplicationTokenSecretManager();
+    appSecretManager.setMasterKey(masterKey);
+
+    // create JobToken file and write token to it
+    ApplicationTokenIdentifier identifier =
+        new ApplicationTokenIdentifier(appId);
+    Token<ApplicationTokenIdentifier> token =
+        new Token<ApplicationTokenIdentifier>(identifier, appSecretManager);
+    token.setService(new Text(nmServiceAddress));
+
+    UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
+    ugi.addToken(token);
+
+    for (Token<? extends TokenIdentifier> t : ugi.getTokens()) {
+      LOG.info("Token added for service " + t.getService()
+          + " with identifer " + t.getIdentifier());
+    }
+  }
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/StringHelper.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/StringHelper.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/StringHelper.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/util/StringHelper.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,169 @@
+/**
+* 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.yarn.util;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import java.util.regex.Pattern;
+
+/**
+ * Common string manipulation helpers
+ */
+public final class StringHelper {
+  // Common joiners to avoid per join creation of joiners
+  public static final Joiner SSV_JOINER = Joiner.on(' ');
+  public static final Joiner CSV_JOINER = Joiner.on(',');
+  public static final Joiner JOINER = Joiner.on("");
+  public static final Joiner _JOINER = Joiner.on('_');
+  public static final Joiner PATH_JOINER = Joiner.on('/');
+  public static final Joiner PATH_ARG_JOINER = Joiner.on("/:");
+  public static final Joiner DOT_JOINER = Joiner.on('.');
+  public static final Splitter SSV_SPLITTER =
+      Splitter.on(' ').omitEmptyStrings().trimResults();
+  public static final Splitter _SPLITTER = Splitter.on('_').trimResults();
+  private static final Pattern ABS_URL_RE =Pattern.compile("^(?:\\w+:)?//");
+
+  /**
+   * Join on space.
+   * @param args to join
+   * @return args joined by space
+   */
+  public static String sjoin(Object... args) {
+    return SSV_JOINER.join(args);
+  }
+
+  /**
+   * Join on comma.
+   * @param args to join
+   * @return args joined by comma
+   */
+  public static String cjoin(Object... args) {
+    return CSV_JOINER.join(args);
+  }
+
+  /**
+   * Join on dot
+   * @param args to join
+   * @return args joined by dot
+   */
+  public static String djoin(Object... args) {
+    return DOT_JOINER.join(args);
+  }
+
+  /**
+   * Join on underscore
+   * @param args to join
+   * @return args joined underscore
+   */
+  public static String _join(Object... args) {
+    return _JOINER.join(args);
+  }
+
+  /**
+   * Join on slash
+   * @param args to join
+   * @return args joined with slash
+   */
+  public static String pjoin(Object... args) {
+    return PATH_JOINER.join(args);
+  }
+
+  /**
+   * Join on slash & colon (e.g., path args in routing spec)
+   * @param args to join
+   * @return args joined with /:
+   */
+  public static String pajoin(Object... args) {
+    return PATH_ARG_JOINER.join(args);
+  }
+
+  /**
+   * Join without separator
+   * @param args
+   * @return joined args with no separator
+   */
+  public static String join(Object... args) {
+    return JOINER.join(args);
+  }
+
+  /**
+   * Join with a separator
+   * @param sep the separator
+   * @param args to join
+   * @return args joined with a separator
+   */
+  public static String joins(String sep, Object...args) {
+    return Joiner.on(sep).join(args);
+  }
+
+  /**
+   * Split on space & trim results.
+   * @param s the string to split
+   * @return an iterable of strings
+   */
+  public static Iterable<String> split(CharSequence s) {
+    return SSV_SPLITTER.split(s);
+  }
+
+  /**
+   * Split on _ & trim results
+   * @param s the string to split
+   * @return an iterable of strings
+   */
+  public static Iterable<String> _split(CharSequence s) {
+    return _SPLITTER.split(s);
+  }
+
+  /**
+   * Check whether a url is absolute or note
+   * @param url to check
+   * @return true if url starts with scheme:// or //
+   */
+  public static boolean isAbsUrl(CharSequence url) {
+    return ABS_URL_RE.matcher(url).find();
+  }
+
+  /**
+   * Join url components
+   * @param pathPrefix for relative urls
+   * @param args url components to join
+   * @return an url string
+   */
+  public static String ujoin(String pathPrefix, String... args) {
+    StringBuilder sb = new StringBuilder();
+    boolean first = true;
+    for (String part : args) {
+      if (first) {
+        first = false;
+        if (part.startsWith("#") || isAbsUrl(part)) {
+          sb.append(part);
+        } else {
+          sb.append('/').append(pathPrefix).append('/').append(part);
+        }
+      } else {
+        sb.append('/').append(part);
+      }
+    }
+    return sb.toString();
+  }
+
+  public static String percent(double value) {
+    return String.format("%.2f", value * 100);
+  }
+}

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/Controller.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/Controller.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/Controller.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/Controller.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,248 @@
+/**
+* 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.yarn.webapp;
+
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.servlet.RequestScoped;
+
+import java.io.PrintWriter;
+import java.util.Map;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import static org.apache.hadoop.yarn.util.StringHelper.*;
+
+import org.apache.hadoop.yarn.webapp.view.DefaultPage;
+
+import org.codehaus.jackson.map.ObjectMapper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class Controller implements Params {
+  public static final Logger LOG = LoggerFactory.getLogger(Controller.class);
+  static final ObjectMapper jsonMapper = new ObjectMapper();
+
+  @RequestScoped
+  public static class RequestContext{
+    final Injector injector;
+    final HttpServletRequest request;
+    final HttpServletResponse response;
+    private Map<String, String> moreParams;
+    private Map<String, Cookie> cookies;
+    int status = 200; // pre 3.0 servlet-api doesn't have getStatus
+    boolean rendered = false;
+    Throwable error;
+    boolean devMode = false;
+    String prefix;
+
+    @Inject RequestContext(Injector injector, HttpServletRequest request,
+                           HttpServletResponse response) {
+      this.injector = injector;
+      this.request = request;
+      this.response = response;
+    }
+
+    public int status() { return status; }
+
+    public void setStatus(int status) {
+      this.status = status;
+      response.setStatus(status);
+    }
+
+    public void setRendered(boolean rendered) {
+      this.rendered = rendered;
+    }
+
+    public Map<String, String> moreParams() {
+      if (moreParams == null) {
+        moreParams = Maps.newHashMap();
+      }
+      return moreParams; // OK
+    }
+
+    public Map<String, Cookie> cookies() {
+      if (cookies == null) {
+        cookies = Maps.newHashMap();
+        Cookie[] rcookies = request.getCookies();
+        if (rcookies != null) {
+          for (Cookie cookie : rcookies) {
+            cookies.put(cookie.getName(), cookie);
+          }
+        }
+      }
+      return cookies; // OK
+    }
+
+    public void set(String key, String value) {
+      moreParams().put(key, value);
+    }
+
+    public String get(String key, String defaultValue) {
+      String value = moreParams().get(key);
+      if (value == null) {
+        value = request.getParameter(key);
+      }
+      return value == null ? defaultValue : value;
+    }
+
+    public String prefix() { return prefix; }
+  }
+
+  private RequestContext context;
+  @Inject Injector injector;
+
+  public Controller() {
+    // Makes injection in subclasses optional.
+    // Time will tell if this buy us more than the NPEs :)
+  }
+
+  public Controller(RequestContext ctx) {
+    context = ctx;
+  }
+
+  public RequestContext context() {
+    if (context == null) {
+      if (injector == null) {
+        // One of the downsides of making injection in subclasses optional.
+        throw new WebAppException(join("Error accessing RequestContext from\n",
+            "a child constructor, either move the usage of the Controller\n",
+            "methods out of the constructor or inject the RequestContext\n",
+            "into the constructor"));
+      }
+      context = injector.getInstance(RequestContext.class);
+    }
+    return context;
+  }
+
+  public Throwable error() { return context().error; }
+
+  public int status() { return context().status; }
+
+  public void setStatus(int status) {
+    context().setStatus(status);
+  }
+
+  public boolean inDevMode() { return context().devMode; }
+
+  public Injector injector() { return context().injector; }
+
+  public HttpServletRequest request() { return context().request; }
+
+  public HttpServletResponse response() { return context().response; }
+
+  public void set(String key, String value) {
+    context().set(key, value);
+  }
+
+  public String get(String key, String defaultValue) {
+    return context().get(key, defaultValue);
+  }
+
+  public String $(String key) {
+    return get(key, "");
+  }
+
+  public void setTitle(String title) {
+    set(TITLE, title);
+  }
+
+  public void setTitle(String title, String url) {
+    setTitle(title);
+    set(TITLE_LINK, url);
+  }
+
+  public ResponseInfo info(String about) {
+    return injector().getInstance(ResponseInfo.class).about(about);
+  }
+
+  /**
+   * Get the cookies
+   * @return the cookies map
+   */
+  public Map<String, Cookie> cookies() {
+    return context().cookies();
+  }
+
+ /**
+   * Create an url from url components
+   * @param parts components to join
+   * @return an url string
+   */
+  public String url(String... parts) {
+    return ujoin(context().prefix, parts);
+  }
+
+  /**
+   * The default action.
+   */
+  public abstract void index();
+
+  public void echo() {
+    render(DefaultPage.class);
+  }
+
+  protected void render(Class<? extends View> cls) {
+    context().rendered = true;
+    injector().getInstance(cls).render();
+  }
+
+  /**
+   * Convenience method for REST APIs (without explicit views)
+   * @param object - the object as the response (in JSON)
+   */
+  protected void renderJSON(Object object) {
+    LOG.debug("{}: {}", MimeType.JSON, object);
+    context().rendered = true;
+    context().response.setContentType(MimeType.JSON);
+    try {
+      jsonMapper.writeValue(writer(), object);
+    } catch (Exception e) {
+      throw new WebAppException(e);
+    }
+  }
+
+  protected void renderJSON(Class<? extends ToJSON> cls) {
+    context().rendered = true;
+    response().setContentType(MimeType.JSON);
+    injector().getInstance(cls).toJSON(writer());
+  }
+
+  /**
+   * Convenience method for hello world :)
+   * @param s - the content to render as plain text
+   */
+  protected void renderText(String s) {
+    LOG.debug("{}: {}", MimeType.TEXT, s);
+    context().rendered = true;
+    response().setContentType(MimeType.TEXT);
+    writer().print(s);
+  }
+
+  protected PrintWriter writer() {
+    try {
+      return response().getWriter();
+    } catch (Exception e) {
+      throw new WebAppException(e);
+    }
+  }
+}



Mime
View raw message