/*******************************************************************************
* Copyright (c) 2012-2017 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.plugin.docker.machine;
import org.eclipse.che.api.core.model.machine.Machine;
import org.eclipse.che.api.core.model.machine.MachineConfig;
import org.eclipse.che.api.environment.server.ContainerNameGenerator;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This class is used for generation docker container name or parsing important information from docker container name.
*
* @author Alexander Andrienko
*/
public class DockerContainerNameGenerator implements ContainerNameGenerator {
private static final String NODE_HOST_GROUP = "(/|(/[0-9a-z.-]+/))?";
private static final String WORKSPACE_ID_GROUP = "(?<workspaceId>workspace[0-9a-z]+)";
private static final String MACHINE_ID_GROUP = "(?<machineId>machine[0-9a-z]+)";
private static final String CONTAINER_NAME_REGEX = "^" + NODE_HOST_GROUP + WORKSPACE_ID_GROUP + "_" + MACHINE_ID_GROUP + "_.+$";
private static final Pattern CONTAINER_NAME_PATTERN = Pattern.compile(CONTAINER_NAME_REGEX);
/**
* Return generated name for docker container. Method generate name for docker container in format:
* <br><p>workspaceId + "_" + machineId + "_" + userName +"_" + machineName</p>
* <b>Notice: if generated container name contains incorrect symbols for creation docker container, then we skip this symbols</b>
*
* @param workspaceId
* unique workspace id, see more (@link WorkspaceConfig#getId)
* @param machineId
* unique machine id, see more {@link Machine#getId()}
* @param userName
* name of the user who is docker container owner
* @param machineName
* name of the workspace machine, see more {@link MachineConfig#getName()}
*/
@Override
public String generateContainerName(String workspaceId, String machineId, String userName, String machineName) {
String containerName = workspaceId + '_' + machineId + '_' + userName + '_' + machineName;
return containerName.toLowerCase().replaceAll("[^a-z0-9_-]+", "");
}
/**
* Parse machine's {@code containerName} to get information about this container (like workspaceId, machineId).
* Notice: method doesn't parse information about userName or machineName, because we do not give guarantees
* about the integrity of this data(see more {@link #generateContainerName(String, String, String, String)})
* Notice: container name can contains node host (e.g. "/node-host.dev.box/workspacebbx2_machineic3_user321_ws-machine)
*
* @param containerName
* name of the container
* @return information about container
*/
public Optional<ContainerNameInfo> parse(String containerName) {
Matcher matcher = CONTAINER_NAME_PATTERN.matcher(containerName);
ContainerNameInfo containerNameInfo = null;
if (matcher.matches()) {
String workspaceId = matcher.group("workspaceId");
String machineId = matcher.group("machineId");
containerNameInfo = new ContainerNameInfo(workspaceId, machineId);
}
return Optional.ofNullable(containerNameInfo);
}
/**
* Class contains information about docker container, which was parsed from docker container name.
* Usually used {@link #parse(String)}
*/
public static class ContainerNameInfo {
private final String workspaceId;
private final String machineId;
private ContainerNameInfo(String workspaceId, String machineId) {
this.workspaceId = workspaceId;
this.machineId = machineId;
}
/**
* Return machineId of the docker container.
*/
public String getMachineId() {
return machineId;
}
/**
* Return workspaceId of the docker container.
*/
public String getWorkspaceId() {
return workspaceId;
}
@Override
public String toString() {
return "ContainerNameInfo{" +
"workspaceId='" + workspaceId + '\'' +
", machineId='" + machineId + '\'' +
'}';
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ContainerNameInfo)) return false;
final ContainerNameInfo other = (ContainerNameInfo)obj;
return Objects.equals(workspaceId, other.workspaceId)
&& Objects.equals(machineId, other.machineId);
}
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + Objects.hashCode(workspaceId);
hash = 31 * hash + Objects.hashCode(machineId);
return hash;
}
}
}