Skip to content

Commit

Permalink
TW-78731: [Azure] Allow more than 12 symbols in Provision Username fi…
Browse files Browse the repository at this point in the history
…eld (#143)

* chore: added more logs for issue investigation

* fix: compatibility with 2022.04 and higher

* fix: compatibility with 2022.04 and higher

* fix: cleanup easy warnings

* feat: TW-78731 Allow more than 12 symbols in Provision Username field

* fix: after review

* fix: after review
  • Loading branch information
wayfarer-rus authored Nov 29, 2022
1 parent 0e50876 commit d3f4e97
Show file tree
Hide file tree
Showing 12 changed files with 286 additions and 283 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ object AzureCompress {
GZIPOutputStream(byteStream).use { stream ->
stream.bufferedWriter().use { writer ->
env.forEach {
writer.appendln("${it.key}=${it.value}")
writer.appendLine("${it.key}=${it.value}")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,31 +103,31 @@ object AzureMetadata {
.useSystemProperties()
.setDefaultRequestConfig(requestConfig)
.build().use {
val response = try {
try {
it.execute(HttpPost(SCHEDULED_EVENTS_METADATA_URL).apply {
val approval = ScheduledRequestApproval(documentIncarnation, listOf(StartRequest(eventId)))
entity = StringEntity(serializeApprovelRequest(approval), ContentType.APPLICATION_JSON)
entity = StringEntity(serializeApprovalRequest(approval), ContentType.APPLICATION_JSON)
})
} catch (e: Exception) {
throw IOException("Failed to connect to $SCHEDULED_EVENTS_METADATA_URL: ${e.message}")
}
}
}
}

private fun serializeApprovelRequest(approval: ScheduledRequestApproval): String {
return GSON.toJson(approval);
private fun serializeApprovalRequest(approval: ScheduledRequestApproval): String {
return GSON.toJson(approval)
}

fun deserializeInstanceMetadata(json: String): Metadata = try {
GSON.fromJson<Metadata>(json, Metadata::class.java)
GSON.fromJson(json, Metadata::class.java)
} catch (e: Exception) {
throw IOException("Invalid instance metadata ${e.message}", e)
}

fun deserializeScheduledEventsMetadata(json: String?): ScheduledEventsMetadata? {
private fun deserializeScheduledEventsMetadata(json: String?): ScheduledEventsMetadata? {
return json?.let {
try {
GSON.fromJson<ScheduledEventsMetadata>(json, ScheduledEventsMetadata::class.java)
GSON.fromJson(json, ScheduledEventsMetadata::class.java)
} catch (e: Exception) {
throw IOException("Invalid instance metadata ${e.message}", e)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,6 @@
package jetbrains.buildServer.clouds.base;

import com.intellij.openapi.diagnostic.Logger;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import jetbrains.buildServer.clouds.*;
import jetbrains.buildServer.clouds.base.beans.CloudImageDetails;
import jetbrains.buildServer.clouds.base.connector.CloudApiConnector;
Expand All @@ -37,111 +30,116 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
* @author Sergey.Pak
* Date: 7/22/2014
* Time: 1:49 PM
* Date: 7/22/2014
* Time: 1:49 PM
*/
public abstract class AbstractCloudClient<G extends AbstractCloudInstance<T>, T extends AbstractCloudImage<G, D>, D extends CloudImageDetails>
implements CloudClientEx, UpdatableCloudErrorProvider {

private static final Logger LOG = Logger.getInstance(AbstractCloudClient.class.getName());
protected final Map<String, T> myImageMap;
protected final UpdatableCloudErrorProvider myErrorProvider;
protected final CloudAsyncTaskExecutor myAsyncTaskExecutor;
@NotNull
protected final CloudApiConnector myApiConnector;
protected final CloudClientParameters myParameters;
private volatile boolean myIsInitialized = false;

public AbstractCloudClient(@NotNull final CloudClientParameters params, @NotNull final CloudApiConnector apiConnector) {
myParameters = params;
myAsyncTaskExecutor = new CloudAsyncTaskExecutor("Async tasks for cloud " + params.getProfileDescription());
myImageMap = new HashMap<String, T>();
myErrorProvider = new CloudErrorMap(new DefaultErrorMessageUpdater());
myApiConnector = apiConnector;
}

public boolean isInitialized() {
return myIsInitialized;
}


public void dispose() {
myAsyncTaskExecutor.dispose();
}

@NotNull
public G startNewInstance(@NotNull final CloudImage baseImage, @NotNull final CloudInstanceUserData tag) throws QuotaException {
final T image = (T) baseImage;
return image.startNewInstance(tag);
}

public void restartInstance(@NotNull final CloudInstance baseInstance) {
final G instance = (G) baseInstance;
instance.getImage().restartInstance(instance);
}

public void terminateInstance(@NotNull final CloudInstance baseInstance) {
final G instance = (G) baseInstance;
instance.getImage().terminateInstance(instance);
}

public boolean canStartNewInstance(@NotNull final CloudImage baseImage) {
final T image = (T) baseImage;
return image.canStartNewInstance();
}

public void populateImagesData(@NotNull final Collection<D> imageDetails) {
populateImagesData(imageDetails, 60 * 1000, 20 * 1000);
}

public void populateImagesData(@NotNull final Collection<D> imageDetails, final long initialDelayMs, final long delayMs) {
for (D details : imageDetails) {
T image = checkAndCreateImage(details);
myImageMap.put(image.getName(), image);
implements CloudClientEx, UpdatableCloudErrorProvider {

private static final Logger LOG = Logger.getInstance(AbstractCloudClient.class.getName());
protected final Map<String, T> myImageMap;
protected final UpdatableCloudErrorProvider myErrorProvider;
protected final CloudAsyncTaskExecutor myAsyncTaskExecutor;
@NotNull
protected final CloudApiConnector myApiConnector;
protected final CloudClientParameters myParameters;
private volatile boolean myIsInitialized = false;

public AbstractCloudClient(@NotNull final CloudClientParameters params, @NotNull final CloudApiConnector apiConnector) {
myParameters = params;
myAsyncTaskExecutor = new CloudAsyncTaskExecutor("Async tasks for cloud " + params.getProfileDescription());
myImageMap = new HashMap<>();
myErrorProvider = new CloudErrorMap(new DefaultErrorMessageUpdater());
myApiConnector = apiConnector;
}
final UpdateInstancesTask<G, T, ?> updateInstancesTask = createUpdateInstancesTask();
if (updateInstancesTask == null) {
return;

public boolean isInitialized() {
return myIsInitialized;
}


public void dispose() {
myAsyncTaskExecutor.dispose();
}
myAsyncTaskExecutor.submit("Populate images data", new Runnable() {
public void run() {
try {
updateInstancesTask.run();
myAsyncTaskExecutor.scheduleWithFixedDelay("Update instances", updateInstancesTask, initialDelayMs, delayMs, TimeUnit.MILLISECONDS);
} finally {
myIsInitialized = true;
LOG.info("Cloud profile '" + myParameters.getProfileDescription() + "' initialized");

@NotNull
public G startNewInstance(@NotNull final CloudImage baseImage, @NotNull final CloudInstanceUserData tag) throws QuotaException {
final T image = (T) baseImage;
return image.startNewInstance(tag);
}

public void restartInstance(@NotNull final CloudInstance baseInstance) {
final G instance = (G) baseInstance;
instance.getImage().restartInstance(instance);
}

public void terminateInstance(@NotNull final CloudInstance baseInstance) {
final G instance = (G) baseInstance;
instance.getImage().terminateInstance(instance);
}

public boolean canStartNewInstance(@NotNull final CloudImage baseImage) {
final T image = (T) baseImage;
return image.canStartNewInstance().isPositive();
}

@NotNull
@Override
public CanStartNewInstanceResult canStartNewInstanceWithDetails(@NotNull CloudImage image) {
final T img = (T) image;
return img.canStartNewInstance();
}

public void populateImagesData(@NotNull final Collection<D> imageDetails, final long initialDelayMs, final long delayMs) {
for (D details : imageDetails) {
T image = checkAndCreateImage(details);
myImageMap.put(image.getName(), image);
}
}
});
}
final UpdateInstancesTask<G, T, ?> updateInstancesTask = createUpdateInstancesTask();

myAsyncTaskExecutor.submit("Populate images data", () -> {
try {
updateInstancesTask.run();
myAsyncTaskExecutor.scheduleWithFixedDelay("Update instances", updateInstancesTask, initialDelayMs, delayMs, TimeUnit.MILLISECONDS);
} finally {
myIsInitialized = true;
LOG.info("Cloud profile '" + myParameters.getProfileDescription() + "' initialized");
}
});
}

protected abstract T checkAndCreateImage(@NotNull final D imageDetails);
protected abstract T checkAndCreateImage(@NotNull final D imageDetails);

@NotNull
protected abstract UpdateInstancesTask<G, T, ?> createUpdateInstancesTask();
@NotNull
protected abstract UpdateInstancesTask<G, T, ?> createUpdateInstancesTask();

@Nullable
public abstract G findInstanceByAgent(@NotNull final AgentDescription agent);
@Nullable
public abstract G findInstanceByAgent(@NotNull final AgentDescription agent);

@Nullable
public T findImageById(@NotNull final String imageId) throws CloudException {
return myImageMap.get(imageId);
}
@Nullable
public T findImageById(@NotNull final String imageId) throws CloudException {
return myImageMap.get(imageId);
}

@NotNull
public Collection<T> getImages() throws CloudException {
return Collections.unmodifiableCollection(myImageMap.values());
}
@NotNull
public Collection<T> getImages() throws CloudException {
return Collections.unmodifiableCollection(myImageMap.values());
}

public void updateErrors(final TypedCloudErrorInfo... errors) {
myErrorProvider.updateErrors(errors);
}
public void updateErrors(final TypedCloudErrorInfo... errors) {
myErrorProvider.updateErrors(errors);
}

@Nullable
public CloudErrorInfo getErrorInfo() {
return myErrorProvider.getErrorInfo();
}
@Nullable
public CloudErrorInfo getErrorInfo() {
return myErrorProvider.getErrorInfo();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@

package jetbrains.buildServer.clouds.base;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import jetbrains.buildServer.clouds.CanStartNewInstanceResult;
import jetbrains.buildServer.clouds.CloudErrorInfo;
import jetbrains.buildServer.clouds.CloudImage;
import jetbrains.buildServer.clouds.CloudInstanceUserData;
Expand All @@ -33,6 +29,11 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* @author Sergey.Pak
* Date: 7/22/2014
Expand Down Expand Up @@ -94,7 +95,7 @@ public boolean addInstanceIfAbsent(@NotNull final T instance) {
return result == null;
}

public abstract boolean canStartNewInstance();
public abstract CanStartNewInstanceResult canStartNewInstance();

public abstract void terminateInstance(@NotNull final T instance);

Expand Down
Loading

0 comments on commit d3f4e97

Please sign in to comment.