adding Application locks, Application Holder and persisting in Autoscaler
Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/18f16549 Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/18f16549 Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/18f16549 Branch: refs/heads/docker-grouping-merge Commit: 18f16549c953f5355afd34c10882c2723e78d9de Parents: 275ba2d Author: Isuru Haththotuwa <[email protected]> Authored: Fri Oct 31 13:34:23 2014 +0530 Committer: Isuru Haththotuwa <[email protected]> Committed: Fri Oct 31 13:34:38 2014 +0530 ---------------------------------------------------------------------- .../applications/ApplicationHolder.java | 113 +++++++++++++++++++ .../autoscaler/registry/RegistryManager.java | 42 +++++++ .../autoscaler/util/AutoScalerConstants.java | 2 +- .../stratos/autoscaler/util/AutoscalerUtil.java | 49 +++++--- .../domain/applications/Applications.java | 46 ++++++++ .../applications/locking/ApplicationLock.java | 59 ++++++++++ .../locking/ApplicationLockHierarchy.java | 88 +++++++++++++++ 7 files changed, 382 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/18f16549/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationHolder.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationHolder.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationHolder.java new file mode 100644 index 0000000..e147d1b --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/ApplicationHolder.java @@ -0,0 +1,113 @@ +/* + * 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.stratos.autoscaler.applications; + +import com.google.gson.Gson; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.util.AutoscalerUtil; +import org.apache.stratos.messaging.domain.applications.Application; +import org.apache.stratos.messaging.domain.applications.Applications; + +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class ApplicationHolder { + + private static final Log log = LogFactory.getLog(ApplicationHolder.class); + + private static volatile ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); + private static volatile ReentrantReadWriteLock.ReadLock readLock = lock.readLock(); + private static volatile ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock(); + private static volatile Applications applications; + + private ApplicationHolder () {} + + public static void acquireReadLock() { + if(log.isDebugEnabled()) { + log.debug("Read lock acquired"); + } + readLock.lock(); + } + + public static void releaseReadLock() { + if(log.isDebugEnabled()) { + log.debug("Read lock released"); + } + readLock.unlock(); + } + + public static void acquireWriteLock() { + if(log.isDebugEnabled()) { + log.debug("Write lock acquired"); + } + writeLock.lock(); + } + + public static void releaseWriteLock() { + if(log.isDebugEnabled()) { + log.debug("Write lock released"); + } + writeLock.unlock(); + } + + public static Applications getApplications () { + + if (applications == null) { + synchronized (ApplicationHolder.class) { + if (applications == null) { + // retrieve from registry + applications = AutoscalerUtil.getApplications(); + if (log.isDebugEnabled()) { + log.debug("Trying to retrieve Applications from registry"); + } + if (applications == null) { + if (log.isDebugEnabled()) { + log.debug("No applications found in Registry"); + } + // create a new Applications object + applications = new Applications(); + } + } + } + } + + return applications; + } + + public static void persistApplication (Application application) { + + synchronized (ApplicationHolder.class) { + if (log.isDebugEnabled()) { + log.debug("Updating topology"); + } + applications.addApplication(application); + AutoscalerUtil.persistApplication(application); + if (log.isDebugEnabled()) { + log.debug(String.format("Topology updated: %s", toJson(applications))); + } + } + + } + + private static String toJson(Object object) { + Gson gson = new Gson(); + return gson.toJson(object); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/18f16549/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/registry/RegistryManager.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/registry/RegistryManager.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/registry/RegistryManager.java index 7b3413e..25caf0e 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/registry/RegistryManager.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/registry/RegistryManager.java @@ -32,6 +32,8 @@ import org.apache.stratos.autoscaler.util.Deserializer; import org.apache.stratos.autoscaler.util.Serializer; import org.apache.stratos.autoscaler.util.ServiceReferenceHolder; import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; +import org.apache.stratos.messaging.domain.applications.Application; +import org.apache.stratos.messaging.domain.applications.Applications; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.Resource; import org.wso2.carbon.registry.core.exceptions.RegistryException; @@ -139,6 +141,46 @@ public class RegistryManager { log.debug(deploymentPolicy.toString()); } } + + public void persistApplication (Application application) { + + String resourcePath = AutoScalerConstants.AUTOSCALER_RESOURCE + AutoScalerConstants.APPLICATIONS_RESOURCE + + "/" + application.getUniqueIdentifier(); + persist(application, resourcePath); + if(log.isDebugEnabled()) { + log.debug("Application [ " + application.getUniqueIdentifier() + + " ] persisted successfully in the Autoscaler Registry"); + } + } + + public String [] getApplicationResourcePaths () { + Object obj = retrieve(AutoScalerConstants.AUTOSCALER_RESOURCE + + AutoScalerConstants.APPLICATIONS_RESOURCE); + + if (obj != null) { + if (obj instanceof String []) { + return (String []) obj; + } else { + log.warn("Expected object type not found for Applications in Registry"); + return null; + } + } + return null; + } + + public Application getApplication (String applicationResourcePath) { + Object obj = retrieve(applicationResourcePath); + + if (obj != null) { + if (obj instanceof Application) { + return (Application) obj; + } else { + log.warn("Expected object type not found for Application " + applicationResourcePath + " in Registry"); + return null; + } + } + return null; + } private Object retrieve(String resourcePath) { try { http://git-wip-us.apache.org/repos/asf/stratos/blob/18f16549/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoScalerConstants.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoScalerConstants.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoScalerConstants.java index 03cf861..b30e0e6 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoScalerConstants.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoScalerConstants.java @@ -38,7 +38,7 @@ public final class AutoScalerConstants { public static final String NETWORK_PARTITION_LB_HOLDER_RESOURCE = "/network-partitions"; public static final String AS_POLICY_RESOURCE = "/policies/autoscalingPolicies"; public static final String DEPLOYMENT_POLICY_RESOURCE = "/policies/deploymentPolicies"; - + public static final String APPLICATIONS_RESOURCE = "/applications"; /** * Configs http://git-wip-us.apache.org/repos/asf/stratos/blob/18f16549/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java index 59dda9f..4b95118 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java @@ -22,24 +22,12 @@ package org.apache.stratos.autoscaler.util; import org.apache.axiom.om.OMElement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.stratos.autoscaler.MemberStatsContext; -import org.apache.stratos.autoscaler.NetworkPartitionContext; -import org.apache.stratos.autoscaler.NetworkPartitionLbHolder; -import org.apache.stratos.autoscaler.PartitionContext; -import org.apache.stratos.autoscaler.deployment.policy.DeploymentPolicy; -import org.apache.stratos.autoscaler.exception.PartitionValidationException; -import org.apache.stratos.autoscaler.exception.PolicyValidationException; -import org.apache.stratos.autoscaler.monitor.cluster.LbClusterMonitor; -import org.apache.stratos.autoscaler.partition.PartitionGroup; -import org.apache.stratos.autoscaler.partition.PartitionManager; -import org.apache.stratos.autoscaler.policy.PolicyManager; -import org.apache.stratos.autoscaler.policy.model.AutoscalePolicy; -import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; -import org.apache.stratos.cloud.controller.stub.pojo.MemberContext; +import org.apache.stratos.autoscaler.registry.RegistryManager; import org.apache.stratos.cloud.controller.stub.pojo.Property; import org.apache.stratos.cloud.controller.stub.pojo.Properties; -import org.apache.stratos.messaging.domain.topology.*; -import org.apache.stratos.messaging.util.Constants; +import org.apache.stratos.messaging.domain.applications.Application; +import org.apache.stratos.messaging.domain.applications.Applications; + import javax.xml.namespace.QName; import java.util.*; @@ -55,6 +43,35 @@ public class AutoscalerUtil { } + public static Applications getApplications () { + + Applications applications; + String [] appResourcePaths = RegistryManager.getInstance().getApplicationResourcePaths(); + if (appResourcePaths != null) { + applications = new Applications(); + for (String appResourcePath : appResourcePaths) { + applications.addApplication(getApplicationFromPath(appResourcePath)); + } + + return applications; + } + + return null; + } + + public static Application getApplication (String appId) { + return getApplicationFromPath(AutoScalerConstants.AUTOSCALER_RESOURCE + AutoScalerConstants.APPLICATIONS_RESOURCE + + "/" + appId); + } + + public static void persistApplication (Application application) { + RegistryManager.getInstance().persistApplication(application); + } + + private static Application getApplicationFromPath (String appResourcePath) { + return RegistryManager.getInstance().getApplication(appResourcePath); + } + /*public static LbClusterMonitor getLBClusterMonitor(Cluster cluster) throws PolicyValidationException, PartitionValidationException { // FIXME fix the following code to correctly update // AutoscalerContext context = AutoscalerContext.getInstance(); http://git-wip-us.apache.org/repos/asf/stratos/blob/18f16549/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/Applications.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/Applications.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/Applications.java new file mode 100644 index 0000000..9455a4c --- /dev/null +++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/Applications.java @@ -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.stratos.messaging.domain.applications; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +public class Applications implements Serializable { + + private static Log log = LogFactory.getLog(Applications.class); + + private Map<String, Application> applicationMap; + + public Applications () { + this.applicationMap = new HashMap<String, Application>(); + } + + public void addApplication (Application application) { + this.applicationMap.put(application.getUniqueIdentifier(), application); + } + + public Application getApplication (String appId) { + return this.applicationMap.get(appId); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/18f16549/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/locking/ApplicationLock.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/locking/ApplicationLock.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/locking/ApplicationLock.java new file mode 100644 index 0000000..5d01e36 --- /dev/null +++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/locking/ApplicationLock.java @@ -0,0 +1,59 @@ +/* + * 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.stratos.messaging.domain.applications.locking; + +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class ApplicationLock { + + private final ReentrantReadWriteLock lock; + + public ApplicationLock () { + lock = new ReentrantReadWriteLock(true); + } + + /** + * acquires write lock + */ + public void acquireWriteLock() { + lock.writeLock().lock(); + } + + /** + * releases write lock + */ + public void releaseWritelock() { + lock.writeLock().unlock(); + } + + /** + * acquires read lock + */ + public void acquireReadLock() { + lock.readLock().lock(); + } + + /** + * releases read lock + */ + public void releaseReadLock() { + lock.readLock().unlock(); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/18f16549/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/locking/ApplicationLockHierarchy.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/locking/ApplicationLockHierarchy.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/locking/ApplicationLockHierarchy.java new file mode 100644 index 0000000..71bfe03 --- /dev/null +++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/applications/locking/ApplicationLockHierarchy.java @@ -0,0 +1,88 @@ +/* + * 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.stratos.messaging.domain.applications.locking; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.HashMap; +import java.util.Map; + +public class ApplicationLockHierarchy { + + private static final Log log = LogFactory.getLog(ApplicationLockHierarchy.class); + + // lock for Applications + private final ApplicationLock applicationLock; + + // key = Application.id + private final Map<String, ApplicationLock> appIdToApplicationLockMap; + + private static volatile ApplicationLockHierarchy applicationLockHierarchy; + + private ApplicationLockHierarchy () { + this.applicationLock = new ApplicationLock(); + this.appIdToApplicationLockMap = new HashMap<String, ApplicationLock>(); + } + + public static ApplicationLockHierarchy getInstance () { + + if (applicationLockHierarchy == null) { + synchronized (ApplicationLockHierarchy.class) { + if (applicationLockHierarchy == null) { + applicationLockHierarchy = new ApplicationLockHierarchy(); + } + } + } + + return applicationLockHierarchy; + } + + public void addApplicationLock (String appId, final ApplicationLock appLock) { + + if (!appIdToApplicationLockMap.containsKey(appId)) { + synchronized (appIdToApplicationLockMap) { + if (!appIdToApplicationLockMap.containsKey(appId)) { + appIdToApplicationLockMap.put(appId, appLock); + log.info("Added lock for Application " + appId); + } + } + } else { + if (log.isDebugEnabled()) { + log.debug("Topology Lock for Application " + appId + " already exists"); + } + } + } + + public ApplicationLock getLock (String appId) { + return appIdToApplicationLockMap.get(appId); + } + + public void removeLock (String appId) { + if (appIdToApplicationLockMap.remove(appId) != null) { + log.info("Removed lock for Application " + appId); + } else { + if (log.isDebugEnabled()) { + log.debug("Lock already removed for Application " + appId); + } + } + } + +}
