Migrate entity ownership to JDT annotations
[mdsal.git] / entityownership / mdsal-eos-common-api / src / main / java / org / opendaylight / mdsal / eos / common / api / GenericEntity.java
1 /*
2  * Copyright (c) 2015 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.mdsal.eos.common.api;
9
10 import static java.util.Objects.requireNonNull;
11
12 import java.io.Serializable;
13 import org.eclipse.jdt.annotation.NonNull;
14 import org.opendaylight.yangtools.concepts.Identifiable;
15 import org.opendaylight.yangtools.concepts.Path;
16
17 /**
18  * A clustered Entity is something which is shared by multiple applications across a cluster. An Entity has a type
19  * and an identifier.
20  *
21  * <p>
22  * The type describes the type of the Entity where examples of a type maybe "openflow" or "netconf"
23  * etc. An Entity type could be tied to how exactly an application shares and "owns" an entity. For example we may want
24  * an application which deals with the openflow entity to be assigned ownership of that entity based on a first come
25  * first served basis. On the other hand for netconf entity types we may want applications to gain ownership based on
26  * a load balancing approach. While this mechanism of assigning a ownership acquisition strategy is not finalized the
27  * intention is that the entity type will play a role in determining the strategy and thus should be put in place.
28  *
29  * <p>
30  * The identifier is an instance identifier path. The reason for the choice of instance identifier path is because it
31  * can easily be used to represent a data node. For example an inventory node represents a shared entity and it is best
32  * referenced by its instance identifier path if the inventory node is stored in the data store.
33  *
34  * <p>
35  * Note that an entity identifier must conform to a valid yang schema. If there is no existing yang schema to
36  * represent an entity, the general-entity yang model can be used.
37  *
38  * <p>
39  *
40  * @author Thomas Pantelis
41  *
42  * @param <T> the entity identifier type
43  */
44 public class GenericEntity<T extends Path<T>> implements Serializable, Identifiable<T> {
45     private static final long serialVersionUID = 1L;
46
47     private final @NonNull String type;
48     private final @NonNull T id;
49
50     protected GenericEntity(@NonNull final String type, @NonNull final T id) {
51         this.type = requireNonNull(type, "type should not be null");
52         this.id = requireNonNull(id, "id should not be null");
53     }
54
55     /**
56      * Gets the id of the entity.
57      * @return the id.
58      */
59     @Override
60     public final @NonNull T getIdentifier() {
61         return id;
62     }
63
64     /**
65      * Gets the type of the entity.
66      * @return the type.
67      */
68     public final @NonNull String getType() {
69         return type;
70     }
71
72     @SuppressWarnings("unchecked")
73     @Override
74     public boolean equals(final Object obj) {
75         if (this == obj) {
76             return true;
77         }
78
79         if (obj == null || getClass() != obj.getClass()) {
80             return false;
81         }
82
83         GenericEntity<T> entity = (GenericEntity<T>) obj;
84
85         if (!id.equals(entity.id)) {
86             return false;
87         }
88
89         if (!type.equals(entity.type)) {
90             return false;
91         }
92
93         return true;
94     }
95
96     @Override
97     public int hashCode() {
98         return 31 * type.hashCode() + id.hashCode();
99     }
100
101     @Override
102     public String toString() {
103         return getClass().getSimpleName() + " [type=" + type + ", id=" + id + "]";
104     }
105 }