You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@brooklyn.apache.org by alasdairhodge <gi...@git.apache.org> on 2017/12/08 09:59:50 UTC

[GitHub] brooklyn-server pull request #913: AbstractMachineLocation base class

GitHub user alasdairhodge opened a pull request:

    https://github.com/apache/brooklyn-server/pull/913

    AbstractMachineLocation base class

    Introduces `AbstractMachineLocation` base class to hold responsibilities that may otherwise be duplicated between `SshMachineLocation` and `WinRmMachineLocation`.

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/alasdairhodge/brooklyn-server abstract-machine-location

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/brooklyn-server/pull/913.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #913
    
----
commit 7e813b2da75f15e1b63bc849ef81bb50c315af5e
Author: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Date:   2017-12-07T18:29:43Z

    Introduce `AbstractMachineLocation` base class.

commit 061cf15e16ce31eec1b0429592557784096107c1
Author: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Date:   2017-12-07T18:47:37Z

    Pull-up machine details

commit 2d417be7fb4105b0a978cee5a193680b1b949cf3
Author: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Date:   2017-12-07T18:50:55Z

    Pull-up mutex support.

commit c09a2ebfd03444aebbd59050da78ea876ed4ba95
Author: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Date:   2017-12-07T18:51:17Z

    Trivial tidies.

----


---

[GitHub] brooklyn-server pull request #913: AbstractMachineLocation base class

Posted by aledsage <gi...@git.apache.org>.
Github user aledsage commented on a diff in the pull request:

    https://github.com/apache/brooklyn-server/pull/913#discussion_r155803922
  
    --- Diff: core/src/main/java/org/apache/brooklyn/core/location/AbstractMachineLocation.java ---
    @@ -0,0 +1,131 @@
    +/*
    + * 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.brooklyn.core.location;
    +
    +import java.util.Map;
    +
    +import org.apache.brooklyn.api.location.MachineDetails;
    +import org.apache.brooklyn.api.location.MachineLocation;
    +import org.apache.brooklyn.api.location.OsDetails;
    +import org.apache.brooklyn.config.ConfigKey;
    +import org.apache.brooklyn.core.config.ConfigKeys;
    +import org.apache.brooklyn.util.collections.MutableMap;
    +import org.apache.brooklyn.util.core.mutex.MutexSupport;
    +import org.apache.brooklyn.util.core.mutex.WithMutexes;
    +import org.apache.brooklyn.util.exceptions.RuntimeInterruptedException;
    +
    +import com.google.common.base.Optional;
    +
    +public abstract class AbstractMachineLocation extends AbstractLocation implements MachineLocation, WithMutexes {
    +
    +    public static final ConfigKey<MachineDetails> MACHINE_DETAILS = ConfigKeys.newConfigKey(
    +            MachineDetails.class,
    +            "machineDetails");
    +
    +    public static final ConfigKey<Boolean> DETECT_MACHINE_DETAILS = ConfigKeys.newBooleanConfigKey("detectMachineDetails",
    +            "Attempt to detect machine details automatically.", true);
    +
    +    protected static final MachineDetails UNKNOWN_MACHINE_DETAILS = new BasicMachineDetails(
    +            new BasicHardwareDetails(-1, -1),
    +            new BasicOsDetails("UNKNOWN", "UNKNOWN", "UNKNOWN")
    +    );
    +
    +    private volatile MachineDetails machineDetails;
    +    private final Object machineDetailsLock = new Object();
    +
    +    private transient WithMutexes mutexSupport;
    +    private transient final Object mutexSupportCreationLock = new Object();
    +
    +
    +    public AbstractMachineLocation() {
    +        this(MutableMap.of());
    +    }
    +
    +    public AbstractMachineLocation(Map<?,?> properties) {
    +        super(properties);
    +    }
    +
    +    /**
    +     * Returns the machine details only if they are already loaded, or available directly as
    +     * config.
    +     */
    +    protected Optional<MachineDetails> getOptionalMachineDetails() {
    +        MachineDetails result = machineDetails != null ? machineDetails : config().get(MACHINE_DETAILS);
    +        return Optional.fromNullable(result);
    +    }
    +
    +    @Override
    +    public MachineDetails getMachineDetails() {
    +        synchronized (machineDetailsLock) {
    +            if (machineDetails == null) {
    +                machineDetails = getConfig(MACHINE_DETAILS);
    +            }
    +            if (machineDetails == null) {
    +                boolean detectionEnabled = getConfig(DETECT_MACHINE_DETAILS);
    +                if (!detectionEnabled || !isManaged()) {
    +                    return UNKNOWN_MACHINE_DETAILS;
    +                }
    +                machineDetails = detectMachineDetails();
    +            }
    +            return machineDetails;
    +        }
    +    }
    +
    +    @Override
    +    public OsDetails getOsDetails() {
    +        return getMachineDetails().getOsDetails();
    +    }
    +
    +    protected abstract MachineDetails detectMachineDetails();
    +
    +    @Override
    +    public void acquireMutex(String mutexId, String description) throws RuntimeInterruptedException {
    --- End diff --
    
    We previously discussed a `MutexSupport mutexes()` method, rather than having all these methods on machine location.
    
    What do you think about just having the `mutexes()` method on `AbstractMachineLocation` (which would have the impl that `getMutexSupport` has), and then leaving the `acquireMutex` etc only in `SshMachineLocation`. We could deprecate the methods there, if we think it's better to do things like `mutexes().acquireMutex()`.
    
    If we did that, then the `AbstractMachineLocation` would not implement `WithMutexes`.


---

[GitHub] brooklyn-server pull request #913: AbstractMachineLocation base class

Posted by asfgit <gi...@git.apache.org>.
Github user asfgit closed the pull request at:

    https://github.com/apache/brooklyn-server/pull/913


---

[GitHub] brooklyn-server issue #913: AbstractMachineLocation base class

Posted by alasdairhodge <gi...@git.apache.org>.
Github user alasdairhodge commented on the issue:

    https://github.com/apache/brooklyn-server/pull/913
  
    Silly issues now resolved, @aledsage 


---

[GitHub] brooklyn-server issue #913: AbstractMachineLocation base class

Posted by alasdairhodge <gi...@git.apache.org>.
Github user alasdairhodge commented on the issue:

    https://github.com/apache/brooklyn-server/pull/913
  
    /cc @aledsage Provides `WithMutexes` capabilities to `WinRmMachineLocation` 


---

[GitHub] brooklyn-server issue #913: AbstractMachineLocation base class

Posted by alasdairhodge <gi...@git.apache.org>.
Github user alasdairhodge commented on the issue:

    https://github.com/apache/brooklyn-server/pull/913
  
    Argh, forgot that interim push woiuld trigger rebuild... in progress.


---

[GitHub] brooklyn-server pull request #913: AbstractMachineLocation base class

Posted by aledsage <gi...@git.apache.org>.
Github user aledsage commented on a diff in the pull request:

    https://github.com/apache/brooklyn-server/pull/913#discussion_r156085895
  
    --- Diff: core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java ---
    @@ -1104,4 +1013,36 @@ public String findPassword() {
             return getConfig(SshTool.PROP_PASSWORD);
         }
     
    +    /** @deprecated since 5.0.1; mutex-related methods are now accessible via {@link #mutexes()} */
    --- End diff --
    
    Should be `since 1.0.0` (same elsewhere).


---

[GitHub] brooklyn-server pull request #913: AbstractMachineLocation base class

Posted by alasdairhodge <gi...@git.apache.org>.
Github user alasdairhodge commented on a diff in the pull request:

    https://github.com/apache/brooklyn-server/pull/913#discussion_r156087749
  
    --- Diff: core/src/main/java/org/apache/brooklyn/location/localhost/LocalhostMachineProvisioningLocation.java ---
    @@ -268,22 +266,15 @@ public void release(SshMachineLocation machine) {
                     BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, 
                     true);
     
    -        private static final WithMutexes mutexSupport = new MutexSupport();
    --- End diff --
    
    Excellent catch, thanks.


---

[GitHub] brooklyn-server pull request #913: AbstractMachineLocation base class

Posted by alasdairhodge <gi...@git.apache.org>.
Github user alasdairhodge commented on a diff in the pull request:

    https://github.com/apache/brooklyn-server/pull/913#discussion_r156087793
  
    --- Diff: core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java ---
    @@ -1104,4 +1013,36 @@ public String findPassword() {
             return getConfig(SshTool.PROP_PASSWORD);
         }
     
    +    /** @deprecated since 5.0.1; mutex-related methods are now accessible via {@link #mutexes()} */
    --- End diff --
    
    D'oh!


---

[GitHub] brooklyn-server pull request #913: AbstractMachineLocation base class

Posted by aledsage <gi...@git.apache.org>.
Github user aledsage commented on a diff in the pull request:

    https://github.com/apache/brooklyn-server/pull/913#discussion_r156085783
  
    --- Diff: core/src/main/java/org/apache/brooklyn/location/localhost/LocalhostMachineProvisioningLocation.java ---
    @@ -268,22 +266,15 @@ public void release(SshMachineLocation machine) {
                     BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, 
                     true);
     
    -        private static final WithMutexes mutexSupport = new MutexSupport();
    --- End diff --
    
    You've change the semantics for localhost - note that this field was static. To preserve that, you can override `WithMutexes mutexes()` to return the static field.
    
    I think you'll be fine removing from the constructor the bit that sets it in the map (note that `SshMachineLocation.mutexSupport` was marked with `@SetFromFlag`). By just overriding `mutexes()`, I think it should be enough.


---

[GitHub] brooklyn-server issue #913: AbstractMachineLocation base class

Posted by aledsage <gi...@git.apache.org>.
Github user aledsage commented on the issue:

    https://github.com/apache/brooklyn-server/pull/913
  
    Thanks @alasdairhodge - LGTM; merging.


---

[GitHub] brooklyn-server pull request #913: AbstractMachineLocation base class

Posted by aledsage <gi...@git.apache.org>.
Github user aledsage commented on a diff in the pull request:

    https://github.com/apache/brooklyn-server/pull/913#discussion_r156030583
  
    --- Diff: core/src/main/java/org/apache/brooklyn/core/location/AbstractMachineLocation.java ---
    @@ -0,0 +1,139 @@
    +/*
    + * 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.brooklyn.core.location;
    +
    +import java.util.Map;
    +
    +import org.apache.brooklyn.api.location.MachineDetails;
    +import org.apache.brooklyn.api.location.MachineLocation;
    +import org.apache.brooklyn.api.location.OsDetails;
    +import org.apache.brooklyn.config.ConfigKey;
    +import org.apache.brooklyn.core.config.ConfigKeys;
    +import org.apache.brooklyn.util.collections.MutableMap;
    +import org.apache.brooklyn.util.core.mutex.MutexSupport;
    +import org.apache.brooklyn.util.core.mutex.WithMutexes;
    +import org.apache.brooklyn.util.exceptions.RuntimeInterruptedException;
    +
    +import com.google.common.base.Optional;
    +
    +public abstract class AbstractMachineLocation extends AbstractLocation implements MachineLocation, WithMutexes {
    +
    +    public static final ConfigKey<MachineDetails> MACHINE_DETAILS = ConfigKeys.newConfigKey(
    +            MachineDetails.class,
    +            "machineDetails");
    +
    +    public static final ConfigKey<Boolean> DETECT_MACHINE_DETAILS = ConfigKeys.newBooleanConfigKey("detectMachineDetails",
    +            "Attempt to detect machine details automatically.", true);
    +
    +    protected static final MachineDetails UNKNOWN_MACHINE_DETAILS = new BasicMachineDetails(
    +            new BasicHardwareDetails(-1, -1),
    +            new BasicOsDetails("UNKNOWN", "UNKNOWN", "UNKNOWN")
    +    );
    +
    +    private volatile MachineDetails machineDetails;
    +    private final Object machineDetailsLock = new Object();
    +
    +    private transient WithMutexes mutexSupport;
    +    private transient final Object mutexSupportCreationLock = new Object();
    +
    +
    +    public AbstractMachineLocation() {
    +        this(MutableMap.of());
    +    }
    +
    +    public AbstractMachineLocation(Map<?,?> properties) {
    +        super(properties);
    +    }
    +
    +    /**
    +     * Returns the machine details only if they are already loaded, or available directly as
    +     * config.
    +     */
    +    protected Optional<MachineDetails> getOptionalMachineDetails() {
    +        MachineDetails result = machineDetails != null ? machineDetails : config().get(MACHINE_DETAILS);
    +        return Optional.fromNullable(result);
    +    }
    +
    +    @Override
    +    public MachineDetails getMachineDetails() {
    +        synchronized (machineDetailsLock) {
    +            if (machineDetails == null) {
    +                machineDetails = getConfig(MACHINE_DETAILS);
    +            }
    +            if (machineDetails == null) {
    +                boolean detectionEnabled = getConfig(DETECT_MACHINE_DETAILS);
    +                if (!detectionEnabled || !isManaged()) {
    +                    return UNKNOWN_MACHINE_DETAILS;
    +                }
    +                machineDetails = detectMachineDetails();
    +            }
    +            return machineDetails;
    +        }
    +    }
    +
    +    @Override
    +    public OsDetails getOsDetails() {
    +        return getMachineDetails().getOsDetails();
    +    }
    +
    +    protected abstract MachineDetails detectMachineDetails();
    +
    +    public WithMutexes mutexes() {
    +        synchronized (mutexSupportCreationLock) {
    +            // create on demand so that it is not null after serialization
    +            if (mutexSupport == null) {
    +                mutexSupport = new MutexSupport();
    +            }
    +            return mutexSupport;
    +        }
    +    }
    +
    +    /** @deprecated Mutex-related methods are now accessible via {@link #mutexes()} */
    +    @Override
    +    @Deprecated
    +    public void acquireMutex(String mutexId, String description) throws RuntimeInterruptedException {
    +        try {
    +            mutexes().acquireMutex(mutexId, description);
    +        } catch (InterruptedException ie) {
    +            throw new RuntimeInterruptedException("Interrupted waiting for mutex: " + mutexId, ie);
    +        }
    +    }
    +
    +    /** @deprecated Mutex-related methods are now accessible via {@link #mutexes()} */
    +    @Override
    +    @Deprecated
    +    public boolean tryAcquireMutex(String mutexId, String description) {
    --- End diff --
    
    Why have these on the new abstract super class? If we want people to use `mutexes().tryAcquireMutex()` instead, then we should leave these methods only on `SshMachineLocation`, and also `AbstractMachineLocation` should not implement `WithMutexes`. It seems wrong to add deprecated methods to the new super-class.


---

[GitHub] brooklyn-server pull request #913: AbstractMachineLocation base class

Posted by alasdairhodge <gi...@git.apache.org>.
Github user alasdairhodge commented on a diff in the pull request:

    https://github.com/apache/brooklyn-server/pull/913#discussion_r156030790
  
    --- Diff: core/src/main/java/org/apache/brooklyn/core/location/AbstractMachineLocation.java ---
    @@ -0,0 +1,139 @@
    +/*
    + * 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.brooklyn.core.location;
    +
    +import java.util.Map;
    +
    +import org.apache.brooklyn.api.location.MachineDetails;
    +import org.apache.brooklyn.api.location.MachineLocation;
    +import org.apache.brooklyn.api.location.OsDetails;
    +import org.apache.brooklyn.config.ConfigKey;
    +import org.apache.brooklyn.core.config.ConfigKeys;
    +import org.apache.brooklyn.util.collections.MutableMap;
    +import org.apache.brooklyn.util.core.mutex.MutexSupport;
    +import org.apache.brooklyn.util.core.mutex.WithMutexes;
    +import org.apache.brooklyn.util.exceptions.RuntimeInterruptedException;
    +
    +import com.google.common.base.Optional;
    +
    +public abstract class AbstractMachineLocation extends AbstractLocation implements MachineLocation, WithMutexes {
    +
    +    public static final ConfigKey<MachineDetails> MACHINE_DETAILS = ConfigKeys.newConfigKey(
    +            MachineDetails.class,
    +            "machineDetails");
    +
    +    public static final ConfigKey<Boolean> DETECT_MACHINE_DETAILS = ConfigKeys.newBooleanConfigKey("detectMachineDetails",
    +            "Attempt to detect machine details automatically.", true);
    +
    +    protected static final MachineDetails UNKNOWN_MACHINE_DETAILS = new BasicMachineDetails(
    +            new BasicHardwareDetails(-1, -1),
    +            new BasicOsDetails("UNKNOWN", "UNKNOWN", "UNKNOWN")
    +    );
    +
    +    private volatile MachineDetails machineDetails;
    +    private final Object machineDetailsLock = new Object();
    +
    +    private transient WithMutexes mutexSupport;
    +    private transient final Object mutexSupportCreationLock = new Object();
    +
    +
    +    public AbstractMachineLocation() {
    +        this(MutableMap.of());
    +    }
    +
    +    public AbstractMachineLocation(Map<?,?> properties) {
    +        super(properties);
    +    }
    +
    +    /**
    +     * Returns the machine details only if they are already loaded, or available directly as
    +     * config.
    +     */
    +    protected Optional<MachineDetails> getOptionalMachineDetails() {
    +        MachineDetails result = machineDetails != null ? machineDetails : config().get(MACHINE_DETAILS);
    +        return Optional.fromNullable(result);
    +    }
    +
    +    @Override
    +    public MachineDetails getMachineDetails() {
    +        synchronized (machineDetailsLock) {
    +            if (machineDetails == null) {
    +                machineDetails = getConfig(MACHINE_DETAILS);
    +            }
    +            if (machineDetails == null) {
    +                boolean detectionEnabled = getConfig(DETECT_MACHINE_DETAILS);
    +                if (!detectionEnabled || !isManaged()) {
    +                    return UNKNOWN_MACHINE_DETAILS;
    +                }
    +                machineDetails = detectMachineDetails();
    +            }
    +            return machineDetails;
    +        }
    +    }
    +
    +    @Override
    +    public OsDetails getOsDetails() {
    +        return getMachineDetails().getOsDetails();
    +    }
    +
    +    protected abstract MachineDetails detectMachineDetails();
    +
    +    public WithMutexes mutexes() {
    +        synchronized (mutexSupportCreationLock) {
    +            // create on demand so that it is not null after serialization
    +            if (mutexSupport == null) {
    +                mutexSupport = new MutexSupport();
    +            }
    +            return mutexSupport;
    +        }
    +    }
    +
    +    /** @deprecated Mutex-related methods are now accessible via {@link #mutexes()} */
    +    @Override
    +    @Deprecated
    +    public void acquireMutex(String mutexId, String description) throws RuntimeInterruptedException {
    +        try {
    +            mutexes().acquireMutex(mutexId, description);
    +        } catch (InterruptedException ie) {
    +            throw new RuntimeInterruptedException("Interrupted waiting for mutex: " + mutexId, ie);
    +        }
    +    }
    +
    +    /** @deprecated Mutex-related methods are now accessible via {@link #mutexes()} */
    +    @Override
    +    @Deprecated
    +    public boolean tryAcquireMutex(String mutexId, String description) {
    --- End diff --
    
    Agree.


---

[GitHub] brooklyn-server pull request #913: AbstractMachineLocation base class

Posted by alasdairhodge <gi...@git.apache.org>.
Github user alasdairhodge commented on a diff in the pull request:

    https://github.com/apache/brooklyn-server/pull/913#discussion_r156050830
  
    --- Diff: core/src/main/java/org/apache/brooklyn/core/location/AbstractMachineLocation.java ---
    @@ -0,0 +1,131 @@
    +/*
    + * 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.brooklyn.core.location;
    +
    +import java.util.Map;
    +
    +import org.apache.brooklyn.api.location.MachineDetails;
    +import org.apache.brooklyn.api.location.MachineLocation;
    +import org.apache.brooklyn.api.location.OsDetails;
    +import org.apache.brooklyn.config.ConfigKey;
    +import org.apache.brooklyn.core.config.ConfigKeys;
    +import org.apache.brooklyn.util.collections.MutableMap;
    +import org.apache.brooklyn.util.core.mutex.MutexSupport;
    +import org.apache.brooklyn.util.core.mutex.WithMutexes;
    +import org.apache.brooklyn.util.exceptions.RuntimeInterruptedException;
    +
    +import com.google.common.base.Optional;
    +
    +public abstract class AbstractMachineLocation extends AbstractLocation implements MachineLocation, WithMutexes {
    +
    +    public static final ConfigKey<MachineDetails> MACHINE_DETAILS = ConfigKeys.newConfigKey(
    +            MachineDetails.class,
    +            "machineDetails");
    +
    +    public static final ConfigKey<Boolean> DETECT_MACHINE_DETAILS = ConfigKeys.newBooleanConfigKey("detectMachineDetails",
    +            "Attempt to detect machine details automatically.", true);
    +
    +    protected static final MachineDetails UNKNOWN_MACHINE_DETAILS = new BasicMachineDetails(
    +            new BasicHardwareDetails(-1, -1),
    +            new BasicOsDetails("UNKNOWN", "UNKNOWN", "UNKNOWN")
    +    );
    +
    +    private volatile MachineDetails machineDetails;
    +    private final Object machineDetailsLock = new Object();
    +
    +    private transient WithMutexes mutexSupport;
    +    private transient final Object mutexSupportCreationLock = new Object();
    +
    +
    +    public AbstractMachineLocation() {
    +        this(MutableMap.of());
    +    }
    +
    +    public AbstractMachineLocation(Map<?,?> properties) {
    +        super(properties);
    +    }
    +
    +    /**
    +     * Returns the machine details only if they are already loaded, or available directly as
    +     * config.
    +     */
    +    protected Optional<MachineDetails> getOptionalMachineDetails() {
    +        MachineDetails result = machineDetails != null ? machineDetails : config().get(MACHINE_DETAILS);
    +        return Optional.fromNullable(result);
    +    }
    +
    +    @Override
    +    public MachineDetails getMachineDetails() {
    +        synchronized (machineDetailsLock) {
    +            if (machineDetails == null) {
    +                machineDetails = getConfig(MACHINE_DETAILS);
    +            }
    +            if (machineDetails == null) {
    +                boolean detectionEnabled = getConfig(DETECT_MACHINE_DETAILS);
    +                if (!detectionEnabled || !isManaged()) {
    +                    return UNKNOWN_MACHINE_DETAILS;
    +                }
    +                machineDetails = detectMachineDetails();
    +            }
    +            return machineDetails;
    +        }
    +    }
    +
    +    @Override
    +    public OsDetails getOsDetails() {
    +        return getMachineDetails().getOsDetails();
    +    }
    +
    +    protected abstract MachineDetails detectMachineDetails();
    +
    +    @Override
    +    public void acquireMutex(String mutexId, String description) throws RuntimeInterruptedException {
    --- End diff --
    
    Now done. Annoyingly, `WithMutexes.acquireMutex()` forces all callers to handle `InterruptedException`. IMO it'd be cleaner to throw an unchecked exception instead, but I appreciate that may be contentious. I've preserved calls to the now-deprecated `SshMachineLocation.acquireMutex()` until this is agreed.


---

[GitHub] brooklyn-server issue #913: AbstractMachineLocation base class

Posted by aledsage <gi...@git.apache.org>.
Github user aledsage commented on the issue:

    https://github.com/apache/brooklyn-server/pull/913
  
    Build failure is real:
    ```
    [ERROR] /home/jenkins/jenkins-slave/workspace/brooklyn-server-pull-requests/core/src/main/java/org/apache/brooklyn/location/localhost/LocalhostMachineProvisioningLocation.java:[284,8] error: method does not override or implement a method from a supertype
    ```
    This is for `@Override LocalhostMachineProvisioningLocation.getMutexSupport()`, I believe.


---